From 2047173ea133a1942b94111c4be98603a474e781 Mon Sep 17 00:00:00 2001 From: Farnaz Babaeian Date: Mon, 26 Feb 2024 17:35:19 +0100 Subject: [PATCH 1/2] Adding CSI Charts --- .github/workflows/chart-lints.yaml | 35 +++ .github/workflows/charts-release.yaml | 34 +++ .gitignore | 2 + .helmignore | 22 ++ charts/Chart.yaml | 11 + charts/templates/_helpers.tpl | 103 ++++++++ charts/templates/csi-clusterrole.yaml | 108 +++++++++ charts/templates/csi-clusterrolebinding.yaml | 55 +++++ charts/templates/csi-controller-deploy.yaml | 215 +++++++++++++++++ charts/templates/csi-driver.yaml | 14 ++ charts/templates/csi-node-ds.yaml | 180 ++++++++++++++ charts/templates/csi-sa.yaml | 11 + charts/templates/podmonitor.yaml | 22 ++ charts/templates/secret.yaml | 14 ++ charts/templates/syncer-job.yaml | 49 ++++ charts/templates/syncer-rbac.yaml | 42 ++++ charts/values.yaml | 233 +++++++++++++++++++ 17 files changed, 1150 insertions(+) create mode 100644 .github/workflows/chart-lints.yaml create mode 100644 .github/workflows/charts-release.yaml create mode 100644 .helmignore create mode 100644 charts/Chart.yaml create mode 100644 charts/templates/_helpers.tpl create mode 100644 charts/templates/csi-clusterrole.yaml create mode 100644 charts/templates/csi-clusterrolebinding.yaml create mode 100644 charts/templates/csi-controller-deploy.yaml create mode 100644 charts/templates/csi-driver.yaml create mode 100644 charts/templates/csi-node-ds.yaml create mode 100644 charts/templates/csi-sa.yaml create mode 100644 charts/templates/podmonitor.yaml create mode 100644 charts/templates/secret.yaml create mode 100644 charts/templates/syncer-job.yaml create mode 100644 charts/templates/syncer-rbac.yaml create mode 100644 charts/values.yaml diff --git a/.github/workflows/chart-lints.yaml b/.github/workflows/chart-lints.yaml new file mode 100644 index 0000000..394290b --- /dev/null +++ b/.github/workflows/chart-lints.yaml @@ -0,0 +1,35 @@ +name: Lint Charts +on: + pull_request: + paths: + - 'charts/**' +jobs: + lint: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Set up Helm + uses: azure/setup-helm@v4.0.0 + with: + version: v3.14.1 + + - uses: actions/setup-python@v4 + with: + python-version: '3.10' + check-latest: true + + # see example https://github.com/helm/chart-testing-action + - name: Set up chart-testing + uses: helm/chart-testing-action@v2.6.0 + + - name: Run chart-testing (list-changed) + id: list-changed + run: | + changed=$(ct list-changed --target-branch ${{ github.event.repository.default_branch }}) + if [[ -n "$changed" ]]; then + echo "changed=true" >> "$GITHUB_OUTPUT" + fi \ No newline at end of file diff --git a/.github/workflows/charts-release.yaml b/.github/workflows/charts-release.yaml new file mode 100644 index 0000000..f88fdbe --- /dev/null +++ b/.github/workflows/charts-release.yaml @@ -0,0 +1,34 @@ +name: Release Charts + +on: + push: + branches: + - master + paths: + - 'charts/**' + +jobs: + release: + permissions: + contents: write + + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Configure Git + run: | + git config user.name "$GITHUB_ACTOR" + git config user.email "$GITHUB_ACTOR@users.noreply.github.com" + + - name: Run chart-releaser + uses: helm/chart-releaser-action@v1.6.0 + with: + version: v1.6.0 + charts_dir: charts + env: + CR_TOKEN: ${{ secrets.GITHUB_TOKEN }} + CR_GENERATE_RELEASE_NOTES: true \ No newline at end of file diff --git a/.gitignore b/.gitignore index 295e96b..ba2f9ed 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ /test/e2e/e2e.test /test/e2e/ginkgo cloud-config +/vendor + diff --git a/.helmignore b/.helmignore new file mode 100644 index 0000000..fbe01f8 --- /dev/null +++ b/.helmignore @@ -0,0 +1,22 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ \ No newline at end of file diff --git a/charts/Chart.yaml b/charts/Chart.yaml new file mode 100644 index 0000000..d298046 --- /dev/null +++ b/charts/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +name: cloudstack-csi +description: A Helm chart for Kubernetes +type: application +version: 1.0.0 +appVersion: 0.3.0 +sources: + - https://github.com/Leaseweb/cloudstack-csi-driver +keywords: + - csi + - cloudStack \ No newline at end of file diff --git a/charts/templates/_helpers.tpl b/charts/templates/_helpers.tpl new file mode 100644 index 0000000..8d5dd4d --- /dev/null +++ b/charts/templates/_helpers.tpl @@ -0,0 +1,103 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "csi.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "csi.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "csi.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Common labels +*/}} +{{- define "csi.labels" -}} +app.kubernetes.io/name: {{ include "csi.name" . }} +helm.sh/chart: {{ include "csi.chart" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end -}} + + +{{/* +Create the name of the service account to use +*/}} +{{- define "csi.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "csi.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Create unified labels for csi components +*/}} +{{- define "csi.common.matchLabels" -}} +app: {{ template "csi.name" . }} +release: {{ .Release.Name }} +{{- end -}} + +{{- define "csi.common.metaLabels" -}} +chart: {{ template "csi.chart" . }} +heritage: {{ .Release.Service }} +{{- if .Values.extraLabels }} +{{ toYaml .Values.extraLabels -}} +{{- end }} +{{- end -}} + +{{- define "csi.controller.matchLabels" -}} +component: controller +{{ include "csi.common.matchLabels" . }} +{{- end -}} + +{{- define "csi.controller.labels" -}} +{{ include "csi.controller.matchLabels" . }} +{{ include "csi.common.metaLabels" . }} +{{- end -}} + +{{- define "csi.node.matchLabels" -}} +component: node +{{ include "csi.common.matchLabels" . }} +{{- end -}} + +{{- define "csi.node.labels" -}} +{{ include "csi.node.matchLabels" . }} +{{ include "csi.common.metaLabels" . }} +{{- end -}} + +{{/* +Create cloud-config makro. +*/}} +{{- define "cloudConfig" -}} +[Global] +{{- range $key, $value := .Values.cloudConfigData.global }} +{{ $key }} = {{ $value | quote }} +{{- end }} +{{- end -}} \ No newline at end of file diff --git a/charts/templates/csi-clusterrole.yaml b/charts/templates/csi-clusterrole.yaml new file mode 100644 index 0000000..b234dcd --- /dev/null +++ b/charts/templates/csi-clusterrole.yaml @@ -0,0 +1,108 @@ +{{ if .Values.rbac.create }} +# This YAML file contains Cluster Role objects, +# which are necessary to run cloudstack-csi-controller +{{ $enableLeaderElection := gt (int .Values.controller.replicaCount) 1 }} +--- +# external Attacher +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-attacher-role + annotations: + {{- with .Values.commonAnnotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +rules: + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get", "list", "watch", "patch"] + - apiGroups: ["storage.k8s.io"] + resources: ["csinodes"] + verbs: ["get", "list", "watch"] + - apiGroups: ["storage.k8s.io"] + resources: ["volumeattachments"] + verbs: ["get", "list", "watch", "patch"] + - apiGroups: ["storage.k8s.io"] + resources: ["volumeattachments/status"] + verbs: ["patch"] + {{- if $enableLeaderElection}} + # leader election + - apiGroups: [coordination.k8s.io] + resources: [leases] + verbs: ["get", "watch", "list", "delete", "update", "create"] + {{- end}} +--- +# external Provisioner +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-provisioner-role + annotations: + {{- with .Values.commonAnnotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +rules: + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get", "list", "watch", "create", "delete"] + - apiGroups: [""] + resources: ["persistentvolumeclaims"] + verbs: ["get", "list", "watch", "update"] + - apiGroups: ["storage.k8s.io"] + resources: ["storageclasses"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["nodes"] + verbs: ["get", "list", "watch"] + - apiGroups: ["storage.k8s.io"] + resources: ["csinodes"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["events"] + verbs: ["list", "watch", "create", "update", "patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots"] + verbs: ["get", "list"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents"] + verbs: ["get", "list"] + {{- if $enableLeaderElection}} + # leader election + - apiGroups: [coordination.k8s.io] + resources: [leases] + verbs: ["get", "watch", "list", "delete", "update", "create"] + {{- end}} +--- +# external Resizer +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-resizer-role +rules: + # The following rule should be uncommented for plugins that require secrets + # for provisioning. + # - apiGroups: [""] + # resources: ["secrets"] + # verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get", "list", "watch", "patch"] + - apiGroups: [""] + resources: ["persistentvolumeclaims"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["pods"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["persistentvolumeclaims/status"] + verbs: ["patch"] + - apiGroups: [""] + resources: ["events"] + verbs: ["list", "watch", "create", "update", "patch"] + {{- if $enableLeaderElection}} + # leader election + - apiGroups: [coordination.k8s.io] + resources: [leases] + verbs: ["get", "watch", "list", "delete", "update", "create"] + {{- end}} +{{- end}} \ No newline at end of file diff --git a/charts/templates/csi-clusterrolebinding.yaml b/charts/templates/csi-clusterrolebinding.yaml new file mode 100644 index 0000000..03b068f --- /dev/null +++ b/charts/templates/csi-clusterrolebinding.yaml @@ -0,0 +1,55 @@ +{{ if .Values.rbac.create }} +# This YAML file contains Cluster Role Binding objects, +# which are necessary to run cloudstack-csi-controller +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-attacher-binding + annotations: + {{- with .Values.commonAnnotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +subjects: + - kind: ServiceAccount + name: {{ .Values.serviceAccount.name }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: csi-attacher-role + apiGroup: rbac.authorization.k8s.io +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-provisioner-binding + annotations: + {{- with .Values.commonAnnotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +subjects: + - kind: ServiceAccount + name: {{ .Values.serviceAccount.name }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: csi-provisioner-role + apiGroup: rbac.authorization.k8s.io +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-resizer-binding + annotations: + {{- with .Values.commonAnnotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +subjects: + - kind: ServiceAccount + name: {{ .Values.serviceAccount.name }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: csi-resizer-role + apiGroup: rbac.authorization.k8s.io +{{- end}} \ No newline at end of file diff --git a/charts/templates/csi-controller-deploy.yaml b/charts/templates/csi-controller-deploy.yaml new file mode 100644 index 0000000..f9d96a1 --- /dev/null +++ b/charts/templates/csi-controller-deploy.yaml @@ -0,0 +1,215 @@ +{{ $enableLeaderElection := gt (int .Values.controller.replicaCount) 1 }} + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "csi.name" . }}-controller + namespace: {{ .Release.Namespace }} + labels: + {{- include "csi.controller.labels" . | nindent 4 }} + annotations: + {{- with .Values.commonAnnotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.controller.replicaCount }} + strategy: + type: {{ .Values.controller.strategy.type }} +{{- if eq .Values.controller.strategy.type "RollingUpdate" }} + rollingUpdate: + maxUnavailable: {{ .Values.controller.strategy.rollingUpdate.maxUnavailable }} + maxSurge: {{ .Values.controller.strategy.rollingUpdate.maxSurge }} +{{- end }} + selector: + matchLabels: + {{- include "csi.controller.matchLabels" . | nindent 6 }} + template: + metadata: + labels: + {{- include "csi.controller.labels" . | nindent 8 }} + annotations: + {{- with .Values.commonAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + serviceAccount: cloudstack-csi-controller + securityContext: + {{- toYaml .Values.controller.podSecurityContext | nindent 8 }} + containers: + - name: cloudstack-csi-controller + securityContext: + {{- toYaml .Values.controller.securityContext | nindent 12 }} + image: "{{ .Values.controller.csiDriverController.image.repository }}:{{ .Values.controller.csiDriverController.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.controller.csiDriverController.image.pullPolicy }} + args: + - "--endpoint=$(CSI_ENDPOINT)" + - "--cloudstackconfig=$(CLOUD_CONFIG)" + - "--debug" + {{- if .Values.controller.csiDriverController.extraArgs }} + {{- with .Values.controller.csiDriverController.extraArgs }} + {{- tpl . $ | trim | nindent 12 }} + {{- end }} + {{- end }} + env: + - name: CSI_ENDPOINT + value: unix:///var/lib/csi/sockets/pluginproxy/csi.sock + - name: CLOUD_CONFIG + value: /etc/config/cloud.conf + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + - name: cloud-config + mountPath: /etc/config/ + {{- with .Values.controller.csiDriverController.volumeMounts }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - containerPort: 9808 + name: healthz + protocol: TCP + {{ if .Values.livenessProbe.enable }} + livenessProbe: {{- toYaml .Values.livenessProbe.livenessProbeSpec | nindent 12 }} + {{- end }} + - name: external-provisioner + securityContext: + {{- toYaml .Values.controller.securityContext | nindent 12 }} + image: "{{ .Values.controller.provisioner.image.repository }}:{{ .Values.controller.provisioner.image.tag }}" + imagePullPolicy: {{ .Values.controller.provisioner.image.pullPolicy }} + args: + - "-v={{ .Values.logVerbosityLevel }}" + - "--csi-address=$(ADDRESS)" + - "--timeout={{ .Values.timeout }}" + - "--feature-gates=Topology={{ .Values.controller.provisioner.topology }}" + - "--timeout=300s" + - "--kube-api-qps=100" + - "--kube-api-burst=100" + {{- if $enableLeaderElection }} + - "--leader-election=true" + - "--leader-election-lease-duration=120s" + - "--leader-election-renew-deadline=60s" + - "--leader-election-retry-period=30s" + {{- end}} + - "--default-fstype=ext4" + - "--strict-topology" + {{- if .Values.controller.provisioner.extraArgs }} + {{- with .Values.controller.provisioner.extraArgs }} + {{- tpl . $ | trim | nindent 12 }} + {{- end }} + {{- end }} + env: + - name: ADDRESS + value: /var/lib/csi/sockets/pluginproxy/csi.sock + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + resources: {{ toYaml .Values.controller.provisioner.resources | nindent 12 }} + - name: external-attacher + securityContext: + {{- toYaml .Values.controller.securityContext | nindent 12 }} + image: "{{ .Values.controller.attacher.image.repository }}:{{ .Values.controller.attacher.image.tag }}" + imagePullPolicy: {{ .Values.controller.attacher.image.pullPolicy }} + args: + - "-v={{ .Values.logVerbosityLevel }}" + - "--csi-address=$(ADDRESS)" + - "--timeout={{ .Values.timeout }}" + - "--default-fstype=ext4" + {{- if $enableLeaderElection }} + - "--leader-election=true" + - "--leader-election-lease-duration=120s" + - "--leader-election-renew-deadline=60s" + - "--leader-election-retry-period=30s" + {{- end}} + - "--kube-api-qps=100" + - "--kube-api-burst=100" + {{- if .Values.controller.attacher.extraArgs }} + {{- with .Values.controller.attacher.extraArgs }} + {{- tpl . $ | trim | nindent 12 }} + {{- end }} + {{- end }} + env: + - name: ADDRESS + value: /var/lib/csi/sockets/pluginproxy/csi.sock + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + resources: {{ toYaml .Values.controller.attacher.resources | nindent 12 }} + - name: external-resizer + securityContext: + {{- toYaml .Values.controller.securityContext | nindent 12 }} + image: "{{ .Values.controller.resizer.image.repository }}:{{ .Values.controller.resizer.image.tag }}" + imagePullPolicy: {{ .Values.controller.resizer.image.pullPolicy }} + args: + - "-v={{ .Values.logVerbosityLevel }}" + - "--csi-address=$(ADDRESS)" + - "--timeout={{ .Values.timeout }}" + {{- if $enableLeaderElection }} + - "--leader-election=true" + - "--leader-election-lease-duration=120s" + - "--leader-election-renew-deadline=60s" + - "--leader-election-retry-period=30s" + {{- end}} + - "--kube-api-qps=100" + - "--kube-api-burst=100" + {{- if .Values.controller.resizer.extraArgs }} + {{- with .Values.controller.resizer.extraArgs }} + {{- tpl . $ | trim | nindent 12 }} + {{- end }} + {{- end }} + env: + - name: ADDRESS + value: /var/lib/csi/sockets/pluginproxy/csi.sock + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + resources: {{ toYaml .Values.controller.resizer.resources | nindent 12 }} + {{ if .Values.livenessProbe.enable }} + - name: liveness-probe + securityContext: + {{- toYaml .Values.node.securityContext | nindent 12 }} + image: "{{ .Values.livenessProbe.image.repository }}:{{ .Values.livenessProbe.image.tag }}" + imagePullPolicy: {{ .Values.livenessProbe.image.pullPolicy }} + args: + - "-v={{ .Values.logVerbosityLevel }}" + - "--csi-address=$(ADDRESS)" + {{- if .Values.livenessProbe.extraArgs }} + {{- with .Values.livenessProbe.extraArgs }} + {{- tpl . $ | trim | nindent 12 }} + {{- end }} + {{- end }} + env: + - name: ADDRESS + value: /var/lib/csi/sockets/pluginproxy/csi.sock + volumeMounts: + - mountPath: /var/lib/csi/sockets/pluginproxy/ + name: socket-dir + resources: {{ toYaml .Values.livenessProbe.resources | nindent 12 }} + {{- end }} + volumes: + - name: socket-dir + emptyDir: {} + {{- if .Values.secret.enabled }} + - name: cloud-config + secret: + secretName: {{ .Values.secret.name }} + {{- else if .Values.secret.hostMount }} + - name: cloud-config + hostPath: + path: /etc/cloudstack-csi-driver + {{- end }} + {{- with .Values.controller.volumes }} + {{- toYaml . | nindent 8 }} + {{- end }} + affinity: {{ toYaml .Values.controller.affinity | nindent 8 }} + nodeSelector: {{ toYaml .Values.controller.nodeSelector | nindent 8 }} + tolerations: {{ toYaml .Values.controller.tolerations | nindent 8 }} + {{- with .Values.controller.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.priorityClassName }} + priorityClassName: {{ .Values.priorityClassName }} + {{- end }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} \ No newline at end of file diff --git a/charts/templates/csi-driver.yaml b/charts/templates/csi-driver.yaml new file mode 100644 index 0000000..9dbc49f --- /dev/null +++ b/charts/templates/csi-driver.yaml @@ -0,0 +1,14 @@ +apiVersion: storage.k8s.io/v1 +kind: CSIDriver +metadata: + name: csi.cloudstack.apache.org + annotations: + {{- with .Values.commonAnnotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + attachRequired: true + podInfoOnMount: true + # Supports only persistent volumes. + volumeLifecycleModes: + - Persistent diff --git a/charts/templates/csi-node-ds.yaml b/charts/templates/csi-node-ds.yaml new file mode 100644 index 0000000..a5b453e --- /dev/null +++ b/charts/templates/csi-node-ds.yaml @@ -0,0 +1,180 @@ +--- +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ include "csi.name" . }}-node + namespace: {{ .Release.Namespace }} + labels: + {{- include "csi.node.labels" . | nindent 4 }} + annotations: + {{- with .Values.commonAnnotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + selector: + matchLabels: + {{- include "csi.node.matchLabels" . | nindent 6 }} + updateStrategy: + type: RollingUpdate + template: + metadata: + labels: + {{- include "csi.node.labels" . | nindent 8 }} + annotations: + {{- with .Values.commonAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + containers: + - name: cloudstack-csi-node + image: "{{ .Values.node.csiDriver.image.repository }}:{{ .Values.node.csiDriver.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.node.csiDriver.image.pullPolicy }} + args: + - "--endpoint=$(CSI_ENDPOINT)" + - "--cloudstackconfig=$(CLOUD_CONFIG)" + - "--nodeName=$(NODE_NAME)" + {{- if .Values.node.csiDriver.extraArgs }} + {{- with .Values.node.csiDriver.extraArgs }} + {{- tpl . $ | trim | nindent 12 }} + {{- end }} + {{- end }} + env: + - name: CSI_ENDPOINT + value: unix:///csi/csi.sock + - name: CLOUD_CONFIG + value: /etc/config/cloud.conf + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + {{ if .Values.livenessProbe.enable }} + livenessProbe: {{- toYaml .Values.livenessProbe.livenessProbeSpec | nindent 12 }} + {{ end }} + ports: + - containerPort: 9808 + name: healthz + protocol: TCP + securityContext: + privileged: true + capabilities: + add: ["SYS_ADMIN"] + allowPrivilegeEscalation: true + volumeMounts: + - name: socket-dir + mountPath: /csi + - name: kubelet-dir + mountPath: {{ .Values.node.kubeletDir }} + # needed so that any mounts setup inside this container are + # propagated back to the host machine. + mountPropagation: "Bidirectional" + - name: pods-probe-dir + mountPath: /dev + mountPropagation: "HostToContainer" + - name: cloud-config + mountPath: /etc/config + {{- with .Values.node.csiDriver.volumeMounts }} + {{- toYaml . | nindent 12 }} + {{- end }} + resources: {{ toYaml .Values.node.csiDriver.resources | nindent 12 }} + - name: node-driver-registrar + securityContext: + {{- toYaml .Values.node.securityContext | nindent 12 }} + image: "{{ .Values.node.nodeDriverRegistrar.image.repository }}:{{ .Values.node.nodeDriverRegistrar.image.tag }}" + imagePullPolicy: {{ .Values.node.nodeDriverRegistrar.image.pullPolicy }} + args: + - "-v={{ .Values.logVerbosityLevel }}" + - "--csi-address=$(ADDRESS)" + - "--kubelet-registration-path=$(DRIVER_REG_SOCK_PATH)" + - "--health-port=9809" + {{- if .Values.node.nodeDriverRegistrar.extraArgs }} + {{- with .Values.node.nodeDriverRegistrar.extraArgs }} + {{- tpl . $ | trim | nindent 12 }} + {{- end }} + {{- end }} + ports: + - containerPort: 9809 + name: healthz + {{ if .Values.livenessProbe.enable }} + livenessProbe: {{- toYaml .Values.livenessProbe.livenessProbeSpec | nindent 12 }} + {{- end }} + env: + - name: ADDRESS + value: /csi/csi.sock + - name: DRIVER_REG_SOCK_PATH + value: {{ .Values.node.kubeletDir }}/plugins/csi.cloudstack.apache.org/csi.sock + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + volumeMounts: + - mountPath: /csi + name: socket-dir + - name: registration-dir + mountPath: /registration + resources: {{ toYaml .Values.node.nodeDriverRegistrar.resources | nindent 12 }} + {{ if .Values.livenessProbe.enable }} + - name: liveness-probe + securityContext: + {{- toYaml .Values.node.securityContext | nindent 12 }} + image: "{{ .Values.livenessProbe.image.repository }}:{{ .Values.livenessProbe.image.tag }}" + imagePullPolicy: {{ .Values.livenessProbe.image.pullPolicy }} + args: + - "-v={{ .Values.logVerbosityLevel }}" + - "--csi-address=$(ADDRESS)" + {{- if .Values.livenessProbe.extraArgs }} + {{- with .Values.livenessProbe.extraArgs }} + {{- tpl . $ | trim | nindent 12 }} + {{- end }} + {{- end }} + env: + - name: ADDRESS + value: /csi/csi.sock + volumeMounts: + - mountPath: /csi/ + name: socket-dir + resources: {{ toYaml .Values.livenessProbe.resources | nindent 12 }} + {{ end }} + volumes: + - name: socket-dir + hostPath: + path: {{ .Values.node.kubeletDir }}/plugins/csi.cloudstack.apache.org/ + type: DirectoryOrCreate + - name: registration-dir + hostPath: + path: {{ .Values.node.kubeletDir }}/plugins_registry/ + type: Directory + - name: kubelet-dir + hostPath: + path: {{ .Values.node.kubeletDir }} + type: Directory + - name: pods-probe-dir + hostPath: + path: /dev + type: Directory + {{- if .Values.secret.enabled }} + - name: cloud-config + secret: + secretName: {{ .Values.secret.name }} + {{- else if .Values.secret.hostMount }} + - name: cloud-config + hostPath: + path: /etc/config + {{- end }} + {{- with .Values.node.volumes }} + {{- toYaml . | nindent 8 }} + {{- end }} + affinity: {{ toYaml .Values.node.affinity | nindent 8 }} + nodeSelector: {{ toYaml .Values.node.nodeSelector | nindent 8 }} + tolerations: {{ toYaml .Values.node.tolerations | nindent 8 }} + dnsPolicy: {{ .Values.node.dnsPolicy }} + {{- with .Values.node.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.priorityClassName }} + priorityClassName: {{ .Values.priorityClassName }} + {{- end }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} \ No newline at end of file diff --git a/charts/templates/csi-sa.yaml b/charts/templates/csi-sa.yaml new file mode 100644 index 0000000..61ffc42 --- /dev/null +++ b/charts/templates/csi-sa.yaml @@ -0,0 +1,11 @@ +{{ if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Values.serviceAccount.name }} + namespace: {{ .Release.Namespace }} + annotations: + {{- with .Values.commonAnnotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +{{ end }} \ No newline at end of file diff --git a/charts/templates/podmonitor.yaml b/charts/templates/podmonitor.yaml new file mode 100644 index 0000000..736dca2 --- /dev/null +++ b/charts/templates/podmonitor.yaml @@ -0,0 +1,22 @@ +{{- if .Values.podMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + labels: + {{- include "csi.controller.labels" . | nindent 4 }} + name: {{ include "csi.name" . }}-controller + namespace: {{ .Release.Namespace }} + annotations: + {{- with .Values.commonAnnotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + podMetricsEndpoints: + - interval: 30s + port: http + scheme: http + jobLabel: component + selector: + matchLabels: + {{- include "csi.controller.matchLabels" . | nindent 6 }} +{{- end }} \ No newline at end of file diff --git a/charts/templates/secret.yaml b/charts/templates/secret.yaml new file mode 100644 index 0000000..fc0f565 --- /dev/null +++ b/charts/templates/secret.yaml @@ -0,0 +1,14 @@ +{{- if and (.Values.secret.create) (.Values.secret.enabled) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ .Values.secret.name | default "cloud.conf" }} + namespace: {{ .Release.Namespace }} + annotations: + {{- with .Values.commonAnnotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +type: Opaque +data: + cloud.conf: {{ include "cloudConfig" . | b64enc }} +{{- end }} \ No newline at end of file diff --git a/charts/templates/syncer-job.yaml b/charts/templates/syncer-job.yaml new file mode 100644 index 0000000..a264b02 --- /dev/null +++ b/charts/templates/syncer-job.yaml @@ -0,0 +1,49 @@ +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ include "csi.name" . }}-sc-syncer + namespace: {{ .Release.Namespace }} + annotations: + {{- with .Values.commonAnnotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + backoffLimit: {{ .Values.syncer.backoffLimit }} + template: + spec: + securityContext: {{- toYaml .Values.syncer.securityContext | nindent 12 }} + serviceAccountName: {{ .Values.syncer.rbac.serviceAccount.name }} + containers: + - image: "{{ .Values.syncer.image.repository }}:{{ .Values.syncer.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.syncer.image.imagePullPolicy }} + name: {{ include "csi.name" . }}-sc-syncer + args: + - "--cloudstackconfig=$(CLOUD_CONFIG)" + - "--kubeconfig=-" + - "--volumeExpansion=true" + {{- if .Values.syncer.extraArgs }} + {{- with .Values.syncer.extraArgs }} + {{- tpl . $ | trim | nindent 12 }} + {{- end }} + {{- end }} + env: + - name: CLOUD_CONFIG + value: /etc/config/cloud.conf + volumeMounts: + - name: cloud-config + mountPath: /etc/config/ + resources: {{ toYaml .Values.controller.resizer.resources | nindent 12 }} + volumes: + {{- if .Values.secret.enabled }} + - name: cloud-config + secret: + secretName: {{ .Values.secret.name }} + {{- else if .Values.secret.hostMount }} + - name: cloud-config + hostPath: + path: /etc/cloudstack-csi-driver + {{- end }} + affinity: {{ toYaml .Values.syncer.affinity | nindent 8 }} + nodeSelector: {{ toYaml .Values.syncer.nodeSelector | nindent 8 }} + restartPolicy: {{ .Values.syncer.restartPolicy }} \ No newline at end of file diff --git a/charts/templates/syncer-rbac.yaml b/charts/templates/syncer-rbac.yaml new file mode 100644 index 0000000..9d12df2 --- /dev/null +++ b/charts/templates/syncer-rbac.yaml @@ -0,0 +1,42 @@ +{{ if .Values.syncer.rbac.create }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Values.syncer.rbac.serviceAccount.name }} + namespace: {{ .Release.Namespace }} + annotations: + {{- with .Values.commonAnnotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: csi-sc-syncer-role + annotations: + {{- with .Values.commonAnnotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +rules: + - apiGroups: ["storage.k8s.io"] + resources: ["storageclasses"] + verbs: ["get", "create", "list", "update", "delete"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: csi-sc-syncer-binding + annotations: + {{- with .Values.commonAnnotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +subjects: + - kind: ServiceAccount + name: {{ .Values.syncer.rbac.serviceAccount.name }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: csi-sc-syncer-role + apiGroup: rbac.authorization.k8s.io +{{- end }} \ No newline at end of file diff --git a/charts/values.yaml b/charts/values.yaml new file mode 100644 index 0000000..07db1ec --- /dev/null +++ b/charts/values.yaml @@ -0,0 +1,233 @@ +extraLabels: {} + +nameOverride: "cloudstack-csi" +fullnameOverride: "" +timeout: 300s + +## Annotations to apply to all resources +commonAnnotations: {} +# commonAnnotations: +# "helm.sh/hook": pre-install,pre-upgrade +# "helm.sh/hook-weight": "-100" +# "helm.sh/hook-delete-policy": before-hook-creation + +# Create Prometheus Operator PodMonitor. Requires http server above. +# See https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#monitoring.coreos.com/v1.PodMonitor +podMonitor: + enabled: false + +## CloudStack CSI Controller Defaults +controller: + attacher: + image: + repository: registry.k8s.io/sig-storage/csi-attacher + tag: v4.4.2 + pullPolicy: IfNotPresent + resources: {} + extraArgs: {} + provisioner: + topology: "true" + image: + repository: registry.k8s.io/sig-storage/csi-provisioner + tag: v3.6.2 + pullPolicy: IfNotPresent + resources: {} + extraArgs: {} + resizer: + image: + repository: registry.k8s.io/sig-storage/csi-resizer + tag: v1.9.2 + pullPolicy: IfNotPresent + resources: {} + extraArgs: {} + csiDriverController: + image: + repository: ghcr.io/leaseweb/cloudstack-csi-driver + pullPolicy: IfNotPresent + tag: 0.3.0 # defaults to .Chart.AppVersion + volumeMounts: + - name: cacert + mountPath: /etc/cacert + readOnly: true + resources: {} + extraArgs: {} + + ## Set number of replicas (If replicaCount set to 1 by default leader-elect will be false) + replicaCount: 1 + strategy: + # RollingUpdate strategy replaces old pods with new ones gradually, + # without incurring downtime. + type: RollingUpdate + rollingUpdate: + # maxUnavailable is the maximum number of pods that can be + # unavailable during the update process. + maxUnavailable: 0 + # maxSurge is the maximum number of pods that can be + # created over the desired number of pods. + maxSurge: 1 + podSecurityContext: + runAsNonRoot: true + runAsUser: 65532 + runAsGroup: 65532 + fsGroup: 65532 + fsGroupChangePolicy: OnRootMismatch + securityContext: {} + # capabilities: + # drop: + # - ALL + # seccompProfile: + # type: RuntimeDefault + # readOnlyRootFilesystem: true + volumes: + - name: cacert + hostPath: + path: /etc/cacert + affinity: {} + nodeSelector: {} + tolerations: [] + # Allow for specifying internal IP addresses for multiple hostnames + hostAliases: {} + # - ip: "10.0.0.1" + # hostnames: + # - "keystone.hostname.com" + +## CloudStack CSI Node Defaults +node: + nodeDriverRegistrar: + image: + repository: registry.k8s.io/sig-storage/csi-node-driver-registrar + tag: v2.9.2 + pullPolicy: IfNotPresent + resources: {} + extraArgs: {} + csiDriver: + image: + repository: ghcr.io/leaseweb/cloudstack-csi-driver + pullPolicy: IfNotPresent + tag: 0.3.0 # defaults to .Chart.AppVersion + resources: {} + extraArgs: {} + volumeMounts: + - name: cacert + mountPath: /etc/cacert + readOnly: true + volumes: + - name: cacert + hostPath: + path: /etc/cacert + + podSecurityContext: {} + + securityContext: {} + # capabilities: + # drop: + # - ALL + # seccompProfile: + # type: RuntimeDefault + + affinity: {} + + nodeSelector: {} + + tolerations: + - operator: Exists + + kubeletDir: /var/lib/kubelet + + # Allow for specifying internal IP addresses for multiple hostnames + hostAliases: + # - ip: "10.0.0.1" + # hostnames: + # - "keystone.hostname.com" + +## CloudStack Storage Class Synecr Job Defaults +syncer: + # Job image + image: + repository: "ghcr.io/leaseweb/cloudstack-csi-sc-syncer" + tag: "0.3.0" # defaults to .Chart.AppVersion + imagePullPolicy: IfNotPresent + + extraArgs: {} + + # Job configurations + backoffLimit: 4 + restartPolicy: Never + + rbac: + create: true + serviceAccount: + name: cloudstack-csi-sc-syncer + + # Define resources + # resources: + # limits: + # cpu: 2 + # memory: 2000Mi + # requests: + # cpu: 500m + # memory: 500Mi + + securityContext: {} + # capabilities: + # drop: + # - ALL + # seccompProfile: + # type: RuntimeDefault + + affinity: {} + + nodeSelector: {} + +# Log verbosity level. +# See https://github.com/kubernetes/community/blob/master/contributors/devel/sig-instrumentation/logging.md +# for description of individual verbosity levels. +logVerbosityLevel: 2 + +# the secret should contain the cloudstack credentials +# there are several options to inject the credentials: +# 1) from kubernetes secret that doesn't exist: set "enabled" and "create" to true, this will create a secret from the values written to "data" down below +# 2) from kubernetes secret that already exists: set "enabled" to true and "create" to false +# 3) from host system path /etc/cloud/cloud.conf: set "enabled" to false and "hostMount" to true +# 4) via agent-injector (e.g. hashicorp vault): set "enabled" and "hostMount" to false, you have to provide credentials on your own by injecting credentials into the pod +secret: + enabled: true + create: false + name: cloud-config + cloudConfigData: + global: + api-url: "" + api-key: "" + secret-key: "" + hostMount: false + +priorityClassName: "" + +imagePullSecrets: [] +# - name: my-imagepull-secret + +serviceAccount: + create: true + name: "cloudstack-csi-controller" + +rbac: + create: true + +livenessProbe: + enable: true + image: + repository: registry.k8s.io/sig-storage/livenessprobe + tag: v2.11.0 + pullPolicy: IfNotPresent + resources: {} + extraArgs: {} + livenessProbeSpec: + httpGet: + path: /healthz + port: healthz + failureThreshold: 5 + initialDelaySeconds: 60 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 15 + From 9c5f4473439a40e1a77e2bd54af7e0261d5fe0cc Mon Sep 17 00:00:00 2001 From: Farnaz Babaeian Date: Mon, 4 Mar 2024 08:10:15 +0000 Subject: [PATCH 2/2] Upgrade Golang lint --- .github/workflows/pr-check.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr-check.yaml b/.github/workflows/pr-check.yaml index 62f05f3..a2e0069 100644 --- a/.github/workflows/pr-check.yaml +++ b/.github/workflows/pr-check.yaml @@ -12,7 +12,7 @@ jobs: - name: golangci-lint uses: golangci/golangci-lint-action@v3 with: - version: v1.53.2 + version: v1.56.2 args: --timeout=5m build: