diff --git a/api/bases/manila.openstack.org_manilaapis.yaml b/api/bases/manila.openstack.org_manilaapis.yaml index 4eb0bded..7171ef84 100644 --- a/api/bases/manila.openstack.org_manilaapis.yaml +++ b/api/bases/manila.openstack.org_manilaapis.yaml @@ -925,6 +925,24 @@ spec: serviceUser: default: manila type: string + tls: + properties: + api: + properties: + internal: + properties: + secretName: + type: string + type: object + public: + properties: + secretName: + type: string + type: object + type: object + caBundleSecretName: + type: string + type: object transportURLSecret: type: string required: diff --git a/api/bases/manila.openstack.org_manilas.yaml b/api/bases/manila.openstack.org_manilas.yaml index 7f2d7045..d4f52ee0 100644 --- a/api/bases/manila.openstack.org_manilas.yaml +++ b/api/bases/manila.openstack.org_manilas.yaml @@ -922,6 +922,24 @@ spec: x-kubernetes-int-or-string: true type: object type: object + tls: + properties: + api: + properties: + internal: + properties: + secretName: + type: string + type: object + public: + properties: + secretName: + type: string + type: object + type: object + caBundleSecretName: + type: string + type: object required: - containerImage type: object diff --git a/api/bases/manila.openstack.org_manilaschedulers.yaml b/api/bases/manila.openstack.org_manilaschedulers.yaml index 217330a9..37ba87a6 100644 --- a/api/bases/manila.openstack.org_manilaschedulers.yaml +++ b/api/bases/manila.openstack.org_manilaschedulers.yaml @@ -874,6 +874,11 @@ spec: serviceUser: default: manila type: string + tls: + properties: + caBundleSecretName: + type: string + type: object transportURLSecret: type: string required: diff --git a/api/bases/manila.openstack.org_manilashares.yaml b/api/bases/manila.openstack.org_manilashares.yaml index 887a4a28..c5dd12f0 100644 --- a/api/bases/manila.openstack.org_manilashares.yaml +++ b/api/bases/manila.openstack.org_manilashares.yaml @@ -874,6 +874,11 @@ spec: serviceUser: default: manila type: string + tls: + properties: + caBundleSecretName: + type: string + type: object transportURLSecret: type: string required: diff --git a/api/v1beta1/manilaapi_types.go b/api/v1beta1/manilaapi_types.go index efb82126..b766fa78 100644 --- a/api/v1beta1/manilaapi_types.go +++ b/api/v1beta1/manilaapi_types.go @@ -19,6 +19,7 @@ package v1beta1 import ( condition "github.com/openstack-k8s-operators/lib-common/modules/common/condition" "github.com/openstack-k8s-operators/lib-common/modules/common/service" + "github.com/openstack-k8s-operators/lib-common/modules/common/tls" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -38,6 +39,11 @@ type ManilaAPITemplate struct { // +kubebuilder:validation:Optional // Override, provides the ability to override the generated manifest of several child resources. Override APIOverrideSpec `json:"override,omitempty"` + + // +kubebuilder:validation:Optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + // TLS - Parameters related to the TLS + TLS tls.API `json:"tls,omitempty"` } // APIOverrideSpec to override the generated manifest of several child resources. diff --git a/api/v1beta1/manilascheduler_types.go b/api/v1beta1/manilascheduler_types.go index 6e61a9d1..91ed3c9d 100644 --- a/api/v1beta1/manilascheduler_types.go +++ b/api/v1beta1/manilascheduler_types.go @@ -18,6 +18,7 @@ package v1beta1 import ( condition "github.com/openstack-k8s-operators/lib-common/modules/common/condition" + "github.com/openstack-k8s-operators/lib-common/modules/common/tls" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -61,6 +62,11 @@ type ManilaSchedulerSpec struct { // +kubebuilder:validation:Required // ServiceAccount - service account name used internally to provide the default SA name ServiceAccount string `json:"serviceAccount"` + + // +kubebuilder:validation:Optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + // TLS - Parameters related to the TLS + TLS tls.Ca `json:"tls,omitempty"` } // ManilaSchedulerStatus defines the observed state of ManilaScheduler diff --git a/api/v1beta1/manilashare_types.go b/api/v1beta1/manilashare_types.go index b46fedb6..a5478566 100644 --- a/api/v1beta1/manilashare_types.go +++ b/api/v1beta1/manilashare_types.go @@ -18,6 +18,7 @@ package v1beta1 import ( condition "github.com/openstack-k8s-operators/lib-common/modules/common/condition" + "github.com/openstack-k8s-operators/lib-common/modules/common/tls" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -61,6 +62,11 @@ type ManilaShareSpec struct { // +kubebuilder:validation:Required // ServiceAccount - service account name used internally to provide the default SA name ServiceAccount string `json:"serviceAccount"` + + // +kubebuilder:validation:Optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + // TLS - Parameters related to the TLS + TLS tls.Ca `json:"tls,omitempty"` } // ManilaShareStatus defines the observed state of ManilaShare diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go index b25479e4..584ca4a2 100644 --- a/api/v1beta1/zz_generated.deepcopy.go +++ b/api/v1beta1/zz_generated.deepcopy.go @@ -229,6 +229,7 @@ func (in *ManilaAPITemplate) DeepCopyInto(out *ManilaAPITemplate) { **out = **in } in.Override.DeepCopyInto(&out.Override) + in.TLS.DeepCopyInto(&out.TLS) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ManilaAPITemplate. @@ -396,6 +397,7 @@ func (in *ManilaSchedulerSpec) DeepCopyInto(out *ManilaSchedulerSpec) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + out.TLS = in.TLS } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ManilaSchedulerSpec. @@ -577,6 +579,7 @@ func (in *ManilaShareSpec) DeepCopyInto(out *ManilaShareSpec) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + out.TLS = in.TLS } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ManilaShareSpec. diff --git a/config/crd/bases/manila.openstack.org_manilaapis.yaml b/config/crd/bases/manila.openstack.org_manilaapis.yaml index 4eb0bded..7171ef84 100644 --- a/config/crd/bases/manila.openstack.org_manilaapis.yaml +++ b/config/crd/bases/manila.openstack.org_manilaapis.yaml @@ -925,6 +925,24 @@ spec: serviceUser: default: manila type: string + tls: + properties: + api: + properties: + internal: + properties: + secretName: + type: string + type: object + public: + properties: + secretName: + type: string + type: object + type: object + caBundleSecretName: + type: string + type: object transportURLSecret: type: string required: diff --git a/config/crd/bases/manila.openstack.org_manilas.yaml b/config/crd/bases/manila.openstack.org_manilas.yaml index 7f2d7045..d4f52ee0 100644 --- a/config/crd/bases/manila.openstack.org_manilas.yaml +++ b/config/crd/bases/manila.openstack.org_manilas.yaml @@ -922,6 +922,24 @@ spec: x-kubernetes-int-or-string: true type: object type: object + tls: + properties: + api: + properties: + internal: + properties: + secretName: + type: string + type: object + public: + properties: + secretName: + type: string + type: object + type: object + caBundleSecretName: + type: string + type: object required: - containerImage type: object diff --git a/config/crd/bases/manila.openstack.org_manilaschedulers.yaml b/config/crd/bases/manila.openstack.org_manilaschedulers.yaml index 217330a9..37ba87a6 100644 --- a/config/crd/bases/manila.openstack.org_manilaschedulers.yaml +++ b/config/crd/bases/manila.openstack.org_manilaschedulers.yaml @@ -874,6 +874,11 @@ spec: serviceUser: default: manila type: string + tls: + properties: + caBundleSecretName: + type: string + type: object transportURLSecret: type: string required: diff --git a/config/crd/bases/manila.openstack.org_manilashares.yaml b/config/crd/bases/manila.openstack.org_manilashares.yaml index 887a4a28..c5dd12f0 100644 --- a/config/crd/bases/manila.openstack.org_manilashares.yaml +++ b/config/crd/bases/manila.openstack.org_manilashares.yaml @@ -874,6 +874,11 @@ spec: serviceUser: default: manila type: string + tls: + properties: + caBundleSecretName: + type: string + type: object transportURLSecret: type: string required: diff --git a/config/samples/layout/tls/kustomization.yaml b/config/samples/layout/tls/kustomization.yaml new file mode 100644 index 00000000..8e678fb3 --- /dev/null +++ b/config/samples/layout/tls/kustomization.yaml @@ -0,0 +1,15 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: +- ../bases/manila +patches: +- patch: |- + - op: replace + path: /spec/secret + value: osp-secret + - op: replace + path: /metadata/namespace + value: manila-kuttl-tests + target: + kind: Manila +- path: tls.yaml diff --git a/config/samples/layout/tls/tls.yaml b/config/samples/layout/tls/tls.yaml new file mode 100644 index 00000000..fb76717a --- /dev/null +++ b/config/samples/layout/tls/tls.yaml @@ -0,0 +1,47 @@ +apiVersion: manila.openstack.org/v1beta1 +kind: Manila +metadata: + name: manila + namespace: openstack +spec: + manilaAPI: + tls: + api: + internal: + secretName: cert-manila-internal-svc + public: + secretName: cert-manila-public-svc + caBundleSecretName: combined-ca-bundle + customServiceConfig: | + [DEFAULT] + enabled_share_protocols = cephfs + manilaShares: + share0: + customServiceConfig: | + [DEFAULT] + enabled_share_backends = cephfs + [cephfs] + driver_handles_share_servers=False + share_backend_name=cephfs + share_driver=manila.share.drivers.cephfs.driver.CephFSDriver + cephfs_conf_path=/etc/ceph/ceph.conf + cephfs_auth_id=openstack + cephfs_cluster_name=ceph + cephfs_protocol_helper_type=CEPHFS + extraMounts: + - name: v1 + region: r1 + extraVol: + - propagation: + - share0 + extraVolType: Ceph + volumes: + - name: ceph + projected: + sources: + - secret: + name: ceph-conf-files + mounts: + - name: ceph + mountPath: "/etc/ceph" + readOnly: true diff --git a/config/samples/manila_v1beta1_manila_tls.yaml b/config/samples/manila_v1beta1_manila_tls.yaml new file mode 100644 index 00000000..fdc2bbec --- /dev/null +++ b/config/samples/manila_v1beta1_manila_tls.yaml @@ -0,0 +1,22 @@ +apiVersion: manila.openstack.org/v1beta1 +kind: Manila +metadata: + name: manila + namespace: openstack +spec: + serviceUser: manila + customServiceConfig: | + [DEFAULT] + debug = true + databaseInstance: openstack + secret: osp-secret + databaseUser: manila + rabbitMqClusterName: rabbitmq + manilaAPI: + tls: + api: + internal: + secretName: cert-manila-internal-svc + public: + secretName: cert-manila-public-svc + caBundleSecretName: combined-ca-bundle diff --git a/controllers/manila_controller.go b/controllers/manila_controller.go index 2a9111f3..291c04ca 100644 --- a/controllers/manila_controller.go +++ b/controllers/manila_controller.go @@ -37,6 +37,7 @@ import ( nad "github.com/openstack-k8s-operators/lib-common/modules/common/networkattachment" common_rbac "github.com/openstack-k8s-operators/lib-common/modules/common/rbac" "github.com/openstack-k8s-operators/lib-common/modules/common/secret" + "github.com/openstack-k8s-operators/lib-common/modules/common/service" "github.com/openstack-k8s-operators/lib-common/modules/common/util" manilav1beta1 "github.com/openstack-k8s-operators/manila-operator/api/v1beta1" "github.com/openstack-k8s-operators/manila-operator/pkg/manila" @@ -210,6 +211,27 @@ func (r *ManilaReconciler) Reconcile(ctx context.Context, req ctrl.Request) (res return r.reconcileNormal(ctx, instance, helper) } +// 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" +) + +var ( + commonWatchFields = []string{ + passwordSecretField, + caBundleSecretNameField, + } + manilaAPIWatchFields = []string{ + passwordSecretField, + caBundleSecretNameField, + tlsAPIInternalField, + tlsAPIPublicField, + } +) + // SetupWithManager sets up the controller with the Manager. func (r *ManilaReconciler) SetupWithManager(mgr ctrl.Manager) error { // transportURLSecretFn - Watch for changes made to the secret associated with the RabbitMQ @@ -874,6 +896,21 @@ func (r *ManilaReconciler) generateServiceConfig( "MemcachedServersWithInet": strings.Join(memcached.Status.ServerListWithInet, ","), } + // create httpd vhost template parameters + httpdVhostConfig := map[string]interface{}{} + for _, endpt := range []service.Endpoint{service.EndpointInternal, service.EndpointPublic} { + endptConfig := map[string]interface{}{} + endptConfig["ServerName"] = fmt.Sprintf("%s-%s.%s.svc", manila.ServiceName, endpt.String(), instance.Namespace) + endptConfig["TLS"] = false // default TLS to false, and set it bellow to true if enabled + if instance.Spec.ManilaAPI.TLS.API.Enabled(endpt) { + endptConfig["TLS"] = true + endptConfig["SSLCertificateFile"] = fmt.Sprintf("/etc/pki/tls/certs/%s.crt", endpt.String()) + endptConfig["SSLCertificateKeyFile"] = fmt.Sprintf("/etc/pki/tls/private/%s.key", endpt.String()) + } + httpdVhostConfig[endpt.String()] = endptConfig + } + templateParameters["VHosts"] = httpdVhostConfig + configTemplates := []util.Template{ // ScriptsConfigMap { @@ -973,6 +1010,7 @@ func (r *ManilaReconciler) schedulerDeploymentCreateOrUpdate(ctx context.Context DatabaseHostname: instance.Status.DatabaseHostname, TransportURLSecret: instance.Status.TransportURLSecret, ServiceAccount: instance.RbacResourceName(), + TLS: instance.Spec.ManilaAPI.TLS.Ca, } op, err := controllerutil.CreateOrUpdate(ctx, r.Client, deployment, func() error { @@ -1009,6 +1047,7 @@ func (r *ManilaReconciler) shareDeploymentCreateOrUpdate(ctx context.Context, in DatabaseHostname: instance.Status.DatabaseHostname, TransportURLSecret: instance.Status.TransportURLSecret, ServiceAccount: instance.RbacResourceName(), + TLS: instance.Spec.ManilaAPI.TLS.Ca, } op, err := controllerutil.CreateOrUpdate(ctx, r.Client, deployment, func() error { diff --git a/controllers/manilaapi_controller.go b/controllers/manilaapi_controller.go index 8f637060..7d5338f5 100644 --- a/controllers/manilaapi_controller.go +++ b/controllers/manilaapi_controller.go @@ -21,11 +21,16 @@ import ( "fmt" "time" + "k8s.io/apimachinery/pkg/fields" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/kubernetes" + "k8s.io/utils/ptr" ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/builder" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/predicate" "github.com/go-logr/logr" @@ -40,6 +45,7 @@ import ( "github.com/openstack-k8s-operators/lib-common/modules/common/secret" "github.com/openstack-k8s-operators/lib-common/modules/common/service" "github.com/openstack-k8s-operators/lib-common/modules/common/statefulset" + "github.com/openstack-k8s-operators/lib-common/modules/common/tls" "github.com/openstack-k8s-operators/lib-common/modules/common/util" manilav1beta1 "github.com/openstack-k8s-operators/manila-operator/api/v1beta1" "github.com/openstack-k8s-operators/manila-operator/pkg/manila" @@ -178,6 +184,7 @@ func (r *ManilaAPIReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( condition.UnknownCondition(condition.KeystoneServiceReadyCondition, condition.InitReason, ""), condition.UnknownCondition(condition.KeystoneEndpointReadyCondition, condition.InitReason, ""), condition.UnknownCondition(condition.NetworkAttachmentsReadyCondition, condition.InitReason, condition.NetworkAttachmentsReadyInitMessage), + condition.UnknownCondition(condition.TLSInputReadyCondition, condition.InitReason, condition.InputReadyInitMessage), ) instance.Status.Conditions.Init(&cl) @@ -256,6 +263,54 @@ func (r *ManilaAPIReconciler) SetupWithManager(mgr ctrl.Manager) error { return nil } + // index passwordSecretField + if err := mgr.GetFieldIndexer().IndexField(context.Background(), &manilav1beta1.ManilaAPI{}, passwordSecretField, func(rawObj client.Object) []string { + // Extract the secret name from the spec, if one is provided + cr := rawObj.(*manilav1beta1.ManilaAPI) + if cr.Spec.Secret == "" { + return nil + } + return []string{cr.Spec.Secret} + }); err != nil { + return err + } + + // index caBundleSecretNameField + if err := mgr.GetFieldIndexer().IndexField(context.Background(), &manilav1beta1.ManilaAPI{}, caBundleSecretNameField, func(rawObj client.Object) []string { + // Extract the secret name from the spec, if one is provided + cr := rawObj.(*manilav1beta1.ManilaAPI) + if cr.Spec.TLS.CaBundleSecretName == "" { + return nil + } + return []string{cr.Spec.TLS.CaBundleSecretName} + }); err != nil { + return err + } + + // index tlsAPIInternalField + if err := mgr.GetFieldIndexer().IndexField(context.Background(), &manilav1beta1.ManilaAPI{}, tlsAPIInternalField, func(rawObj client.Object) []string { + // Extract the secret name from the spec, if one is provided + cr := rawObj.(*manilav1beta1.ManilaAPI) + if cr.Spec.TLS.API.Internal.SecretName == nil { + return nil + } + return []string{*cr.Spec.TLS.API.Internal.SecretName} + }); err != nil { + return err + } + + // index tlsAPIPublicField + if err := mgr.GetFieldIndexer().IndexField(context.Background(), &manilav1beta1.ManilaAPI{}, tlsAPIPublicField, func(rawObj client.Object) []string { + // Extract the secret name from the spec, if one is provided + cr := rawObj.(*manilav1beta1.ManilaAPI) + if cr.Spec.TLS.API.Public.SecretName == nil { + return nil + } + return []string{*cr.Spec.TLS.API.Public.SecretName} + }); err != nil { + return err + } + return ctrl.NewControllerManagedBy(mgr). For(&manilav1beta1.ManilaAPI{}). Owns(&keystonev1.KeystoneService{}). @@ -266,9 +321,47 @@ func (r *ManilaAPIReconciler) SetupWithManager(mgr ctrl.Manager) error { // watch the secrets we don't own Watches(&source.Kind{Type: &corev1.Secret{}}, handler.EnqueueRequestsFromMapFunc(secretFn)). + Watches( + &source.Kind{Type: &corev1.Secret{}}, + handler.EnqueueRequestsFromMapFunc(r.findObjectsForSrc), + builder.WithPredicates(predicate.ResourceVersionChangedPredicate{}), + ). Complete(r) } +func (r *ManilaAPIReconciler) findObjectsForSrc(src client.Object) []reconcile.Request { + requests := []reconcile.Request{} + + l := log.FromContext(context.Background()).WithName("Controllers").WithName("ManilaAPI") + + for _, field := range manilaAPIWatchFields { + crList := &manilav1beta1.ManilaAPIList{} + listOps := &client.ListOptions{ + FieldSelector: fields.OneTermEqualSelector(field, src.GetName()), + Namespace: src.GetNamespace(), + } + err := r.List(context.TODO(), crList, listOps) + if err != nil { + return []reconcile.Request{} + } + + for _, item := range crList.Items { + l.Info(fmt.Sprintf("input source %s changed, reconcile: %s - %s", src.GetName(), item.GetName(), item.GetNamespace())) + + requests = append(requests, + reconcile.Request{ + NamespacedName: types.NamespacedName{ + Name: item.GetName(), + Namespace: item.GetNamespace(), + }, + }, + ) + } + } + + return requests +} + func (r *ManilaAPIReconciler) reconcileDelete(ctx context.Context, instance *manilav1beta1.ManilaAPI, helper *helper.Helper) (ctrl.Result, error) { r.Log.Info(fmt.Sprintf("Reconciling Service '%s' delete", instance.Name)) @@ -422,7 +515,12 @@ func (r *ManilaAPIReconciler) reconcileInit( } // create service - end - // TODO: TLS, pass in https as protocol + // if TLS is enabled + if instance.Spec.TLS.API.Enabled(endpointType) { + // set endpoint protocol to https + data.Protocol = ptr.To(service.ProtocolHTTPS) + } + apiEndpointsV2[string(endpointType)], err = svc.GetAPIEndpoint( svcOverride.EndpointURL, data.Protocol, data.Path) if err != nil { @@ -540,9 +638,6 @@ func (r *ManilaAPIReconciler) reconcileNormal(ctx context.Context, instance *man fmt.Sprintf("%s-config-data", parentManilaName), //ConfigSecret } - // - // Create Secrets required as input for the Service and calculate an overall hash of hashes - // for _, parentSecret := range parentSecrets { ctrlResult, err = r.getSecret(ctx, helper, instance, parentSecret, &configVars) if err != nil { @@ -551,13 +646,64 @@ func (r *ManilaAPIReconciler) reconcileNormal(ctx context.Context, instance *man } instance.Status.Conditions.MarkTrue(condition.InputReadyCondition, condition.InputReadyMessage) + // + // TLS input validation + // + // Validate the CA cert secret if provided + if instance.Spec.TLS.CaBundleSecretName != "" { + hash, ctrlResult, err := tls.ValidateCACertSecret( + ctx, + helper.GetClient(), + types.NamespacedName{ + Name: instance.Spec.TLS.CaBundleSecretName, + Namespace: instance.Namespace, + }, + ) + if err != nil { + instance.Status.Conditions.Set(condition.FalseCondition( + condition.TLSInputReadyCondition, + condition.ErrorReason, + condition.SeverityWarning, + condition.TLSInputErrorMessage, + err.Error())) + return ctrlResult, err + } else if (ctrlResult != ctrl.Result{}) { + return ctrlResult, nil + } + + if hash != "" { + configVars[tls.CABundleKey] = env.SetValue(hash) + } + + // Validate API service certs secrets + certsHash, ctrlResult, err := instance.Spec.TLS.API.ValidateCertSecrets(ctx, helper, instance.Namespace) + if err != nil { + instance.Status.Conditions.Set(condition.FalseCondition( + condition.TLSInputReadyCondition, + condition.ErrorReason, + condition.SeverityWarning, + condition.TLSInputErrorMessage, + err.Error())) + return ctrlResult, err + } else if (ctrlResult != ctrl.Result{}) { + return ctrlResult, nil + } + + configVars[tls.TLSHashName] = env.SetValue(certsHash) + } + + // all cert input checks out so report InputReady + instance.Status.Conditions.MarkTrue(condition.TLSInputReadyCondition, condition.InputReadyMessage) + + // + // Create secrets required as input for the Service and calculate an overall hash of hashes + // serviceLabels := map[string]string{ common.AppSelector: manila.ServiceName, common.ComponentSelector: manilaapi.Component, } - // - // create Secrets for manila-api service + // create custom config for this manila service // err = r.generateServiceConfig(ctx, helper, instance, &configVars, serviceLabels) if err != nil { @@ -569,8 +715,6 @@ func (r *ManilaAPIReconciler) reconcileNormal(ctx context.Context, instance *man err.Error())) return ctrl.Result{}, err } - - // // create hash over all the different input resources to identify if any those changed // and a restart/recreate is required. // @@ -652,12 +796,20 @@ func (r *ManilaAPIReconciler) reconcileNormal(ctx context.Context, instance *man // // Define a new Statefulset - ssDef := statefulset.NewStatefulSet( - manilaapi.StatefulSet(instance, inputHash, serviceLabels, serviceAnnotations), - time.Duration(5)*time.Second, - ) + ssDef, err := manilaapi.StatefulSet(instance, inputHash, serviceLabels, serviceAnnotations) + if err != nil { + instance.Status.Conditions.Set(condition.FalseCondition( + condition.DeploymentReadyCondition, + condition.ErrorReason, + condition.SeverityWarning, + condition.DeploymentReadyErrorMessage, + err.Error())) + return ctrl.Result{}, err + } + + ss := statefulset.NewStatefulSet(ssDef, time.Duration(5)*time.Second) - ctrlResult, err = ssDef.CreateOrPatch(ctx, helper) + ctrlResult, err = ss.CreateOrPatch(ctx, helper) if err != nil { instance.Status.Conditions.Set(condition.FalseCondition( condition.DeploymentReadyCondition, @@ -674,7 +826,7 @@ func (r *ManilaAPIReconciler) reconcileNormal(ctx context.Context, instance *man condition.DeploymentReadyRunningMessage)) return ctrlResult, nil } - instance.Status.ReadyCount = ssDef.GetStatefulSet().Status.ReadyReplicas + instance.Status.ReadyCount = ss.GetStatefulSet().Status.ReadyReplicas networkReady := false networkAttachmentStatus := map[string][]string{} diff --git a/controllers/manilascheduler_controller.go b/controllers/manilascheduler_controller.go index 18108536..7e62d076 100644 --- a/controllers/manilascheduler_controller.go +++ b/controllers/manilascheduler_controller.go @@ -24,13 +24,17 @@ import ( appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" k8s_errors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/fields" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/kubernetes" ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/builder" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "sigs.k8s.io/controller-runtime/pkg/handler" "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/predicate" "sigs.k8s.io/controller-runtime/pkg/reconcile" "sigs.k8s.io/controller-runtime/pkg/source" @@ -43,6 +47,7 @@ import ( nad "github.com/openstack-k8s-operators/lib-common/modules/common/networkattachment" "github.com/openstack-k8s-operators/lib-common/modules/common/secret" "github.com/openstack-k8s-operators/lib-common/modules/common/statefulset" + "github.com/openstack-k8s-operators/lib-common/modules/common/tls" "github.com/openstack-k8s-operators/lib-common/modules/common/util" manilav1beta1 "github.com/openstack-k8s-operators/manila-operator/api/v1beta1" "github.com/openstack-k8s-operators/manila-operator/pkg/manila" @@ -151,6 +156,7 @@ func (r *ManilaSchedulerReconciler) Reconcile(ctx context.Context, req ctrl.Requ condition.UnknownCondition(condition.ServiceConfigReadyCondition, condition.InitReason, condition.ServiceConfigReadyInitMessage), condition.UnknownCondition(condition.DeploymentReadyCondition, condition.InitReason, condition.DeploymentReadyInitMessage), condition.UnknownCondition(condition.NetworkAttachmentsReadyCondition, condition.InitReason, condition.NetworkAttachmentsReadyInitMessage), + condition.UnknownCondition(condition.TLSInputReadyCondition, condition.InitReason, condition.InputReadyInitMessage), ) instance.Status.Conditions.Init(&cl) @@ -227,6 +233,30 @@ func (r *ManilaSchedulerReconciler) SetupWithManager(mgr ctrl.Manager) error { return nil } + // index passwordSecretField + if err := mgr.GetFieldIndexer().IndexField(context.Background(), &manilav1beta1.ManilaScheduler{}, passwordSecretField, func(rawObj client.Object) []string { + // Extract the secret name from the spec, if one is provided + cr := rawObj.(*manilav1beta1.ManilaScheduler) + if cr.Spec.Secret == "" { + return nil + } + return []string{cr.Spec.Secret} + }); err != nil { + return err + } + + // index caBundleSecretNameField + if err := mgr.GetFieldIndexer().IndexField(context.Background(), &manilav1beta1.ManilaScheduler{}, caBundleSecretNameField, func(rawObj client.Object) []string { + // Extract the secret name from the spec, if one is provided + cr := rawObj.(*manilav1beta1.ManilaScheduler) + if cr.Spec.TLS.CaBundleSecretName == "" { + return nil + } + return []string{cr.Spec.TLS.CaBundleSecretName} + }); err != nil { + return err + } + return ctrl.NewControllerManagedBy(mgr). For(&manilav1beta1.ManilaScheduler{}). Owns(&appsv1.StatefulSet{}). @@ -234,9 +264,47 @@ func (r *ManilaSchedulerReconciler) SetupWithManager(mgr ctrl.Manager) error { // watch the secrets we don't own Watches(&source.Kind{Type: &corev1.Secret{}}, handler.EnqueueRequestsFromMapFunc(secretFn)). + Watches( + &source.Kind{Type: &corev1.Secret{}}, + handler.EnqueueRequestsFromMapFunc(r.findObjectsForSrc), + builder.WithPredicates(predicate.ResourceVersionChangedPredicate{}), + ). Complete(r) } +func (r *ManilaSchedulerReconciler) findObjectsForSrc(src client.Object) []reconcile.Request { + requests := []reconcile.Request{} + + l := log.FromContext(context.Background()).WithName("Controllers").WithName("ManilaScheduler") + + for _, field := range commonWatchFields { + crList := &manilav1beta1.ManilaSchedulerList{} + listOps := &client.ListOptions{ + FieldSelector: fields.OneTermEqualSelector(field, src.GetName()), + Namespace: src.GetNamespace(), + } + err := r.List(context.TODO(), crList, listOps) + if err != nil { + return []reconcile.Request{} + } + + for _, item := range crList.Items { + l.Info(fmt.Sprintf("input source %s changed, reconcile: %s - %s", src.GetName(), item.GetName(), item.GetNamespace())) + + requests = append(requests, + reconcile.Request{ + NamespacedName: types.NamespacedName{ + Name: item.GetName(), + Namespace: item.GetNamespace(), + }, + }, + ) + } + } + + return requests +} + func (r *ManilaSchedulerReconciler) reconcileDelete(ctx context.Context, instance *manilav1beta1.ManilaScheduler, helper *helper.Helper) (ctrl.Result, error) { r.Log.Info(fmt.Sprintf("Reconciling Service '%s' delete", instance.Name)) @@ -304,6 +372,38 @@ func (r *ManilaSchedulerReconciler) reconcileNormal(ctx context.Context, instanc } instance.Status.Conditions.MarkTrue(condition.InputReadyCondition, condition.InputReadyMessage) + // + // TLS input validation + // + // Validate the CA cert secret if provided + if instance.Spec.TLS.CaBundleSecretName != "" { + hash, ctrlResult, err := tls.ValidateCACertSecret( + ctx, + helper.GetClient(), + types.NamespacedName{ + Name: instance.Spec.TLS.CaBundleSecretName, + Namespace: instance.Namespace, + }, + ) + if err != nil { + instance.Status.Conditions.Set(condition.FalseCondition( + condition.TLSInputReadyCondition, + condition.ErrorReason, + condition.SeverityWarning, + condition.TLSInputErrorMessage, + err.Error())) + return ctrlResult, err + } else if (ctrlResult != ctrl.Result{}) { + return ctrlResult, nil + } + + if hash != "" { + configVars[tls.CABundleKey] = env.SetValue(hash) + } + } + // all cert input checks out so report InputReady + instance.Status.Conditions.MarkTrue(condition.TLSInputReadyCondition, condition.InputReadyMessage) + // // Create Secrets required as input for the Service and calculate an overall hash of hashes // diff --git a/controllers/manilashare_controller.go b/controllers/manilashare_controller.go index 734b7f8f..0da833d0 100644 --- a/controllers/manilashare_controller.go +++ b/controllers/manilashare_controller.go @@ -24,13 +24,17 @@ import ( appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" k8s_errors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/fields" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/kubernetes" ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/builder" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "sigs.k8s.io/controller-runtime/pkg/handler" "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/predicate" "sigs.k8s.io/controller-runtime/pkg/reconcile" "sigs.k8s.io/controller-runtime/pkg/source" @@ -43,6 +47,7 @@ import ( nad "github.com/openstack-k8s-operators/lib-common/modules/common/networkattachment" "github.com/openstack-k8s-operators/lib-common/modules/common/secret" "github.com/openstack-k8s-operators/lib-common/modules/common/statefulset" + "github.com/openstack-k8s-operators/lib-common/modules/common/tls" "github.com/openstack-k8s-operators/lib-common/modules/common/util" manilav1beta1 "github.com/openstack-k8s-operators/manila-operator/api/v1beta1" "github.com/openstack-k8s-operators/manila-operator/pkg/manila" @@ -152,6 +157,7 @@ func (r *ManilaShareReconciler) Reconcile(ctx context.Context, req ctrl.Request) condition.UnknownCondition(condition.ServiceConfigReadyCondition, condition.InitReason, condition.ServiceConfigReadyInitMessage), condition.UnknownCondition(condition.DeploymentReadyCondition, condition.InitReason, condition.DeploymentReadyInitMessage), condition.UnknownCondition(condition.NetworkAttachmentsReadyCondition, condition.InitReason, condition.NetworkAttachmentsReadyInitMessage), + condition.UnknownCondition(condition.TLSInputReadyCondition, condition.InitReason, condition.InputReadyInitMessage), ) instance.Status.Conditions.Init(&cl) @@ -225,6 +231,30 @@ func (r *ManilaShareReconciler) SetupWithManager(mgr ctrl.Manager) error { return nil } + // index passwordSecretField + if err := mgr.GetFieldIndexer().IndexField(context.Background(), &manilav1beta1.ManilaShare{}, passwordSecretField, func(rawObj client.Object) []string { + // Extract the secret name from the spec, if one is provided + cr := rawObj.(*manilav1beta1.ManilaShare) + if cr.Spec.Secret == "" { + return nil + } + return []string{cr.Spec.Secret} + }); err != nil { + return err + } + + // index caBundleSecretNameField + if err := mgr.GetFieldIndexer().IndexField(context.Background(), &manilav1beta1.ManilaShare{}, caBundleSecretNameField, func(rawObj client.Object) []string { + // Extract the secret name from the spec, if one is provided + cr := rawObj.(*manilav1beta1.ManilaShare) + if cr.Spec.TLS.CaBundleSecretName == "" { + return nil + } + return []string{cr.Spec.TLS.CaBundleSecretName} + }); err != nil { + return err + } + return ctrl.NewControllerManagedBy(mgr). For(&manilav1beta1.ManilaShare{}). Owns(&appsv1.StatefulSet{}). @@ -232,9 +262,47 @@ func (r *ManilaShareReconciler) SetupWithManager(mgr ctrl.Manager) error { // watch the secrets we don't own Watches(&source.Kind{Type: &corev1.Secret{}}, handler.EnqueueRequestsFromMapFunc(secretFn)). + Watches( + &source.Kind{Type: &corev1.Secret{}}, + handler.EnqueueRequestsFromMapFunc(r.findObjectsForSrc), + builder.WithPredicates(predicate.ResourceVersionChangedPredicate{}), + ). Complete(r) } +func (r *ManilaShareReconciler) findObjectsForSrc(src client.Object) []reconcile.Request { + requests := []reconcile.Request{} + + l := log.FromContext(context.Background()).WithName("Controllers").WithName("ManilaShare") + + for _, field := range commonWatchFields { + crList := &manilav1beta1.ManilaShareList{} + listOps := &client.ListOptions{ + FieldSelector: fields.OneTermEqualSelector(field, src.GetName()), + Namespace: src.GetNamespace(), + } + err := r.List(context.TODO(), crList, listOps) + if err != nil { + return []reconcile.Request{} + } + + for _, item := range crList.Items { + l.Info(fmt.Sprintf("input source %s changed, reconcile: %s - %s", src.GetName(), item.GetName(), item.GetNamespace())) + + requests = append(requests, + reconcile.Request{ + NamespacedName: types.NamespacedName{ + Name: item.GetName(), + Namespace: item.GetNamespace(), + }, + }, + ) + } + } + + return requests +} + func (r *ManilaShareReconciler) reconcileDelete(ctx context.Context, instance *manilav1beta1.ManilaShare, helper *helper.Helper) (ctrl.Result, error) { r.Log.Info(fmt.Sprintf("Reconciling Service '%s' delete", instance.Name)) @@ -303,6 +371,38 @@ func (r *ManilaShareReconciler) reconcileNormal(ctx context.Context, instance *m } instance.Status.Conditions.MarkTrue(condition.InputReadyCondition, condition.InputReadyMessage) + // + // TLS input validation + // + // Validate the CA cert secret if provided + if instance.Spec.TLS.CaBundleSecretName != "" { + hash, ctrlResult, err := tls.ValidateCACertSecret( + ctx, + helper.GetClient(), + types.NamespacedName{ + Name: instance.Spec.TLS.CaBundleSecretName, + Namespace: instance.Namespace, + }, + ) + if err != nil { + instance.Status.Conditions.Set(condition.FalseCondition( + condition.TLSInputReadyCondition, + condition.ErrorReason, + condition.SeverityWarning, + condition.TLSInputErrorMessage, + err.Error())) + return ctrlResult, err + } else if (ctrlResult != ctrl.Result{}) { + return ctrlResult, nil + } + + if hash != "" { + configVars[tls.CABundleKey] = env.SetValue(hash) + } + } + // all cert input checks out so report InputReady + instance.Status.Conditions.MarkTrue(condition.TLSInputReadyCondition, condition.InputReadyMessage) + serviceLabels := map[string]string{ common.AppSelector: manila.ServiceName, common.ComponentSelector: manilashare.Component, diff --git a/go.mod b/go.mod index 76ff5eba..eb354ae1 100644 --- a/go.mod +++ b/go.mod @@ -59,7 +59,7 @@ require ( github.com/spf13/pflag v1.0.5 // indirect go.uber.org/multierr v1.10.0 // indirect go.uber.org/zap v1.26.0 // indirect - golang.org/x/exp v0.0.0-20240119083558-1b970713d09a // indirect + golang.org/x/exp v0.0.0-20240119083558-1b970713d09a golang.org/x/mod v0.14.0 // indirect golang.org/x/net v0.20.0 // indirect golang.org/x/oauth2 v0.7.0 // indirect diff --git a/pkg/manila/cronjob.go b/pkg/manila/cronjob.go index 0b158897..1c4a54f9 100644 --- a/pkg/manila/cronjob.go +++ b/pkg/manila/cronjob.go @@ -17,6 +17,7 @@ package manila import ( "fmt" + manilav1 "github.com/openstack-k8s-operators/manila-operator/api/v1beta1" batchv1 "k8s.io/api/batch/v1" @@ -73,6 +74,12 @@ func CronJob( }, } + // add CA cert if defined + if instance.Spec.ManilaAPI.TLS.CaBundleSecretName != "" { + cronJobVolume = append(cronJobVolume, instance.Spec.ManilaAPI.TLS.CreateVolume()) + cronJobVolumeMounts = append(cronJobVolumeMounts, instance.Spec.ManilaAPI.TLS.CreateVolumeMounts(nil)...) + } + cronjob := &batchv1.CronJob{ ObjectMeta: metav1.ObjectMeta{ Name: fmt.Sprintf("%s-db-purge", ServiceName), diff --git a/pkg/manila/dbsync.go b/pkg/manila/dbsync.go index f8292245..3000311e 100644 --- a/pkg/manila/dbsync.go +++ b/pkg/manila/dbsync.go @@ -34,6 +34,10 @@ func DbSyncJob(instance *manilav1.Manila, labels map[string]string, annotations Key: DefaultsConfigFileName, Path: DefaultsConfigFileName, }, + { + Key: CustomConfigFileName, + Path: CustomConfigFileName, + }, }, }, }, @@ -64,6 +68,13 @@ func DbSyncJob(instance *manilav1.Manila, labels map[string]string, annotations } args := []string{"-c", DBSyncCommand} + + // add CA cert if defined + if instance.Spec.ManilaAPI.TLS.CaBundleSecretName != "" { + dbSyncVolume = append(dbSyncVolume, instance.Spec.ManilaAPI.TLS.CreateVolume()) + dbSyncMounts = append(dbSyncMounts, instance.Spec.ManilaAPI.TLS.CreateVolumeMounts(nil)...) + } + runAsUser := int64(0) envVars := map[string]env.Setter{} envVars["KOLLA_CONFIG_STRATEGY"] = env.SetValue("COPY_ALWAYS") diff --git a/pkg/manilaapi/statefulset.go b/pkg/manilaapi/statefulset.go index fde2bff1..7a40de4f 100644 --- a/pkg/manilaapi/statefulset.go +++ b/pkg/manilaapi/statefulset.go @@ -16,6 +16,8 @@ import ( common "github.com/openstack-k8s-operators/lib-common/modules/common" "github.com/openstack-k8s-operators/lib-common/modules/common/affinity" "github.com/openstack-k8s-operators/lib-common/modules/common/env" + "github.com/openstack-k8s-operators/lib-common/modules/common/service" + "github.com/openstack-k8s-operators/lib-common/modules/common/tls" manilav1 "github.com/openstack-k8s-operators/manila-operator/api/v1beta1" manila "github.com/openstack-k8s-operators/manila-operator/pkg/manila" @@ -36,7 +38,7 @@ func StatefulSet( configHash string, labels map[string]string, annotations map[string]string, -) *appsv1.StatefulSet { +) (*appsv1.StatefulSet, error) { runAsUser := int64(0) livenessProbe := &corev1.Probe{ @@ -54,12 +56,47 @@ func StatefulSet( // // https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/ // + livenessProbe.HTTPGet = &corev1.HTTPGetAction{ Path: "/healthcheck", Port: intstr.IntOrString{Type: intstr.Int, IntVal: int32(manila.ManilaPublicPort)}, } readinessProbe.HTTPGet = livenessProbe.HTTPGet + if instance.Spec.TLS.API.Enabled(service.EndpointPublic) { + livenessProbe.HTTPGet.Scheme = corev1.URISchemeHTTPS + readinessProbe.HTTPGet.Scheme = corev1.URISchemeHTTPS + } + + // create Volume and VolumeMounts + volumes := append(GetVolumes(manila.GetOwningManilaName(instance), instance.Name, instance.Spec.ExtraMounts), GetLogVolume()) + volumeMounts := append(GetVolumeMounts(instance.Spec.ExtraMounts), GetLogVolumeMount()) + + // add CA cert if defined + if instance.Spec.TLS.CaBundleSecretName != "" { + volumes = append(volumes, instance.Spec.TLS.CreateVolume()) + volumeMounts = append(volumeMounts, instance.Spec.TLS.CreateVolumeMounts(nil)...) + } + + for _, endpt := range []service.Endpoint{service.EndpointInternal, service.EndpointPublic} { + if instance.Spec.TLS.API.Enabled(endpt) { + var tlsEndptCfg tls.GenericService + switch endpt { + case service.EndpointPublic: + tlsEndptCfg = instance.Spec.TLS.API.Public + case service.EndpointInternal: + tlsEndptCfg = instance.Spec.TLS.API.Internal + } + + svc, err := tlsEndptCfg.ToService() + if err != nil { + return nil, err + } + volumes = append(volumes, svc.CreateVolume(endpt.String())) + volumeMounts = append(volumeMounts, svc.CreateVolumeMounts(endpt.String())...) + } + } + envVars := map[string]env.Setter{} envVars["KOLLA_CONFIG_STRATEGY"] = env.SetValue("COPY_ALWAYS") envVars["CONFIG_HASH"] = env.SetValue(configHash) @@ -116,23 +153,20 @@ func StatefulSet( SecurityContext: &corev1.SecurityContext{ RunAsUser: &runAsUser, }, - Env: env.MergeEnvs([]corev1.EnvVar{}, envVars), - VolumeMounts: append(GetVolumeMounts(instance.Spec.ExtraMounts), - []corev1.VolumeMount{GetLogVolumeMount()}...), + Env: env.MergeEnvs([]corev1.EnvVar{}, envVars), + VolumeMounts: volumeMounts, Resources: instance.Spec.Resources, ReadinessProbe: readinessProbe, LivenessProbe: livenessProbe, }, }, NodeSelector: instance.Spec.NodeSelector, + Volumes: volumes, }, }, }, } - statefulset.Spec.Template.Spec.Volumes = append(GetVolumes( - manila.GetOwningManilaName(instance), - instance.Name, - instance.Spec.ExtraMounts), GetLogVolume()) + // If possible two pods of the same service should not // run on the same worker node. If this is not possible // the get still created on the same worker node. @@ -147,5 +181,5 @@ func StatefulSet( statefulset.Spec.Template.Spec.NodeSelector = instance.Spec.NodeSelector } - return statefulset + return statefulset, nil } diff --git a/pkg/manilascheduler/statefulset.go b/pkg/manilascheduler/statefulset.go index 2818018a..3d27387a 100644 --- a/pkg/manilascheduler/statefulset.go +++ b/pkg/manilascheduler/statefulset.go @@ -73,8 +73,18 @@ func StatefulSet( envVars["KOLLA_CONFIG_STRATEGY"] = env.SetValue("COPY_ALWAYS") envVars["CONFIG_HASH"] = env.SetValue(configHash) + volumes := GetVolumes( + manila.GetOwningManilaName(instance), + instance.Name, + instance.Spec.ExtraMounts) + volumeMounts := GetVolumeMounts(instance.Spec.ExtraMounts) + // Add the CA bundle + if instance.Spec.TLS.CaBundleSecretName != "" { + volumes = append(volumes, instance.Spec.TLS.CreateVolume()) + volumeMounts = append(volumeMounts, instance.Spec.TLS.CreateVolumeMounts(nil)...) + } statefulset := &appsv1.StatefulSet{ ObjectMeta: metav1.ObjectMeta{ Name: instance.Name, @@ -122,15 +132,12 @@ func StatefulSet( }, }, NodeSelector: instance.Spec.NodeSelector, + Volumes: volumes, }, }, }, } - statefulset.Spec.Template.Spec.Volumes = GetVolumes( - manila.GetOwningManilaName(instance), - instance.Name, - instance.Spec.ExtraMounts, - ) + // If possible two pods of the same service should not // run on the same worker node. If this is not possible // the get still created on the same worker node. diff --git a/pkg/manilashare/statefulset.go b/pkg/manilashare/statefulset.go index 0f455157..713eb826 100644 --- a/pkg/manilashare/statefulset.go +++ b/pkg/manilashare/statefulset.go @@ -83,11 +83,22 @@ func StatefulSet( envVars["MALLOC_MMAP_THRESHOLD_"] = env.SetValue("131072") envVars["MALLOC_TRIM_THRESHOLD_"] = env.SetValue("262144") + volumes := GetVolumes( + manila.GetOwningManilaName(instance), + instance.Name, + instance.Spec.ExtraMounts) + volumeMounts := GetVolumeMounts( instance.Name, instance.Spec.ExtraMounts, ) + // Add the CA bundle + if instance.Spec.TLS.CaBundleSecretName != "" { + volumes = append(volumes, instance.Spec.TLS.CreateVolume()) + volumeMounts = append(volumeMounts, instance.Spec.TLS.CreateVolumeMounts(nil)...) + } + statefulset := &appsv1.StatefulSet{ ObjectMeta: metav1.ObjectMeta{ Name: instance.Name, @@ -136,15 +147,12 @@ func StatefulSet( }, }, NodeSelector: instance.Spec.NodeSelector, + Volumes: volumes, }, }, }, } - statefulset.Spec.Template.Spec.Volumes = GetVolumes( - manila.GetOwningManilaName(instance), - instance.Name, - instance.Spec.ExtraMounts, - ) + // If possible two pods of the same service should not // run on the same worker node. If this is not possible // the get still created on the same worker node. diff --git a/templates/manila/config/10-manila_wsgi.conf b/templates/manila/config/10-manila_wsgi.conf index 7c170151..81a4d0a9 100644 --- a/templates/manila/config/10-manila_wsgi.conf +++ b/templates/manila/config/10-manila_wsgi.conf @@ -1,5 +1,7 @@ +{{ range $endpt, $vhost := .VHosts }} +# {{ $endpt }} vhost {{ $vhost.ServerName }} configuration - ServerName manilaapi.openstack.svc + ServerName {{ $vhost.ServerName }} ## Vhost docroot DocumentRoot "/var/www/cgi-bin/manila" @@ -16,11 +18,21 @@ ErrorLog /dev/stdout ServerSignature Off CustomLog /dev/stdout combined + +{{- if $vhost.TLS }} SetEnvIf X-Forwarded-Proto https HTTPS=1 + ## SSL directives + SSLEngine on + SSLCertificateFile "{{ $vhost.SSLCertificateFile }}" + SSLCertificateKeyFile "{{ $vhost.SSLCertificateKeyFile }}" +{{- end }} + ## WSGI configuration WSGIApplicationGroup %{GLOBAL} - WSGIDaemonProcess manila-api display-name=manila_wsgi group=manila processes=4 threads=1 user=manila - WSGIProcessGroup manila-api + WSGIDaemonProcess {{ $endpt }} display-name={{ $endpt }} group=manila processes=4 threads=1 user=manila + WSGIProcessGroup {{ $endpt }} WSGIScriptAlias / "/var/www/cgi-bin/manila/manila-wsgi" + WSGIPassAuthorization On +{{ end }} diff --git a/templates/manila/config/manila-api-config.json b/templates/manila/config/manila-api-config.json index f58c45b0..6c33a8b3 100644 --- a/templates/manila/config/manila-api-config.json +++ b/templates/manila/config/manila-api-config.json @@ -12,6 +12,28 @@ "dest": "/etc/httpd/conf.d/10-manila_wsgi.conf", "owner": "root", "perm": "0644" + }, + { + "source": "/var/lib/config-data/default/ssl.conf", + "dest": "/etc/httpd/conf.d/ssl.conf", + "owner": "root", + "perm": "0644" + }, + { + "source": "/var/lib/config-data/tls/certs/*", + "dest": "/etc/pki/tls/certs/", + "owner": "root", + "perm": "0640", + "optional": true, + "merge": true + }, + { + "source": "/var/lib/config-data/tls/private/*", + "dest": "/etc/pki/tls/private/", + "owner": "root", + "perm": "0600", + "optional": true, + "merge": true } ], "permissions": [ diff --git a/templates/manila/config/ssl.conf b/templates/manila/config/ssl.conf new file mode 100644 index 00000000..e3da4ecb --- /dev/null +++ b/templates/manila/config/ssl.conf @@ -0,0 +1,21 @@ + + SSLRandomSeed startup builtin + SSLRandomSeed startup file:/dev/urandom 512 + SSLRandomSeed connect builtin + SSLRandomSeed connect file:/dev/urandom 512 + + AddType application/x-x509-ca-cert .crt + AddType application/x-pkcs7-crl .crl + + SSLPassPhraseDialog builtin + SSLSessionCache "shmcb:/var/cache/mod_ssl/scache(512000)" + SSLSessionCacheTimeout 300 + Mutex default + SSLCryptoDevice builtin + SSLHonorCipherOrder On + SSLUseStapling Off + SSLStaplingCache "shmcb:/run/httpd/ssl_stapling(32768)" + SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5:!RC4:!3DES + SSLProtocol all -SSLv2 -SSLv3 -TLSv1 + SSLOptions StdEnvVars + diff --git a/test/functional/base_test.go b/test/functional/base_test.go index e5f67a6e..bfd3104c 100644 --- a/test/functional/base_test.go +++ b/test/functional/base_test.go @@ -15,7 +15,9 @@ package functional import ( "fmt" + . "github.com/onsi/gomega" + "golang.org/x/exp/maps" corev1 "k8s.io/api/core/v1" k8s_errors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -103,6 +105,15 @@ func GetManilaCommonSpec(spec map[string]interface{}) map[string]interface{} { return defaultSpec } +func GetTLSManilaSpec() map[string]interface{} { + return map[string]interface{}{ + "databaseInstance": "openstack", + "secret": SecretName, + "manilaAPI": GetTLSManilaAPISpec(), + "manilaScheduler": GetDefaultManilaSchedulerSpec(), + } +} + func GetDefaultManilaAPISpec() map[string]interface{} { return map[string]interface{}{ "secret": SecretName, @@ -234,6 +245,25 @@ func GetManilaShare(name types.NamespacedName) *manilav1.ManilaShare { return instance } +func GetTLSManilaAPISpec() map[string]interface{} { + spec := GetDefaultManilaAPISpec() + maps.Copy(spec, map[string]interface{}{ + "tls": map[string]interface{}{ + "api": map[string]interface{}{ + "internal": map[string]interface{}{ + "secretName": InternalCertSecretName, + }, + "public": map[string]interface{}{ + "secretName": PublicCertSecretName, + }, + }, + "caBundleSecretName": CABundleSecretName, + }, + }) + + return spec +} + func ManilaAPIConditionGetter(name types.NamespacedName) condition.Conditions { instance := GetManilaAPI(name) return instance.Status.Conditions diff --git a/test/functional/manila_controller_test.go b/test/functional/manila_controller_test.go index c2b65c4d..48f6a7f1 100644 --- a/test/functional/manila_controller_test.go +++ b/test/functional/manila_controller_test.go @@ -445,4 +445,158 @@ var _ = Describe("Manila controller", func() { Expect(endpoints).To(HaveKeyWithValue("internal", "http://manila-internal."+manila.Namespace+".svc:8786/v2")) }) }) + When("A Manila with TLS is created", func() { + BeforeEach(func() { + DeferCleanup(th.DeleteInstance, CreateManila(manilaTest.Instance, GetTLSManilaSpec())) + DeferCleanup(k8sClient.Delete, ctx, CreateManilaMessageBusSecret(manilaTest.Instance.Namespace, manilaTest.RabbitmqSecretName)) + DeferCleanup(th.DeleteInstance, CreateManilaAPI(manilaTest.Instance, GetDefaultManilaAPISpec())) + DeferCleanup(th.DeleteInstance, CreateManilaScheduler(manilaTest.Instance, GetDefaultManilaSchedulerSpec())) + DeferCleanup(th.DeleteInstance, CreateManilaShare(manilaTest.Instance, GetDefaultManilaShareSpec())) + DeferCleanup( + mariadb.DeleteDBService, + mariadb.CreateDBService( + manilaTest.Instance.Namespace, + GetManila(manilaName).Spec.DatabaseInstance, + corev1.ServiceSpec{ + Ports: []corev1.ServicePort{{Port: 3306}}, + }, + ), + ) + infra.SimulateTransportURLReady(manilaTest.ManilaTransportURL) + DeferCleanup(infra.DeleteMemcached, infra.CreateMemcached(namespace, manilaTest.MemcachedInstance, memcachedSpec)) + infra.SimulateMemcachedReady(manilaTest.ManilaMemcached) + DeferCleanup(keystone.DeleteKeystoneAPI, keystone.CreateKeystoneAPI(manilaTest.Instance.Namespace)) + mariadb.SimulateMariaDBDatabaseCompleted(manilaTest.Instance) + mariadb.SimulateMariaDBAccountCompleted(manilaTest.Instance) + th.SimulateJobSuccess(manilaTest.ManilaDBSync) + }) + + It("reports that the CA secret is missing", func() { + th.ExpectConditionWithDetails( + manilaTest.ManilaAPI, + ConditionGetterFunc(ManilaAPIConditionGetter), + condition.TLSInputReadyCondition, + corev1.ConditionFalse, + condition.ErrorReason, + fmt.Sprintf("TLSInput error occured in TLS sources Secret %s/combined-ca-bundle not found", namespace), + ) + + th.ExpectConditionWithDetails( + manilaTest.ManilaScheduler, + ConditionGetterFunc(ManilaSchedulerConditionGetter), + condition.TLSInputReadyCondition, + corev1.ConditionFalse, + condition.ErrorReason, + fmt.Sprintf("TLSInput error occured in TLS sources Secret %s/combined-ca-bundle not found", namespace), + ) + }) + + It("reports that the internal cert secret is missing", func() { + DeferCleanup(k8sClient.Delete, ctx, th.CreateCABundleSecret(manilaTest.CABundleSecret)) + th.ExpectConditionWithDetails( + manilaTest.ManilaAPI, + ConditionGetterFunc(ManilaAPIConditionGetter), + condition.TLSInputReadyCondition, + corev1.ConditionFalse, + condition.ErrorReason, + fmt.Sprintf("TLSInput error occured in TLS sources Secret %s/internal-tls-certs not found", namespace), + ) + }) + + It("reports that the public cert secret is missing", func() { + DeferCleanup(k8sClient.Delete, ctx, th.CreateCABundleSecret(manilaTest.CABundleSecret)) + DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(manilaTest.InternalCertSecret)) + th.ExpectConditionWithDetails( + manilaTest.ManilaAPI, + ConditionGetterFunc(ManilaAPIConditionGetter), + condition.TLSInputReadyCondition, + corev1.ConditionFalse, + condition.ErrorReason, + fmt.Sprintf("TLSInput error occured in TLS sources Secret %s/public-tls-certs not found", namespace), + ) + }) + + It("Creates ManilaAPI", func() { + DeferCleanup(k8sClient.Delete, ctx, th.CreateCABundleSecret(manilaTest.CABundleSecret)) + DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(manilaTest.InternalCertSecret)) + DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(manilaTest.PublicCertSecret)) + keystone.SimulateKeystoneEndpointReady(manilaTest.ManilaKeystoneEndpoint) + + ManilaAPIExists(manilaTest.Instance) + + d := th.GetStatefulSet(manilaTest.ManilaAPI) + // Check the resulting deployment fields + Expect(int(*d.Spec.Replicas)).To(Equal(1)) + + Expect(d.Spec.Template.Spec.Volumes).To(HaveLen(9)) + Expect(d.Spec.Template.Spec.Containers).To(HaveLen(2)) + + // cert deployment volumes + th.AssertVolumeExists(manilaTest.CABundleSecret.Name, d.Spec.Template.Spec.Volumes) + th.AssertVolumeExists(manilaTest.InternalCertSecret.Name, d.Spec.Template.Spec.Volumes) + th.AssertVolumeExists(manilaTest.PublicCertSecret.Name, d.Spec.Template.Spec.Volumes) + + // cert volumeMounts + container := d.Spec.Template.Spec.Containers[1] + th.AssertVolumeMountExists(manilaTest.InternalCertSecret.Name, "tls.key", container.VolumeMounts) + th.AssertVolumeMountExists(manilaTest.InternalCertSecret.Name, "tls.crt", container.VolumeMounts) + th.AssertVolumeMountExists(manilaTest.PublicCertSecret.Name, "tls.key", container.VolumeMounts) + th.AssertVolumeMountExists(manilaTest.PublicCertSecret.Name, "tls.crt", container.VolumeMounts) + th.AssertVolumeMountExists(manilaTest.CABundleSecret.Name, "tls-ca-bundle.pem", container.VolumeMounts) + + Expect(container.ReadinessProbe.HTTPGet.Scheme).To(Equal(corev1.URISchemeHTTPS)) + Expect(container.LivenessProbe.HTTPGet.Scheme).To(Equal(corev1.URISchemeHTTPS)) + }) + + It("reconfigures the manila pods when CA changes", func() { + DeferCleanup(k8sClient.Delete, ctx, th.CreateCABundleSecret(manilaTest.CABundleSecret)) + DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(manilaTest.InternalCertSecret)) + DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(manilaTest.PublicCertSecret)) + keystone.SimulateKeystoneEndpointReady(manilaTest.ManilaKeystoneEndpoint) + + ManilaAPIExists(manilaTest.Instance) + ManilaSchedulerExists(manilaTest.Instance) + + // Grab the current config hash + apiOriginalHash := GetEnvVarValue( + th.GetStatefulSet(manilaTest.ManilaAPI).Spec.Template.Spec.Containers[0].Env, "CONFIG_HASH", "") + Expect(apiOriginalHash).NotTo(BeEmpty()) + schedulerOriginalHash := GetEnvVarValue( + th.GetStatefulSet(manilaTest.ManilaScheduler).Spec.Template.Spec.Containers[0].Env, "CONFIG_HASH", "") + Expect(schedulerOriginalHash).NotTo(BeEmpty()) + + // Change the content of the CA secret + th.UpdateSecret(manilaTest.CABundleSecret, "tls-ca-bundle.pem", []byte("DifferentCAData")) + + // Assert that the deployment is updated + Eventually(func(g Gomega) { + newHash := GetEnvVarValue( + th.GetStatefulSet(manilaTest.ManilaAPI).Spec.Template.Spec.Containers[0].Env, "CONFIG_HASH", "") + g.Expect(newHash).NotTo(BeEmpty()) + g.Expect(newHash).NotTo(Equal(apiOriginalHash)) + }, timeout, interval).Should(Succeed()) + Eventually(func(g Gomega) { + newHash := GetEnvVarValue( + th.GetStatefulSet(manilaTest.ManilaScheduler).Spec.Template.Spec.Containers[0].Env, "CONFIG_HASH", "") + g.Expect(newHash).NotTo(BeEmpty()) + g.Expect(newHash).NotTo(Equal(schedulerOriginalHash)) + }, timeout, interval).Should(Succeed()) + }) + + It("Assert Services are created", func() { + DeferCleanup(k8sClient.Delete, ctx, th.CreateCABundleSecret(manilaTest.CABundleSecret)) + DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(manilaTest.InternalCertSecret)) + DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(manilaTest.PublicCertSecret)) + keystone.SimulateKeystoneEndpointReady(manilaTest.ManilaKeystoneEndpoint) + + th.AssertServiceExists(manilaTest.ManilaServicePublic) + th.AssertServiceExists(manilaTest.ManilaServiceInternal) + + // check keystone endpoints + keystoneEndpoint := keystone.GetKeystoneEndpoint(manilaTest.ManilaKeystoneEndpoint) + endpoints := keystoneEndpoint.Spec.Endpoints + Expect(endpoints).To(HaveKeyWithValue("public", "https://manila-public."+namespace+".svc:8786/v2")) + Expect(endpoints).To(HaveKeyWithValue("internal", "https://manila-internal."+namespace+".svc:8786/v2")) + }) + }) }) diff --git a/test/functional/manila_test_data.go b/test/functional/manila_test_data.go index 13b90e34..479d7db6 100644 --- a/test/functional/manila_test_data.go +++ b/test/functional/manila_test_data.go @@ -19,12 +19,19 @@ package functional import ( "fmt" + "k8s.io/apimachinery/pkg/types" ) const ( // MemcachedInstance - name of the memcached instance MemcachedInstance = "memcached" + //PublicCertSecretName - + PublicCertSecretName = "public-tls-certs" + //InternalCertSecretName - + InternalCertSecretName = "internal-tls-certs" + //CABundleSecretName - + CABundleSecretName = "combined-ca-bundle" ) // ManilaTestData is the data structure used to provide input data to envTest @@ -57,6 +64,9 @@ type ManilaTestData struct { ManilaDefaultShare types.NamespacedName InternalAPINAD types.NamespacedName ContainerImage string + CABundleSecret types.NamespacedName + InternalCertSecret types.NamespacedName + PublicCertSecret types.NamespacedName } // GetManilaTestData is a function that initialize the ManilaTestData @@ -159,5 +169,18 @@ func GetManilaTestData(manilaName types.NamespacedName) ManilaTestData { ManilaPassword: "12345678", ManilaServiceUser: "manila", ContainerImage: "test://manila", + CABundleSecret: types.NamespacedName{ + Namespace: manilaName.Namespace, + Name: CABundleSecretName, + }, + + InternalCertSecret: types.NamespacedName{ + Namespace: manilaName.Namespace, + Name: InternalCertSecretName, + }, + PublicCertSecret: types.NamespacedName{ + Namespace: manilaName.Namespace, + Name: PublicCertSecretName, + }, } } diff --git a/test/kuttl/tests/manila-multibackend/01-assert.yaml b/test/kuttl/tests/manila-multibackend/01-assert.yaml index d3af2ed2..a777270d 100644 --- a/test/kuttl/tests/manila-multibackend/01-assert.yaml +++ b/test/kuttl/tests/manila-multibackend/01-assert.yaml @@ -205,6 +205,10 @@ status: reason: Ready status: "True" type: ServiceConfigReady + - message: Input data complete + reason: Ready + status: "True" + type: TLSInputReady readyCount: 1 --- # when using image digests the containerImage URLs are SHA's so we verify them with a script diff --git a/test/kuttl/tests/manila-multibackend/02-assert.yaml b/test/kuttl/tests/manila-multibackend/02-assert.yaml index bd28a69a..9fbc8693 100644 --- a/test/kuttl/tests/manila-multibackend/02-assert.yaml +++ b/test/kuttl/tests/manila-multibackend/02-assert.yaml @@ -211,6 +211,10 @@ status: reason: Ready status: "True" type: ServiceConfigReady + - message: Input data complete + reason: Ready + status: "True" + type: TLSInputReady readyCount: 1 --- apiVersion: manila.openstack.org/v1beta1 @@ -250,4 +254,8 @@ status: reason: Ready status: "True" type: ServiceConfigReady + - message: Input data complete + reason: Ready + status: "True" + type: TLSInputReady readyCount: 1 diff --git a/test/kuttl/tests/manila-multibackend/03-assert.yaml b/test/kuttl/tests/manila-multibackend/03-assert.yaml index cb12a501..99a469f6 100644 --- a/test/kuttl/tests/manila-multibackend/03-assert.yaml +++ b/test/kuttl/tests/manila-multibackend/03-assert.yaml @@ -207,6 +207,10 @@ status: reason: Ready status: "True" type: ServiceConfigReady + - message: Input data complete + reason: Ready + status: "True" + type: TLSInputReady readyCount: 1 --- # when using image digests the containerImage URLs are SHA's so we verify them with a script diff --git a/test/kuttl/tests/manila-tls/01-assert.yaml b/test/kuttl/tests/manila-tls/01-assert.yaml new file mode 100644 index 00000000..8d5a6043 --- /dev/null +++ b/test/kuttl/tests/manila-tls/01-assert.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Secret +metadata: + name: cert-manila-internal-svc +--- +apiVersion: v1 +kind: Secret +metadata: + name: cert-manila-public-svc +--- +apiVersion: v1 +kind: Secret +metadata: + name: combined-ca-bundle diff --git a/test/kuttl/tests/manila-tls/01-tls_certificates.yaml b/test/kuttl/tests/manila-tls/01-tls_certificates.yaml new file mode 100644 index 00000000..8f6f8797 --- /dev/null +++ b/test/kuttl/tests/manila-tls/01-tls_certificates.yaml @@ -0,0 +1,31 @@ +# Hardcoded certs secret, so kuttl doesn't require cert-manager at test runtime +apiVersion: v1 +kind: Secret +metadata: + name: combined-ca-bundle + labels: + service: manila +data: + tls-ca-bundle.pem: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJmVENDQVNLZ0F3SUJBZ0lRUHhtRFFscmxjNTNhb215RVU5MU9pakFLQmdncWhrak9QUVFEQWpBZU1Sd3cKR2dZRFZRUURFeE5yZFhSMGJDMXpaV3htYzJsbmJtVmtMV05oTUI0WERUSXpNVEF4T0RFeU1EazFNMW9YRFRJMApNREV4TmpFeU1EazFNMW93SGpFY01Cb0dBMVVFQXhNVGEzVjBkR3d0YzJWc1puTnBaMjVsWkMxallUQlpNQk1HCkJ5cUdTTTQ5QWdFR0NDcUdTTTQ5QXdFSEEwSUFCSVdJY0JiR0cveEg4Lzlkc2lMbkJCdnRqcEZoQ2JRM3U4R0EKZXBVcnhTY25XM0hrZ2hrc1BCVE12M3NCeGdnVFQwL0Eva0dtazRYTkJ0dElnbUZJaFBpalFqQkFNQTRHQTFVZApEd0VCL3dRRUF3SUNwREFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQjBHQTFVZERnUVdCQlFKaDd3VklFYjgxcFlsCkl3RDAraTBwSnlCTjNqQUtCZ2dxaGtqT1BRUURBZ05KQURCR0FpRUF2a3h5RzZjNzltSDlRWHRIVWFSM014REkKUUVRRGVtL1hZR3VGY1ZCUDJpQUNJUUNFeEZqeStQUTBkNFU5dEJacTVOd1gzdmxibnQxVlNCYWE5VFIrNkNkbAozdz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tIyByb290Y2EtaW50ZXJuYWwKLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJmekNDQVNhZ0F3SUJBZ0lRUWxlcTNZcDBtU2kwVDNiTm03Q29UVEFLQmdncWhrak9QUVFEQWpBZ01SNHcKSEFZRFZRUURFeFZ5YjI5MFkyRXRhM1YwZEd3dGFXNTBaWEp1WVd3d0hoY05NalF3TVRFMU1URTBOelUwV2hjTgpNelF3TVRFeU1URTBOelUwV2pBZ01SNHdIQVlEVlFRREV4VnliMjkwWTJFdGEzVjBkR3d0YVc1MFpYSnVZV3d3CldUQVRCZ2NxaGtqT1BRSUJCZ2dxaGtqT1BRTUJCd05DQUFTRk9rNHJPUldVUGhoTjUrK09EN1I2MW5Gb1lBY0QKenpvUS91SW93NktjeGhwRWNQTDFxb3ZZUGxUYUJabEh3c2FpNE50VHA4aDA1RHVRSGZKOE9JNXFvMEl3UURBTwpCZ05WSFE4QkFmOEVCQU1DQXFRd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBZEJnTlZIUTRFRmdRVXE3TGtFSk1TCm1MOVpKWjBSOUluKzZkclhycEl3Q2dZSUtvWkl6ajBFQXdJRFJ3QXdSQUlnVlN1K00ydnZ3QlF3eTJHMVlhdkkKQld2RGtSNlRla0I5U0VqdzJIblRSMWtDSUZSNFNkWGFPQkFGWjVHa2RLWCtSY2IzaDFIZm52eFJEVW96bTl2agphenp3Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KIyByb290Y2EtcHVibGljCi0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlCZXpDQ0FTS2dBd0lCQWdJUU5IREdZc0JzNzk4aWJERDdxL28ybGpBS0JnZ3Foa2pPUFFRREFqQWVNUnd3CkdnWURWUVFERXhOeWIyOTBZMkV0YTNWMGRHd3RjSFZpYkdsak1CNFhEVEkwTURFeE5URXdNVFV6TmxvWERUTTAKTURFeE1qRXdNVFV6Tmxvd0hqRWNNQm9HQTFVRUF4TVRjbTl2ZEdOaExXdDFkSFJzTFhCMVlteHBZekJaTUJNRwpCeXFHU000OUFnRUdDQ3FHU000OUF3RUhBMElBQkQ3OGF2WHFocmhDNXc4czlXa2Q0SXBiZUV1MDNDUitYWFVkCmtEek9SeXhhOXdjY0lkRGl2YkdKakpGWlRUY1ZtYmpxMUJNWXNqcjEyVUlFNUVUM1ZscWpRakJBTUE0R0ExVWQKRHdFQi93UUVBd0lDcERBUEJnTlZIUk1CQWY4RUJUQURBUUgvTUIwR0ExVWREZ1FXQkJUS0ppeldVSjllVUtpMQpkczBscjZjNnNEN0VCREFLQmdncWhrak9QUVFEQWdOSEFEQkVBaUJJWndZcTYxQnFNSmFCNlVjRm9Sc3hlY3dICjV6L3pNT2RyT3llMG1OaThKZ0lnUUxCNHdES3JwZjl0WDJsb00rMHVUb3BBRFNZSW5yY2ZWdTRGQnVZVTNJZz0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= +--- +apiVersion: v1 +kind: Secret +metadata: + name: cert-manila-internal-svc + labels: + service: manila +data: + ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJkVENDQVJxZ0F3SUJBZ0lRTkZUVDE2eTc0RGJaOGJTL25ESDBkakFLQmdncWhrak9QUVFEQWpBYU1SZ3cKRmdZRFZRUURFdzl5YjI5MFkyRXRhVzUwWlhKdVlXd3dIaGNOTWpRd01URXdNVFV5T0RBMFdoY05NalF3TkRBNQpNVFV5T0RBMFdqQWFNUmd3RmdZRFZRUURFdzl5YjI5MFkyRXRhVzUwWlhKdVlXd3dXVEFUQmdjcWhrak9QUUlCCkJnZ3Foa2pPUFFNQkJ3TkNBQVFjK2d5OVFCNmw1NFNBQlkxUTJKZWx5MEhSTGEvMzlkRUxzU2RhNnJDRENKQWwKWjJ2bGlGbUo5WVlJNCtSbGRIejJWNXYvYjBpK2x0RjcxMGZ1OHJTbW8wSXdRREFPQmdOVkhROEJBZjhFQkFNQwpBcVF3RHdZRFZSMFRBUUgvQkFVd0F3RUIvekFkQmdOVkhRNEVGZ1FVeUsyc0hXaUxHNnR6bWlVbENkUmhsRTJLCnNHSXdDZ1lJS29aSXpqMEVBd0lEU1FBd1JnSWhBSzVtTi9zQlBVcXAwckd1QjhnMVRxY21KR3ZMVUpyNjlnaEEKaEozMldCT1BBaUVBbEtwU0dVTzhac25UcVQrQ1hWbXNuWkxBcVJMV1NhbUI5U2NyczNDZ05zWT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= + tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNhekNDQWhHZ0F3SUJBZ0lSQU1GRmpzWkpHY3BuaVBFNXNmQytrOEV3Q2dZSUtvWkl6ajBFQXdJd0dqRVkKTUJZR0ExVUVBeE1QY205dmRHTmhMV2x1ZEdWeWJtRnNNQjRYRFRJME1ERXhOVEV4TkRnMU1sb1hEVE0wTURFeApNakV4TkRnMU1sb3dBRENDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFNRzhQSWwzCnc4RXdXMHdUUG5qRURpU2dTdVI4WHJaajcrSjYyUkJMTHJ3ZUxKdWd1Wm1MaUh3M09uSldWa0hEOVpaZzlYSGUKbGZ6UDY3Wi8rYXBNMzJ5VWJTVUcrRjlBdXlGMHRTK2lPODFkUFRSY1luNzVBK0xWdnk1UkVpOGIvTFkzNTNPbgpxUEhuK2kyeTNLUC9HZkhjSi9lVlVXNFJkV2wyTHEyejRtRDRUK2twS0VwSnRGSTJQa2lrSVNOV2RRdmtEeW1WClF3a1B3U01FVy9yaEdGL2s3b0gvVWtwdy9wU1N1R0M2a1lpSnlwOTFHT0xCMlVoc254Z3dLelh5VS9MdGFrZXoKS2RHSFUvNUNLTTRKczg0ZnlNTDBBNXMxalpZQXZEWkVLNEgvYVpCb3EzV0NoQ1R4WWhIOVVuczhIQy9KbHJCMApHaitwVHNuaEc2cUlFQ2tDQXdFQUFhT0JoakNCZ3pBT0JnTlZIUThCQWY4RUJBTUNCYUF3RXdZRFZSMGxCQXd3CkNnWUlLd1lCQlFVSEF3RXdEQVlEVlIwVEFRSC9CQUl3QURBZkJnTlZIU01FR0RBV2dCVElyYXdkYUlzYnEzT2EKSlNVSjFHR1VUWXF3WWpBdEJnTlZIUkVCQWY4RUl6QWhnaDlyWlhsemRHOXVaUzFwYm5SbGNtNWhiQzV2Y0dWdQpjM1JoWTJzdWMzWmpNQW9HQ0NxR1NNNDlCQU1DQTBnQU1FVUNJRTFJYXcxcnRnU0ROZmxBSjJRek9VQjJxU1llCk03ZWdsaXZLVW01cmVOZThBaUVBMU93SGcwQ1YxOUNhYUpSSi9SS25UcXNJTGhNdjBEUVNPdnFwbWc0MWZDTT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= + tls.key: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb3dJQkFBS0NBUUVBd2J3OGlYZkR3VEJiVEJNK2VNUU9KS0JLNUh4ZXRtUHY0bnJaRUVzdXZCNHNtNkM1Cm1ZdUlmRGM2Y2xaV1FjUDFsbUQxY2Q2Vi9NL3J0bi81cWt6ZmJKUnRKUWI0WDBDN0lYUzFMNkk3elYwOU5GeGkKZnZrRDR0Vy9MbEVTTHh2OHRqZm5jNmVvOGVmNkxiTGNvLzhaOGR3bjk1VlJiaEYxYVhZdXJiUGlZUGhQNlNrbwpTa20wVWpZK1NLUWhJMVoxQytRUEtaVkRDUS9CSXdSYit1RVlYK1R1Z2Y5U1NuRCtsSks0WUxxUmlJbktuM1VZCjRzSFpTR3lmR0RBck5mSlQ4dTFxUjdNcDBZZFQva0lvemdtenpoL0l3dlFEbXpXTmxnQzhOa1FyZ2Y5cGtHaXIKZFlLRUpQRmlFZjFTZXp3Y0w4bVdzSFFhUDZsT3llRWJxb2dRS1FJREFRQUJBb0lCQVFDQ0hweUdNK05OY040UQo1V2Z6RXJMeEZKdlloRlBVcXFDbWU1NG9uR1ppUU4zekZPc3pYbzBuNkt3ZnVTOHI4cUtUQXNJM1hhbGRhSVRIClNZTDFSN1pVSmdoOGN3Y0VhdVNFbnU5R2MrODRpbVFlTStLUHAwNWQzdlFOOXJPQTRvcEVGSjRtaHJnbzZZYVYKaE9rK1dJc2piNXVFWlV5UTRiYjdRejRzdW9IVVlDYXFkVGlqU1lYQzNOd092YUlwa3pTNEo0cU5CUlhyYnNWSwowaGt4ZFNIY1hKNEREN0hybktpcEsxT2xUbUVObVZYbmlaNnRPcWc2eUNFeXFteWN0UnlUVTZRRzVPbVM2clJVCm82Z25EclA1TlgwRUhuakY3b1lka0JVbGJxWk96UHVGbG5CdUVKOFpTUEtOZHA5ejhuS3lqbGJiL0YxWGRDdEkKZERhVUhmREZBb0dCQVBFZkZZbDhPb2VhU21oSElKcGpxd3RCanYrRjFuOXNJbHNuZWNyQ1JmN243RW53d1hXaQpReStXQ3l6aDJGRVVad1dod2RQeXFJT3NVaG1vaXBIQmN3NlVUaW9xalM4SlpvSDlURFBQUEd5OXIwMHZwRkNuCnFkdjNXMkhWVytRckMrWk1nc2ZKdUlTTnFtbFdFeHpCNFBJQWRHQTdKVzFMY0ZCcG1Zd25DdXZyQW9HQkFNMncKbS94cVRhMmgySjFnNUI0elE5UnBhM280SEoyL2pTaHEzNW9heVNGNWJDYWtnWGRxek0yU0FwQ0x4dzlvY3doRAp3WWRaMWliaHl6b1dDQVZZZ0RlaXViUi96ZTN3Nzk4NktScUNmNnptMk5HOEoxODVDZDdKSjBiaTZBTTgvalpTCnFqWkJIK0FqanF2aFFJM0FMMEdzNlFvc2Z3L3hOL2k1cG00UWM5TTdBb0dBZjZCbFpQVmxnWnN3WVV1c3ZTdWUKUUlIOTc5Qm12ZUY5dWVRR09rVmtpVTAzSzlnTWZuaFp1WmxnNXV2UDlQS29xVGw2Zi9aRUxoWUxDdHZFSk94UgpPMWxTbWswVmw5MFE3aU1scjVLMHVCWWE4TzhUdVVGVnprRjZsQ2s3ejJUZGtwUFM4VzhiaE1YN2VtLytBODIzCmhFQ3JXTGhWMGlrSkZQY2dPQ2YrUnVzQ2dZQTYvcld1cnhxNmUxb3l3WENNVE8zZWhhSUMrd2NTSTdlcjZRTmIKSXVXZlNVRkEwQndtRVNiT3ExczY5Q3hTK2dWTVVJcTRkSWJjdmhSWkE2cW5SZHY0bVI2a2E2ZTM0RXdjZllUKwppb0Z1S1FQMUcvODY2NVF1SndteDVqRGZoT1h3MU1MbkxzU2l0L0FhMGs5K21LbTFMNC9qa0NHZGcvVW16TEMwCmp0bDVzd0tCZ0VPTVI3ODVLT2hyNXFoWmE2b0MvU25JeEptS1FxTWdXU0NGV1pGMDZrVlRnSmthb1hwUEl0bUIKOUZGbE1nTTJSeC91S2V3YTNDSTdQK240ek1uYSswTmhDL0RwNkMxVFVsVWlrcnJYQ3I5a1NPR2dXaEFISDljTwozRENvdkhOcE1PaG51dnhoMlpDeTdYbjFJeGgxWXdlYnVobFZzeTFvR0tDQ0lJb00rOVg1Ci0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg== +--- +apiVersion: v1 +kind: Secret +metadata: + name: cert-manila-public-svc + labels: + service: manila +data: + ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJlekNDQVNLZ0F3SUJBZ0lRTkhER1lzQnM3OThpYkREN3EvbzJsakFLQmdncWhrak9QUVFEQWpBZU1Sd3cKR2dZRFZRUURFeE55YjI5MFkyRXRhM1YwZEd3dGNIVmliR2xqTUI0WERUSTBNREV4TlRFd01UVXpObG9YRFRNMApNREV4TWpFd01UVXpObG93SGpFY01Cb0dBMVVFQXhNVGNtOXZkR05oTFd0MWRIUnNMWEIxWW14cFl6QlpNQk1HCkJ5cUdTTTQ5QWdFR0NDcUdTTTQ5QXdFSEEwSUFCRDc4YXZYcWhyaEM1dzhzOVdrZDRJcGJlRXUwM0NSK1hYVWQKa0R6T1J5eGE5d2NjSWREaXZiR0pqSkZaVFRjVm1ianExQk1Zc2pyMTJVSUU1RVQzVmxxalFqQkFNQTRHQTFVZApEd0VCL3dRRUF3SUNwREFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQjBHQTFVZERnUVdCQlRLSml6V1VKOWVVS2kxCmRzMGxyNmM2c0Q3RUJEQUtCZ2dxaGtqT1BRUURBZ05IQURCRUFpQklad1lxNjFCcU1KYUI2VWNGb1JzeGVjd0gKNXovek1PZHJPeWUwbU5pOEpnSWdRTEI0d0RLcnBmOXRYMmxvTSswdVRvcEFEU1lJbnJjZlZ1NEZCdVlVM0lnPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== + tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNiVENDQWhPZ0F3SUJBZ0lSQUtacXlMbUhLNC9VRTZmMi9LNWxiQnN3Q2dZSUtvWkl6ajBFQXdJd0hqRWMKTUJvR0ExVUVBeE1UY205dmRHTmhMV3QxZEhSc0xYQjFZbXhwWXpBZUZ3MHlOREF4TVRVeE1ESXdOVFJhRncwegpOREF4TVRJeE1ESXdOVFJhTUFBd2dnRWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUUMxCjhDcFJRVG1abHNzSUlmZ2hIK2ltUUtFMFdZVlJOeS8vMVM0aDVtV2tBcUZiVkhoUmptbFJ2cCtQUWpKOU16TDUKMXpXdmYxandEQ2pzYUxvL2FwSW9OSXJIcjN4TTRoYWl0emU0RjFwZzNoL3MvblExNWN5Q2U5dHdHR0RuWEllMwo2djBuNE9LNnAwSWJjcVk2Q1RBMTBwcGJZa3V6bzdVRkx6ZWxsc1ZhRlhzZ21JWDg4bTRXNmNBTi84cjJPWUI3Ck9HM0ZNOXAxSUFxT0hyT21EelFlTldqOUVjQy9TSCs5MGg4c1FyY1pvMWtWa1g1b2tpSUhDZjRlc2o3Q08rTGgKR3lsTmZyRzl6QTlPM0c3QVNDWVdPVWwyZTBhNHhZbE9QMmI4ejFEV3NIMTBVYXVsZHlRQXNtbkhtaW1VNzBmKwpEazZkQ1hXVHN4cGZ2cXphOVR4YkFnTUJBQUdqZ1lRd2dZRXdEZ1lEVlIwUEFRSC9CQVFEQWdXZ01CTUdBMVVkCkpRUU1NQW9HQ0NzR0FRVUZCd01CTUF3R0ExVWRFd0VCL3dRQ01BQXdId1lEVlIwakJCZ3dGb0FVeWlZczFsQ2YKWGxDb3RYYk5KYStuT3JBK3hBUXdLd1lEVlIwUkFRSC9CQ0V3SDRJZGEyVjVjM1J2Ym1VdGNIVmliR2xqTG05dwpaVzV6ZEdGamF5NXpkbU13Q2dZSUtvWkl6ajBFQXdJRFNBQXdSUUlnTzAzT2JmNm9uV2RiZG4xa282OVpuTFhMCmtQSHFYU3VRNlcxTDFvY3NDR3NDSVFEakEyVm9pWVdYN0hzSjVGNkZYV3FsZnl0RmduVVgvTmhvT1lIVnB2TWQKSGc9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== + tls.key: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcEFJQkFBS0NBUUVBdGZBcVVVRTVtWmJMQ0NINElSL29wa0NoTkZtRlVUY3YvOVV1SWVabHBBS2hXMVI0ClVZNXBVYjZmajBJeWZUTXkrZGMxcjM5WThBd283R2k2UDJxU0tEU0t4Njk4VE9JV29yYzN1QmRhWU40ZjdQNTAKTmVYTWdudmJjQmhnNTF5SHQrcjlKK0RpdXFkQ0czS21PZ2t3TmRLYVcySkxzNk8xQlM4M3BaYkZXaFY3SUppRgovUEp1RnVuQURmL0s5am1BZXpodHhUUGFkU0FLamg2enBnODBIalZvL1JIQXYwaC92ZElmTEVLM0dhTlpGWkYrCmFKSWlCd24rSHJJK3dqdmk0UnNwVFg2eHZjd1BUdHh1d0VnbUZqbEpkbnRHdU1XSlRqOW0vTTlRMXJCOWRGR3IKcFhja0FMSnB4NW9wbE85SC9nNU9uUWwxazdNYVg3NnMydlU4V3dJREFRQUJBb0lCQUd0eVdvdUNLYkk3Qzh6Ugp3dWhOSCtpUFlxUzMrYlB0RTd2UytsdXE1WHZtMGNST0xvQjd5bGNzYks3K09UTVhlWk56TlpGZmMvYlFONXJtCmZwZlZLRnYySzcraU01WjBMMG9KU2k2K0cvSDVQSUdLQkxlUDd5ZGdYa2ZsSGRXRkgrSE9OWlBIakI4UGlFc04KZW4zcnp6ejZFNDdFamxDWTdkOFI4NXNuWDRYREN2bG1CQnhvcnpqVERuK1dTWWpKS09SSk5zY3oxQXFYR1VjVwpQaHRNYkwybC8zN2hPbTA4SjRRWXowTWduOWE5VUFXLzFNS2lXbHVpc1NHNG9YaFNPS1hkdk1IS3VxS09sUDJzCk9xWjBlR3JBNmpKdWlmZVY2Q2NIU2p3VUgwdHpiMmdZQVM2cm5RQlREbFkxR1I4Skx0YWhWREtqdUwyV0hjclkKbHhCOGZBRUNnWUVBMWpxc01weFo5cG9LNkpmRDZzVTU0ZUU1UWlNYlB0MERRZjlYU1J6NW5zQXlraHdKWEZDVwpKWTNiU3BhcGREeEgzakpDQ0VzN3NSWUhUeDRzNVJQSldtWC9oZTFwVEs4TDVlaFV2TmVudG5nVTB3aE4rZVEzCjl4Sk1VbHVYdGkvU0FpNi9jQk5HY1ZjQjFGRStmVzY0VDhqYVVQakRrL0Z2dFRXOXkzZnNVZnNDZ1lFQTJXbXMKYStuZ2RaS24rVTlCMlFCTXB0K0RLL0txNVF6RW1qZDVMSjJMb3FLUjhGbjlpVVZoUVljUEpobDJVV3VjTTl0RQp0QUlYdEY0anVUejlqUUNMMGQ5a09DeCswdTBKUFZJejdlVmFFVGs1enF0azRsTnhVUkJhQ3pCUEJkdjZJd3BDCkR4UXJWRXBXYlMra1JvYTNKSElOdHdjUWt2Nk50N1JIajd1WEVTRUNnWUJsREozbTdZc2Q0QUZmUHg4Qm9YQXgKRkt5T2ZzSytQei9uSkl0R2lHMVNMWFJ0S041ZGRnR3N5eUh5SitqY1ZBYk9UMFNJWnZ4TUJva0NEOGk3Y1Q3Ygo3aHErVUlNSDBkVzU1NEg0NVh4TmZJek9FaSs5dktHTllFc3gyZFJROG5PTDVnTVUyWEt6eVllcVgzd3JiRXR5CkR0cXpzUE9IMkMySiswU0FNaHY5ZXdLQmdRQ2szeWs5TUwvaUNWUk9rTmNybTdtRk5xeS9rQ2dleU43eTRDeUoKTS9RbllrZHYwSjZmRWJrZU96QzJ3TXBrRmtuL1hVR3RqSVN6YUV5STlnS0ZnaXVGL1hWL3orWmhTQllncFl6eAoxR0xIK3ZDbWxIMU4wTjkzRFFKcng3ZTFoc3NhOVhXQS85ZVg5VU96UzFTMWt3V2hvc2haeXdhN29rU1FVaXVPCmlVQ1hZUUtCZ1FEUVZUVHc3WUY3QzNTVmg5OWRObUdTaHV2LzZ2aTJmNDlOMklGMURNQ1haaEpoOUVZck9TV2kKY05oakxGRFhmdzVlZlFURWU3Ykx5bTJGVDd0YnZFSm5USHFyakVuUDRUWExqZnczL3RiQ3RxWVNZRlRqdThFUApadHVwd21ZWjhFVU1pSnVHS2l2SExmSjk2dy8xR21BOHVCZUVtV05YRW9FUU1ySmxuM3g5d3c9PQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo= diff --git a/test/kuttl/tests/manila-tls/02-manila-deploy.yaml b/test/kuttl/tests/manila-tls/02-manila-deploy.yaml new file mode 100644 index 00000000..6da54441 --- /dev/null +++ b/test/kuttl/tests/manila-tls/02-manila-deploy.yaml @@ -0,0 +1,5 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - script: | + oc kustomize ../../../../config/samples/layout/tls | oc apply -n $NAMESPACE -f - diff --git a/test/kuttl/tests/manila-tls/03-assert.yaml b/test/kuttl/tests/manila-tls/03-assert.yaml new file mode 100644 index 00000000..6392a8fd --- /dev/null +++ b/test/kuttl/tests/manila-tls/03-assert.yaml @@ -0,0 +1,535 @@ +apiVersion: manila.openstack.org/v1beta1 +kind: Manila +metadata: + name: manila + namespace: manila-kuttl-tests +spec: + customServiceConfig: | + [DEFAULT] + debug = true + databaseInstance: openstack + databaseUser: manila + dbPurge: + age: 30 + schedule: 1 0 * * * + extraMounts: + - extraVol: + - extraVolType: Ceph + mounts: + - mountPath: /etc/ceph + name: ceph + readOnly: true + propagation: + - share0 + volumes: + - name: ceph + projected: + sources: + - secret: + name: ceph-conf-files + name: v1 + region: r1 + manilaAPI: + customServiceConfig: | + [DEFAULT] + enabled_share_protocols = cephfs + override: {} + replicas: 1 + resources: {} + tls: + api: + internal: + secretName: cert-manila-internal-svc + public: + secretName: cert-manila-public-svc + caBundleSecretName: combined-ca-bundle + manilaScheduler: + customServiceConfig: '# add your customization here' + replicas: 1 + resources: {} + manilaShares: + share0: + customServiceConfig: | + [DEFAULT] + enabled_share_backends = cephfs + [cephfs] + driver_handles_share_servers=False + share_backend_name=cephfs + share_driver=manila.share.drivers.cephfs.driver.CephFSDriver + cephfs_conf_path=/etc/ceph/ceph.conf + cephfs_auth_id=openstack + cephfs_cluster_name=ceph + cephfs_protocol_helper_type=CEPHFS + replicas: 1 + resources: {} + memcachedInstance: memcached + passwordSelectors: + database: ManilaDatabasePassword + service: ManilaPassword + preserveJobs: false + rabbitMqClusterName: rabbitmq + secret: osp-secret + serviceUser: manila +status: + conditions: + - message: Setup complete + reason: Ready + status: "True" + type: Ready + - message: CronJob completed + reason: Ready + status: "True" + type: CronJobReady + - message: DB create completed + reason: Ready + status: "True" + type: DBReady + - message: DBsync completed + reason: Ready + status: "True" + type: DBSyncReady + - message: Input data complete + reason: Ready + status: "True" + type: InputReady + - message: Setup complete + reason: Ready + status: "True" + type: ManilaAPIReady + - message: Setup complete + reason: Ready + status: "True" + type: ManilaSchedulerReady + - message: Deployment completed + reason: Ready + status: "True" + type: ManilaShareReady + - message: " Memcached instance has been provisioned" + reason: Ready + status: "True" + type: MemcachedReady + - message: NetworkAttachments completed + reason: Ready + status: "True" + type: NetworkAttachmentsReady + - message: RabbitMqTransportURL successfully created + reason: Ready + status: "True" + type: RabbitMqTransportURLReady + - message: RoleBinding created + reason: Ready + status: "True" + type: RoleBindingReady + - message: Role created + reason: Ready + status: "True" + type: RoleReady + - message: ServiceAccount created + reason: Ready + status: "True" + type: ServiceAccountReady + - message: Service config create completed + reason: Ready + status: "True" + type: ServiceConfigReady + databaseHostname: openstack.manila-kuttl-tests.svc + manilaAPIReadyCount: 1 + manilaSchedulerReadyCount: 1 + manilaSharesReadyCounts: + share0: 1 + transportURLSecret: rabbitmq-transport-url-manila-manila-transport +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: manila-db-purge +spec: + jobTemplate: + metadata: + labels: + service: manila + spec: + completions: 1 + parallelism: 1 + template: + spec: + containers: + - args: + - -c + - /usr/bin/manila-manage --config-dir /etc/manila/manila.conf.d + db purge 30 + command: + - /bin/bash + name: manila-db-purge + volumeMounts: + - mountPath: /etc/manila/manila.conf.d + name: db-purge-config-data + readOnly: true + - mountPath: /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem + name: combined-ca-bundle + readOnly: true + serviceAccount: manila-manila + serviceAccountName: manila-manila + volumes: + - name: db-purge-config-data + secret: + defaultMode: 420 + items: + - key: 00-config.conf + path: 00-config.conf + secretName: manila-config-data + - name: combined-ca-bundle + secret: + defaultMode: 292 + secretName: combined-ca-bundle + schedule: 1 0 * * * + suspend: false +--- +apiVersion: manila.openstack.org/v1beta1 +kind: ManilaShare +metadata: + name: manila-share-share0 +spec: + databaseHostname: openstack.manila-kuttl-tests.svc + databaseUser: manila + passwordSelectors: + database: ManilaDatabasePassword + service: ManilaPassword + replicas: 1 + resources: {} + secret: osp-secret + serviceAccount: manila-manila + serviceUser: manila + transportURLSecret: rabbitmq-transport-url-manila-manila-transport +status: + conditions: + - message: Setup complete + reason: Ready + status: "True" + type: Ready + - message: Deployment completed + reason: Ready + status: "True" + type: DeploymentReady + - message: Input data complete + reason: Ready + status: "True" + type: InputReady + - message: NetworkAttachments completed + reason: Ready + status: "True" + type: NetworkAttachmentsReady + - message: Service config create completed + reason: Ready + status: "True" + type: ServiceConfigReady + - message: Input data complete + reason: Ready + status: "True" + type: TLSInputReady + readyCount: 1 +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: manila-api + namespace: manila-kuttl-tests +spec: + replicas: 1 + selector: + matchLabels: + component: manila-api + service: manila + template: + metadata: + labels: + component: manila-api + service: manila + spec: + serviceAccountName: manila-manila + containers: + - args: + - --single-child + - -- + - /usr/bin/tail + - -n+1 + - -F + - /var/log/manila/manila-api.log + volumeMounts: + - name: logs + mountPath: /var/log/manila + - args: + - -c + - /usr/local/bin/kolla_set_configs && /usr/local/bin/kolla_start + volumeMounts: + - mountPath: /etc/machine-id + name: etc-machine-id + readOnly: true + - mountPath: /etc/localtime + name: etc-localtime + readOnly: true + - mountPath: /var/lib/config-data/default + name: config-data + - mountPath: /usr/local/bin/container-scripts + name: scripts + - mountPath: /etc/manila/manila.conf.d + name: config-data-custom + readOnly: true + - mountPath: /var/lib/kolla/config_files/config.json + name: config-data + readOnly: true + subPath: manila-api-config.json + - mountPath: /var/log/manila + name: logs + - mountPath: /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem + name: combined-ca-bundle + readOnly: true + - mountPath: /var/lib/config-data/tls/certs/internal.crt + name: internal-tls-certs + readOnly: true + subPath: tls.crt + - mountPath: /var/lib/config-data/tls/private/internal.key + name: internal-tls-certs + readOnly: true + subPath: tls.key + - mountPath: /var/lib/config-data/tls/certs/public.crt + name: public-tls-certs + readOnly: true + subPath: tls.crt + - mountPath: /var/lib/config-data/tls/private/public.key + name: public-tls-certs + readOnly: true + subPath: tls.key + volumes: + - name: etc-machine-id + hostPath: + path: /etc/machine-id + - name: etc-localtime + hostPath: + path: /etc/localtime + - name: scripts + secret: + secretName: manila-scripts + - name: config-data + secret: + secretName: manila-config-data + - name: config-data-custom + secret: + secretName: manila-api-config-data + - name: logs + emptyDir: {} + - name: combined-ca-bundle + secret: + defaultMode: 292 + secretName: combined-ca-bundle + - name: internal-tls-certs + secret: + defaultMode: 256 + secretName: cert-manila-internal-svc + - name: public-tls-certs + secret: + defaultMode: 256 + secretName: cert-manila-public-svc +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: manila-share-share0 + namespace: manila-kuttl-tests +spec: + replicas: 1 + selector: + matchLabels: + component: manila-share + service: manila + template: + metadata: + labels: + component: manila-share + service: manila + spec: + serviceAccountName: manila-manila + containers: + - args: + - -c + - /usr/local/bin/kolla_set_configs && /usr/local/bin/kolla_start + volumeMounts: + - mountPath: /etc/machine-id + name: etc-machine-id + - mountPath: /etc/localtime + name: etc-localtime + readOnly: true + - mountPath: /var/lib/config-data/default + name: config-data + readOnly: true + - mountPath: /usr/local/bin/container-scripts + name: scripts + readOnly: true + - mountPath: /etc/ceph + name: ceph + readOnly: true + - mountPath: /etc/manila/manila.conf.d + name: config-data-custom + readOnly: true + - mountPath: /var/lib/manila + name: var-lib-manila + - mountPath: /var/lib/kolla/config_files/config.json + name: config-data + readOnly: true + subPath: manila-share-config.json + - mountPath: /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem + name: combined-ca-bundle + readOnly: true + subPath: tls-ca-bundle.pem + - command: + - /usr/local/bin/container-scripts/healthcheck.py + - share + - /etc/manila/manila.conf.d + volumeMounts: + - mountPath: /etc/machine-id + name: etc-machine-id + - mountPath: /etc/localtime + name: etc-localtime + readOnly: true + - mountPath: /var/lib/config-data/default + name: config-data + readOnly: true + - mountPath: /usr/local/bin/container-scripts + name: scripts + readOnly: true + - mountPath: /etc/ceph + name: ceph + readOnly: true + - mountPath: /etc/manila/manila.conf.d + name: config-data-custom + readOnly: true + - mountPath: /var/lib/manila + name: var-lib-manila + - mountPath: /var/lib/kolla/config_files/config.json + name: config-data + readOnly: true + subPath: manila-share-config.json + - mountPath: /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem + name: combined-ca-bundle + readOnly: true + subPath: tls-ca-bundle.pem + volumes: + - name: etc-machine-id + hostPath: + path: /etc/machine-id + - name: etc-localtime + hostPath: + path: /etc/localtime + - name: scripts + secret: + secretName: manila-scripts + - name: config-data + secret: + secretName: manila-config-data + - name: ceph + projected: + sources: + - secret: + name: ceph-conf-files + - name: var-lib-manila + hostPath: + path: /var/lib/manila + - name: config-data-custom + secret: + secretName: manila-share-share0-config-data + - name: combined-ca-bundle + secret: + secretName: combined-ca-bundle +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: manila-scheduler + namespace: manila-kuttl-tests +spec: + replicas: 1 + selector: + matchLabels: + component: manila-scheduler + service: manila + template: + metadata: + labels: + component: manila-scheduler + service: manila + spec: + serviceAccountName: manila-manila + containers: + - args: + - -c + - /usr/local/bin/kolla_set_configs && /usr/local/bin/kolla_start + volumeMounts: + - mountPath: /etc/machine-id + name: etc-machine-id + - mountPath: /etc/localtime + name: etc-localtime + readOnly: true + - mountPath: /var/lib/config-data/default + name: config-data + readOnly: true + - mountPath: /usr/local/bin/container-scripts + name: scripts + readOnly: true + - mountPath: /etc/manila/manila.conf.d + name: config-data-custom + readOnly: true + - mountPath: /var/lib/kolla/config_files/config.json + name: config-data + readOnly: true + subPath: manila-scheduler-config.json + - mountPath: /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem + name: combined-ca-bundle + readOnly: true + subPath: tls-ca-bundle.pem + - command: + - /usr/local/bin/container-scripts/healthcheck.py + - scheduler + - /etc/manila/manila.conf.d + volumeMounts: + - mountPath: /etc/machine-id + name: etc-machine-id + readOnly: true + - mountPath: /etc/localtime + name: etc-localtime + readOnly: true + - mountPath: /var/lib/config-data/default + name: config-data + readOnly: true + - mountPath: /usr/local/bin/container-scripts + name: scripts + readOnly: true + - mountPath: /etc/manila/manila.conf.d + name: config-data-custom + readOnly: true + - mountPath: /var/lib/kolla/config_files/config.json + name: config-data + readOnly: true + subPath: manila-scheduler-config.json + - mountPath: /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem + name: combined-ca-bundle + readOnly: true + subPath: tls-ca-bundle.pem + volumes: + - name: etc-machine-id + hostPath: + path: /etc/machine-id + - name: etc-localtime + hostPath: + path: /etc/localtime + - name: scripts + secret: + secretName: manila-scripts + - name: config-data + secret: + secretName: manila-config-data + - name: config-data-custom + secret: + secretName: manila-scheduler-config-data + - name: combined-ca-bundle + secret: + secretName: combined-ca-bundle diff --git a/test/kuttl/tests/manila-tls/04-cleanup-manila.yaml b/test/kuttl/tests/manila-tls/04-cleanup-manila.yaml new file mode 100644 index 00000000..884b9d39 --- /dev/null +++ b/test/kuttl/tests/manila-tls/04-cleanup-manila.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +delete: +- apiVersion: manila.openstack.org/v1beta1 + kind: Manila + name: manila