From 61bc9a2777df4c546b66162bd8f8b1ea747a3a7a Mon Sep 17 00:00:00 2001 From: Karthik K Date: Tue, 14 Feb 2023 14:08:09 +0530 Subject: [PATCH 1/4] Changes added for sample yaml parameter for powerstore as configurable parameter --- .github/containerscan/allowedlist.yaml | 2 + .github/workflows/actions.yml | 2 +- config/rbac/role.yaml | 12 + config/samples/kustomization.yaml | 1 + config/samples/storage_v1_csm_powerstore.yaml | 117 ++++++++ controllers/csm_controller.go | 7 +- deploy/operator.yaml | 12 + .../powerstore/v2.5.0/controller.yaml | 257 ++++++++++++++++++ .../powerstore/v2.5.0/csidriver.yaml | 27 ++ .../v2.5.0/driver-config-params.yaml | 25 ++ .../driverconfig/powerstore/v2.5.0/node.yaml | 214 +++++++++++++++ .../powerstore/v2.5.0/upgrade-path.yaml | 1 + pkg/drivers/commonconfig.go | 6 + pkg/drivers/powerstore.go | 126 +++++++++ pkg/utils/status.go | 3 +- samples/storage_csm_powerstore_v250.yaml | 118 ++++++++ 16 files changed, 927 insertions(+), 3 deletions(-) create mode 100644 config/samples/storage_v1_csm_powerstore.yaml create mode 100644 operatorconfig/driverconfig/powerstore/v2.5.0/controller.yaml create mode 100644 operatorconfig/driverconfig/powerstore/v2.5.0/csidriver.yaml create mode 100644 operatorconfig/driverconfig/powerstore/v2.5.0/driver-config-params.yaml create mode 100644 operatorconfig/driverconfig/powerstore/v2.5.0/node.yaml create mode 100644 operatorconfig/driverconfig/powerstore/v2.5.0/upgrade-path.yaml create mode 100644 pkg/drivers/powerstore.go create mode 100644 samples/storage_csm_powerstore_v250.yaml diff --git a/.github/containerscan/allowedlist.yaml b/.github/containerscan/allowedlist.yaml index 68cd46343..1a9cc7bd4 100644 --- a/.github/containerscan/allowedlist.yaml +++ b/.github/containerscan/allowedlist.yaml @@ -3,6 +3,8 @@ general: # list of CVEs that are currently unfixed - CVE-2022-42898 - CVE-2022-47629 # this will be removed with the libskba library is updated in the UBI image + - CVE-2019-1010022 + - CVE-2022-28948 bestPracticeViolations: # list of best practies violatied that needs a fix diff --git a/.github/workflows/actions.yml b/.github/workflows/actions.yml index 22e78db8d..ee034fb95 100644 --- a/.github/workflows/actions.yml +++ b/.github/workflows/actions.yml @@ -12,7 +12,7 @@ jobs: - name: Checkout the code uses: actions/checkout@v2 - name: Run the formatter, linter, and vetter - uses: dell/common-github-actions/go-code-formatter-linter-vetter@update-go-version + uses: dell/common-github-actions/go-code-formatter-linter-vetter@main with: directories: ./... # Removing forbidden checks for now. Todo - maintain consistency across platforms diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index 70d5cba18..4901218d7 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -657,6 +657,18 @@ rules: - list - update - watch +- apiGroups: + - storage.k8s.io + resources: + - csistoragecapacities + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - storage.k8s.io resources: diff --git a/config/samples/kustomization.yaml b/config/samples/kustomization.yaml index 156b74b7b..7d171de3b 100644 --- a/config/samples/kustomization.yaml +++ b/config/samples/kustomization.yaml @@ -2,4 +2,5 @@ resources: - storage_v1_csm_powerscale.yaml - storage_v1_csm_powerflex.yaml + - storage_v1_csm_powerstore.yaml #+kubebuilder:scaffold:manifestskustomizesamples \ No newline at end of file diff --git a/config/samples/storage_v1_csm_powerstore.yaml b/config/samples/storage_v1_csm_powerstore.yaml new file mode 100644 index 000000000..2257e19e5 --- /dev/null +++ b/config/samples/storage_v1_csm_powerstore.yaml @@ -0,0 +1,117 @@ +apiVersion: storage.dell.com/v1 +kind: ContainerStorageModule +metadata: + name: test-powerstore + namespace: test-powerstore +spec: + driver: + csiDriverType: "powerstore" + csiDriverSpec: + # fsGroupPolicy: Defines if the underlying volume supports changing ownership and permission of the volume before being mounted. + # Allowed values: ReadWriteOnceWithFSType, File , None + # Default value: ReadWriteOnceWithFSType + fSGroupPolicy: "ReadWriteOnceWithFSType" + # Config version for CSI PowerStore v2.5.0 driver + configVersion: v2.5.0 + # Controller count + replicas: 2 + dnsPolicy: ClusterFirstWithHostNet + forceUpdate: false + common: + # Image for CSI PowerStore driver v2.5.0 + image: "dellemc/csi-powerstore:v2.5.0" + imagePullPolicy: IfNotPresent + envs: + - name: X_CSI_POWERSTORE_NODE_NAME_PREFIX + value: "csi-node" + - name: X_CSI_FC_PORTS_FILTER_FILE_PATH + value: "/etc/fc-ports-filter" + - name: KUBELET_CONFIG_DIR + value: /var/lib/kubelet + - name: CSI_LOG_LEVEL + value: debug + + sideCars: + # health monitor is disabled by default, refer to driver documentation before enabling it + # Also set the env variable controller.envs.X_CSI_HEALTH_MONITOR_ENABLED to "true". + - name: external-health-monitor + enabled: false + args: ["--monitor-interval=60s"] + controller: + envs: + # X_CSI_NFS_ACLS: enables setting permissions on NFS mount directory + # This value will be the default value if a storage class and array config in secret + # do not contain the NFS ACL (nfsAcls) parameter specified + # Permissions can be specified in two formats: + # 1) Unix mode (NFSv3) + # 2) NFSv4 ACLs (NFSv4) + # NFSv4 ACLs are supported on NFSv4 share only. + # Allowed values: + # 1) Unix mode: valid octal mode number + # Examples: "0777", "777", "0755" + # 2) NFSv4 acls: valid NFSv4 acls, seperated by comma + # Examples: "A::OWNER@:RWX,A::GROUP@:RWX", "A::OWNER@:rxtncy" + # Optional: true + # Default value: "0777" + # nfsAcls: "0777" + - name: X_CSI_NFS_ACLS + value: "0777" + # X_CSI_HEALTH_MONITOR_ENABLED: Enable/Disable health monitor of CSI volumes from Controller plugin - volume condition. + # Install the 'external-health-monitor' sidecar accordingly. + # Allowed values: + # true: enable checking of health condition of CSI volumes + # false: disable checking of health condition of CSI volumes + # Default value: false + - name: X_CSI_HEALTH_MONITOR_ENABLED + value: "false" + + # nodeSelector: Define node selection constraints for controller pods. + # For the pod to be eligible to run on a node, the node must have each + # of the indicated key-value pairs as labels. + # Leave as blank to consider all nodes + # Allowed values: map of key-value pairs + # Default value: None + nodeSelector: + # Uncomment if nodes you wish to use have the node-role.kubernetes.io/control-plane taint + # node-role.kubernetes.io/control-plane: "" + + # tolerations: Define tolerations for the controllers, if required. + # Leave as blank to install controller on worker nodes + # Default value: None + tolerations: + # Uncomment if nodes you wish to use have the node-role.kubernetes.io/control-plane taint + # - key: "node-role.kubernetes.io/control-plane" + # operator: "Exists" + # effect: "NoSchedule" + node: + envs: + # Set to "true" to enable ISCSI CHAP Authentication + # CHAP password will be autogenerated by driver + - name: "X_CSI_POWERSTORE_ENABLE_CHAP" + value: "false" + # X_CSI_HEALTH_MONITOR_ENABLED: Enable/Disable health monitor of CSI volumes from node plugin - volume usage + # Allowed values: + # true: enable checking of health condition of CSI volumes + # false: disable checking of health condition of CSI volumes + # Default value: false + - name: X_CSI_HEALTH_MONITOR_ENABLED + value: "false" + + # nodeSelector: Define node selection constraints for node pods. + # For the pod to be eligible to run on a node, the node must have each + # of the indicated key-value pairs as labels. + # Leave as blank to consider all nodes + # Allowed values: map of key-value pairs + # Default value: None + nodeSelector: + # Uncomment if nodes you wish to use have the node-role.kubernetes.io/control-plane taint + # node-role.kubernetes.io/control-plane: "" + + # tolerations: Define tolerations for the controllers, if required. + # Leave as blank to install controller on worker nodes + # Default value: None + tolerations: + # Uncomment if nodes you wish to use have the node-role.kubernetes.io/control-plane taint + # - key: "node-role.kubernetes.io/control-plane" + # operator: "Exists" + # effect: "NoSchedule" \ No newline at end of file diff --git a/controllers/csm_controller.go b/controllers/csm_controller.go index 6315ab925..ea28d6237 100644 --- a/controllers/csm_controller.go +++ b/controllers/csm_controller.go @@ -179,6 +179,7 @@ var ( // +kubebuilder:rbac:groups="certificates.k8s.io",resources=signers,resourceNames=issuers.cert-manager.io/*;clusterissuers.cert-manager.io/*,verbs=sign // +kubebuilder:rbac:groups="",resources=configmaps,resourceNames=cert-manager-cainjector-leader-election;cert-manager-cainjector-leader-election-core;cert-manager-controller,verbs=get;update;patch // +kubebuilder:rbac:groups="batch",resources=jobs,verbs=list;watch;create;update;delete +// +kubebuilder:rbac:groups="storage.k8s.io",resources=csistoragecapacities,verbs=get;list;watch;create;update;patch;delete // Reconcile is part of the main kubernetes reconciliation loop which aims to // move the current state of the cluster closer to the desired state. @@ -1017,7 +1018,11 @@ func (r *ContainerStorageModuleReconciler) PreChecks(ctx context.Context, cr *cs if err != nil { return fmt.Errorf("failed powerflex validation: %v", err) } - + case csmv1.PowerStore: + err := drivers.PrecheckPowerStore(ctx, cr, operatorConfig, r.GetClient()) + if err != nil { + return fmt.Errorf("failed powerstore validation: %v", err) + } default: for _, m := range cr.Spec.Modules { if m.Name == csmv1.AuthorizationServer { diff --git a/deploy/operator.yaml b/deploy/operator.yaml index 575f53984..5c8819110 100644 --- a/deploy/operator.yaml +++ b/deploy/operator.yaml @@ -701,6 +701,18 @@ rules: - list - update - watch +- apiGroups: + - storage.k8s.io + resources: + - csistoragecapacities + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - storage.k8s.io resources: diff --git a/operatorconfig/driverconfig/powerstore/v2.5.0/controller.yaml b/operatorconfig/driverconfig/powerstore/v2.5.0/controller.yaml new file mode 100644 index 000000000..cc42d41ef --- /dev/null +++ b/operatorconfig/driverconfig/powerstore/v2.5.0/controller.yaml @@ -0,0 +1,257 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: -controller + namespace: +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: -controller +rules: + - apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["get", "watch", "list", "delete", "update", "create"] + - apiGroups: [""] + resources: ["events"] + verbs: ["list", "watch", "create", "update", "patch"] + - apiGroups: [""] + resources: ["nodes"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get", "list", "watch", "create", "delete", "update", "patch"] + - apiGroups: [""] + resources: ["persistentvolumeclaims"] + verbs: ["get", "list", "watch", "update"] + - apiGroups: ["storage.k8s.io"] + resources: ["storageclasses"] + verbs: ["get", "list", "watch"] + - apiGroups: ["storage.k8s.io"] + resources: ["volumeattachments"] + verbs: ["get", "list", "watch", "update", "patch"] + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "list"] + - apiGroups: ["volumegroup.storage.dell.com"] + resources: ["dellcsivolumegroupsnapshots","dellcsivolumegroupsnapshots/status"] + verbs: ["create", "list", "watch", "delete", "update"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotclasses"] + verbs: ["get", "list", "watch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents"] + verbs: ["create", "get", "list", "watch", "update", "delete", "patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents/status"] + verbs: ["update", "patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots", "volumesnapshots/status"] + verbs: ["get", "list", "watch", "update"] + - apiGroups: ["storage.k8s.io"] + resources: ["volumeattachments/status"] + verbs: ["patch"] + - apiGroups: [""] + resources: ["pods"] + verbs: ["get", "list", "watch"] + - apiGroups: ["apiextensions.k8s.io"] + resources: ["customresourcedefinitions"] + verbs: ["create", "list", "watch", "delete"] + - apiGroups: ["storage.k8s.io"] + resources: ["csinodes"] + verbs: ["get", "list", "watch"] + # below for resizer + - apiGroups: [""] + resources: ["persistentvolumeclaims/status"] + verbs: ["update", "patch"] + # Permissions for CSIStorageCapacity + - apiGroups: ["storage.k8s.io"] + resources: ["csistoragecapacities"] + verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] + - apiGroups: [""] + resources: ["pods"] + verbs: ["get"] + - apiGroups: ["apps"] + resources: ["replicasets"] + verbs: ["get"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: -controller +subjects: + - kind: ServiceAccount + name: -controller + namespace: +roleRef: + kind: ClusterRole + name: -controller + apiGroup: rbac.authorization.k8s.io +--- +kind: Deployment +apiVersion: apps/v1 +metadata: + name: -controller + namespace: +spec: + selector: + matchLabels: + name: -controller + replicas: 2 + template: + metadata: + labels: + name: -controller + spec: + serviceAccountName: -controller + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: name + operator: In + values: + - -controller + topologyKey: kubernetes.io/hostname + containers: + - name: attacher + image: k8s.gcr.io/sig-storage/csi-attacher:v4.0.0 + imagePullPolicy: IfNotPresent + args: + - "--csi-address=$(ADDRESS)" + - "--v=5" + - "--leader-election" + - "--worker-threads=130" + - "--resync=10s" + - "--timeout=130s" + env: + - name: ADDRESS + value: /var/run/csi/csi.sock + volumeMounts: + - name: socket-dir + mountPath: /var/run/csi + - name: resizer + image: k8s.gcr.io/sig-storage/csi-resizer:v1.6.0 + imagePullPolicy: IfNotPresent + args: + - "--csi-address=$(ADDRESS)" + - "--v=5" + - "--leader-election" + env: + - name: ADDRESS + value: /var/run/csi/csi.sock + volumeMounts: + - name: socket-dir + mountPath: /var/run/csi + - name: provisioner + image: k8s.gcr.io/sig-storage/csi-provisioner:v3.3.0 + imagePullPolicy: IfNotPresent + args: + - "--csi-address=$(ADDRESS)" + - "--volume-name-prefix=csivol" + - "--volume-name-uuid-length=10" + - "--v=5" + - "--leader-election" + - "--default-fstype=ext4" + - "--extra-create-metadata" + - "--feature-gates=Topology=true" + - "--enable-capacity=false" + - "--capacity-ownerref-level=2" + - "--capacity-poll-interval=5m" + env: + - name: ADDRESS + value: /var/run/csi/csi.sock + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + volumeMounts: + - name: socket-dir + mountPath: /var/run/csi + - name: snapshotter + image: k8s.gcr.io/sig-storage/csi-snapshotter:v6.1.0 + imagePullPolicy: IfNotPresent + args: + - "--csi-address=$(ADDRESS)" + - "--v=5" + - "--leader-election" + - "--snapshot-name-prefix=csisnap" + env: + - name: ADDRESS + value: /var/run/csi/csi.sock + volumeMounts: + - name: socket-dir + mountPath: /var/run/csi + - name: external-health-monitor + image: k8s.gcr.io/sig-storage/csi-external-health-monitor-controller:v0.7.0 + imagePullPolicy: IfNotPresent + args: + - "--v=5" + - "--csi-address=$(ADDRESS)" + - "--leader-election" + - "--http-endpoint=:8080" + - "--enable-node-watcher=true" + - "--monitor-interval=60s" + - "--timeout=180s" + - "--leader-election-renew-deadline=10s" + - "--leader-election-lease-duration=15s" + - "--leader-election-retry-period=5s" + env: + - name: ADDRESS + value: /var/run/csi/csi.sock + volumeMounts: + - name: socket-dir + mountPath: /var/run/csi + - name: driver + image: dellemc/csi-powerstore:v2.5.0 + imagePullPolicy: IfNotPresent + command: [ "/csi-powerstore" ] + args: + - "--array-config=/powerstore-config/config" + - "--driver-config-params=/powerstore-config-params/driver-config-params.yaml" + env: + - name: ENABLE_TRACING + value: + - name: CSI_ENDPOINT + value: /var/run/csi/csi.sock + - name: X_CSI_MODE + value: controller + - name: X_CSI_DRIVER_NAME + value: "csi-powerstore.dellemc.com" + - name: X_CSI_POWERSTORE_EXTERNAL_ACCESS + value: "None" + - name: X_CSI_NFS_ACLS + value: "" + - name: X_CSI_POWERSTORE_CONFIG_PATH + value: /powerstore-config/config + - name: X_CSI_POWERSTORE_CONFIG_PARAMS_PATH + value: /powerstore-config-params/driver-config-params.yaml + - name: GOPOWERSTORE_DEBUG + value: true + - name: CSI_AUTO_ROUND_OFF_FILESYSTEM_SIZE + value: false + - name: X_CSI_PODMON_API_PORT + value: 8083 + - name: X_CSI_HEALTH_MONITOR_ENABLED + value: "" + volumeMounts: + - name: socket-dir + mountPath: /var/run/csi + - name: powerstore-config + mountPath: /powerstore-config + - name: powerstore-config-params + mountPath: /powerstore-config-params + volumes: + - name: socket-dir + emptyDir: + - name: powerstore-config-params + configMap: + name: -config-params + - name: powerstore-config + secret: + secretName: -config \ No newline at end of file diff --git a/operatorconfig/driverconfig/powerstore/v2.5.0/csidriver.yaml b/operatorconfig/driverconfig/powerstore/v2.5.0/csidriver.yaml new file mode 100644 index 000000000..46a642104 --- /dev/null +++ b/operatorconfig/driverconfig/powerstore/v2.5.0/csidriver.yaml @@ -0,0 +1,27 @@ +# +# +# Copyright © 2020-2022 Dell Inc. or its subsidiaries. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# + +apiVersion: storage.k8s.io/v1 +kind: CSIDriver +metadata: + name: csi-powerstore.dellemc.com +spec: + storageCapacity: false + podInfoOnMount: true + fsGroupPolicy: ReadWriteOnceWithFSType + volumeLifecycleModes: + - Persistent + - Ephemeral \ No newline at end of file diff --git a/operatorconfig/driverconfig/powerstore/v2.5.0/driver-config-params.yaml b/operatorconfig/driverconfig/powerstore/v2.5.0/driver-config-params.yaml new file mode 100644 index 000000000..3dac47765 --- /dev/null +++ b/operatorconfig/driverconfig/powerstore/v2.5.0/driver-config-params.yaml @@ -0,0 +1,25 @@ +# +# +# Copyright © 2021-2022 Dell Inc. or its subsidiaries. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# + +apiVersion: v1 +kind: ConfigMap +metadata: + name: -config-params + namespace: +data: + driver-config-params.yaml: | + CSI_LOG_LEVEL: "debug" + CSI_LOG_FORMAT: "JSON" \ No newline at end of file diff --git a/operatorconfig/driverconfig/powerstore/v2.5.0/node.yaml b/operatorconfig/driverconfig/powerstore/v2.5.0/node.yaml new file mode 100644 index 000000000..3df1b5abf --- /dev/null +++ b/operatorconfig/driverconfig/powerstore/v2.5.0/node.yaml @@ -0,0 +1,214 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: -node + namespace: +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: -node +rules: + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["create", "delete", "get", "list", "watch", "update"] + - apiGroups: [""] + resources: ["persistentvolumeclaims"] + verbs: ["get", "list", "watch", "update"] + - apiGroups: [""] + resources: ["events"] + verbs: ["get", "list", "watch", "create", "update", "patch"] + - apiGroups: [""] + resources: ["nodes"] + verbs: ["get", "list", "watch", "update", "patch"] + - apiGroups: ["storage.k8s.io"] + resources: ["volumeattachments"] + verbs: ["get", "list", "watch", "update"] + - apiGroups: ["storage.k8s.io"] + resources: ["storageclasses"] + verbs: ["get", "list", "watch"] + - apiGroups: ["storage.k8s.io"] + resources: ["volumeattachments"] + verbs: ["get", "list", "watch", "update"] + - apiGroups: ["security.openshift.io"] + resourceNames: ["privileged"] + resources: ["securitycontextconstraints"] + verbs: ["use"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: -node +subjects: + - kind: ServiceAccount + name: -node + namespace: +roleRef: + kind: ClusterRole + name: -node + apiGroup: rbac.authorization.k8s.io +--- +kind: DaemonSet +apiVersion: apps/v1 +metadata: + name: -node + namespace: +spec: + selector: + matchLabels: + app: -node + template: + metadata: + labels: + app: -node + spec: + #nodeSelector: + #tolerations: + serviceAccount: -node + dnsPolicy: ClusterFirstWithHostNet + hostNetwork: true + hostIPC: true + containers: + - name: driver + securityContext: + privileged: true + capabilities: + add: ["SYS_ADMIN"] + allowPrivilegeEscalation: true + image: dellemc/csi-powerstore:v2.5.0 + imagePullPolicy: IfNotPresent + command: [ "/csi-powerstore" ] + args: + - "--array-config=/powerstore-config/config" + - "--driver-config-params=/powerstore-config-params/driver-config-params.yaml" + env: + - name: ENABLE_TRACING + value: + - name: CSI_ENDPOINT + value: unix:///var/lib/kubelet/plugins/csi-powerstore.dellemc.com/csi_sock + - name: X_CSI_MODE + value: node + - name: X_CSI_POWERSTORE_KUBE_NODE_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + - name: X_CSI_POWERSTORE_NODE_NAME_PREFIX + value: + - name: X_CSI_POWERSTORE_NODE_ID_PATH + value: /node-id + - name: X_CSI_POWERSTORE_NODE_CHROOT_PATH + value: /noderoot + - name: X_CSI_POWERSTORE_TMP_DIR + value: /var/lib/kubelet/plugins/csi-powerstore.dellemc.com/tmp + - name: X_CSI_DRIVER_NAME + value: "csi-powerstore.dellemc.com" + - name: X_CSI_FC_PORTS_FILTER_FILE_PATH + value: + - name: X_CSI_POWERSTORE_ENABLE_CHAP + value: "" + - name: X_CSI_POWERSTORE_CONFIG_PATH + value: /powerstore-config/config + - name: X_CSI_POWERSTORE_CONFIG_PARAMS_PATH + value: /powerstore-config-params/driver-config-params.yaml + - name: GOPOWERSTORE_DEBUG + value: "true" + - name: X_CSI_HEALTH_MONITOR_ENABLED + value: "" + volumeMounts: + - name: driver-path + mountPath: /var/lib/kubelet/plugins/csi-powerstore.dellemc.com + - name: csi-path + mountPath: /var/lib/kubelet/plugins/kubernetes.io/csi + mountPropagation: "Bidirectional" + - name: pods-path + mountPath: /var/lib/kubelet/pods + mountPropagation: "Bidirectional" + - name: dev + mountPath: /dev + - name: sys + mountPath: /sys + - name: run + mountPath: /run + - name: node-id + mountPath: /node-id + - name: etciscsi + mountPath: /etc/iscsi + - name: mpath + mountPath: /etc/multipath.conf + - name: noderoot + mountPath: /noderoot + - name: powerstore-config + mountPath: /powerstore-config + - name: powerstore-config-params + mountPath: /powerstore-config-params + - name: registrar + image: k8s.gcr.io/sig-storage/csi-node-driver-registrar:v2.6.0 + imagePullPolicy: IfNotPresent + args: + - "--v=5" + - "--csi-address=$(ADDRESS)" + - --kubelet-registration-path=/var/lib/kubelet/plugins/csi-powerstore.dellemc.com/csi_sock + env: + - name: ADDRESS + value: /csi/csi_sock + - name: KUBE_NODE_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + volumeMounts: + - name: registration-dir + mountPath: /registration + - name: driver-path + mountPath: /csi + volumes: + - name: registration-dir + hostPath: + path: /var/lib/kubelet/plugins_registry/ + type: DirectoryOrCreate + - name: driver-path + hostPath: + path: /var/lib/kubelet/plugins/csi-powerstore.dellemc.com + type: DirectoryOrCreate + - name: csi-path + hostPath: + path: /var/lib/kubelet/plugins/kubernetes.io/csi + - name: pods-path + hostPath: + path: /var/lib/kubelet/pods + type: Directory + - name: dev + hostPath: + path: /dev + type: Directory + - name: node-id + hostPath: + path: /etc/machine-id + type: File + - name: etciscsi + hostPath: + path: /etc/iscsi + type: DirectoryOrCreate + - name: mpath + hostPath: + path: /etc/multipath.conf + type: FileOrCreate + - name: noderoot + hostPath: + path: / + type: Directory + - name: sys + hostPath: + path: /sys + type: Directory + - name: run + hostPath: + path: /run + type: Directory + - name: powerstore-config-params + configMap: + name: -config-params + - name: powerstore-config + secret: + secretName: -config \ No newline at end of file diff --git a/operatorconfig/driverconfig/powerstore/v2.5.0/upgrade-path.yaml b/operatorconfig/driverconfig/powerstore/v2.5.0/upgrade-path.yaml new file mode 100644 index 000000000..0a370aaa5 --- /dev/null +++ b/operatorconfig/driverconfig/powerstore/v2.5.0/upgrade-path.yaml @@ -0,0 +1 @@ +minUpgradePath: v2.5.0 \ No newline at end of file diff --git a/pkg/drivers/commonconfig.go b/pkg/drivers/commonconfig.go index 3547570f2..1f904ef4f 100644 --- a/pkg/drivers/commonconfig.go +++ b/pkg/drivers/commonconfig.go @@ -45,6 +45,9 @@ func GetController(ctx context.Context, cr csmv1.ContainerStorageModule, operato } YamlString := utils.ModifyCommonCR(string(buf), cr) + if cr.Spec.Driver.CSIDriverType == "powerstore" { + YamlString = ModifyPowerstoreCR(YamlString, cr, "Controller") + } driverYAML, err := utils.GetDriverYaml(YamlString, "Deployment") if err != nil { @@ -158,6 +161,9 @@ func GetNode(ctx context.Context, cr csmv1.ContainerStorageModule, operatorConfi } YamlString := utils.ModifyCommonCR(string(buf), cr) + if cr.Spec.Driver.CSIDriverType == "powerstore" { + YamlString = ModifyPowerstoreCR(YamlString, cr, "Node") + } driverYAML, err := utils.GetDriverYaml(YamlString, "DaemonSet") if err != nil { diff --git a/pkg/drivers/powerstore.go b/pkg/drivers/powerstore.go new file mode 100644 index 000000000..24426743b --- /dev/null +++ b/pkg/drivers/powerstore.go @@ -0,0 +1,126 @@ +// Copyright © 2021 - 2022 Dell Inc. or its subsidiaries. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package drivers + +import ( + "context" + "fmt" + csmv1 "github.com/dell/csm-operator/api/v1" + "github.com/dell/csm-operator/pkg/logger" + "github.com/dell/csm-operator/pkg/utils" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/types" + "os" + "sigs.k8s.io/controller-runtime/pkg/client" + "strings" +) + +const ( + // PowerStorePluginIdentifier - + PowerStorePluginIdentifier = "powerstore" + + // PowerStoreConfigParamsVolumeMount - + PowerStoreConfigParamsVolumeMount = "csi-powerstore-config-params" + + // Powerstore Node Name Prefix + CsiPowerstoreNodeNamePrefix = "" + + // Powerstore Fc Port Filter File Path + CsiFcPortFilterFilePath = "" + + // Powerstore variable setting the permissions on NFS mount directory + CsiNfsAcls= "" + + // Powerstore health monitor + CsiHealthMonitorEnabled = "" + + // Powerstore CHAP + CsiPowerstoreEnableChap = "" +) + +// PrecheckPowerStore do input validation +func PrecheckPowerStore(ctx context.Context, cr *csmv1.ContainerStorageModule, operatorConfig utils.OperatorConfig, ct client.Client) error { + log := logger.GetLogger(ctx) + // Check for secret only + config := cr.Name + "-config" + + // Check if driver version is supported by doing a stat on a config file + configFilePath := fmt.Sprintf("%s/driverconfig/powerstore/%s/upgrade-path.yaml", operatorConfig.ConfigDirectory, cr.Spec.Driver.ConfigVersion) + if _, err := os.Stat(configFilePath); os.IsNotExist(err) { + log.Errorw("PreCheckPowerStore failed in version check", "Error", err.Error()) + return fmt.Errorf("%s %s not supported", csmv1.PowerStore, cr.Spec.Driver.ConfigVersion) + } + secrets := []string{config} + + for _, name := range secrets { + found := &corev1.Secret{} + err := ct.Get(ctx, types.NamespacedName{Name: name, Namespace: cr.GetNamespace()}, found) + if err != nil { + log.Error(err, "Failed query for secret ", name) + if errors.IsNotFound(err) { + return fmt.Errorf("failed to find secret %s", name) + } + } + } + + log.Debugw("preCheck", "secrets", len(secrets)) + return nil +} + +// ModifyPowerstoreCR - +func ModifyPowerstoreCR(yamlString string, cr csmv1.ContainerStorageModule, fileType string) string { + // Parameters to initialise CR values + nodePrefix := "" + fcPortFilter := "" + nfsAcls := "" + healthMonitorController := "" + chap := "" + healthMonitorNode := "" + + switch fileType { + case "Node": + for _, env := range cr.Spec.Driver.Common.Envs { + if env.Name == "X_CSI_POWERSTORE_NODE_NAME_PREFIX" { + nodePrefix = env.Value + } + if env.Name == "X_CSI_FC_PORTS_FILTER_FILE_PATH" { + fcPortFilter = env.Value + } + } + for _, env := range cr.Spec.Driver.Node.Envs { + if env.Name == "X_CSI_POWERSTORE_ENABLE_CHAP" { + chap = env.Value + } + if env.Name == "X_CSI_HEALTH_MONITOR_ENABLED" { + healthMonitorNode = env.Value + } + } + yamlString = strings.ReplaceAll(yamlString, CsiPowerstoreNodeNamePrefix, nodePrefix) + yamlString = strings.ReplaceAll(yamlString, CsiFcPortFilterFilePath, fcPortFilter) + yamlString = strings.ReplaceAll(yamlString, CsiPowerstoreEnableChap, chap) + yamlString = strings.ReplaceAll(yamlString, CsiHealthMonitorEnabled, healthMonitorNode) + case "Controller": + for _, env := range cr.Spec.Driver.Controller.Envs { + if env.Name == "X_CSI_NFS_ACLS" { + nfsAcls = env.Value + } + if env.Name == "X_CSI_HEALTH_MONITOR_ENABLED" { + healthMonitorController = env.Value + } + } + yamlString = strings.ReplaceAll(yamlString, CsiNfsAcls, nfsAcls) + yamlString = strings.ReplaceAll(yamlString, CsiHealthMonitorEnabled, healthMonitorController) + } + return yamlString +} diff --git a/pkg/utils/status.go b/pkg/utils/status.go index a91c94b20..a39d0a277 100644 --- a/pkg/utils/status.go +++ b/pkg/utils/status.go @@ -75,10 +75,11 @@ func getDeploymentStatus(ctx context.Context, instance *csmv1.ContainerStorageMo //powerflex and powerscale use different label names for the controller name: //app=test-isilon-controller //name=test-vxflexos-controller + //name=test-powerstore-controller driver := instance.GetDriverType() log.Infof("driver type: %s", driver) controllerLabelName := "app" - if driver == "powerflex" { + if (driver == "powerflex") || (driver == "powerstore") { controllerLabelName = "name" } label := instance.GetNamespace() + "-controller" diff --git a/samples/storage_csm_powerstore_v250.yaml b/samples/storage_csm_powerstore_v250.yaml new file mode 100644 index 000000000..12d2207ca --- /dev/null +++ b/samples/storage_csm_powerstore_v250.yaml @@ -0,0 +1,118 @@ +apiVersion: storage.dell.com/v1 +kind: ContainerStorageModule +metadata: + name: test-powerstore + namespace: test-powerstore +spec: + driver: + csiDriverType: "powerstore" + csiDriverSpec: + # fsGroupPolicy: Defines if the underlying volume supports changing ownership and permission of the volume before being mounted. + # Allowed values: ReadWriteOnceWithFSType, File , None + # Default value: ReadWriteOnceWithFSType + fSGroupPolicy: "ReadWriteOnceWithFSType" + # Config version for CSI PowerStore v2.5.0 driver + configVersion: v2.5.0 + authSecret: test-powerstore-config + # Controller count + replicas: 2 + dnsPolicy: ClusterFirstWithHostNet + forceUpdate: true + forceRemoveDriver: true + common: + # Image for CSI PowerStore driver v2.5.0 + image: "dellemc/csi-powerstore:v2.5.0" + imagePullPolicy: IfNotPresent + envs: + - name: X_CSI_POWERSTORE_NODE_NAME_PREFIX + value: "csi-node" + - name: X_CSI_FC_PORTS_FILTER_FILE_PATH + value: "/etc/fc-ports-filter" + - name: KUBELET_CONFIG_DIR + value: /var/lib/kubelet + - name: CSI_LOG_LEVEL + value: debug + + sideCars: + # health monitor is disabled by default, refer to driver documentation before enabling it + - name: external-health-monitor + enabled: false + args: ["--monitor-interval=60s"] + controller: + envs: + # X_CSI_NFS_ACLS: enables setting permissions on NFS mount directory + # This value will be the default value if a storage class and array config in secret + # do not contain the NFS ACL (nfsAcls) parameter specified + # Permissions can be specified in two formats: + # 1) Unix mode (NFSv3) + # 2) NFSv4 ACLs (NFSv4) + # NFSv4 ACLs are supported on NFSv4 share only. + # Allowed values: + # 1) Unix mode: valid octal mode number + # Examples: "0777", "777", "0755" + # 2) NFSv4 acls: valid NFSv4 acls, seperated by comma + # Examples: "A::OWNER@:RWX,A::GROUP@:RWX", "A::OWNER@:rxtncy" + # Optional: true + # Default value: "0777" + # nfsAcls: "0777" + - name: X_CSI_NFS_ACLS + value: "0777" + # X_CSI_HEALTH_MONITOR_ENABLED: Enable/Disable health monitor of CSI volumes from Controller plugin - volume condition. + # Install the 'external-health-monitor' sidecar accordingly. + # Allowed values: + # true: enable checking of health condition of CSI volumes + # false: disable checking of health condition of CSI volumes + # Default value: false + - name: X_CSI_HEALTH_MONITOR_ENABLED + value: "false" + + # nodeSelector: Define node selection constraints for controller pods. + # For the pod to be eligible to run on a node, the node must have each + # of the indicated key-value pairs as labels. + # Leave as blank to consider all nodes + # Allowed values: map of key-value pairs + # Default value: None + nodeSelector: + # Uncomment if nodes you wish to use have the node-role.kubernetes.io/control-plane taint + # node-role.kubernetes.io/control-plane: "" + + # tolerations: Define tolerations for the controllers, if required. + # Leave as blank to install controller on worker nodes + # Default value: None + tolerations: + # Uncomment if nodes you wish to use have the node-role.kubernetes.io/control-plane taint + # - key: "node-role.kubernetes.io/control-plane" + # operator: "Exists" + # effect: "NoSchedule" + node: + envs: + # Set to "true" to enable ISCSI CHAP Authentication + # CHAP password will be autogenerated by driver + - name: "X_CSI_POWERSTORE_ENABLE_CHAP" + value: "false" + # X_CSI_HEALTH_MONITOR_ENABLED: Enable/Disable health monitor of CSI volumes from node plugin - volume usage + # Allowed values: + # true: enable checking of health condition of CSI volumes + # false: disable checking of health condition of CSI volumes + # Default value: false + - name: X_CSI_HEALTH_MONITOR_ENABLED + value: "false" + + # nodeSelector: Define node selection constraints for node pods. + # For the pod to be eligible to run on a node, the node must have each + # of the indicated key-value pairs as labels. + # Leave as blank to consider all nodes + # Allowed values: map of key-value pairs + # Default value: None + nodeSelector: + # Uncomment if nodes you wish to use have the node-role.kubernetes.io/control-plane taint + # node-role.kubernetes.io/control-plane: "" + + # tolerations: Define tolerations for the controllers, if required. + # Leave as blank to install controller on worker nodes + # Default value: None + tolerations: + # Uncomment if nodes you wish to use have the node-role.kubernetes.io/control-plane taint + # - key: "node-role.kubernetes.io/control-plane" + # operator: "Exists" + # effect: "NoSchedule" From 863c8da1dc088aa79b4feb1a4a03485e4e93eb53 Mon Sep 17 00:00:00 2001 From: Indukuri Date: Tue, 14 Feb 2023 15:22:28 +0530 Subject: [PATCH 2/4] Resolved lint violations --- pkg/drivers/powerstore.go | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/pkg/drivers/powerstore.go b/pkg/drivers/powerstore.go index 24426743b..2c07ff8fc 100644 --- a/pkg/drivers/powerstore.go +++ b/pkg/drivers/powerstore.go @@ -15,15 +15,16 @@ package drivers import ( "context" "fmt" + "os" + "strings" + csmv1 "github.com/dell/csm-operator/api/v1" "github.com/dell/csm-operator/pkg/logger" "github.com/dell/csm-operator/pkg/utils" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/types" - "os" "sigs.k8s.io/controller-runtime/pkg/client" - "strings" ) const ( @@ -33,19 +34,19 @@ const ( // PowerStoreConfigParamsVolumeMount - PowerStoreConfigParamsVolumeMount = "csi-powerstore-config-params" - // Powerstore Node Name Prefix + // CsiPowerstoreNodeNamePrefix - Node Name Prefix CsiPowerstoreNodeNamePrefix = "" - // Powerstore Fc Port Filter File Path + // CsiFcPortFilterFilePath- Fc Port Filter File Path CsiFcPortFilterFilePath = "" - // Powerstore variable setting the permissions on NFS mount directory - CsiNfsAcls= "" + // CsiNfsAcls - variable setting the permissions on NFS mount directory + CsiNfsAcls = "" - // Powerstore health monitor + // CsiHealthMonitorEnabled - health monitor flag CsiHealthMonitorEnabled = "" - // Powerstore CHAP + // CsiPowerstoreEnableChap - CHAP flag CsiPowerstoreEnableChap = "" ) @@ -79,7 +80,7 @@ func PrecheckPowerStore(ctx context.Context, cr *csmv1.ContainerStorageModule, o } // ModifyPowerstoreCR - -func ModifyPowerstoreCR(yamlString string, cr csmv1.ContainerStorageModule, fileType string) string { +func ModifyPowerstoreCR(yamlString string, cr csmv1.ContainerStorageModule, fileType string) string { // Parameters to initialise CR values nodePrefix := "" fcPortFilter := "" @@ -96,7 +97,7 @@ func ModifyPowerstoreCR(yamlString string, cr csmv1.ContainerStorageModule, fil } if env.Name == "X_CSI_FC_PORTS_FILTER_FILE_PATH" { fcPortFilter = env.Value - } + } } for _, env := range cr.Spec.Driver.Node.Envs { if env.Name == "X_CSI_POWERSTORE_ENABLE_CHAP" { @@ -109,7 +110,7 @@ func ModifyPowerstoreCR(yamlString string, cr csmv1.ContainerStorageModule, fil yamlString = strings.ReplaceAll(yamlString, CsiPowerstoreNodeNamePrefix, nodePrefix) yamlString = strings.ReplaceAll(yamlString, CsiFcPortFilterFilePath, fcPortFilter) yamlString = strings.ReplaceAll(yamlString, CsiPowerstoreEnableChap, chap) - yamlString = strings.ReplaceAll(yamlString, CsiHealthMonitorEnabled, healthMonitorNode) + yamlString = strings.ReplaceAll(yamlString, CsiHealthMonitorEnabled, healthMonitorNode) case "Controller": for _, env := range cr.Spec.Driver.Controller.Envs { if env.Name == "X_CSI_NFS_ACLS" { From 616b4ddad85afe52cd64b2b833f5ea93e3aa8546 Mon Sep 17 00:00:00 2001 From: Indukuri Date: Tue, 14 Feb 2023 15:30:40 +0530 Subject: [PATCH 3/4] Correctd one more lint issue --- pkg/drivers/powerstore.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/drivers/powerstore.go b/pkg/drivers/powerstore.go index 2c07ff8fc..3c26cc1e8 100644 --- a/pkg/drivers/powerstore.go +++ b/pkg/drivers/powerstore.go @@ -37,7 +37,7 @@ const ( // CsiPowerstoreNodeNamePrefix - Node Name Prefix CsiPowerstoreNodeNamePrefix = "" - // CsiFcPortFilterFilePath- Fc Port Filter File Path + // CsiFcPortFilterFilePath - Fc Port Filter File Path CsiFcPortFilterFilePath = "" // CsiNfsAcls - variable setting the permissions on NFS mount directory From dfcb8d40c4400c3d5b57400d81b849556af3f7bc Mon Sep 17 00:00:00 2001 From: Karthik K Date: Tue, 14 Feb 2023 15:52:00 +0530 Subject: [PATCH 4/4] Removing multiple volume mounts --- operatorconfig/driverconfig/powerstore/v2.5.0/node.yaml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/operatorconfig/driverconfig/powerstore/v2.5.0/node.yaml b/operatorconfig/driverconfig/powerstore/v2.5.0/node.yaml index eef9bfa05..3df1b5abf 100644 --- a/operatorconfig/driverconfig/powerstore/v2.5.0/node.yaml +++ b/operatorconfig/driverconfig/powerstore/v2.5.0/node.yaml @@ -123,15 +123,6 @@ spec: mountPropagation: "Bidirectional" - name: pods-path mountPath: /var/lib/kubelet/pods - value: "false" - volumeMounts: - - name: driver-path - mountPath: var/lib/kubelet/plugins/csi-powerstore.dellemc.com - - name: csi-path - mountPath: var/lib/kubelet/plugins/kubernetes.io/csi - mountPropagation: "Bidirectional" - - name: pods-path - mountPath: var/lib/kubelet/pods mountPropagation: "Bidirectional" - name: dev mountPath: /dev