Skip to content

Commit 28afb78

Browse files
committed
Allow customize http vhost config using HttpdCustomization.CustomConfigSecret
This change allows to customize the httpd vhost config using this parameter to specify a secret that contains service config data. The content of each provided snippet gets rendered as a go template and placed into /etc/httpd/conf/httpd_custom_<endpoint>_<key> . At the end of the vhost config in the default httpd template these custom configs get included using `Include conf/httpd_custom_<endpoint>_*`. For information on how sections in httpd configuration get merged, check section "How the sections are merged" in https://httpd.apache.org/docs/current/sections.html#merging All possible parameters which can be use in a template can be looked up in the <service>-config-data secret of the service like: $ oc get secret -n openstack designateapi-config-data -o json | jq -r .data.templatingParameters | base64 -d or in the running pod of the service in the file: $ cat /var/lib/config-data/default/templatingParameters The content is a versioned dump of the parameters of the service operator, like: ~~~ DatabaseConnection: mysql+pymysql://user:[email protected]/keystone?read_default_file=/etc/my.cnf KeystoneEndpointInternal: https://keystone-internal.openstack.svc:5000 KeystoneEndpointPublic: https://keystone-public-openstack.apps-crc.testing TransportURL: rabbit://user:[email protected]:5671/?ssl=1 VHosts: internal: Override: false SSLCertificateFile: /etc/pki/tls/certs/internal.crt SSLCertificateKeyFile: /etc/pki/tls/private/internal.key ServerName: designateapi-internal.openstack.svc TLS: true public: Override: false SSLCertificateFile: /etc/pki/tls/certs/public.crt SSLCertificateKeyFile: /etc/pki/tls/private/public.key ServerName: designateapi-public.openstack.svc TLS: true ... ~~~ Depends-On: openstack-k8s-operators/lib-common#591 Depends-On: openstack-k8s-operators/lib-common#593 Jira: https://issues.redhat.com/browse/OSPRH-13100 Signed-off-by: Martin Schuppert <[email protected]>
1 parent c44a879 commit 28afb78

21 files changed

+307
-44
lines changed

api/bases/designate.openstack.org_designateapis.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,20 @@ spec:
107107
But can also be used to add additional files. Those get added to the service config dir in /etc/<service> .
108108
TODO: -> implement
109109
type: object
110+
httpdCustomization:
111+
description: HttpdCustomization - customize the httpd service
112+
properties:
113+
customConfigSecret:
114+
description: |-
115+
CustomConfigSecret - customize the httpd vhost config using this parameter to specify
116+
a secret that contains service config data. The content of each provided snippet gets
117+
rendered as a go template and placed into /etc/httpd/conf/httpd_custom_<key> .
118+
In the default httpd template at the end of the vhost those custom configs get
119+
included using `Include conf/httpd_custom_<endpoint>_*`.
120+
For information on how sections in httpd configuration get merged, check section
121+
"How the sections are merged" in https://httpd.apache.org/docs/current/sections.html#merging
122+
type: string
123+
type: object
110124
networkAttachments:
111125
description: NetworkAttachments is a list of NetworkAttachment resource
112126
names to expose the services to the given network

api/bases/designate.openstack.org_designates.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,20 @@ spec:
154154
But can also be used to add additional files. Those get added to the service config dir in /etc/<service> .
155155
TODO: -> implement
156156
type: object
157+
httpdCustomization:
158+
description: HttpdCustomization - customize the httpd service
159+
properties:
160+
customConfigSecret:
161+
description: |-
162+
CustomConfigSecret - customize the httpd vhost config using this parameter to specify
163+
a secret that contains service config data. The content of each provided snippet gets
164+
rendered as a go template and placed into /etc/httpd/conf/httpd_custom_<key> .
165+
In the default httpd template at the end of the vhost those custom configs get
166+
included using `Include conf/httpd_custom_<endpoint>_*`.
167+
For information on how sections in httpd configuration get merged, check section
168+
"How the sections are merged" in https://httpd.apache.org/docs/current/sections.html#merging
169+
type: string
170+
type: object
157171
networkAttachments:
158172
description: NetworkAttachments is a list of NetworkAttachment
159173
resource names to expose the services to the given network

api/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ go 1.21
44

55
require (
66
github.com/onsi/ginkgo/v2 v2.20.1
7-
github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20241216113837-d172b3ac0f4e
7+
github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20250116145727-01a8948d5dd7
88
github.com/openstack-k8s-operators/lib-common/modules/storage v0.5.1-0.20241216113837-d172b3ac0f4e
99
k8s.io/api v0.29.10
1010
k8s.io/apimachinery v0.29.10

api/go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ github.com/onsi/ginkgo/v2 v2.20.1 h1:YlVIbqct+ZmnEph770q9Q7NVAz4wwIiVNahee6JyUzo
7272
github.com/onsi/ginkgo/v2 v2.20.1/go.mod h1:lG9ey2Z29hR41WMVthyJBGUBcBhGOtoPF2VFMvBXFCI=
7373
github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k=
7474
github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY=
75-
github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20241216113837-d172b3ac0f4e h1:hf4kVQBkyG79WcHBxdQ25QrDBbGFdarebS1Tc0Xclq4=
76-
github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20241216113837-d172b3ac0f4e/go.mod h1:YpNTuJhDWhbXM50O3qBkhO7M+OOyRmWkNVmJ4y3cyFs=
75+
github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20250116145727-01a8948d5dd7 h1:vXHpH93PjbAgg5ZN6n5WmxkybVQOs0nhXvVw62o7aZs=
76+
github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20250116145727-01a8948d5dd7/go.mod h1:YpNTuJhDWhbXM50O3qBkhO7M+OOyRmWkNVmJ4y3cyFs=
7777
github.com/openstack-k8s-operators/lib-common/modules/storage v0.5.1-0.20241216113837-d172b3ac0f4e h1:Qz0JFEoRDUyjEWorNY3LggwxTsmpMtQkcpmZDQulGHQ=
7878
github.com/openstack-k8s-operators/lib-common/modules/storage v0.5.1-0.20241216113837-d172b3ac0f4e/go.mod h1:tfgBeLRqmlH/NQkLPe7396rj+t0whv2wPuMb8Ttvh8w=
7979
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=

api/v1beta1/designateapi_types.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ type DesignateAPISpecBase struct {
8282
// +kubebuilder:validation:Optional
8383
// APITimeout for HAProxy and Apache defaults to DesignateSpecCore APITimeout (seconds)
8484
APITimeout int `json:"apiTimeout"`
85+
86+
// +kubebuilder:validation:Optional
87+
// HttpdCustomization - customize the httpd service
88+
HttpdCustomization HttpdCustomization `json:"httpdCustomization,omitempty"`
8589
}
8690

8791
// APIOverrideSpec to override the generated manifest of several child resources.
@@ -91,6 +95,19 @@ type APIOverrideSpec struct {
9195
Service map[service.Endpoint]service.RoutedOverrideSpec `json:"service,omitempty"`
9296
}
9397

98+
// HttpdCustomization - customize the httpd service
99+
type HttpdCustomization struct {
100+
// +kubebuilder:validation:Optional
101+
// CustomConfigSecret - customize the httpd vhost config using this parameter to specify
102+
// a secret that contains service config data. The content of each provided snippet gets
103+
// rendered as a go template and placed into /etc/httpd/conf/httpd_custom_<key> .
104+
// In the default httpd template at the end of the vhost those custom configs get
105+
// included using `Include conf/httpd_custom_<endpoint>_*`.
106+
// For information on how sections in httpd configuration get merged, check section
107+
// "How the sections are merged" in https://httpd.apache.org/docs/current/sections.html#merging
108+
CustomConfigSecret *string `json:"customConfigSecret,omitempty"`
109+
}
110+
94111
// DesignateAPIStatus defines the observed state of DesignateAPI
95112
type DesignateAPIStatus struct {
96113
// Map of hashes to track e.g. job status

api/v1beta1/zz_generated.deepcopy.go

Lines changed: 21 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/crd/bases/designate.openstack.org_designateapis.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,20 @@ spec:
107107
But can also be used to add additional files. Those get added to the service config dir in /etc/<service> .
108108
TODO: -> implement
109109
type: object
110+
httpdCustomization:
111+
description: HttpdCustomization - customize the httpd service
112+
properties:
113+
customConfigSecret:
114+
description: |-
115+
CustomConfigSecret - customize the httpd vhost config using this parameter to specify
116+
a secret that contains service config data. The content of each provided snippet gets
117+
rendered as a go template and placed into /etc/httpd/conf/httpd_custom_<key> .
118+
In the default httpd template at the end of the vhost those custom configs get
119+
included using `Include conf/httpd_custom_<endpoint>_*`.
120+
For information on how sections in httpd configuration get merged, check section
121+
"How the sections are merged" in https://httpd.apache.org/docs/current/sections.html#merging
122+
type: string
123+
type: object
110124
networkAttachments:
111125
description: NetworkAttachments is a list of NetworkAttachment resource
112126
names to expose the services to the given network

config/crd/bases/designate.openstack.org_designates.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,20 @@ spec:
154154
But can also be used to add additional files. Those get added to the service config dir in /etc/<service> .
155155
TODO: -> implement
156156
type: object
157+
httpdCustomization:
158+
description: HttpdCustomization - customize the httpd service
159+
properties:
160+
customConfigSecret:
161+
description: |-
162+
CustomConfigSecret - customize the httpd vhost config using this parameter to specify
163+
a secret that contains service config data. The content of each provided snippet gets
164+
rendered as a go template and placed into /etc/httpd/conf/httpd_custom_<key> .
165+
In the default httpd template at the end of the vhost those custom configs get
166+
included using `Include conf/httpd_custom_<endpoint>_*`.
167+
For information on how sections in httpd configuration get merged, check section
168+
"How the sections are merged" in https://httpd.apache.org/docs/current/sections.html#merging
169+
type: string
170+
type: object
157171
networkAttachments:
158172
description: NetworkAttachments is a list of NetworkAttachment
159173
resource names to expose the services to the given network

controllers/designate_controller.go

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"sort"
2323
"time"
2424

25+
"gopkg.in/yaml.v2"
2526
k8s_errors "k8s.io/apimachinery/pkg/api/errors"
2627
"k8s.io/apimachinery/pkg/runtime"
2728
"k8s.io/apimachinery/pkg/types"
@@ -231,10 +232,11 @@ func (r *DesignateReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
231232

232233
// fields to index to reconcile when change
233234
const (
234-
passwordSecretField = ".spec.secret"
235-
caBundleSecretNameField = ".spec.tls.caBundleSecretName"
236-
tlsAPIInternalField = ".spec.tls.api.internal.secretName"
237-
tlsAPIPublicField = ".spec.tls.api.public.secretName"
235+
passwordSecretField = ".spec.secret"
236+
caBundleSecretNameField = ".spec.tls.caBundleSecretName"
237+
tlsAPIInternalField = ".spec.tls.api.internal.secretName"
238+
tlsAPIPublicField = ".spec.tls.api.public.secretName"
239+
httpdCustomServiceConfigSecretField = ".spec.httpdCustomization.customServiceConfigSecret"
238240
)
239241

240242
// SetupWithManager sets up the controller with the Manager.
@@ -1372,6 +1374,13 @@ func (r *DesignateReconciler) generateServiceConfigMaps(
13721374
}
13731375
templateParameters["AdminPassword"] = string(adminPasswordSecret.Data["DesignatePassword"])
13741376

1377+
// Marshal the templateParameters map to YAML
1378+
yamlData, err := yaml.Marshal(templateParameters)
1379+
if err != nil {
1380+
return fmt.Errorf("Error marshalling to YAML: %w", err)
1381+
}
1382+
customData[common.TemplateParameters] = string(yamlData)
1383+
13751384
cms := []util.Template{
13761385
// ScriptsConfigMap
13771386
{

controllers/designateapi_controller.go

Lines changed: 48 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"fmt"
2323
"time"
2424

25+
"gopkg.in/yaml.v2"
2526
appsv1 "k8s.io/api/apps/v1"
2627
corev1 "k8s.io/api/core/v1"
2728
k8s_errors "k8s.io/apimachinery/pkg/api/errors"
@@ -268,6 +269,18 @@ func (r *DesignateAPIReconciler) SetupWithManager(ctx context.Context, mgr ctrl.
268269
return err
269270
}
270271

272+
// index httpdOverrideSecretField
273+
if err := mgr.GetFieldIndexer().IndexField(ctx, &designatev1beta1.DesignateAPI{}, httpdCustomServiceConfigSecretField, func(rawObj client.Object) []string {
274+
// Extract the secret name from the spec, if one is provided
275+
cr := rawObj.(*designatev1beta1.DesignateAPI)
276+
if cr.Spec.HttpdCustomization.CustomConfigSecret == nil {
277+
return nil
278+
}
279+
return []string{*cr.Spec.HttpdCustomization.CustomConfigSecret}
280+
}); err != nil {
281+
return err
282+
}
283+
271284
svcSecretFn := func(ctx context.Context, o client.Object) []reconcile.Request {
272285
var namespace string = o.GetNamespace()
273286
var secretName string = o.GetName()
@@ -363,6 +376,7 @@ func (r *DesignateAPIReconciler) findObjectsForSrc(ctx context.Context, src clie
363376
caBundleSecretNameField,
364377
tlsAPIInternalField,
365378
tlsAPIPublicField,
379+
httpdCustomServiceConfigSecretField,
366380
}
367381

368382
for _, field := range allWatchFields {
@@ -1070,6 +1084,14 @@ func (r *DesignateAPIReconciler) generateServiceConfigMaps(
10701084
return err
10711085
}
10721086

1087+
httpdOverrideSecret := &corev1.Secret{}
1088+
if instance.Spec.HttpdCustomization.CustomConfigSecret != nil && *instance.Spec.HttpdCustomization.CustomConfigSecret != "" {
1089+
httpdOverrideSecret, _, err = oko_secret.GetSecret(ctx, h, *instance.Spec.HttpdCustomization.CustomConfigSecret, instance.Namespace)
1090+
if err != nil {
1091+
return err
1092+
}
1093+
}
1094+
10731095
customData[common.CustomServiceConfigFileName] = instance.Spec.CustomServiceConfig
10741096

10751097
databaseAccount, dbSecret, err := mariadbv1.GetAccountAndSecret(
@@ -1105,6 +1127,7 @@ func (r *DesignateAPIReconciler) generateServiceConfigMaps(
11051127
templateParameters["TimeOut"] = instance.Spec.APITimeout
11061128

11071129
// create httpd vhost template parameters
1130+
customTemplates := map[string]string{}
11081131
httpdVhostConfig := map[string]interface{}{}
11091132
for _, endpt := range []service.Endpoint{service.EndpointInternal, service.EndpointPublic} {
11101133
endptConfig := map[string]interface{}{}
@@ -1115,6 +1138,16 @@ func (r *DesignateAPIReconciler) generateServiceConfigMaps(
11151138
endptConfig["SSLCertificateFile"] = fmt.Sprintf("/etc/pki/tls/certs/%s.crt", endpt.String())
11161139
endptConfig["SSLCertificateKeyFile"] = fmt.Sprintf("/etc/pki/tls/private/%s.key", endpt.String())
11171140
}
1141+
1142+
endptConfig["Override"] = false
1143+
if len(httpdOverrideSecret.Data) > 0 {
1144+
endptConfig["Override"] = true
1145+
for key, data := range httpdOverrideSecret.Data {
1146+
if len(data) > 0 {
1147+
customTemplates["httpd_custom_"+endpt.String()+"_"+key] = string(data)
1148+
}
1149+
}
1150+
}
11181151
httpdVhostConfig[endpt.String()] = endptConfig
11191152
}
11201153
templateParameters["VHosts"] = httpdVhostConfig
@@ -1161,6 +1194,13 @@ func (r *DesignateAPIReconciler) generateServiceConfigMaps(
11611194
}
11621195
templateParameters["AdminPassword"] = string(adminPasswordSecret.Data["DesignatePassword"])
11631196

1197+
// Marshal the templateParameters map to YAML
1198+
yamlData, err := yaml.Marshal(templateParameters)
1199+
if err != nil {
1200+
return fmt.Errorf("Error marshalling to YAML: %w", err)
1201+
}
1202+
customData[common.TemplateParameters] = string(yamlData)
1203+
11641204
cms := []util.Template{
11651205
// ScriptsConfigMap
11661206
{
@@ -1173,13 +1213,14 @@ func (r *DesignateAPIReconciler) generateServiceConfigMaps(
11731213
},
11741214
// Custom ConfigMap
11751215
{
1176-
Name: fmt.Sprintf("%s-config-data", instance.Name),
1177-
Namespace: instance.Namespace,
1178-
Type: util.TemplateTypeConfig,
1179-
InstanceType: instance.Kind,
1180-
CustomData: customData,
1181-
ConfigOptions: templateParameters,
1182-
Labels: cmLabels,
1216+
Name: fmt.Sprintf("%s-config-data", instance.Name),
1217+
Namespace: instance.Namespace,
1218+
Type: util.TemplateTypeConfig,
1219+
InstanceType: instance.Kind,
1220+
CustomData: customData,
1221+
ConfigOptions: templateParameters,
1222+
StringTemplate: customTemplates,
1223+
Labels: cmLabels,
11831224
},
11841225
}
11851226

0 commit comments

Comments
 (0)