diff --git a/api/v1/types.go b/api/v1/types.go index 4499fcf41..e88f4a261 100644 --- a/api/v1/types.go +++ b/api/v1/types.go @@ -451,6 +451,10 @@ type ContainerTemplate struct { // PrivateKey is a private key used for a certificate/private-key pair // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Private key for certificate/private-key pair" PrivateKey string `json:"privateKey,omitempty" yaml:"privateKey,omitempty"` + + // CertificateAuthority is a certificate authority used to validate a certificate + // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Certificate authority for validating a certificate" + CertificateAuthority string `json:"certificateAuthority,omitempty" yaml:"certificateAuthority,omitempty"` } // SnapshotClass struct diff --git a/deploy/crds/storage.dell.com.crds.all.yaml b/deploy/crds/storage.dell.com.crds.all.yaml index 562b4a42f..79c61c3cd 100644 --- a/deploy/crds/storage.dell.com.crds.all.yaml +++ b/deploy/crds/storage.dell.com.crds.all.yaml @@ -76,6 +76,9 @@ spec: certificate: description: Certificate is a certificate used for a certificate/private-key pair type: string + certificateAuthority: + description: CertificateAuthority is a certificate authority used to validate a certificate + type: string commander: description: Commander is the image tag for the Container type: string @@ -402,6 +405,9 @@ spec: certificate: description: Certificate is a certificate used for a certificate/private-key pair type: string + certificateAuthority: + description: CertificateAuthority is a certificate authority used to validate a certificate + type: string commander: description: Commander is the image tag for the Container type: string @@ -717,6 +723,9 @@ spec: certificate: description: Certificate is a certificate used for a certificate/private-key pair type: string + certificateAuthority: + description: CertificateAuthority is a certificate authority used to validate a certificate + type: string commander: description: Commander is the image tag for the Container type: string @@ -1122,6 +1131,9 @@ spec: certificate: description: Certificate is a certificate used for a certificate/private-key pair type: string + certificateAuthority: + description: CertificateAuthority is a certificate authority used to validate a certificate + type: string commander: description: Commander is the image tag for the Container type: string @@ -1437,6 +1449,9 @@ spec: certificate: description: Certificate is a certificate used for a certificate/private-key pair type: string + certificateAuthority: + description: CertificateAuthority is a certificate authority used to validate a certificate + type: string commander: description: Commander is the image tag for the Container type: string @@ -1771,6 +1786,9 @@ spec: certificate: description: Certificate is a certificate used for a certificate/private-key pair type: string + certificateAuthority: + description: CertificateAuthority is a certificate authority used to validate a certificate + type: string commander: description: Commander is the image tag for the Container type: string @@ -2084,6 +2102,9 @@ spec: certificate: description: Certificate is a certificate used for a certificate/private-key pair type: string + certificateAuthority: + description: CertificateAuthority is a certificate authority used to validate a certificate + type: string commander: description: Commander is the image tag for the Container type: string @@ -2402,6 +2423,9 @@ spec: certificate: description: Certificate is a certificate used for a certificate/private-key pair type: string + certificateAuthority: + description: CertificateAuthority is a certificate authority used to validate a certificate + type: string commander: description: Commander is the image tag for the Container type: string @@ -2741,6 +2765,9 @@ spec: certificate: description: Certificate is a certificate used for a certificate/private-key pair type: string + certificateAuthority: + description: CertificateAuthority is a certificate authority used to validate a certificate + type: string commander: description: Commander is the image tag for the Container type: string @@ -3065,6 +3092,9 @@ spec: certificate: description: Certificate is a certificate used for a certificate/private-key pair type: string + certificateAuthority: + description: CertificateAuthority is a certificate authority used to validate a certificate + type: string commander: description: Commander is the image tag for the Container type: string diff --git a/operatorconfig/moduleconfig/authorization/v1.10.0/deployment.yaml b/operatorconfig/moduleconfig/authorization/v1.10.0/deployment.yaml index d48c19d18..1ac00049c 100644 --- a/operatorconfig/moduleconfig/authorization/v1.10.0/deployment.yaml +++ b/operatorconfig/moduleconfig/authorization/v1.10.0/deployment.yaml @@ -242,53 +242,6 @@ roleRef: name: storage-service apiGroup: rbac.authorization.k8s.io --- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: storage-service - namespace: - labels: - app: storage-service -spec: - replicas: 1 - selector: - matchLabels: - app: storage-service - template: - metadata: - labels: - csm: - app: storage-service - spec: - serviceAccountName: storage-service - containers: - - name: storage-service - image: - imagePullPolicy: Always - ports: - - containerPort: 50051 - name: grpc - env: - - name: NAMESPACE - value: - volumeMounts: - - name: storage-volume - mountPath: /etc/karavi-authorization/storage - - name: config-volume - mountPath: /etc/karavi-authorization/config - - name: csm-config-params - mountPath: /etc/karavi-authorization/csm-config-params - volumes: - - name: storage-volume - secret: - secretName: karavi-storage-secret - - name: config-volume - secret: - secretName: karavi-config-secret - - name: csm-config-params - configMap: - name: csm-config-params ---- apiVersion: v1 kind: Service metadata: diff --git a/operatorconfig/moduleconfig/authorization/v1.9.0/deployment.yaml b/operatorconfig/moduleconfig/authorization/v1.9.0/deployment.yaml index 4ff948e4c..741534e31 100644 --- a/operatorconfig/moduleconfig/authorization/v1.9.0/deployment.yaml +++ b/operatorconfig/moduleconfig/authorization/v1.9.0/deployment.yaml @@ -242,53 +242,6 @@ roleRef: name: storage-service apiGroup: rbac.authorization.k8s.io --- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: storage-service - namespace: - labels: - app: storage-service -spec: - replicas: 1 - selector: - matchLabels: - app: storage-service - template: - metadata: - labels: - csm: - app: storage-service - spec: - serviceAccountName: storage-service - containers: - - name: storage-service - image: - imagePullPolicy: Always - ports: - - containerPort: 50051 - name: grpc - env: - - name: NAMESPACE - value: - volumeMounts: - - name: storage-volume - mountPath: /etc/karavi-authorization/storage - - name: config-volume - mountPath: /etc/karavi-authorization/config - - name: csm-config-params - mountPath: /etc/karavi-authorization/csm-config-params - volumes: - - name: storage-volume - secret: - secretName: karavi-storage-secret - - name: config-volume - secret: - secretName: karavi-config-secret - - name: csm-config-params - configMap: - name: csm-config-params ---- apiVersion: v1 kind: Service metadata: diff --git a/operatorconfig/moduleconfig/authorization/v1.9.1/deployment.yaml b/operatorconfig/moduleconfig/authorization/v1.9.1/deployment.yaml index 5d4179ce0..be6d2f4a4 100644 --- a/operatorconfig/moduleconfig/authorization/v1.9.1/deployment.yaml +++ b/operatorconfig/moduleconfig/authorization/v1.9.1/deployment.yaml @@ -242,53 +242,6 @@ roleRef: name: storage-service apiGroup: rbac.authorization.k8s.io --- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: storage-service - namespace: - labels: - app: storage-service -spec: - replicas: 1 - selector: - matchLabels: - app: storage-service - template: - metadata: - labels: - app: storage-service - csm: - spec: - serviceAccountName: storage-service - containers: - - name: storage-service - image: - imagePullPolicy: Always - ports: - - containerPort: 50051 - name: grpc - env: - - name: NAMESPACE - value: - volumeMounts: - - name: storage-volume - mountPath: /etc/karavi-authorization/storage - - name: config-volume - mountPath: /etc/karavi-authorization/config - - name: csm-config-params - mountPath: /etc/karavi-authorization/csm-config-params - volumes: - - name: storage-volume - secret: - secretName: karavi-storage-secret - - name: config-volume - secret: - secretName: karavi-config-secret - - name: csm-config-params - configMap: - name: csm-config-params ---- apiVersion: v1 kind: Service metadata: diff --git a/operatorconfig/moduleconfig/authorization/v2.0.0-alpha/deployment.yaml b/operatorconfig/moduleconfig/authorization/v2.0.0-alpha/deployment.yaml index 24e621020..dbd81d9c6 100644 --- a/operatorconfig/moduleconfig/authorization/v2.0.0-alpha/deployment.yaml +++ b/operatorconfig/moduleconfig/authorization/v2.0.0-alpha/deployment.yaml @@ -317,70 +317,6 @@ subjects: name: storage-service namespace: --- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: storage-service - namespace: - labels: - app: storage-service -spec: - replicas: - selector: - matchLabels: - app: storage-service - template: - metadata: - labels: - csm: - app: storage-service - spec: - serviceAccountName: storage-service - containers: - - name: storage-service - image: - imagePullPolicy: Always - env: - - name: NAMESPACE - value: - - name: SENTINELS - value: - - name: REDIS_PASSWORD - valueFrom: - secretKeyRef: - name: redis-csm-secret - key: password - args: - - "--redis-sentinel=$(SENTINELS)" - - "--redis-password=$(REDIS_PASSWORD)" - - "--vault-address=" - - "--vault-kv-engine-path=" - - "--vault-skip-certificate-validation=" - - "--vault-role=" - - "--leader-election=" - ports: - - containerPort: 50051 - name: grpc - volumeMounts: - - name: config-volume - mountPath: /etc/karavi-authorization/config - - name: csm-config-params - mountPath: /etc/karavi-authorization/csm-config-params - - name: vault-client-certificate - mountPath: /etc/vault - volumes: - - name: config-volume - secret: - secretName: karavi-config-secret - - name: csm-config-params - configMap: - name: csm-config-params - - name: vault-client-certificate - projected: - sources: - - secret: - name: storage-service-selfsigned-tls ---- apiVersion: v1 kind: Service metadata: diff --git a/pkg/modules/authorization.go b/pkg/modules/authorization.go index 8be6a2b11..46df6c1a1 100644 --- a/pkg/modules/authorization.go +++ b/pkg/modules/authorization.go @@ -14,6 +14,7 @@ package modules import ( "context" + "encoding/base64" "encoding/json" "errors" "fmt" @@ -30,6 +31,7 @@ import ( "github.com/dell/csm-operator/pkg/logger" utils "github.com/dell/csm-operator/pkg/utils" "golang.org/x/mod/semver" + appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" networking "k8s.io/api/networking/v1" k8serrors "k8s.io/apimachinery/pkg/api/errors" @@ -631,6 +633,462 @@ func AuthorizationServerDeployment(ctx context.Context, isDeleting bool, op util return err } + err = applyDeleteAuthorizationStorageService(ctx, isDeleting, cr, ctrlClient) + if err != nil { + return err + } + + return nil +} + +// AuthorizationStorageService - apply/delete storage service deployment and volume objects +func applyDeleteAuthorizationStorageService(ctx context.Context, isDeleting bool, cr csmv1.ContainerStorageModule, ctrlClient crclient.Client) error { + authModule, err := getAuthorizationModule(cr) + if err != nil { + return err + } + + switch semver.Major(authModule.ConfigVersion) { + case "v2": + return authorizationStorageServiceV2(ctx, isDeleting, cr, ctrlClient) + case "v1": + return authorizationStorageServiceV1(ctx, isDeleting, cr, ctrlClient) + default: + return fmt.Errorf("authorization major version %s not supported", semver.Major(authModule.ConfigVersion)) + } +} + +func authorizationStorageServiceV1(ctx context.Context, isDeleting bool, cr csmv1.ContainerStorageModule, ctrlClient crclient.Client) error { + authModule, err := getAuthorizationModule(cr) + if err != nil { + return err + } + + // get component variables + image := "" + for _, component := range authModule.Components { + switch component.Name { + case AuthProxyServerComponent: + image = component.StorageService + } + } + + deployment := getStorageServiceScaffold(cr.Name, cr.Namespace, image, 1) + + // set karavi-storage-secret volume + deployment.Spec.Template.Spec.Volumes = append(deployment.Spec.Template.Spec.Volumes, corev1.Volume{ + Name: "storage-volume", + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: "karavi-storage-secret", + }, + }, + }) + for i, c := range deployment.Spec.Template.Spec.Containers { + if c.Name == "storage-service" { + deployment.Spec.Template.Spec.Containers[i].VolumeMounts = append(deployment.Spec.Template.Spec.Containers[i].VolumeMounts, corev1.VolumeMount{ + Name: "storage-volume", + MountPath: "/etc/karavi-authorization/storage", + }) + break + } + } + + deploymentBytes, err := json.Marshal(&deployment) + if err != nil { + return fmt.Errorf("marshalling storage-service deployment: %w", err) + } + + deploymentYaml, err := yaml.JSONToYAML(deploymentBytes) + if err != nil { + return fmt.Errorf("converting storage-service json to yaml: %w", err) + } + + return applyDeleteObjects(ctx, ctrlClient, string(deploymentYaml), isDeleting) +} + +func authorizationStorageServiceV2(ctx context.Context, isDeleting bool, cr csmv1.ContainerStorageModule, ctrlClient crclient.Client) error { + authModule, err := getAuthorizationModule(cr) + if err != nil { + return err + } + + err = applyDeleteVaultCertificates(ctx, isDeleting, cr, ctrlClient) + if err != nil { + return fmt.Errorf("applying/deleting vault certificates: %w", err) + } + + replicas := 0 + sentinels := "" + image := "" + vaultAddress := "" + vaultRole := "" + vaultKVEnginePath := "" + vaultSkipCertificateValidation := false + vaultCertificate := "" + vaultPrivateKey := "" + vaultCertificateAuthority := "" + leaderElection := true + for _, component := range authModule.Components { + switch component.Name { + case AuthProxyServerComponent: + replicas = component.StorageServiceReplicas + image = component.StorageService + leaderElection = component.LeaderElection + case AuthRedisComponent: + var sentinelValues []string + for i := 0; i < component.RedisReplicas; i++ { + sentinelValues = append(sentinelValues, fmt.Sprintf("sentinel-%d.sentinel.%s.svc.cluster.local:5000", i, cr.Namespace)) + } + sentinels = strings.Join(sentinelValues, ", ") + case AuthVaultComponent: + vaultAddress = component.VaultAddress + vaultRole = component.VaultRole + vaultKVEnginePath = component.KvEnginePath + vaultSkipCertificateValidation = component.SkipCertificateValidation + vaultCertificate = component.Certificate + vaultPrivateKey = component.PrivateKey + vaultCertificateAuthority = component.CertificateAuthority + default: + continue + } + } + + deployment := getStorageServiceScaffold(cr.Name, cr.Namespace, image, int32(replicas)) + + // set vault volumes + volume := corev1.Volume{ + Name: "vault-client-certificate", + VolumeSource: corev1.VolumeSource{ + Projected: &corev1.ProjectedVolumeSource{ + Sources: []corev1.VolumeProjection{{}}, + }, + }, + } + + if vaultCertificateAuthority != "" { + volume.VolumeSource.Projected.Sources = append(volume.VolumeSource.Projected.Sources, corev1.VolumeProjection{ + Secret: &corev1.SecretProjection{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "vault-certificate-authority", + }, + }, + }) + } + + if vaultCertificate != "" && vaultPrivateKey != "" { + volume.VolumeSource.Projected.Sources = append(volume.VolumeSource.Projected.Sources, corev1.VolumeProjection{ + Secret: &corev1.SecretProjection{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "vault-client-certificate", + }, + }, + }) + } else { + volume.VolumeSource.Projected.Sources = append(volume.VolumeSource.Projected.Sources, corev1.VolumeProjection{ + Secret: &corev1.SecretProjection{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "storage-service-selfsigned-tls", + }, + }, + }) + } + deployment.Spec.Template.Spec.Volumes = append(deployment.Spec.Template.Spec.Volumes, volume) + for i, c := range deployment.Spec.Template.Spec.Containers { + if c.Name == "storage-service" { + deployment.Spec.Template.Spec.Containers[i].VolumeMounts = append(deployment.Spec.Template.Spec.Containers[i].VolumeMounts, corev1.VolumeMount{ + Name: "vault-client-certificate", + MountPath: "/etc/vault", + }) + break + } + } + + // set redis envs + redis := []corev1.EnvVar{ + { + Name: "SENTINELS", + Value: sentinels, + }, + { + Name: "REDIS_PASSWORD", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "redis-csm-secret", + }, + Key: "password", + }, + }, + }, + } + for i, c := range deployment.Spec.Template.Spec.Containers { + if c.Name == "storage-service" { + deployment.Spec.Template.Spec.Containers[i].Env = append(deployment.Spec.Template.Spec.Containers[i].Env, redis...) + break + } + } + + // set arguments + args := []string{ + "--redis-sentinel=$(SENTINELS)", + "--redis-password=$(REDIS_PASSWORD)", + fmt.Sprintf("--vault-address=%s", vaultAddress), + fmt.Sprintf("--vault-role=%s", vaultRole), + fmt.Sprintf("--vault-kv-engine-path=%s", vaultKVEnginePath), + fmt.Sprintf("--vault-skip-certificate-validation=%t", vaultSkipCertificateValidation), + fmt.Sprintf("--leader-election=%t", leaderElection), + } + for i, c := range deployment.Spec.Template.Spec.Containers { + if c.Name == "storage-service" { + deployment.Spec.Template.Spec.Containers[i].Args = append(deployment.Spec.Template.Spec.Containers[i].Args, args...) + break + } + } + + deploymentBytes, err := json.Marshal(&deployment) + if err != nil { + return fmt.Errorf("marshalling storage-service deployment: %w", err) + } + + deploymentYaml, err := yaml.JSONToYAML(deploymentBytes) + if err != nil { + return fmt.Errorf("converting storage-service json to yaml: %w", err) + } + + err = applyDeleteObjects(ctx, ctrlClient, string(deploymentYaml), isDeleting) + if err != nil { + return fmt.Errorf("applying storage-service deployment: %w", err) + } + return nil +} + +// getStorageServiceScaffold returns the storage-service deployment with the common elements between v1 and v2 +// callers must ensure that other elements specific for the version get set in the returned deployment +func getStorageServiceScaffold(name string, namespace string, image string, replicas int32) appsv1.Deployment { + return appsv1.Deployment{ + TypeMeta: metav1.TypeMeta{ + Kind: "Deployment", + APIVersion: "apps/v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "storage-service", + Namespace: namespace, + Labels: map[string]string{ + "app": "storage-service", + }, + }, + Spec: appsv1.DeploymentSpec{ + Replicas: &replicas, + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app": "storage-service", + }, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "csm": name, + "app": "storage-service", + }, + }, + Spec: corev1.PodSpec{ + ServiceAccountName: "storage-service", + Containers: []corev1.Container{ + { + Name: "storage-service", + Image: image, + ImagePullPolicy: "Always", + Ports: []corev1.ContainerPort{ + { + ContainerPort: 50051, + Name: "grpc", + }, + }, + Env: []corev1.EnvVar{ + { + Name: "NAMESPACE", + Value: namespace, + }, + }, + VolumeMounts: []corev1.VolumeMount{ + { + Name: "config-volume", + MountPath: "/etc/karavi-authorization/config", + }, + { + Name: "csm-config-params", + MountPath: "/etc/karavi-authorization/csm-config-params", + }, + }, + }, + }, + Volumes: []corev1.Volume{ + { + Name: "config-volume", + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: "karavi-config-secret", + }, + }, + }, + { + Name: "csm-config-params", + VolumeSource: corev1.VolumeSource{ + ConfigMap: &corev1.ConfigMapVolumeSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "csm-config-params", + }, + }, + }, + }, + }, + }, + }, + }, + } +} + +func applyDeleteVaultCertificates(ctx context.Context, isDeleting bool, cr csmv1.ContainerStorageModule, ctrlClient crclient.Client) error { + authModule, err := getAuthorizationModule(cr) + if err != nil { + return err + } + + // get vault certificate data from CR + vaultCertificate := "" + vaultPrivateKey := "" + vaultCertificateAuthority := "" + for _, component := range authModule.Components { + switch component.Name { + case AuthVaultComponent: + vaultCertificate = component.Certificate + vaultPrivateKey = component.PrivateKey + vaultCertificateAuthority = component.CertificateAuthority + default: + continue + } + } + + // apply/delete vault-certificate-authority secret if it was provided + if vaultCertificateAuthority != "" { + vaultCABytes, err := base64.StdEncoding.DecodeString(vaultCertificateAuthority) + if err != nil { + return fmt.Errorf("decoding vault certificate authority: %w", err) + } + + secret := corev1.Secret{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "v1", + Kind: "Secret", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "vault-certificate-authority", + Namespace: cr.Namespace, + }, + Type: corev1.SecretTypeOpaque, + Data: map[string][]byte{ + "ca.crt": vaultCABytes, + }, + } + + secretBytes, err := json.Marshal(&secret) + if err != nil { + return fmt.Errorf("marshalling vault certificate authority secret: %w", err) + } + + yamlString, err := yaml.JSONToYAML(secretBytes) + if err != nil { + return fmt.Errorf("converting vault certificate authority json to yaml: %w", err) + } + + err = applyDeleteObjects(ctx, ctrlClient, string(yamlString), isDeleting) + if err != nil { + return fmt.Errorf("applying vault certificate authority secret: %w", err) + } + } + + // apply/delete vault-client-certificate secret if it was provided + if vaultCertificate != "" && vaultPrivateKey != "" { + vaultCertBytes, err := base64.StdEncoding.DecodeString(vaultCertificate) + if err != nil { + return fmt.Errorf("decoding vault certificate: %w", err) + } + + vaultKeyBytes, err := base64.StdEncoding.DecodeString(vaultPrivateKey) + if err != nil { + return fmt.Errorf("decoding vault private key: %w", err) + } + + secret := corev1.Secret{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "v1", + Kind: "Secret", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "vault-client-certificate", + Namespace: cr.Namespace, + }, + Type: corev1.SecretTypeTLS, + Data: map[string][]byte{ + "tls.crt": vaultCertBytes, + "tls.key": vaultKeyBytes, + }, + } + + secretBytes, err := json.Marshal(&secret) + if err != nil { + return fmt.Errorf("marshalling vault certificate secret: %w", err) + } + + yamlString, err := yaml.JSONToYAML(secretBytes) + if err != nil { + return fmt.Errorf("converting vault certificate json to yaml: %w", err) + } + + err = applyDeleteObjects(ctx, ctrlClient, string(yamlString), isDeleting) + if err != nil { + return fmt.Errorf("applying vault certificate secret: %w", err) + } + return nil + } + + // apply/delete storage-service-selfsigned issuer and certificate + issuer := createSelfSignedIssuer(cr, "storage-service-selfsigned") + + issuerByes, err := json.Marshal(issuer) + if err != nil { + return fmt.Errorf("marshaling storage-service-selfsigned issuer: %v", err) + } + + issuerYaml, err := yaml.JSONToYAML(issuerByes) + if err != nil { + return fmt.Errorf("converting storage-service-selfsigned issuer json to yaml: %v", err) + } + + // create/delete issuer + err = applyDeleteObjects(ctx, ctrlClient, string(issuerYaml), isDeleting) + if err != nil { + return err + } + + certificate := createSelfSignedCertificate(cr, []string{fmt.Sprintf("storage-service.%s.svc.cluster.local", cr.Namespace)}, "storage-service-selfsigned", "storage-service-selfsigned-tls", "storage-service-selfsigned") + + certBytes, err := json.Marshal(certificate) + if err != nil { + return fmt.Errorf("marshaling storage-service-selfsigned certificate: %v", err) + } + + certYaml, err := yaml.JSONToYAML(certBytes) + if err != nil { + return fmt.Errorf("converting storage-service-selfsigned certificate json to yaml: %v", err) + } + + // create/delete certificate + err = applyDeleteObjects(ctx, ctrlClient, string(certYaml), isDeleting) + if err != nil { + return err + } return nil } @@ -793,7 +1251,7 @@ func InstallWithCerts(ctx context.Context, isDeleting bool, op utils.OperatorCon } if useSelfSignedCert { - issuer := createSelfSignedIssuer(cr) + issuer := createSelfSignedIssuer(cr, "selfsigned") issuerByes, err := json.Marshal(issuer) if err != nil { return fmt.Errorf("marshaling ingress: %v", err) @@ -810,11 +1268,13 @@ func InstallWithCerts(ctx context.Context, isDeleting bool, op utils.OperatorCon return err } - cert, err := createSelfSignedCertificate(cr) + hosts, err := getHosts(cr) if err != nil { return err } + cert := createSelfSignedCertificate(cr, hosts, "karavi-auth", "karavi-selfsigned-tls", "selfsigned") + certBytes, err := json.Marshal(cert) if err != nil { return fmt.Errorf("marshaling ingress: %v", err) @@ -863,6 +1323,16 @@ func getAuthCrdDeploy(op utils.OperatorConfig, cr csmv1.ContainerStorageModule) // AuthCrdDeploy - apply and delete Auth crds deployment func AuthCrdDeploy(ctx context.Context, op utils.OperatorConfig, cr csmv1.ContainerStorageModule, ctrlClient crclient.Client) error { + auth, err := getAuthorizationModule(cr) + if err != nil { + return err + } + + // v1 does not have custom resources, so treat it like a no-op + if semver.Compare(auth.ConfigVersion, "v2.0.0-alpha") < 0 { + return nil + } + yamlString, err := getAuthCrdDeploy(op, cr) if err != nil { return err @@ -876,13 +1346,13 @@ func AuthCrdDeploy(ctx context.Context, op utils.OperatorConfig, cr csmv1.Contai return nil } -func createSelfSignedIssuer(cr csmv1.ContainerStorageModule) *certificate.Issuer { +func createSelfSignedIssuer(cr csmv1.ContainerStorageModule, name string) *certificate.Issuer { issuer := &certificate.Issuer{ TypeMeta: metav1.TypeMeta{ Kind: "Issuer", }, ObjectMeta: metav1.ObjectMeta{ - Name: "selfsigned", + Name: name, Namespace: cr.Namespace, }, Spec: certificate.IssuerSpec{ @@ -897,22 +1367,17 @@ func createSelfSignedIssuer(cr csmv1.ContainerStorageModule) *certificate.Issuer return issuer } -func createSelfSignedCertificate(cr csmv1.ContainerStorageModule) (*certificate.Certificate, error) { - hosts, err := getHosts(cr) - if err != nil { - return nil, fmt.Errorf("getting hosts: %v", err) - } - +func createSelfSignedCertificate(cr csmv1.ContainerStorageModule, hosts []string, name string, secretName string, issuerName string) *certificate.Certificate { certificate := &certificate.Certificate{ TypeMeta: metav1.TypeMeta{ Kind: "Certificate", }, ObjectMeta: metav1.ObjectMeta{ - Name: "karavi-auth", + Name: name, Namespace: cr.Namespace, }, Spec: certificate.CertificateSpec{ - SecretName: "karavi-selfsigned-tls", + SecretName: secretName, Duration: &metav1.Duration{ Duration: duration, // 90d }, @@ -934,14 +1399,14 @@ func createSelfSignedCertificate(cr csmv1.ContainerStorageModule) (*certificate. }, DNSNames: hosts, IssuerRef: cmmetav1.ObjectReference{ - Name: "selfsigned", + Name: issuerName, Kind: "Issuer", Group: "cert-manager.io", }, }, } - return certificate, nil + return certificate } func createIngress(cr csmv1.ContainerStorageModule) (*networking.Ingress, error) { diff --git a/pkg/modules/authorization_test.go b/pkg/modules/authorization_test.go index 694c518c4..00dd62fc6 100644 --- a/pkg/modules/authorization_test.go +++ b/pkg/modules/authorization_test.go @@ -10,6 +10,7 @@ package modules import ( "context" + "fmt" "testing" csmv1 "github.com/dell/csm-operator/api/v1" @@ -614,6 +615,7 @@ func TestAuthorizationServerDeployment(t *testing.T) { }, } + certmanagerv1.AddToScheme(scheme.Scheme) sourceClient := ctrlClientFake.NewClientBuilder().WithObjects(cm).Build() return true, true, tmpCR, sourceClient, operatorConfig @@ -625,7 +627,31 @@ func TestAuthorizationServerDeployment(t *testing.T) { } tmpCR := customResource + certmanagerv1.AddToScheme(scheme.Scheme) + sourceClient := ctrlClientFake.NewClientBuilder().WithObjects().Build() + + return true, false, tmpCR, sourceClient, operatorConfig + }, + "success - creating with vault client certificates": func(*testing.T) (bool, bool, csmv1.ContainerStorageModule, ctrlClient.Client, utils.OperatorConfig) { + customResource, err := getCustomResource("./testdata/cr_auth_proxy_vault_cert.yaml") + if err != nil { + panic(err) + } + + tmpCR := customResource + certmanagerv1.AddToScheme(scheme.Scheme) + sourceClient := ctrlClientFake.NewClientBuilder().WithObjects().Build() + + return true, false, tmpCR, sourceClient, operatorConfig + }, + "success - creating v1": func(*testing.T) (bool, bool, csmv1.ContainerStorageModule, ctrlClient.Client, utils.OperatorConfig) { + customResource, err := getCustomResource("./testdata/cr_auth_proxy_v1100.yaml") + if err != nil { + panic(err) + } + tmpCR := customResource + certmanagerv1.AddToScheme(scheme.Scheme) sourceClient := ctrlClientFake.NewClientBuilder().WithObjects().Build() return true, false, tmpCR, sourceClient, operatorConfig @@ -637,7 +663,7 @@ func TestAuthorizationServerDeployment(t *testing.T) { } tmpCR := customResource - + certmanagerv1.AddToScheme(scheme.Scheme) sourceClient := ctrlClientFake.NewClientBuilder().WithObjects().Build() return true, false, tmpCR, sourceClient, operatorConfig @@ -649,7 +675,43 @@ func TestAuthorizationServerDeployment(t *testing.T) { } tmpCR := customResource + certmanagerv1.AddToScheme(scheme.Scheme) + sourceClient := ctrlClientFake.NewClientBuilder().WithObjects().Build() + + return false, false, tmpCR, sourceClient, operatorConfig + }, + "fail - corrupt vault ca": func(*testing.T) (bool, bool, csmv1.ContainerStorageModule, ctrlClient.Client, utils.OperatorConfig) { + customResource, err := getCustomResource("./testdata/cr_auth_proxy_bad_vault_ca.yaml") + if err != nil { + panic(err) + } + + tmpCR := customResource + certmanagerv1.AddToScheme(scheme.Scheme) + sourceClient := ctrlClientFake.NewClientBuilder().WithObjects().Build() + + return false, false, tmpCR, sourceClient, operatorConfig + }, + "fail - corrupt vault client cert": func(*testing.T) (bool, bool, csmv1.ContainerStorageModule, ctrlClient.Client, utils.OperatorConfig) { + customResource, err := getCustomResource("./testdata/cr_auth_proxy_bad_vault_cert.yaml") + if err != nil { + panic(err) + } + + tmpCR := customResource + certmanagerv1.AddToScheme(scheme.Scheme) + sourceClient := ctrlClientFake.NewClientBuilder().WithObjects().Build() + + return false, false, tmpCR, sourceClient, operatorConfig + }, + "fail - corrupt vault client key": func(*testing.T) (bool, bool, csmv1.ContainerStorageModule, ctrlClient.Client, utils.OperatorConfig) { + customResource, err := getCustomResource("./testdata/cr_auth_proxy_bad_vault_key.yaml") + if err != nil { + panic(err) + } + tmpCR := customResource + certmanagerv1.AddToScheme(scheme.Scheme) sourceClient := ctrlClientFake.NewClientBuilder().WithObjects().Build() return false, false, tmpCR, sourceClient, operatorConfig @@ -663,6 +725,7 @@ func TestAuthorizationServerDeployment(t *testing.T) { if success { assert.NoError(t, err) } else { + fmt.Println(err) assert.Error(t, err) } }) @@ -740,6 +803,56 @@ func TestAuthorizationIngress(t *testing.T) { return true, true, tmpCR, sourceClient }, + "success - creating with certs": func(*testing.T) (bool, bool, csmv1.ContainerStorageModule, ctrlClient.Client) { + customResource, err := getCustomResource("./testdata/cr_auth_proxy_certs.yaml") + if err != nil { + panic(err) + } + + tmpCR := customResource + namespace := customResource.Namespace + name := namespace + "-ingress-nginx-controller" + + dp := &appsv1.Deployment{ + TypeMeta: metav1.TypeMeta{ + Kind: "Deployment", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app.kubernetes.io/name": "ingress-nginx"}, + }, + }, + } + + pod := &corev1.Pod{ + TypeMeta: metav1.TypeMeta{ + Kind: "Pod", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + } + + sourceClient := ctrlClientFake.NewClientBuilder().WithObjects(dp, pod).Build() + + return true, true, tmpCR, sourceClient + }, + "success - creating with openshift and other annotations": func(*testing.T) (bool, bool, csmv1.ContainerStorageModule, ctrlClient.Client) { + customResource, err := getCustomResource("./testdata/cr_auth_proxy_openshift.yaml") + if err != nil { + panic(err) + } + + tmpCR := customResource + sourceClient := ctrlClientFake.NewClientBuilder().WithObjects().Build() + + return true, true, tmpCR, sourceClient + }, "success - creating v1.10.0": func(*testing.T) (bool, bool, csmv1.ContainerStorageModule, ctrlClient.Client) { customResource, err := getCustomResource("./testdata/cr_auth_proxy_v1100.yaml") if err != nil { @@ -1060,6 +1173,18 @@ func TestAuthorizationCrdDeploy(t *testing.T) { sourceClient := ctrlClientFake.NewClientBuilder().WithObjects().Build() return true, tmpCR, sourceClient, operatorConfig }, + "success - creating v1": func(*testing.T) (bool, csmv1.ContainerStorageModule, ctrlClient.Client, utils.OperatorConfig) { + customResource, err := getCustomResource("./testdata/cr_auth_proxy_v1100.yaml") + if err != nil { + panic(err) + } + + tmpCR := customResource + + apiextv1.AddToScheme(scheme.Scheme) + sourceClient := ctrlClientFake.NewClientBuilder().WithObjects().Build() + return true, tmpCR, sourceClient, operatorConfig + }, "fail - auth deployment file bad yaml": func(*testing.T) (bool, csmv1.ContainerStorageModule, ctrlClient.Client, utils.OperatorConfig) { customResource, err := getCustomResource("./testdata/cr_auth_proxy.yaml") if err != nil { diff --git a/pkg/modules/testdata/cr_auth_proxy.yaml b/pkg/modules/testdata/cr_auth_proxy.yaml index 4364bb4b0..9eb85dc82 100644 --- a/pkg/modules/testdata/cr_auth_proxy.yaml +++ b/pkg/modules/testdata/cr_auth_proxy.yaml @@ -92,6 +92,18 @@ spec: vaultRole: csm-authorization skipCertificateValidation: true kvEnginePath: secret + # certificate: base64-encoded certificate for cert/private-key pair -- add cert here to use custom certificates + # for self-signed certs, leave empty string + # Allowed values: string + certificate: "" + # privateKey: base64-encoded private key for cert/private-key pair -- add private key here to use custom certificates + # for self-signed certs, leave empty string + # Allowed values: string + privateKey: "" + # certificateAuthority: base64-encoded certificate authority for validating vault server certificate -- add certificate authority here to use custom certificates + # for self-signed certs, leave empty string + # Allowed values: string + certificateAuthority: "" --- apiVersion: v1 diff --git a/pkg/modules/testdata/cr_auth_proxy_bad_vault_ca.yaml b/pkg/modules/testdata/cr_auth_proxy_bad_vault_ca.yaml new file mode 100644 index 000000000..388dd258a --- /dev/null +++ b/pkg/modules/testdata/cr_auth_proxy_bad_vault_ca.yaml @@ -0,0 +1,117 @@ +apiVersion: storage.dell.com/v1 +kind: ContainerStorageModule +metadata: + name: authorization + namespace: authorization +spec: + modules: + # Authorization: enable csm-authorization proxy server for RBAC + - name: authorization-proxy-server + # enable: Enable/Disable csm-authorization + enabled: true + configVersion: v2.0.0-alpha + forceRemoveModule: true + + # For OpenShift Container Platform only + # enabled: Enable/Disable OpenShift Ingress Controller + # Allowed values: + # true: enable use of OpenShift Ingress Controller + # false: disable use of OpenShift Ingress Controller only if you have your own ingress controller. Set the appropriate annotations for the ingresses in the proxy-server section + # Default value: false + openshift: false + + components: + # For Kubernetes Container Platform only + # enabled: Enable/Disable NGINX Ingress Controller + # Allowed values: + # true: enable deployment of NGINX Ingress Controller + # false: disable deployment of NGINX Ingress Controller only if you have your own ingress controller. Set the appropriate annotations for the ingresses in the proxy-server section + # Default value: true + - name: nginx + enabled: true + + # enabled: Enable/Disable cert-manager + # Allowed values: + # true: enable deployment of cert-manager + # false: disable deployment of cert-manager only if it's already deployed + # Default value: true + - name: cert-manager + enabled: true + + - name: proxy-server + # enable: Enable/Disable csm-authorization proxy server + enabled: true + proxyService: dellemc/csm-authorization-proxy:v2.0.0-alpha + tenantService: dellemc/csm-authorization-tenant:v2.0.0-alpha + roleService: dellemc/csm-authorization-role:v2.0.0-alpha + storageService: dellemc/csm-authorization-storage:v2.0.0-alpha + opa: openpolicyagent/opa + opaKubeMgmt: openpolicyagent/kube-mgmt:0.11 + + # certificate: base64-encoded certificate for cert/private-key pair -- add certificate here to use custom certificates + # for self-signed certs, leave empty string + # Allowed values: string + certificate: "" + + # privateKey: base64-encoded private key for cert/private-key pair -- add private key here to use custom certificates + # for self-signed certs, leave empty string + # Allowed values: string + privateKey: "" + + # proxy-server ingress will use this hostname + # NOTE: an additional hostname can be configured in proxyServerIngress.hosts + # NOTE: proxy-server ingress is configured to accept IP address connections so hostnames are not required + hostname: "csm-authorization.com" + + # proxy-server ingress configuration + proxyServerIngress: + - ingressClassName: nginx + + # additional host rules for the proxy-server ingress + hosts: + - authorization-ingress-nginx-controller.authorization.svc.cluster.local + + # additional annotations for the proxy-server ingress + annotations: {} + + - name: redis + redis: redis:6.0.8-alpine + commander: rediscommander/redis-commander:latest + redisName: redis-csm + redisCommander: redicommander + sentinel: sentinel + redisReplicas: 5 + # by default, csm-authorization will deploy a local (https://kubernetes.io/docs/concepts/storage/storage-classes/#local) volume for redis + # to use a different storage class for redis, specify the name of the storage class + # NOTE: the storage class must NOT be a storage class provisioned by a CSI driver using this installation of CSM Authorization + # Default value: None + storageclass: "local-storage" + + - name: vault + vaultAddress: https://10.0.0.1:8400 + vaultRole: csm-authorization + skipCertificateValidation: true + kvEnginePath: secret + # certificate: base64-encoded certificate for cert/private-key pair -- add cert here to use custom certificates + # for self-signed certs, leave empty string + # Allowed values: string + certificate: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCmR1bW15Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=" + # privateKey: base64-encoded private key for cert/private-key pair -- add private key here to use custom certificates + # for self-signed certs, leave empty string + # Allowed values: string + privateKey: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCmR1bW15Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=" + # certificateAuthority: base64-encoded certificate authority for validating vault server certificate -- add certificate authority here to use custom certificates + # for self-signed certs, leave empty string + # Allowed values: string + certificateAuthority: "XXXXXaGVsbG8=" + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: csm-config-params + namespace: authorization +data: + csm-config-params.yaml: | + CONCURRENT_POWERFLEX_REQUESTS: 10 + LOG_LEVEL: debug diff --git a/pkg/modules/testdata/cr_auth_proxy_bad_vault_cert.yaml b/pkg/modules/testdata/cr_auth_proxy_bad_vault_cert.yaml new file mode 100644 index 000000000..35b4c5860 --- /dev/null +++ b/pkg/modules/testdata/cr_auth_proxy_bad_vault_cert.yaml @@ -0,0 +1,117 @@ +apiVersion: storage.dell.com/v1 +kind: ContainerStorageModule +metadata: + name: authorization + namespace: authorization +spec: + modules: + # Authorization: enable csm-authorization proxy server for RBAC + - name: authorization-proxy-server + # enable: Enable/Disable csm-authorization + enabled: true + configVersion: v2.0.0-alpha + forceRemoveModule: true + + # For OpenShift Container Platform only + # enabled: Enable/Disable OpenShift Ingress Controller + # Allowed values: + # true: enable use of OpenShift Ingress Controller + # false: disable use of OpenShift Ingress Controller only if you have your own ingress controller. Set the appropriate annotations for the ingresses in the proxy-server section + # Default value: false + openshift: false + + components: + # For Kubernetes Container Platform only + # enabled: Enable/Disable NGINX Ingress Controller + # Allowed values: + # true: enable deployment of NGINX Ingress Controller + # false: disable deployment of NGINX Ingress Controller only if you have your own ingress controller. Set the appropriate annotations for the ingresses in the proxy-server section + # Default value: true + - name: nginx + enabled: true + + # enabled: Enable/Disable cert-manager + # Allowed values: + # true: enable deployment of cert-manager + # false: disable deployment of cert-manager only if it's already deployed + # Default value: true + - name: cert-manager + enabled: true + + - name: proxy-server + # enable: Enable/Disable csm-authorization proxy server + enabled: true + proxyService: dellemc/csm-authorization-proxy:v2.0.0-alpha + tenantService: dellemc/csm-authorization-tenant:v2.0.0-alpha + roleService: dellemc/csm-authorization-role:v2.0.0-alpha + storageService: dellemc/csm-authorization-storage:v2.0.0-alpha + opa: openpolicyagent/opa + opaKubeMgmt: openpolicyagent/kube-mgmt:0.11 + + # certificate: base64-encoded certificate for cert/private-key pair -- add certificate here to use custom certificates + # for self-signed certs, leave empty string + # Allowed values: string + certificate: "" + + # privateKey: base64-encoded private key for cert/private-key pair -- add private key here to use custom certificates + # for self-signed certs, leave empty string + # Allowed values: string + privateKey: "" + + # proxy-server ingress will use this hostname + # NOTE: an additional hostname can be configured in proxyServerIngress.hosts + # NOTE: proxy-server ingress is configured to accept IP address connections so hostnames are not required + hostname: "csm-authorization.com" + + # proxy-server ingress configuration + proxyServerIngress: + - ingressClassName: nginx + + # additional host rules for the proxy-server ingress + hosts: + - authorization-ingress-nginx-controller.authorization.svc.cluster.local + + # additional annotations for the proxy-server ingress + annotations: {} + + - name: redis + redis: redis:6.0.8-alpine + commander: rediscommander/redis-commander:latest + redisName: redis-csm + redisCommander: redicommander + sentinel: sentinel + redisReplicas: 5 + # by default, csm-authorization will deploy a local (https://kubernetes.io/docs/concepts/storage/storage-classes/#local) volume for redis + # to use a different storage class for redis, specify the name of the storage class + # NOTE: the storage class must NOT be a storage class provisioned by a CSI driver using this installation of CSM Authorization + # Default value: None + storageclass: "local-storage" + + - name: vault + vaultAddress: https://10.0.0.1:8400 + vaultRole: csm-authorization + skipCertificateValidation: true + kvEnginePath: secret + # certificate: base64-encoded certificate for cert/private-key pair -- add cert here to use custom certificates + # for self-signed certs, leave empty string + # Allowed values: string + certificate: "XXXXXaGVsbG8=" + # privateKey: base64-encoded private key for cert/private-key pair -- add private key here to use custom certificates + # for self-signed certs, leave empty string + # Allowed values: string + privateKey: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCmR1bW15Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=" + # certificateAuthority: base64-encoded certificate authority for validating vault server certificate -- add certificate authority here to use custom certificates + # for self-signed certs, leave empty string + # Allowed values: string + certificateAuthority: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCmR1bW15Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=" + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: csm-config-params + namespace: authorization +data: + csm-config-params.yaml: | + CONCURRENT_POWERFLEX_REQUESTS: 10 + LOG_LEVEL: debug diff --git a/pkg/modules/testdata/cr_auth_proxy_bad_vault_key.yaml b/pkg/modules/testdata/cr_auth_proxy_bad_vault_key.yaml new file mode 100644 index 000000000..9d5b23287 --- /dev/null +++ b/pkg/modules/testdata/cr_auth_proxy_bad_vault_key.yaml @@ -0,0 +1,117 @@ +apiVersion: storage.dell.com/v1 +kind: ContainerStorageModule +metadata: + name: authorization + namespace: authorization +spec: + modules: + # Authorization: enable csm-authorization proxy server for RBAC + - name: authorization-proxy-server + # enable: Enable/Disable csm-authorization + enabled: true + configVersion: v2.0.0-alpha + forceRemoveModule: true + + # For OpenShift Container Platform only + # enabled: Enable/Disable OpenShift Ingress Controller + # Allowed values: + # true: enable use of OpenShift Ingress Controller + # false: disable use of OpenShift Ingress Controller only if you have your own ingress controller. Set the appropriate annotations for the ingresses in the proxy-server section + # Default value: false + openshift: false + + components: + # For Kubernetes Container Platform only + # enabled: Enable/Disable NGINX Ingress Controller + # Allowed values: + # true: enable deployment of NGINX Ingress Controller + # false: disable deployment of NGINX Ingress Controller only if you have your own ingress controller. Set the appropriate annotations for the ingresses in the proxy-server section + # Default value: true + - name: nginx + enabled: true + + # enabled: Enable/Disable cert-manager + # Allowed values: + # true: enable deployment of cert-manager + # false: disable deployment of cert-manager only if it's already deployed + # Default value: true + - name: cert-manager + enabled: true + + - name: proxy-server + # enable: Enable/Disable csm-authorization proxy server + enabled: true + proxyService: dellemc/csm-authorization-proxy:v2.0.0-alpha + tenantService: dellemc/csm-authorization-tenant:v2.0.0-alpha + roleService: dellemc/csm-authorization-role:v2.0.0-alpha + storageService: dellemc/csm-authorization-storage:v2.0.0-alpha + opa: openpolicyagent/opa + opaKubeMgmt: openpolicyagent/kube-mgmt:0.11 + + # certificate: base64-encoded certificate for cert/private-key pair -- add certificate here to use custom certificates + # for self-signed certs, leave empty string + # Allowed values: string + certificate: "" + + # privateKey: base64-encoded private key for cert/private-key pair -- add private key here to use custom certificates + # for self-signed certs, leave empty string + # Allowed values: string + privateKey: "" + + # proxy-server ingress will use this hostname + # NOTE: an additional hostname can be configured in proxyServerIngress.hosts + # NOTE: proxy-server ingress is configured to accept IP address connections so hostnames are not required + hostname: "csm-authorization.com" + + # proxy-server ingress configuration + proxyServerIngress: + - ingressClassName: nginx + + # additional host rules for the proxy-server ingress + hosts: + - authorization-ingress-nginx-controller.authorization.svc.cluster.local + + # additional annotations for the proxy-server ingress + annotations: {} + + - name: redis + redis: redis:6.0.8-alpine + commander: rediscommander/redis-commander:latest + redisName: redis-csm + redisCommander: redicommander + sentinel: sentinel + redisReplicas: 5 + # by default, csm-authorization will deploy a local (https://kubernetes.io/docs/concepts/storage/storage-classes/#local) volume for redis + # to use a different storage class for redis, specify the name of the storage class + # NOTE: the storage class must NOT be a storage class provisioned by a CSI driver using this installation of CSM Authorization + # Default value: None + storageclass: "local-storage" + + - name: vault + vaultAddress: https://10.0.0.1:8400 + vaultRole: csm-authorization + skipCertificateValidation: true + kvEnginePath: secret + # certificate: base64-encoded certificate for cert/private-key pair -- add cert here to use custom certificates + # for self-signed certs, leave empty string + # Allowed values: string + certificate: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCmR1bW15Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=" + # privateKey: base64-encoded private key for cert/private-key pair -- add private key here to use custom certificates + # for self-signed certs, leave empty string + # Allowed values: string + privateKey: "XXXXXaGVsbG8=" + # certificateAuthority: base64-encoded certificate authority for validating vault server certificate -- add certificate authority here to use custom certificates + # for self-signed certs, leave empty string + # Allowed values: string + certificateAuthority: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCmR1bW15Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=" + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: csm-config-params + namespace: authorization +data: + csm-config-params.yaml: | + CONCURRENT_POWERFLEX_REQUESTS: 10 + LOG_LEVEL: debug diff --git a/pkg/modules/testdata/cr_auth_proxy_openshift.yaml b/pkg/modules/testdata/cr_auth_proxy_openshift.yaml new file mode 100644 index 000000000..0055e587f --- /dev/null +++ b/pkg/modules/testdata/cr_auth_proxy_openshift.yaml @@ -0,0 +1,118 @@ +apiVersion: storage.dell.com/v1 +kind: ContainerStorageModule +metadata: + name: authorization + namespace: authorization +spec: + modules: + # Authorization: enable csm-authorization proxy server for RBAC + - name: authorization-proxy-server + # enable: Enable/Disable csm-authorization + enabled: true + configVersion: v2.0.0-alpha + forceRemoveModule: true + + # For OpenShift Container Platform only + # enabled: Enable/Disable OpenShift Ingress Controller + # Allowed values: + # true: enable use of OpenShift Ingress Controller + # false: disable use of OpenShift Ingress Controller only if you have your own ingress controller. Set the appropriate annotations for the ingresses in the proxy-server section + # Default value: false + openshift: true + + components: + # For Kubernetes Container Platform only + # enabled: Enable/Disable NGINX Ingress Controller + # Allowed values: + # true: enable deployment of NGINX Ingress Controller + # false: disable deployment of NGINX Ingress Controller only if you have your own ingress controller. Set the appropriate annotations for the ingresses in the proxy-server section + # Default value: true + - name: nginx + enabled: true + + # enabled: Enable/Disable cert-manager + # Allowed values: + # true: enable deployment of cert-manager + # false: disable deployment of cert-manager only if it's already deployed + # Default value: true + - name: cert-manager + enabled: true + + - name: proxy-server + # enable: Enable/Disable csm-authorization proxy server + enabled: true + proxyService: dellemc/csm-authorization-proxy:v2.0.0-alpha + tenantService: dellemc/csm-authorization-tenant:v2.0.0-alpha + roleService: dellemc/csm-authorization-role:v2.0.0-alpha + storageService: dellemc/csm-authorization-storage:v2.0.0-alpha + opa: openpolicyagent/opa + opaKubeMgmt: openpolicyagent/kube-mgmt:0.11 + + # certificate: base64-encoded certificate for cert/private-key pair -- add certificate here to use custom certificates + # for self-signed certs, leave empty string + # Allowed values: string + certificate: "" + + # privateKey: base64-encoded private key for cert/private-key pair -- add private key here to use custom certificates + # for self-signed certs, leave empty string + # Allowed values: string + privateKey: "" + + # proxy-server ingress will use this hostname + # NOTE: an additional hostname can be configured in proxyServerIngress.hosts + # NOTE: proxy-server ingress is configured to accept IP address connections so hostnames are not required + hostname: "csm-authorization.com" + + # proxy-server ingress configuration + proxyServerIngress: + - ingressClassName: nginx + + # additional host rules for the proxy-server ingress + hosts: + - authorization-ingress-nginx-controller.authorization.svc.cluster.local + + # additional annotations for the proxy-server ingress + annotations: + "label": "value" + + - name: redis + redis: redis:6.0.8-alpine + commander: rediscommander/redis-commander:latest + redisName: redis-csm + redisCommander: redicommander + sentinel: sentinel + redisReplicas: 5 + # by default, csm-authorization will deploy a local (https://kubernetes.io/docs/concepts/storage/storage-classes/#local) volume for redis + # to use a different storage class for redis, specify the name of the storage class + # NOTE: the storage class must NOT be a storage class provisioned by a CSI driver using this installation of CSM Authorization + # Default value: None + storageclass: "local-storage" + + - name: vault + vaultAddress: https://10.0.0.1:8400 + vaultRole: csm-authorization + skipCertificateValidation: true + kvEnginePath: secret + # certificate: base64-encoded certificate for cert/private-key pair -- add cert here to use custom certificates + # for self-signed certs, leave empty string + # Allowed values: string + certificate: "" + # privateKey: base64-encoded private key for cert/private-key pair -- add private key here to use custom certificates + # for self-signed certs, leave empty string + # Allowed values: string + privateKey: "" + # certificateAuthority: base64-encoded certificate authority for validating vault server certificate -- add certificate authority here to use custom certificates + # for self-signed certs, leave empty string + # Allowed values: string + certificateAuthority: "" + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: csm-config-params + namespace: authorization +data: + csm-config-params.yaml: | + CONCURRENT_POWERFLEX_REQUESTS: 10 + LOG_LEVEL: debug diff --git a/pkg/modules/testdata/cr_auth_proxy_vault_cert.yaml b/pkg/modules/testdata/cr_auth_proxy_vault_cert.yaml new file mode 100644 index 000000000..da93144c6 --- /dev/null +++ b/pkg/modules/testdata/cr_auth_proxy_vault_cert.yaml @@ -0,0 +1,117 @@ +apiVersion: storage.dell.com/v1 +kind: ContainerStorageModule +metadata: + name: authorization + namespace: authorization +spec: + modules: + # Authorization: enable csm-authorization proxy server for RBAC + - name: authorization-proxy-server + # enable: Enable/Disable csm-authorization + enabled: true + configVersion: v2.0.0-alpha + forceRemoveModule: true + + # For OpenShift Container Platform only + # enabled: Enable/Disable OpenShift Ingress Controller + # Allowed values: + # true: enable use of OpenShift Ingress Controller + # false: disable use of OpenShift Ingress Controller only if you have your own ingress controller. Set the appropriate annotations for the ingresses in the proxy-server section + # Default value: false + openshift: false + + components: + # For Kubernetes Container Platform only + # enabled: Enable/Disable NGINX Ingress Controller + # Allowed values: + # true: enable deployment of NGINX Ingress Controller + # false: disable deployment of NGINX Ingress Controller only if you have your own ingress controller. Set the appropriate annotations for the ingresses in the proxy-server section + # Default value: true + - name: nginx + enabled: true + + # enabled: Enable/Disable cert-manager + # Allowed values: + # true: enable deployment of cert-manager + # false: disable deployment of cert-manager only if it's already deployed + # Default value: true + - name: cert-manager + enabled: true + + - name: proxy-server + # enable: Enable/Disable csm-authorization proxy server + enabled: true + proxyService: dellemc/csm-authorization-proxy:v2.0.0-alpha + tenantService: dellemc/csm-authorization-tenant:v2.0.0-alpha + roleService: dellemc/csm-authorization-role:v2.0.0-alpha + storageService: dellemc/csm-authorization-storage:v2.0.0-alpha + opa: openpolicyagent/opa + opaKubeMgmt: openpolicyagent/kube-mgmt:0.11 + + # certificate: base64-encoded certificate for cert/private-key pair -- add certificate here to use custom certificates + # for self-signed certs, leave empty string + # Allowed values: string + certificate: "" + + # privateKey: base64-encoded private key for cert/private-key pair -- add private key here to use custom certificates + # for self-signed certs, leave empty string + # Allowed values: string + privateKey: "" + + # proxy-server ingress will use this hostname + # NOTE: an additional hostname can be configured in proxyServerIngress.hosts + # NOTE: proxy-server ingress is configured to accept IP address connections so hostnames are not required + hostname: "csm-authorization.com" + + # proxy-server ingress configuration + proxyServerIngress: + - ingressClassName: nginx + + # additional host rules for the proxy-server ingress + hosts: + - authorization-ingress-nginx-controller.authorization.svc.cluster.local + + # additional annotations for the proxy-server ingress + annotations: {} + + - name: redis + redis: redis:6.0.8-alpine + commander: rediscommander/redis-commander:latest + redisName: redis-csm + redisCommander: redicommander + sentinel: sentinel + redisReplicas: 5 + # by default, csm-authorization will deploy a local (https://kubernetes.io/docs/concepts/storage/storage-classes/#local) volume for redis + # to use a different storage class for redis, specify the name of the storage class + # NOTE: the storage class must NOT be a storage class provisioned by a CSI driver using this installation of CSM Authorization + # Default value: None + storageclass: "local-storage" + + - name: vault + vaultAddress: https://10.0.0.1:8400 + vaultRole: csm-authorization + skipCertificateValidation: true + kvEnginePath: secret + # certificate: base64-encoded certificate for cert/private-key pair -- add cert here to use custom certificates + # for self-signed certs, leave empty string + # Allowed values: string + certificate: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCmR1bW15Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=" + # privateKey: base64-encoded private key for cert/private-key pair -- add private key here to use custom certificates + # for self-signed certs, leave empty string + # Allowed values: string + privateKey: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCmR1bW15Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=" + # certificateAuthority: base64-encoded certificate authority for validating vault server certificate -- add certificate authority here to use custom certificates + # for self-signed certs, leave empty string + # Allowed values: string + certificateAuthority: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCmR1bW15Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=" + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: csm-config-params + namespace: authorization +data: + csm-config-params.yaml: | + CONCURRENT_POWERFLEX_REQUESTS: 10 + LOG_LEVEL: debug diff --git a/samples/authorization/csm_authorization_proxy_server_v200-alpha.yaml b/samples/authorization/csm_authorization_proxy_server_v200-alpha.yaml index a1834d2bc..4e1b10572 100644 --- a/samples/authorization/csm_authorization_proxy_server_v200-alpha.yaml +++ b/samples/authorization/csm_authorization_proxy_server_v200-alpha.yaml @@ -88,17 +88,24 @@ spec: redisCommander: redicommander sentinel: sentinel redisReplicas: 5 - # by default, csm-authorization will deploy a local (https://kubernetes.io/docs/concepts/storage/storage-classes/#local) volume for redis - # to use a different storage class for redis, specify the name of the storage class - # NOTE: the storage class must NOT be a storage class provisioned by a CSI driver using this installation of CSM Authorization - # Default value: None - storageclass: "" - name: vault vaultAddress: https://10.0.0.1:8400 vaultRole: csm-authorization skipCertificateValidation: true kvEnginePath: secret + # certificate: base64-encoded certificate for cert/private-key pair -- add cert here to use custom certificates + # for self-signed certs, leave empty string + # Allowed values: string + certificate: "" + # privateKey: base64-encoded private key for cert/private-key pair -- add private key here to use custom certificates + # for self-signed certs, leave empty string + # Allowed values: string + privateKey: "" + # certificateAuthority: base64-encoded certificate authority for validating vault server certificate -- add certificate authority here to use custom certificates + # for self-signed certs, leave empty string + # Allowed values: string + certificateAuthority: "" --- apiVersion: v1