diff --git a/api/bases/designate.openstack.org_designateapis.yaml b/api/bases/designate.openstack.org_designateapis.yaml index 8dee9f35..7c4bb441 100644 --- a/api/bases/designate.openstack.org_designateapis.yaml +++ b/api/bases/designate.openstack.org_designateapis.yaml @@ -107,6 +107,20 @@ spec: But can also be used to add additional files. Those get added to the service config dir in /etc/ . TODO: -> implement type: object + httpdCustomization: + description: HttpdCustomization - customize the httpd service + properties: + customConfigSecret: + description: |- + CustomConfigSecret - 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_ . + In the default httpd template at the end of the vhost those custom configs get + included using `Include conf/httpd_custom__*`. + 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 + type: string + type: object networkAttachments: description: NetworkAttachments is a list of NetworkAttachment resource names to expose the services to the given network diff --git a/api/bases/designate.openstack.org_designates.yaml b/api/bases/designate.openstack.org_designates.yaml index 34cbe347..c9cd51df 100644 --- a/api/bases/designate.openstack.org_designates.yaml +++ b/api/bases/designate.openstack.org_designates.yaml @@ -154,6 +154,20 @@ spec: But can also be used to add additional files. Those get added to the service config dir in /etc/ . TODO: -> implement type: object + httpdCustomization: + description: HttpdCustomization - customize the httpd service + properties: + customConfigSecret: + description: |- + CustomConfigSecret - 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_ . + In the default httpd template at the end of the vhost those custom configs get + included using `Include conf/httpd_custom__*`. + 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 + type: string + type: object networkAttachments: description: NetworkAttachments is a list of NetworkAttachment resource names to expose the services to the given network diff --git a/api/go.mod b/api/go.mod index c7c1bab2..64479fd2 100644 --- a/api/go.mod +++ b/api/go.mod @@ -4,7 +4,7 @@ go 1.21 require ( github.com/onsi/ginkgo/v2 v2.20.1 - github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20241216113837-d172b3ac0f4e + github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20250116145727-01a8948d5dd7 github.com/openstack-k8s-operators/lib-common/modules/storage v0.5.1-0.20241216113837-d172b3ac0f4e k8s.io/api v0.29.10 k8s.io/apimachinery v0.29.10 diff --git a/api/go.sum b/api/go.sum index 71bb6777..4fb93881 100644 --- a/api/go.sum +++ b/api/go.sum @@ -72,8 +72,8 @@ github.com/onsi/ginkgo/v2 v2.20.1 h1:YlVIbqct+ZmnEph770q9Q7NVAz4wwIiVNahee6JyUzo github.com/onsi/ginkgo/v2 v2.20.1/go.mod h1:lG9ey2Z29hR41WMVthyJBGUBcBhGOtoPF2VFMvBXFCI= github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= -github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20241216113837-d172b3ac0f4e h1:hf4kVQBkyG79WcHBxdQ25QrDBbGFdarebS1Tc0Xclq4= -github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20241216113837-d172b3ac0f4e/go.mod h1:YpNTuJhDWhbXM50O3qBkhO7M+OOyRmWkNVmJ4y3cyFs= +github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20250116145727-01a8948d5dd7 h1:vXHpH93PjbAgg5ZN6n5WmxkybVQOs0nhXvVw62o7aZs= +github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20250116145727-01a8948d5dd7/go.mod h1:YpNTuJhDWhbXM50O3qBkhO7M+OOyRmWkNVmJ4y3cyFs= github.com/openstack-k8s-operators/lib-common/modules/storage v0.5.1-0.20241216113837-d172b3ac0f4e h1:Qz0JFEoRDUyjEWorNY3LggwxTsmpMtQkcpmZDQulGHQ= github.com/openstack-k8s-operators/lib-common/modules/storage v0.5.1-0.20241216113837-d172b3ac0f4e/go.mod h1:tfgBeLRqmlH/NQkLPe7396rj+t0whv2wPuMb8Ttvh8w= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= diff --git a/api/v1beta1/designateapi_types.go b/api/v1beta1/designateapi_types.go index 94251f12..8364fff0 100644 --- a/api/v1beta1/designateapi_types.go +++ b/api/v1beta1/designateapi_types.go @@ -82,6 +82,10 @@ type DesignateAPISpecBase struct { // +kubebuilder:validation:Optional // APITimeout for HAProxy and Apache defaults to DesignateSpecCore APITimeout (seconds) APITimeout int `json:"apiTimeout"` + + // +kubebuilder:validation:Optional + // HttpdCustomization - customize the httpd service + HttpdCustomization HttpdCustomization `json:"httpdCustomization,omitempty"` } // APIOverrideSpec to override the generated manifest of several child resources. @@ -91,6 +95,19 @@ type APIOverrideSpec struct { Service map[service.Endpoint]service.RoutedOverrideSpec `json:"service,omitempty"` } +// HttpdCustomization - customize the httpd service +type HttpdCustomization struct { + // +kubebuilder:validation:Optional + // CustomConfigSecret - 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_ . + // In the default httpd template at the end of the vhost those custom configs get + // included using `Include conf/httpd_custom__*`. + // 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 + CustomConfigSecret *string `json:"customConfigSecret,omitempty"` +} + // DesignateAPIStatus defines the observed state of DesignateAPI type DesignateAPIStatus struct { // Map of hashes to track e.g. job status diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go index f2f0e5da..bb9de23b 100644 --- a/api/v1beta1/zz_generated.deepcopy.go +++ b/api/v1beta1/zz_generated.deepcopy.go @@ -163,6 +163,7 @@ func (in *DesignateAPISpecBase) DeepCopyInto(out *DesignateAPISpecBase) { } in.Override.DeepCopyInto(&out.Override) in.TLS.DeepCopyInto(&out.TLS) + in.HttpdCustomization.DeepCopyInto(&out.HttpdCustomization) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DesignateAPISpecBase. @@ -1510,6 +1511,26 @@ func (in *DesignateWorkerStatus) DeepCopy() *DesignateWorkerStatus { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HttpdCustomization) DeepCopyInto(out *HttpdCustomization) { + *out = *in + if in.CustomConfigSecret != nil { + in, out := &in.CustomConfigSecret, &out.CustomConfigSecret + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HttpdCustomization. +func (in *HttpdCustomization) DeepCopy() *HttpdCustomization { + if in == nil { + return nil + } + out := new(HttpdCustomization) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *PasswordSelector) DeepCopyInto(out *PasswordSelector) { *out = *in diff --git a/config/crd/bases/designate.openstack.org_designateapis.yaml b/config/crd/bases/designate.openstack.org_designateapis.yaml index 8dee9f35..7c4bb441 100644 --- a/config/crd/bases/designate.openstack.org_designateapis.yaml +++ b/config/crd/bases/designate.openstack.org_designateapis.yaml @@ -107,6 +107,20 @@ spec: But can also be used to add additional files. Those get added to the service config dir in /etc/ . TODO: -> implement type: object + httpdCustomization: + description: HttpdCustomization - customize the httpd service + properties: + customConfigSecret: + description: |- + CustomConfigSecret - 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_ . + In the default httpd template at the end of the vhost those custom configs get + included using `Include conf/httpd_custom__*`. + 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 + type: string + type: object networkAttachments: description: NetworkAttachments is a list of NetworkAttachment resource names to expose the services to the given network diff --git a/config/crd/bases/designate.openstack.org_designates.yaml b/config/crd/bases/designate.openstack.org_designates.yaml index 34cbe347..c9cd51df 100644 --- a/config/crd/bases/designate.openstack.org_designates.yaml +++ b/config/crd/bases/designate.openstack.org_designates.yaml @@ -154,6 +154,20 @@ spec: But can also be used to add additional files. Those get added to the service config dir in /etc/ . TODO: -> implement type: object + httpdCustomization: + description: HttpdCustomization - customize the httpd service + properties: + customConfigSecret: + description: |- + CustomConfigSecret - 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_ . + In the default httpd template at the end of the vhost those custom configs get + included using `Include conf/httpd_custom__*`. + 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 + type: string + type: object networkAttachments: description: NetworkAttachments is a list of NetworkAttachment resource names to expose the services to the given network diff --git a/controllers/designate_controller.go b/controllers/designate_controller.go index 9f8c1211..869201d7 100644 --- a/controllers/designate_controller.go +++ b/controllers/designate_controller.go @@ -22,6 +22,7 @@ import ( "sort" "time" + "gopkg.in/yaml.v2" k8s_errors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" @@ -231,10 +232,11 @@ func (r *DesignateReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( // fields to index to reconcile when change const ( - passwordSecretField = ".spec.secret" - caBundleSecretNameField = ".spec.tls.caBundleSecretName" - tlsAPIInternalField = ".spec.tls.api.internal.secretName" - tlsAPIPublicField = ".spec.tls.api.public.secretName" + passwordSecretField = ".spec.secret" + caBundleSecretNameField = ".spec.tls.caBundleSecretName" + tlsAPIInternalField = ".spec.tls.api.internal.secretName" + tlsAPIPublicField = ".spec.tls.api.public.secretName" + httpdCustomServiceConfigSecretField = ".spec.httpdCustomization.customServiceConfigSecret" ) // SetupWithManager sets up the controller with the Manager. @@ -1402,6 +1404,13 @@ func (r *DesignateReconciler) generateServiceConfigMaps( } templateParameters["AdminPassword"] = string(adminPasswordSecret.Data["DesignatePassword"]) + // Marshal the templateParameters map to YAML + yamlData, err := yaml.Marshal(templateParameters) + if err != nil { + return fmt.Errorf("Error marshalling to YAML: %w", err) + } + customData[common.TemplateParameters] = string(yamlData) + cms := []util.Template{ // ScriptsConfigMap { diff --git a/controllers/designateapi_controller.go b/controllers/designateapi_controller.go index c18ab7af..d88f17ad 100644 --- a/controllers/designateapi_controller.go +++ b/controllers/designateapi_controller.go @@ -22,6 +22,7 @@ import ( "fmt" "time" + "gopkg.in/yaml.v2" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" k8s_errors "k8s.io/apimachinery/pkg/api/errors" @@ -268,6 +269,18 @@ func (r *DesignateAPIReconciler) SetupWithManager(ctx context.Context, mgr ctrl. return err } + // index httpdOverrideSecretField + if err := mgr.GetFieldIndexer().IndexField(ctx, &designatev1beta1.DesignateAPI{}, httpdCustomServiceConfigSecretField, func(rawObj client.Object) []string { + // Extract the secret name from the spec, if one is provided + cr := rawObj.(*designatev1beta1.DesignateAPI) + if cr.Spec.HttpdCustomization.CustomConfigSecret == nil { + return nil + } + return []string{*cr.Spec.HttpdCustomization.CustomConfigSecret} + }); err != nil { + return err + } + svcSecretFn := func(ctx context.Context, o client.Object) []reconcile.Request { var namespace string = o.GetNamespace() var secretName string = o.GetName() @@ -363,6 +376,7 @@ func (r *DesignateAPIReconciler) findObjectsForSrc(ctx context.Context, src clie caBundleSecretNameField, tlsAPIInternalField, tlsAPIPublicField, + httpdCustomServiceConfigSecretField, } for _, field := range allWatchFields { @@ -1070,6 +1084,14 @@ func (r *DesignateAPIReconciler) generateServiceConfigMaps( return err } + httpdOverrideSecret := &corev1.Secret{} + if instance.Spec.HttpdCustomization.CustomConfigSecret != nil && *instance.Spec.HttpdCustomization.CustomConfigSecret != "" { + httpdOverrideSecret, _, err = oko_secret.GetSecret(ctx, h, *instance.Spec.HttpdCustomization.CustomConfigSecret, instance.Namespace) + if err != nil { + return err + } + } + customData[common.CustomServiceConfigFileName] = instance.Spec.CustomServiceConfig databaseAccount, dbSecret, err := mariadbv1.GetAccountAndSecret( @@ -1105,6 +1127,7 @@ func (r *DesignateAPIReconciler) generateServiceConfigMaps( templateParameters["TimeOut"] = instance.Spec.APITimeout // create httpd vhost template parameters + customTemplates := map[string]string{} httpdVhostConfig := map[string]interface{}{} for _, endpt := range []service.Endpoint{service.EndpointInternal, service.EndpointPublic} { endptConfig := map[string]interface{}{} @@ -1115,6 +1138,16 @@ func (r *DesignateAPIReconciler) generateServiceConfigMaps( endptConfig["SSLCertificateFile"] = fmt.Sprintf("/etc/pki/tls/certs/%s.crt", endpt.String()) endptConfig["SSLCertificateKeyFile"] = fmt.Sprintf("/etc/pki/tls/private/%s.key", endpt.String()) } + + endptConfig["Override"] = false + if len(httpdOverrideSecret.Data) > 0 { + endptConfig["Override"] = true + for key, data := range httpdOverrideSecret.Data { + if len(data) > 0 { + customTemplates["httpd_custom_"+endpt.String()+"_"+key] = string(data) + } + } + } httpdVhostConfig[endpt.String()] = endptConfig } templateParameters["VHosts"] = httpdVhostConfig @@ -1161,6 +1194,13 @@ func (r *DesignateAPIReconciler) generateServiceConfigMaps( } templateParameters["AdminPassword"] = string(adminPasswordSecret.Data["DesignatePassword"]) + // Marshal the templateParameters map to YAML + yamlData, err := yaml.Marshal(templateParameters) + if err != nil { + return fmt.Errorf("Error marshalling to YAML: %w", err) + } + customData[common.TemplateParameters] = string(yamlData) + cms := []util.Template{ // ScriptsConfigMap { @@ -1173,13 +1213,14 @@ func (r *DesignateAPIReconciler) generateServiceConfigMaps( }, // Custom ConfigMap { - Name: fmt.Sprintf("%s-config-data", instance.Name), - Namespace: instance.Namespace, - Type: util.TemplateTypeConfig, - InstanceType: instance.Kind, - CustomData: customData, - ConfigOptions: templateParameters, - Labels: cmLabels, + Name: fmt.Sprintf("%s-config-data", instance.Name), + Namespace: instance.Namespace, + Type: util.TemplateTypeConfig, + InstanceType: instance.Kind, + CustomData: customData, + ConfigOptions: templateParameters, + StringTemplate: customTemplates, + Labels: cmLabels, }, } diff --git a/controllers/designatebackendbind9_controller.go b/controllers/designatebackendbind9_controller.go index f6d2252f..41227372 100644 --- a/controllers/designatebackendbind9_controller.go +++ b/controllers/designatebackendbind9_controller.go @@ -20,6 +20,7 @@ import ( "fmt" "time" + "gopkg.in/yaml.v2" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" k8s_errors "k8s.io/apimachinery/pkg/api/errors" @@ -721,6 +722,13 @@ func (r *DesignateBackendbind9Reconciler) generateServiceConfigMaps( // TODO: we need the rndc key value and pod addr but those are going to be supplied by the init container and // information mounted into the init container. + // Marshal the templateParameters map to YAML + yamlData, err := yaml.Marshal(templateParameters) + if err != nil { + return fmt.Errorf("Error marshalling to YAML: %w", err) + } + customData[common.TemplateParameters] = string(yamlData) + cms := []util.Template{ // ScriptsConfigMap { diff --git a/controllers/designatecentral_controller.go b/controllers/designatecentral_controller.go index b3aecf60..b992fe1a 100644 --- a/controllers/designatecentral_controller.go +++ b/controllers/designatecentral_controller.go @@ -22,6 +22,7 @@ import ( "fmt" "time" + "gopkg.in/yaml.v2" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" k8s_errors "k8s.io/apimachinery/pkg/api/errors" @@ -814,6 +815,13 @@ func (r *DesignateCentralReconciler) generateServiceConfigMaps( templateParameters["TransportURL"] = string(transportURLSecret.Data["transport_url"]) templateParameters["ServiceUser"] = instance.Spec.ServiceUser + // Marshal the templateParameters map to YAML + yamlData, err := yaml.Marshal(templateParameters) + if err != nil { + return fmt.Errorf("Error marshalling to YAML: %w", err) + } + customData[common.TemplateParameters] = string(yamlData) + cms := []util.Template{ // ScriptsConfigMap { diff --git a/controllers/designatemdns_controller.go b/controllers/designatemdns_controller.go index 34d180f9..1f7afb3c 100644 --- a/controllers/designatemdns_controller.go +++ b/controllers/designatemdns_controller.go @@ -21,6 +21,7 @@ import ( "fmt" "time" + "gopkg.in/yaml.v2" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" k8s_errors "k8s.io/apimachinery/pkg/api/errors" @@ -845,6 +846,13 @@ func (r *DesignateMdnsReconciler) generateServiceConfigMaps( } templateParameters["TransportURL"] = string(transportURLSecret.Data["transport_url"]) + // Marshal the templateParameters map to YAML + yamlData, err := yaml.Marshal(templateParameters) + if err != nil { + return fmt.Errorf("Error marshalling to YAML: %w", err) + } + customData[common.TemplateParameters] = string(yamlData) + cms := []util.Template{ // ScriptsConfigMap { diff --git a/controllers/designateproducer_controller.go b/controllers/designateproducer_controller.go index 0933f15a..333f9ca3 100644 --- a/controllers/designateproducer_controller.go +++ b/controllers/designateproducer_controller.go @@ -38,6 +38,7 @@ import ( "github.com/openstack-k8s-operators/lib-common/modules/common/tls" "github.com/openstack-k8s-operators/lib-common/modules/common/util" mariadbv1 "github.com/openstack-k8s-operators/mariadb-operator/api/v1beta1" + "gopkg.in/yaml.v2" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" k8s_errors "k8s.io/apimachinery/pkg/api/errors" @@ -814,6 +815,13 @@ func (r *DesignateProducerReconciler) generateServiceConfigMaps( templateParameters["TransportURL"] = string(transportURLSecret.Data["transport_url"]) templateParameters["ServiceUser"] = instance.Spec.ServiceUser + // Marshal the templateParameters map to YAML + yamlData, err := yaml.Marshal(templateParameters) + if err != nil { + return fmt.Errorf("Error marshalling to YAML: %w", err) + } + customData[common.TemplateParameters] = string(yamlData) + cms := []util.Template{ // ScriptsConfigMap { diff --git a/controllers/designateunbound_controller.go b/controllers/designateunbound_controller.go index 50845ad9..70a8540c 100644 --- a/controllers/designateunbound_controller.go +++ b/controllers/designateunbound_controller.go @@ -25,6 +25,7 @@ import ( networkv1 "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1" designatev1 "github.com/openstack-k8s-operators/designate-operator/api/v1beta1" "github.com/openstack-k8s-operators/designate-operator/pkg/designateunbound" + "gopkg.in/yaml.v2" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" k8s_errors "k8s.io/apimachinery/pkg/api/errors" @@ -426,6 +427,13 @@ func (r *UnboundReconciler) generateServiceConfigMaps( templateParameters["ListenIP"] = "0.0.0.0" templateParameters["ExternalNetCidr"] = "0.0.0.0/0" + // Marshal the templateParameters map to YAML + yamlData, err := yaml.Marshal(templateParameters) + if err != nil { + return fmt.Errorf("Error marshalling to YAML: %w", err) + } + customData[common.TemplateParameters] = string(yamlData) + cms := []util.Template{ // ScriptsConfigMap { @@ -447,7 +455,7 @@ func (r *UnboundReconciler) generateServiceConfigMaps( Labels: cmLabels, }, } - err := secret.EnsureSecrets(ctx, h, instance, cms, envVars) + err = secret.EnsureSecrets(ctx, h, instance, cms, envVars) if err != nil { r.Log.Error(err, "uanble to process config map") diff --git a/controllers/designateworker_controller.go b/controllers/designateworker_controller.go index 8b986b00..e7ed724f 100644 --- a/controllers/designateworker_controller.go +++ b/controllers/designateworker_controller.go @@ -21,6 +21,7 @@ import ( "fmt" "time" + "gopkg.in/yaml.v2" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" k8s_errors "k8s.io/apimachinery/pkg/api/errors" @@ -779,6 +780,13 @@ func (r *DesignateWorkerReconciler) generateServiceConfigMaps( ), } + // Marshal the templateParameters map to YAML + yamlData, err := yaml.Marshal(templateParameters) + if err != nil { + return fmt.Errorf("Error marshalling to YAML: %w", err) + } + customData[common.TemplateParameters] = string(yamlData) + cms := []util.Template{ // ScriptsConfigMap { diff --git a/go.mod b/go.mod index 63c678a3..55f50107 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/openstack-k8s-operators/designate-operator/api v0.1.1-0.20240807132522-6c2eca7c6bbb github.com/openstack-k8s-operators/infra-operator/apis v0.5.1-0.20241213080025-18e54a028c8b github.com/openstack-k8s-operators/keystone-operator/api v0.5.1-0.20241212135809-dc78e7221d12 - github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20241216113837-d172b3ac0f4e + github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20250116145727-01a8948d5dd7 github.com/openstack-k8s-operators/lib-common/modules/test v0.5.1-0.20241029151503-4878b3fa3333 github.com/openstack-k8s-operators/mariadb-operator/api v0.5.1-0.20241212160155-4e7d8f749820 gopkg.in/yaml.v2 v2.4.0 diff --git a/go.sum b/go.sum index a15715d4..c6a2728e 100644 --- a/go.sum +++ b/go.sum @@ -94,8 +94,8 @@ github.com/openstack-k8s-operators/infra-operator/apis v0.5.1-0.20241213080025-1 github.com/openstack-k8s-operators/infra-operator/apis v0.5.1-0.20241213080025-18e54a028c8b/go.mod h1:SSYBbFbgQbOwyY2cQNet7fSdQHHPb2rLo6GXE97Awp8= github.com/openstack-k8s-operators/keystone-operator/api v0.5.1-0.20241212135809-dc78e7221d12 h1:37tN4oVifWqkerafFrx3DFDDTOOzn2H+c67WIQ1Vkss= github.com/openstack-k8s-operators/keystone-operator/api v0.5.1-0.20241212135809-dc78e7221d12/go.mod h1:AZhHY6dZzGyG9iVOf1poD7pTS9c7ZG/f99Fg+GdFVEk= -github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20241216113837-d172b3ac0f4e h1:hf4kVQBkyG79WcHBxdQ25QrDBbGFdarebS1Tc0Xclq4= -github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20241216113837-d172b3ac0f4e/go.mod h1:YpNTuJhDWhbXM50O3qBkhO7M+OOyRmWkNVmJ4y3cyFs= +github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20250116145727-01a8948d5dd7 h1:vXHpH93PjbAgg5ZN6n5WmxkybVQOs0nhXvVw62o7aZs= +github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20250116145727-01a8948d5dd7/go.mod h1:YpNTuJhDWhbXM50O3qBkhO7M+OOyRmWkNVmJ4y3cyFs= github.com/openstack-k8s-operators/lib-common/modules/openstack v0.5.1-0.20241216113837-d172b3ac0f4e h1:HFo4OqPY0x4ZQeaWI2YGonTXAGTQFt+rOEJlfZVhS7s= github.com/openstack-k8s-operators/lib-common/modules/openstack v0.5.1-0.20241216113837-d172b3ac0f4e/go.mod h1:IASoGvp5QM/tBJUd/8i8uIjj4DBnI+64Ydh4r7pmnvA= github.com/openstack-k8s-operators/lib-common/modules/storage v0.5.1-0.20241216113837-d172b3ac0f4e h1:Qz0JFEoRDUyjEWorNY3LggwxTsmpMtQkcpmZDQulGHQ= diff --git a/templates/designateapi/config/designate-api-config.json b/templates/designateapi/config/designate-api-config.json index fa284a3c..4da4f7b1 100644 --- a/templates/designateapi/config/designate-api-config.json +++ b/templates/designateapi/config/designate-api-config.json @@ -46,6 +46,13 @@ "perm": "0400", "optional": true, "merge": true + }, + { + "source": "/var/lib/config-data/default/httpd_custom_*", + "dest": "/etc/httpd/conf/", + "owner": "apache", + "perm": "0444", + "optional": true } ], "permissions": [ diff --git a/templates/designateapi/config/httpd.conf b/templates/designateapi/config/httpd.conf index 0c05e506..45cb9c02 100644 --- a/templates/designateapi/config/httpd.conf +++ b/templates/designateapi/config/httpd.conf @@ -26,31 +26,36 @@ CustomLog /dev/stdout proxy env=forwarded TimeOut {{ $.TimeOut }} {{ range $endpt, $vhost := .VHosts }} - # {{ $endpt }} vhost {{ $vhost.ServerName }} configuration - - ServerName {{ $vhost.ServerName }} - = 2.4> - ErrorLogFormat "%M" - - ErrorLog /dev/stdout - SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded - CustomLog /dev/stdout combined env=!forwarded - CustomLog /dev/stdout proxy env=forwarded - - {{- if $vhost.TLS }} - SetEnvIf X-Forwarded-Proto https HTTPS=1 - - ## SSL directives - SSLEngine on - SSLCertificateFile "{{ $vhost.SSLCertificateFile }}" - SSLCertificateKeyFile "{{ $vhost.SSLCertificateKeyFile }}" - {{- end }} - - ## WSGI configuration - WSGIProcessGroup {{ $endpt }} - WSGIApplicationGroup %{GLOBAL} - WSGIPassAuthorization On - WSGIDaemonProcess {{ $endpt }} processes=5 threads=1 user=designate group=designate display-name={{ $endpt }} - WSGIScriptAlias / "/usr/bin/designate-api-wsgi" +# {{ $endpt }} vhost {{ $vhost.ServerName }} configuration + + ServerName {{ $vhost.ServerName }} + = 2.4> + ErrorLogFormat "%M" + + ErrorLog /dev/stdout + SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded + CustomLog /dev/stdout combined env=!forwarded + CustomLog /dev/stdout proxy env=forwarded + +{{- if $vhost.TLS }} + SetEnvIf X-Forwarded-Proto https HTTPS=1 + + ## SSL directives + SSLEngine on + SSLCertificateFile "{{ $vhost.SSLCertificateFile }}" + SSLCertificateKeyFile "{{ $vhost.SSLCertificateKeyFile }}" +{{- end }} + + ## WSGI configuration + WSGIProcessGroup {{ $endpt }} + WSGIApplicationGroup %{GLOBAL} + WSGIPassAuthorization On + WSGIDaemonProcess {{ $endpt }} processes=5 threads=1 user=designate group=designate display-name={{ $endpt }} + WSGIScriptAlias / "/usr/bin/designate-api-wsgi" + +{{- if $vhost.Override }} + Include conf/httpd_custom_{{ $endpt }}_* +{{- end }} + {{ end }} diff --git a/tests/functional/designateapi_controller_test.go b/tests/functional/designateapi_controller_test.go index 64f55d12..f79e74ae 100644 --- a/tests/functional/designateapi_controller_test.go +++ b/tests/functional/designateapi_controller_test.go @@ -31,6 +31,7 @@ import ( "github.com/openstack-k8s-operators/designate-operator/pkg/designate" . "github.com/openstack-k8s-operators/lib-common/modules/common/test/helpers" + "github.com/openstack-k8s-operators/lib-common/modules/common" mariadbv1 "github.com/openstack-k8s-operators/mariadb-operator/api/v1beta1" ) @@ -246,6 +247,64 @@ var _ = Describe("DesignateAPI controller", func() { }) }) + When("A DesignateAPI is created with HttpdCustomization.CustomConfigSecret", func() { + var keystonePublicEndpoint string + + BeforeEach(func() { + customServiceConfigSecretName := types.NamespacedName{Name: "foo", Namespace: namespace} + customConfig := []byte(`CustomParam "foo" +CustomKeystonePublicURL "{{ .KeystonePublicURL }}"`) + th.CreateSecret( + customServiceConfigSecretName, + map[string][]byte{ + "bar.conf": customConfig, + }, + ) + keystoneName := keystone.CreateKeystoneAPI(namespace) + DeferCleanup(keystone.DeleteKeystoneAPI, keystoneName) + keystoneInternalEndpoint := fmt.Sprintf("http://keystone-for-%s-internal", designateAPIName.Name) + keystonePublicEndpoint = fmt.Sprintf("http://keystone-for-%s-public", designateAPIName.Name) + SimulateKeystoneReady(keystoneName, keystonePublicEndpoint, keystoneInternalEndpoint) + + DeferCleanup(k8sClient.Delete, ctx, CreateDesignateSecret(namespace)) + DeferCleanup(k8sClient.Delete, ctx, CreateTransportURLSecret(transportURLSecretName)) + spec["httpdCustomization"] = map[string]interface{}{ + "customConfigSecret": customServiceConfigSecretName.Name, + } + DeferCleanup(th.DeleteInstance, CreateDesignateAPI(designateAPIName, spec)) + + mariaDBDatabaseName := mariadb.CreateMariaDBDatabase(namespace, designate.DatabaseCRName, mariadbv1.MariaDBDatabaseSpec{}) + mariaDBDatabase := mariadb.GetMariaDBDatabase(mariaDBDatabaseName) + DeferCleanup(k8sClient.Delete, ctx, mariaDBDatabase) + + designateAPI := GetDesignateAPI(designateAPIName) + apiMariaDBAccount, apiMariaDBSecret := mariadb.CreateMariaDBAccountAndSecret( + types.NamespacedName{ + Namespace: namespace, + Name: designateAPI.Spec.DatabaseAccount, + }, mariadbv1.MariaDBAccountSpec{}) + DeferCleanup(k8sClient.Delete, ctx, apiMariaDBAccount) + DeferCleanup(k8sClient.Delete, ctx, apiMariaDBSecret) + }) + + It("it renders the custom template and adds it to the designateapi-config-data secret", func() { + scrt := th.GetSecret(types.NamespacedName{ + Namespace: designateAPIName.Namespace, + Name: fmt.Sprintf("%s-config-data", designateAPIName.Name)}) + Expect(scrt).ShouldNot(BeNil()) + Expect(scrt.Data).Should(HaveKey(common.TemplateParameters)) + configData := string(scrt.Data[common.TemplateParameters]) + Expect(configData).Should(ContainSubstring(fmt.Sprintf("KeystonePublicURL: %s", keystonePublicEndpoint))) + + for _, cfg := range []string{"httpd_custom_internal_bar.conf", "httpd_custom_public_bar.conf"} { + Expect(scrt.Data).Should(HaveKey(cfg)) + configData := string(scrt.Data[cfg]) + Expect(configData).Should(ContainSubstring("CustomParam \"foo\"")) + Expect(configData).Should(ContainSubstring(fmt.Sprintf("CustomKeystonePublicURL \"%s\"", keystonePublicEndpoint))) + } + }) + }) + // NAD // Networks Annotation