From 3cc3a2f2d52e13b30447db0eba6eec2c82afd28b Mon Sep 17 00:00:00 2001 From: Dmytro Date: Fri, 17 Sep 2021 00:47:34 +0300 Subject: [PATCH 1/2] Added ability to mount external PVCs to cdap deployments and statefulsets. --- api/v1alpha1/cdapmaster_types.go | 8 ++ .../crd/bases/cdap.cdap.io_cdapmasters.yaml | 88 +++++++++++++++++++ controllers/deployment.go | 6 ++ controllers/spec.go | 23 +++++ templates/cdap-deployment.yaml | 9 ++ templates/cdap-sts.yaml | 9 ++ 6 files changed, 143 insertions(+) diff --git a/api/v1alpha1/cdapmaster_types.go b/api/v1alpha1/cdapmaster_types.go index ce259890..08079817 100644 --- a/api/v1alpha1/cdapmaster_types.go +++ b/api/v1alpha1/cdapmaster_types.go @@ -54,6 +54,10 @@ type CDAPMasterSpec struct { // Key is the secret object name. Value is the mount path. // This adds Secret data to the directory specified by the volume mount path. SecretVolumes map[string]string `json:"secretVolumes,omitempty"` + // PVCVolumes defines a map from Persistent Volume Claim names to volume mount path. + // Key is the PVC object name. Value is the mount path. + // This mounts PVC to the directory specified by the volume mount path. + PVCVolumes map[string]string `json:"pvcVolumes,omitempty"` // SystemAppConfigs specifies configs used by CDAP to run system apps // dynamically. Each entry is of format which will // create a separate system config file with entry value as file content. @@ -117,6 +121,10 @@ type CDAPServiceSpec struct { // Key is the secret object name. Value is the mount path. // This adds Secret data to the directory specified by the volume mount path. SecretVolumes map[string]string `json:"secretVolumes,omitempty"` + // PVCVolumes defines a map from Persistent Volume Claim names to volume mount path. + // Key is the PVC object name. Value is the mount path. + // This mounts PVC to the directory specified by the volume mount path. + PVCVolumes map[string]string `json:"pvcVolumes,omitempty"` // SecurityContext overrides the security context for the service pods. SecurityContext *SecurityContext `json:"securityContext,omitempty"` } diff --git a/config/crd/bases/cdap.cdap.io_cdapmasters.yaml b/config/crd/bases/cdap.cdap.io_cdapmasters.yaml index ab1b878d..058ae45c 100644 --- a/config/crd/bases/cdap.cdap.io_cdapmasters.yaml +++ b/config/crd/bases/cdap.cdap.io_cdapmasters.yaml @@ -199,6 +199,14 @@ spec: is the mount path. This adds Secret data to the directory specified by the volume mount path. type: object + pvcVolumes: + additionalProperties: + type: string + description: PVCVolumes defines a map from Persistent Volume Claim + names to volume mount path. Key is the PVC object name. Value is the + mount path. This mounts PVC to the directory specified by the volume + mount path. + type: object securityContext: description: SecurityContext overrides the security context for the service pods. @@ -421,6 +429,14 @@ spec: is the mount path. This adds Secret data to the directory specified by the volume mount path. type: object + pvcVolumes: + additionalProperties: + type: string + description: PVCVolumes defines a map from Persistent Volume Claim + names to volume mount path. Key is the PVC object name. Value is the + mount path. This mounts PVC to the directory specified by the volume + mount path. + type: object securityContext: description: SecurityContext overrides the security context for the service pods. @@ -656,6 +672,14 @@ spec: is the mount path. This adds Secret data to the directory specified by the volume mount path. type: object + pvcVolumes: + additionalProperties: + type: string + description: PVCVolumes defines a map from Persistent Volume Claim + names to volume mount path. Key is the PVC object name. Value is the + mount path. This mounts PVC to the directory specified by the volume + mount path. + type: object securityContext: description: SecurityContext overrides the security context for the service pods. @@ -870,6 +894,14 @@ spec: is the mount path. This adds Secret data to the directory specified by the volume mount path. type: object + pvcVolumes: + additionalProperties: + type: string + description: PVCVolumes defines a map from Persistent Volume Claim + names to volume mount path. Key is the PVC object name. Value is the + mount path. This mounts PVC to the directory specified by the volume + mount path. + type: object securityContext: description: SecurityContext overrides the security context for the service pods. @@ -1088,6 +1120,14 @@ spec: is the mount path. This adds Secret data to the directory specified by the volume mount path. type: object + pvcVolumes: + additionalProperties: + type: string + description: PVCVolumes defines a map from Persistent Volume Claim + names to volume mount path. Key is the PVC object name. Value is the + mount path. This mounts PVC to the directory specified by the volume + mount path. + type: object securityContext: description: SecurityContext overrides the security context for the service pods. @@ -1294,6 +1334,14 @@ spec: is the mount path. This adds Secret data to the directory specified by the volume mount path. type: object + pvcVolumes: + additionalProperties: + type: string + description: PVCVolumes defines a map from Persistent Volume Claim + names to volume mount path. Key is the PVC object name. Value is the + mount path. This mounts PVC to the directory specified by the volume + mount path. + type: object securityContext: description: SecurityContext overrides the security context for the service pods. @@ -1508,6 +1556,14 @@ spec: is the mount path. This adds Secret data to the directory specified by the volume mount path. type: object + pvcVolumes: + additionalProperties: + type: string + description: PVCVolumes defines a map from Persistent Volume Claim + names to volume mount path. Key is the PVC object name. Value is the + mount path. This mounts PVC to the directory specified by the volume + mount path. + type: object securityContext: description: SecurityContext overrides the security context for the service pods. @@ -1726,6 +1782,14 @@ spec: is the mount path. This adds Secret data to the directory specified by the volume mount path. type: object + pvcVolumes: + additionalProperties: + type: string + description: PVCVolumes defines a map from Persistent Volume Claim + names to volume mount path. Key is the PVC object name. Value is the + mount path. This mounts PVC to the directory specified by the volume + mount path. + type: object securityContext: description: SecurityContext overrides the security context for the service pods. @@ -1944,6 +2008,14 @@ spec: is the mount path. This adds Secret data to the directory specified by the volume mount path. type: object + pvcVolumes: + additionalProperties: + type: string + description: PVCVolumes defines a map from Persistent Volume Claim + names to volume mount path. Key is the PVC object name. Value is the + mount path. This mounts PVC to the directory specified by the volume + mount path. + type: object securityContext: description: SecurityContext overrides the security context for the service pods. @@ -2007,6 +2079,14 @@ spec: This adds Secret data to the directory specified by the volume mount path. type: object + pvcVolumes: + additionalProperties: + type: string + description: PVCVolumes defines a map from Persistent Volume Claim + names to volume mount path. Key is the PVC object name. Value is the + mount path. This mounts PVC to the directory specified by the volume + mount path. + type: object securityContext: description: SecurityContext defines the security context for all pods for all services. @@ -2226,6 +2306,14 @@ spec: is the mount path. This adds Secret data to the directory specified by the volume mount path. type: object + pvcVolumes: + additionalProperties: + type: string + description: PVCVolumes defines a map from Persistent Volume Claim + names to volume mount path. Key is the PVC object name. Value is the + mount path. This mounts PVC to the directory specified by the volume + mount path. + type: object securityContext: description: SecurityContext overrides the security context for the service pods. diff --git a/controllers/deployment.go b/controllers/deployment.go index 092a5bba..f4fd66df 100644 --- a/controllers/deployment.go +++ b/controllers/deployment.go @@ -198,6 +198,9 @@ func buildStatefulSets(master *v1alpha1.CDAPMaster, name string, services Servic if _, err := spec.addSecretVolumes(ss.SecretVolumes); err != nil { return nil, err } + if _, err := spec.addPVCVolumes(ss.PVCVolumes); err != nil { + return nil, err + } } // All services are optional services and are disabled in CR. @@ -283,6 +286,9 @@ func buildDeployment(master *v1alpha1.CDAPMaster, name string, services ServiceG if _, err := spec.addSecretVolumes(ss.SecretVolumes); err != nil { return nil, err } + if _, err := spec.addPVCVolumes(ss.PVCVolumes); err != nil { + return nil, err + } } // All services are optional services and are disabled in CR. // Return nil to indicate no deployment is built. diff --git a/controllers/spec.go b/controllers/spec.go index b03725b1..a50feb5d 100644 --- a/controllers/spec.go +++ b/controllers/spec.go @@ -137,6 +137,7 @@ type BaseSpec struct { SysAppConf string `json:"sysAppConf,omitempty"` ConfigMapVolumes map[string]string `json:"configMapVolumes,omitempty"` SecretVolumes map[string]string `json:"secretVolumes,omitempty"` + PVCVolumes map[string]string `json:"pvcVolumes,omitempty"` SecurityContext *v1alpha1.SecurityContext `json:"securityContext,omitempty"` } @@ -156,6 +157,7 @@ func newBaseSpec(master *v1alpha1.CDAPMaster, name string, labels map[string]str s.SysAppConf = sysappconf s.ConfigMapVolumes = cloneMap(master.Spec.ConfigMapVolumes) s.SecretVolumes = cloneMap(master.Spec.SecretVolumes) + s.PVCVolumes = cloneMap(master.Spec.PVCVolumes) return s } @@ -205,6 +207,13 @@ func (s *BaseSpec) addSecretVolumes(volumes map[string]string) (*BaseSpec, error return s, nil } +func (s *BaseSpec) addPVCVolumes(volumes map[string]string) (*BaseSpec, error) { + if err := addVolumes(s.PVCVolumes, volumes, "Persistent Volume Claim"); err != nil { + return nil, err + } + return s, nil +} + func addVolumes(volumes, newVolumes map[string]string, typeName string) error { for k, v := range newVolumes { if val, exists := volumes[k]; exists { @@ -306,6 +315,13 @@ func (s *DeploymentSpec) addSecretVolumes(volumes map[string]string) (*Deploymen return s, nil } +func (s *DeploymentSpec) addPVCVolumes(volumes map[string]string) (*DeploymentSpec, error) { + if _, err := s.Base.addPVCVolumes(volumes); err != nil { + return nil, err + } + return s, nil +} + func (s *DeploymentSpec) setSecurityContext(securityContext *v1alpha1.SecurityContext) *DeploymentSpec { s.Base.setSecurityContext(securityContext) return s @@ -397,6 +413,13 @@ func (s *StatefulSpec) addSecretVolumes(volumes map[string]string) (*StatefulSpe return s, nil } +func (s *StatefulSpec) addPVCVolumes(volumes map[string]string) (*StatefulSpec, error) { + if _, err := s.Base.addPVCVolumes(volumes); err != nil { + return nil, err + } + return s, nil +} + func (s *StatefulSpec) setSecurityContext(securityContext *v1alpha1.SecurityContext) *StatefulSpec { s.Base.setSecurityContext(securityContext) return s diff --git a/templates/cdap-deployment.yaml b/templates/cdap-deployment.yaml index 0df3fe3c..7c785ecc 100644 --- a/templates/cdap-deployment.yaml +++ b/templates/cdap-deployment.yaml @@ -132,6 +132,10 @@ spec: - name: cdap-se-vol-{{$k}} mountPath: {{$v}} {{end}} + {{range $k,$v := $.Base.PVCVolumes}} + - name: cdap-vol-{{$k}} + mountPath: {{$v}} + {{end}} {{end}} volumes: - name: podinfo @@ -170,3 +174,8 @@ spec: secret: secretName: {{$k}} {{end}} + {{range $k,$v := $.Base.PVCVolumes}} + - name: cdap-vol-{{$k}} + persistentVolumeClaim: + claimName: {{$k}} + {{end}} diff --git a/templates/cdap-sts.yaml b/templates/cdap-sts.yaml index 71cefebc..6ed5160a 100644 --- a/templates/cdap-sts.yaml +++ b/templates/cdap-sts.yaml @@ -172,6 +172,10 @@ spec: - name: cdap-se-vol-{{$k}} mountPath: {{$v}} {{end}} + {{range $k,$v := $.Base.PVCVolumes}} + - name: cdap-vol-{{$k}} + mountPath: {{$v}} + {{end}} {{end}} volumes: - name: podinfo @@ -210,6 +214,11 @@ spec: secret: secretName: {{$k}} {{end}} + {{range $k,$v := $.Base.PVCVolumes}} + - name: cdap-vol-{{$k}} + persistentVolumeClaim: + claimName: {{$k}} + {{end}} volumeClaimTemplates: - metadata: name: {{.Base.Name}}-data From 2e48e893d2f50629bcfe66e857506cfda2942524 Mon Sep 17 00:00:00 2001 From: Dmytro Date: Fri, 17 Sep 2021 11:35:29 +0300 Subject: [PATCH 2/2] Added ability to mount external PVCs to cdap deployments and statefulsets. Unit tests update. --- controllers/testdata/appfabric.json | 28 ++++++++++++++++++++++++ controllers/testdata/authentication.json | 10 +++++++++ controllers/testdata/cdap_master_cr.json | 6 +++++ controllers/testdata/logs.json | 14 ++++++++++++ controllers/testdata/messaging.json | 14 ++++++++++++ controllers/testdata/metadata.json | 10 +++++++++ controllers/testdata/metrics.json | 14 ++++++++++++ controllers/testdata/preview.json | 14 ++++++++++++ controllers/testdata/router.json | 10 +++++++++ controllers/testdata/runtime.json | 14 ++++++++++++ controllers/testdata/userinterface.json | 10 +++++++++ 11 files changed, 144 insertions(+) diff --git a/controllers/testdata/appfabric.json b/controllers/testdata/appfabric.json index 8bfdd26e..fe361ee9 100644 --- a/controllers/testdata/appfabric.json +++ b/controllers/testdata/appfabric.json @@ -136,6 +136,14 @@ { "mountPath": "/my/secret/1", "name": "cdap-se-vol-my-secret-1" + }, + { + "mountPath": "/my/pvc/0", + "name": "cdap-vol-my-pvc-0" + }, + { + "mountPath": "/my/pvc/1", + "name": "cdap-vol-my-pvc-1" } ] } @@ -189,6 +197,14 @@ { "mountPath": "/my/secret/1", "name": "cdap-se-vol-my-secret-1" + }, + { + "mountPath": "/my/pvc/0", + "name": "cdap-vol-my-pvc-0" + }, + { + "mountPath": "/my/pvc/1", + "name": "cdap-vol-my-pvc-1" } ] } @@ -283,6 +299,18 @@ "defaultMode": 420, "secretName": "my-secret-1" } + }, + { + "name": "cdap-vol-my-pvc-0", + "persistentVolumeClaim": { + "claimName": "my-pvc-0" + } + }, + { + "name": "cdap-vol-my-pvc-1", + "persistentVolumeClaim": { + "claimName": "my-pvc-1" + } } ] } diff --git a/controllers/testdata/authentication.json b/controllers/testdata/authentication.json index 2f5f9cee..2da54b76 100644 --- a/controllers/testdata/authentication.json +++ b/controllers/testdata/authentication.json @@ -135,6 +135,10 @@ { "mountPath": "/my/secret/key", "name": "cdap-se-vol-secret-key" + }, + { + "mountPath": "/my/pvc/0", + "name": "cdap-vol-my-pvc-0" } ] } @@ -233,6 +237,12 @@ "secret": { "secretName": "secret-key" } + }, + { + "name": "cdap-vol-my-pvc-0", + "persistentVolumeClaim": { + "claimName": "my-pvc-0" + } } ] } diff --git a/controllers/testdata/cdap_master_cr.json b/controllers/testdata/cdap_master_cr.json index 5a4a2264..f56153af 100644 --- a/controllers/testdata/cdap_master_cr.json +++ b/controllers/testdata/cdap_master_cr.json @@ -42,6 +42,9 @@ "runAsGroup": 3000, "fsGroup": 4000, "runAsNonRoot": false + }, + "pvcVolumes": { + "my-pvc-1": "/my/pvc/1" } }, "authentication": { @@ -81,6 +84,9 @@ "secretVolumes": { "my-secret-1": "/my/secret/1" }, + "pvcVolumes": { + "my-pvc-0": "/my/pvc/0" + }, "image": "gcr.io/cloud-data-fusion-images/cloud-data-fusion:6.1.0.5", "locationURI": "hdfs://hadoop:9000", "logs": { diff --git a/controllers/testdata/logs.json b/controllers/testdata/logs.json index ff23b1b4..ff7076b3 100644 --- a/controllers/testdata/logs.json +++ b/controllers/testdata/logs.json @@ -125,6 +125,10 @@ { "mountPath": "/my/secret/1", "name": "cdap-se-vol-my-secret-1" + }, + { + "mountPath": "/my/pvc/0", + "name": "cdap-vol-my-pvc-0" } ] } @@ -182,6 +186,10 @@ { "mountPath": "/my/secret/1", "name": "cdap-se-vol-my-secret-1" + }, + { + "mountPath": "/my/pvc/0", + "name": "cdap-vol-my-pvc-0" } ] } @@ -275,6 +283,12 @@ "defaultMode": 420, "secretName": "my-secret-1" } + }, + { + "name": "cdap-vol-my-pvc-0", + "persistentVolumeClaim": { + "claimName": "my-pvc-0" + } } ] } diff --git a/controllers/testdata/messaging.json b/controllers/testdata/messaging.json index 37bc04db..3cd63806 100644 --- a/controllers/testdata/messaging.json +++ b/controllers/testdata/messaging.json @@ -125,6 +125,10 @@ { "mountPath": "/my/secret/1", "name": "cdap-se-vol-my-secret-1" + }, + { + "mountPath": "/my/pvc/0", + "name": "cdap-vol-my-pvc-0" } ] } @@ -182,6 +186,10 @@ { "mountPath": "/my/secret/1", "name": "cdap-se-vol-my-secret-1" + }, + { + "mountPath": "/my/pvc/0", + "name": "cdap-vol-my-pvc-0" } ] } @@ -275,6 +283,12 @@ "defaultMode": 420, "secretName": "my-secret-1" } + }, + { + "name": "cdap-vol-my-pvc-0", + "persistentVolumeClaim": { + "claimName": "my-pvc-0" + } } ] } diff --git a/controllers/testdata/metadata.json b/controllers/testdata/metadata.json index 1c6343a6..59e85e77 100644 --- a/controllers/testdata/metadata.json +++ b/controllers/testdata/metadata.json @@ -131,6 +131,10 @@ { "mountPath": "/my/secret/1", "name": "cdap-se-vol-my-secret-1" + }, + { + "mountPath": "/my/pvc/0", + "name": "cdap-vol-my-pvc-0" } ] } @@ -223,6 +227,12 @@ "defaultMode": 420, "secretName": "my-secret-1" } + }, + { + "name": "cdap-vol-my-pvc-0", + "persistentVolumeClaim": { + "claimName": "my-pvc-0" + } } ] } diff --git a/controllers/testdata/metrics.json b/controllers/testdata/metrics.json index 5374a6f5..88cf81f1 100644 --- a/controllers/testdata/metrics.json +++ b/controllers/testdata/metrics.json @@ -125,6 +125,10 @@ { "mountPath": "/my/secret/1", "name": "cdap-se-vol-my-secret-1" + }, + { + "mountPath": "/my/pvc/0", + "name": "cdap-vol-my-pvc-0" } ] } @@ -182,6 +186,10 @@ { "mountPath": "/my/secret/1", "name": "cdap-se-vol-my-secret-1" + }, + { + "mountPath": "/my/pvc/0", + "name": "cdap-vol-my-pvc-0" } ] } @@ -275,6 +283,12 @@ "defaultMode": 420, "secretName": "my-secret-1" } + }, + { + "name": "cdap-vol-my-pvc-0", + "persistentVolumeClaim": { + "claimName": "my-pvc-0" + } } ] } diff --git a/controllers/testdata/preview.json b/controllers/testdata/preview.json index cc7d7dec..363ea72f 100644 --- a/controllers/testdata/preview.json +++ b/controllers/testdata/preview.json @@ -125,6 +125,10 @@ { "mountPath": "/my/secret/1", "name": "cdap-se-vol-my-secret-1" + }, + { + "mountPath": "/my/pvc/0", + "name": "cdap-vol-my-pvc-0" } ] } @@ -182,6 +186,10 @@ { "mountPath": "/my/secret/1", "name": "cdap-se-vol-my-secret-1" + }, + { + "mountPath": "/my/pvc/0", + "name": "cdap-vol-my-pvc-0" } ] } @@ -273,6 +281,12 @@ "defaultMode": 420, "secretName": "my-secret-1" } + }, + { + "name": "cdap-vol-my-pvc-0", + "persistentVolumeClaim": { + "claimName": "my-pvc-0" + } } ] } diff --git a/controllers/testdata/router.json b/controllers/testdata/router.json index 4b0f514b..b64ec84b 100644 --- a/controllers/testdata/router.json +++ b/controllers/testdata/router.json @@ -134,6 +134,10 @@ { "mountPath": "/my/secret/key", "name": "cdap-se-vol-secret-key" + }, + { + "mountPath": "/my/pvc/0", + "name": "cdap-vol-my-pvc-0" } ] } @@ -232,6 +236,12 @@ "secret": { "secretName": "secret-key" } + }, + { + "name": "cdap-vol-my-pvc-0", + "persistentVolumeClaim": { + "claimName": "my-pvc-0" + } } ] } diff --git a/controllers/testdata/runtime.json b/controllers/testdata/runtime.json index fd652322..47a3ea27 100644 --- a/controllers/testdata/runtime.json +++ b/controllers/testdata/runtime.json @@ -136,6 +136,10 @@ { "mountPath": "/my/secret/1", "name": "cdap-se-vol-my-secret-1" + }, + { + "mountPath": "/my/pvc/0", + "name": "cdap-vol-my-pvc-0" } ] } @@ -189,6 +193,10 @@ { "mountPath": "/my/secret/1", "name": "cdap-se-vol-my-secret-1" + }, + { + "mountPath": "/my/pvc/0", + "name": "cdap-vol-my-pvc-0" } ] } @@ -281,6 +289,12 @@ "defaultMode": 420, "secretName": "my-secret-1" } + }, + { + "name": "cdap-vol-my-pvc-0", + "persistentVolumeClaim": { + "claimName": "my-pvc-0" + } } ] } diff --git a/controllers/testdata/userinterface.json b/controllers/testdata/userinterface.json index 2238a426..8f0eff12 100644 --- a/controllers/testdata/userinterface.json +++ b/controllers/testdata/userinterface.json @@ -137,6 +137,10 @@ { "mountPath": "/my/secret/1", "name": "cdap-se-vol-my-secret-1" + }, + { + "mountPath": "/my/pvc/0", + "name": "cdap-vol-my-pvc-0" } ], "workingDir": "/opt/cdap/ui" @@ -230,6 +234,12 @@ "defaultMode": 420, "secretName": "my-secret-1" } + }, + { + "name": "cdap-vol-my-pvc-0", + "persistentVolumeClaim": { + "claimName": "my-pvc-0" + } } ] }