diff --git a/addons/csi-digitalocean/crds.yaml b/addons/csi-digitalocean/crds.yaml new file mode 100644 index 000000000..43f023722 --- /dev/null +++ b/addons/csi-digitalocean/crds.yaml @@ -0,0 +1,525 @@ +# Copyright 2022 DigitalOcean +# +# 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. + + +############################################## +########### ############ +########### Snapshot CRDs ############ +########### ############ +############################################## +# +# Source: https://github.com/kubernetes-csi/external-snapshotter +# + +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.3.0 + api-approved.kubernetes.io: "https://github.com/kubernetes-csi/external-snapshotter/pull/139" + creationTimestamp: null + name: volumesnapshotclasses.snapshot.storage.k8s.io +spec: + group: snapshot.storage.k8s.io + names: + kind: VolumeSnapshotClass + listKind: VolumeSnapshotClassList + plural: volumesnapshotclasses + singular: volumesnapshotclass + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .driver + name: Driver + type: string + - description: Determines whether a VolumeSnapshotContent created through the + VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. + jsonPath: .deletionPolicy + name: DeletionPolicy + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: VolumeSnapshotClass specifies parameters that a underlying storage + system uses when creating a volume snapshot. A specific VolumeSnapshotClass + is used by specifying its name in a VolumeSnapshot object. VolumeSnapshotClasses + are non-namespaced + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + deletionPolicy: + description: deletionPolicy determines whether a VolumeSnapshotContent + created through the VolumeSnapshotClass should be deleted when its bound + VolumeSnapshot is deleted. Supported values are "Retain" and "Delete". + "Retain" means that the VolumeSnapshotContent and its physical snapshot + on underlying storage system are kept. "Delete" means that the VolumeSnapshotContent + and its physical snapshot on underlying storage system are deleted. + Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the storage driver that handles this + VolumeSnapshotClass. Required. + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + parameters: + additionalProperties: + type: string + description: parameters is a key-value map with storage driver specific + parameters for creating snapshots. These values are opaque to Kubernetes. + type: object + required: + - deletionPolicy + - driver + type: object + served: true + storage: true + subresources: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] + +--- + +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.3.0 + api-approved.kubernetes.io: "https://github.com/kubernetes-csi/external-snapshotter/pull/139" + creationTimestamp: null + name: volumesnapshotcontents.snapshot.storage.k8s.io +spec: + group: snapshot.storage.k8s.io + names: + kind: VolumeSnapshotContent + listKind: VolumeSnapshotContentList + plural: volumesnapshotcontents + singular: volumesnapshotcontent + scope: Cluster + versions: + - additionalPrinterColumns: + - description: Indicates if a snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: Represents the complete size of the snapshot in bytes + jsonPath: .status.restoreSize + name: RestoreSize + type: integer + - description: Determines whether this VolumeSnapshotContent and its physical + snapshot on the underlying storage system should be deleted when its bound + VolumeSnapshot is deleted. + jsonPath: .spec.deletionPolicy + name: DeletionPolicy + type: string + - description: Name of the CSI driver used to create the physical snapshot on + the underlying storage system. + jsonPath: .spec.driver + name: Driver + type: string + - description: Name of the VolumeSnapshotClass to which this snapshot belongs. + jsonPath: .spec.volumeSnapshotClassName + name: VolumeSnapshotClass + type: string + - description: Name of the VolumeSnapshot object to which this VolumeSnapshotContent + object is bound. + jsonPath: .spec.volumeSnapshotRef.name + name: VolumeSnapshot + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: VolumeSnapshotContent represents the actual "on-disk" snapshot + object in the underlying storage system + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + spec: + description: spec defines properties of a VolumeSnapshotContent created + by the underlying storage system. Required. + properties: + deletionPolicy: + description: deletionPolicy determines whether this VolumeSnapshotContent + and its physical snapshot on the underlying storage system should + be deleted when its bound VolumeSnapshot is deleted. Supported values + are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent + and its physical snapshot on underlying storage system are kept. + "Delete" means that the VolumeSnapshotContent and its physical snapshot + on underlying storage system are deleted. In dynamic snapshot creation + case, this field will be filled in with the "DeletionPolicy" field + defined in the VolumeSnapshotClass the VolumeSnapshot refers to. + For pre-existing snapshots, users MUST specify this field when creating + the VolumeSnapshotContent object. Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the CSI driver used to create the + physical snapshot on the underlying storage system. This MUST be + the same as the name returned by the CSI GetPluginName() call for + that driver. Required. + type: string + source: + description: source specifies from where a snapshot will be created. + This field is immutable after creation. Required. + properties: + snapshotHandle: + description: snapshotHandle specifies the CSI "snapshot_id" of + a pre-existing snapshot on the underlying storage system. This + field is immutable. + type: string + volumeHandle: + description: volumeHandle specifies the CSI "volume_id" of the + volume from which a snapshot should be dynamically taken from. + This field is immutable. + type: string + type: object + volumeSnapshotClassName: + description: name of the VolumeSnapshotClass to which this snapshot + belongs. + type: string + volumeSnapshotRef: + description: volumeSnapshotRef specifies the VolumeSnapshot object + to which this VolumeSnapshotContent object is bound. VolumeSnapshot.Spec.VolumeSnapshotContentName + field must reference to this VolumeSnapshotContent's name for the + bidirectional binding to be valid. For a pre-existing VolumeSnapshotContent + object, name and namespace of the VolumeSnapshot object MUST be + provided for binding to happen. This field is immutable after creation. + Required. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead of + an entire object, this string should contain a valid JSON/Go + field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within + a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" + (container with index 2 in this pod). This syntax is chosen + only to have some well-defined way of referencing a part of + an object. TODO: this design is not final and this field is + subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + required: + - deletionPolicy + - driver + - source + - volumeSnapshotRef + type: object + status: + description: status represents the current information of a snapshot. + properties: + creationTime: + description: creationTime is the timestamp when the point-in-time + snapshot is taken by the underlying storage system. In dynamic snapshot + creation case, this field will be filled in with the "creation_time" + value returned from CSI "CreateSnapshotRequest" gRPC call. For a + pre-existing snapshot, this field will be filled with the "creation_time" + value returned from the CSI "ListSnapshots" gRPC call if the driver + supports it. If not specified, it indicates the creation time is + unknown. The format of this field is a Unix nanoseconds time encoded + as an int64. On Unix, the command `date +%s%N` returns the current + time in nanoseconds since 1970-01-01 00:00:00 UTC. + format: int64 + type: integer + error: + description: error is the latest observed error during snapshot creation, + if any. + properties: + message: + description: 'message is a string detailing the encountered error + during snapshot creation if specified. NOTE: message may be + logged, and it should not contain sensitive information.' + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if a snapshot is ready to be used + to restore a volume. In dynamic snapshot creation case, this field + will be filled in with the "ready_to_use" value returned from CSI + "CreateSnapshotRequest" gRPC call. For a pre-existing snapshot, + this field will be filled with the "ready_to_use" value returned + from the CSI "ListSnapshots" gRPC call if the driver supports it, + otherwise, this field will be set to "True". If not specified, it + means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + description: restoreSize represents the complete size of the snapshot + in bytes. In dynamic snapshot creation case, this field will be + filled in with the "size_bytes" value returned from CSI "CreateSnapshotRequest" + gRPC call. For a pre-existing snapshot, this field will be filled + with the "size_bytes" value returned from the CSI "ListSnapshots" + gRPC call if the driver supports it. When restoring a volume from + this snapshot, the size of the volume MUST NOT be smaller than the + restoreSize if it is specified, otherwise the restoration will fail. + If not specified, it indicates that the size is unknown. + format: int64 + minimum: 0 + type: integer + snapshotHandle: + description: snapshotHandle is the CSI "snapshot_id" of a snapshot + on the underlying storage system. If not specified, it indicates + that dynamic snapshot creation has either failed or it is still + in progress. + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] + +--- + +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.3.0 + api-approved.kubernetes.io: "https://github.com/kubernetes-csi/external-snapshotter/pull/139" + creationTimestamp: null + name: volumesnapshots.snapshot.storage.k8s.io +spec: + group: snapshot.storage.k8s.io + names: + kind: VolumeSnapshot + listKind: VolumeSnapshotList + plural: volumesnapshots + singular: volumesnapshot + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Indicates if a snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: Name of the source PVC from where a dynamically taken snapshot + will be created. + jsonPath: .spec.source.persistentVolumeClaimName + name: SourcePVC + type: string + - description: Name of the VolumeSnapshotContent which represents a pre-provisioned + snapshot. + jsonPath: .spec.source.volumeSnapshotContentName + name: SourceSnapshotContent + type: string + - description: Represents the complete size of the snapshot. + jsonPath: .status.restoreSize + name: RestoreSize + type: string + - description: The name of the VolumeSnapshotClass requested by the VolumeSnapshot. + jsonPath: .spec.volumeSnapshotClassName + name: SnapshotClass + type: string + - description: The name of the VolumeSnapshotContent to which this VolumeSnapshot + is bound. + jsonPath: .status.boundVolumeSnapshotContentName + name: SnapshotContent + type: string + - description: Timestamp when the point-in-time snapshot is taken by the underlying + storage system. + jsonPath: .status.creationTime + name: CreationTime + type: date + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: VolumeSnapshot is a user's request for either creating a point-in-time + snapshot of a persistent volume, or binding to a pre-existing snapshot. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + spec: + description: 'spec defines the desired characteristics of a snapshot requested + by a user. More info: https://kubernetes.io/docs/concepts/storage/volume-snapshots#volumesnapshots + Required.' + properties: + source: + description: source specifies where a snapshot will be created from. + This field is immutable after creation. Required. + properties: + persistentVolumeClaimName: + description: persistentVolumeClaimName specifies the name of the + PersistentVolumeClaim object in the same namespace as the VolumeSnapshot + object where the snapshot should be dynamically taken from. + This field is immutable. + type: string + volumeSnapshotContentName: + description: volumeSnapshotContentName specifies the name of a + pre-existing VolumeSnapshotContent object. This field is immutable. + type: string + type: object + volumeSnapshotClassName: + description: 'volumeSnapshotClassName is the name of the VolumeSnapshotClass + requested by the VolumeSnapshot. If not specified, the default snapshot + class will be used if one exists. If not specified, and there is + no default snapshot class, dynamic snapshot creation will fail. + Empty string is not allowed for this field. TODO(xiangqian): a webhook + validation on empty string. More info: https://kubernetes.io/docs/concepts/storage/volume-snapshot-classes' + type: string + required: + - source + type: object + status: + description: 'status represents the current information of a snapshot. + NOTE: status can be modified by sources other than system controllers, + and must not be depended upon for accuracy. Controllers should only + use information from the VolumeSnapshotContent object after verifying + that the binding is accurate and complete.' + properties: + boundVolumeSnapshotContentName: + description: 'boundVolumeSnapshotContentName represents the name of + the VolumeSnapshotContent object to which the VolumeSnapshot object + is bound. If not specified, it indicates that the VolumeSnapshot + object has not been successfully bound to a VolumeSnapshotContent + object yet. NOTE: Specified boundVolumeSnapshotContentName alone + does not mean binding is valid. Controllers MUST always verify + bidirectional binding between VolumeSnapshot and VolumeSnapshotContent + to avoid possible security issues.' + type: string + creationTime: + description: creationTime is the timestamp when the point-in-time + snapshot is taken by the underlying storage system. In dynamic snapshot + creation case, this field will be filled in with the "creation_time" + value returned from CSI "CreateSnapshotRequest" gRPC call. For a + pre-existing snapshot, this field will be filled with the "creation_time" + value returned from the CSI "ListSnapshots" gRPC call if the driver + supports it. If not specified, it indicates that the creation time + of the snapshot is unknown. + format: date-time + type: string + error: + description: error is the last observed error during snapshot creation, + if any. This field could be helpful to upper level controllers(i.e., + application controller) to decide whether they should continue on + waiting for the snapshot to be created based on the type of error + reported. + properties: + message: + description: 'message is a string detailing the encountered error + during snapshot creation if specified. NOTE: message may be + logged, and it should not contain sensitive information.' + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if a snapshot is ready to be used + to restore a volume. In dynamic snapshot creation case, this field + will be filled in with the "ready_to_use" value returned from CSI + "CreateSnapshotRequest" gRPC call. For a pre-existing snapshot, + this field will be filled with the "ready_to_use" value returned + from the CSI "ListSnapshots" gRPC call if the driver supports it, + otherwise, this field will be set to "True". If not specified, it + means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + type: string + description: restoreSize represents the complete size of the snapshot + in bytes. In dynamic snapshot creation case, this field will be + filled in with the "size_bytes" value returned from CSI "CreateSnapshotRequest" + gRPC call. For a pre-existing snapshot, this field will be filled + with the "size_bytes" value returned from the CSI "ListSnapshots" + gRPC call if the driver supports it. When restoring a volume from + this snapshot, the size of the volume MUST NOT be smaller than the + restoreSize if it is specified, otherwise the restoration will fail. + If not specified, it indicates that the size is unknown. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/addons/csi-digitalocean/driver.yaml b/addons/csi-digitalocean/driver.yaml new file mode 100644 index 000000000..80384ecd2 --- /dev/null +++ b/addons/csi-digitalocean/driver.yaml @@ -0,0 +1,441 @@ +# Copyright 2022 DigitalOcean +# +# 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. + + +# Install the CSI Driver. This simplifies driver discovery and enables us to +# customize Kubernetes behavior +# https://kubernetes-csi.github.io/docs/csi-driver-object.html +apiVersion: storage.k8s.io/v1 +kind: CSIDriver +metadata: + name: dobs.csi.digitalocean.com +spec: + attachRequired: true + podInfoOnMount: true +--- +############################################## +########### ############ +########### Controller plugin ############ +########### ############ +############################################## + +kind: StatefulSet +apiVersion: apps/v1 +metadata: + name: csi-do-controller + namespace: kube-system +spec: + serviceName: "csi-do" + selector: + matchLabels: + app: csi-do-controller + replicas: 1 + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: csi-do-plugin + labels: + app: csi-do-controller + role: csi-do + spec: + priorityClassName: system-cluster-critical + serviceAccount: csi-do-controller-sa + containers: + - name: csi-provisioner + image: {{ .InternalImages.Get "DigitalOceanCSIProvisioner" }} + args: + - "--csi-address=$(ADDRESS)" + - "--default-fstype=ext4" + - "--v=5" + env: + - name: ADDRESS + value: /var/lib/csi/sockets/pluginproxy/csi.sock + imagePullPolicy: "IfNotPresent" + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + - name: csi-attacher + image: {{ .InternalImages.Get "DigitalOceanCSIAttacher" }} + args: + - "--csi-address=$(ADDRESS)" + - "--v=5" + env: + - name: ADDRESS + value: /var/lib/csi/sockets/pluginproxy/csi.sock + imagePullPolicy: "IfNotPresent" + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + - name: csi-snapshotter + image: {{ .InternalImages.Get "DigitalOceanCSISnapshotter" }} + args: + - "--csi-address=$(ADDRESS)" + - "--v=5" + env: + - name: ADDRESS + value: /var/lib/csi/sockets/pluginproxy/csi.sock + imagePullPolicy: IfNotPresent + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + - name: csi-resizer + image: {{ .InternalImages.Get "DigitalOceanCSIResizer" }} + args: + - "--csi-address=$(ADDRESS)" + - "--timeout=30s" + - "--v=5" + # DO volumes support online resize. + - "--handle-volume-inuse-error=false" + env: + - name: ADDRESS + value: /var/lib/csi/sockets/pluginproxy/csi.sock + imagePullPolicy: "IfNotPresent" + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + - name: csi-do-plugin + image: {{ .InternalImages.Get "DigitalOceanCSI" }} + args : + - "--endpoint=$(CSI_ENDPOINT)" + - "--token=$(DIGITALOCEAN_ACCESS_TOKEN)" + - "--url=$(DIGITALOCEAN_API_URL)" + env: + - name: CSI_ENDPOINT + value: unix:///var/lib/csi/sockets/pluginproxy/csi.sock + - name: DIGITALOCEAN_API_URL + value: https://api.digitalocean.com/ + - name: DIGITALOCEAN_ACCESS_TOKEN + valueFrom: + secretKeyRef: + name: kubeone-ccm-credentials + key: DO_TOKEN + imagePullPolicy: "Always" + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + volumes: + - name: socket-dir + emptyDir: {} + +--- + +kind: ServiceAccount +apiVersion: v1 +metadata: + name: csi-do-controller-sa + namespace: kube-system + +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-do-provisioner-role +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: ["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"] + - apiGroups: [ "storage.k8s.io" ] + resources: [ "csinodes" ] + verbs: [ "get", "list", "watch" ] + - apiGroups: [ "" ] + resources: [ "nodes" ] + verbs: [ "get", "list", "watch" ] + - apiGroups: ["storage.k8s.io"] + resources: ["volumeattachments"] + verbs: ["get", "list", "watch"] + +--- + +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-do-provisioner-binding +subjects: + - kind: ServiceAccount + name: csi-do-controller-sa + namespace: kube-system +roleRef: + kind: ClusterRole + name: csi-do-provisioner-role + apiGroup: rbac.authorization.k8s.io + +--- +# Attacher must be able to work with PVs, nodes and VolumeAttachments +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-do-attacher-role +rules: + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get", "list", "watch", "update", "patch"] + - apiGroups: [""] + resources: ["nodes"] + verbs: ["get", "list", "watch"] + - apiGroups: ["storage.k8s.io"] + resources: ["csinodes"] + verbs: ["get", "list", "watch"] + - apiGroups: ["storage.k8s.io"] + resources: ["volumeattachments"] + verbs: ["get", "list", "watch", "update", "patch"] + - apiGroups: ["storage.k8s.io"] + resources: ["volumeattachments/status"] + verbs: ["patch"] + +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-do-attacher-binding +subjects: + - kind: ServiceAccount + name: csi-do-controller-sa + namespace: kube-system +roleRef: + kind: ClusterRole + name: csi-do-attacher-role + apiGroup: rbac.authorization.k8s.io + +--- + +# Snapshotter sidecar + +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-do-snapshotter-role +rules: + - apiGroups: [""] + resources: ["events"] + verbs: ["list", "watch", "create", "update", "patch"] + - 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"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents/status"] + verbs: ["update"] + +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-do-snapshotter-binding +subjects: + - kind: ServiceAccount + name: csi-do-controller-sa + namespace: kube-system +roleRef: + kind: ClusterRole + name: csi-do-snapshotter-role + apiGroup: rbac.authorization.k8s.io + +--- + +# Resizer must be able to work with PVCs, PVs, SCs. +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-do-resizer-role +rules: + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get", "list", "watch", "update", "patch"] + - apiGroups: [""] + resources: ["persistentvolumeclaims"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["persistentvolumeclaims/status"] + verbs: ["update", "patch"] + - apiGroups: [""] + resources: ["events"] + verbs: ["list", "watch", "create", "update", "patch"] + +--- + +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-do-resizer-binding +subjects: + - kind: ServiceAccount + name: csi-do-controller-sa + namespace: kube-system +roleRef: + kind: ClusterRole + name: csi-do-resizer-role + apiGroup: rbac.authorization.k8s.io + +--- + +######################################## +########### ############ +########### Node plugin ############ +########### ############ +######################################## + +kind: DaemonSet +apiVersion: apps/v1 +metadata: + name: csi-do-node + namespace: kube-system +spec: + selector: + matchLabels: + app: csi-do-node + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: csi-do-plugin + labels: + app: csi-do-node + role: csi-do + spec: + priorityClassName: system-node-critical + serviceAccount: csi-do-node-sa + hostNetwork: true + initContainers: + # Delete automount udev rule running on all DO droplets. The rule mounts + # devices briefly and may conflict with CSI-managed droplets (leading to + # "resource busy" errors). We can safely delete it in DOKS. + - name: automount-udev-deleter + image: {{ .InternalImages.Get "DigitalOceanCSIAlpine" }} + args: + - "rm" + - "-f" + - "/etc/udev/rules.d/99-digitalocean-automount.rules" + volumeMounts: + - name: udev-rules-dir + mountPath: /etc/udev/rules.d/ + containers: + - name: csi-node-driver-registrar + image: {{ .InternalImages.Get "DigitalOceanCSINodeDriverRegistar" }} + args: + - "--v=5" + - "--csi-address=$(ADDRESS)" + - "--kubelet-registration-path=$(DRIVER_REG_SOCK_PATH)" + lifecycle: + preStop: + exec: + command: ["/bin/sh", "-c", "rm -rf /registration/dobs.csi.digitalocean.com /registration/dobs.csi.digitalocean.com-reg.sock"] + env: + - name: ADDRESS + value: /csi/csi.sock + - name: DRIVER_REG_SOCK_PATH + value: /var/lib/kubelet/plugins/dobs.csi.digitalocean.com/csi.sock + - name: KUBE_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + volumeMounts: + - name: plugin-dir + mountPath: /csi/ + - name: registration-dir + mountPath: /registration/ + - name: csi-do-plugin + image: {{ .InternalImages.Get "DigitalOceanCSI" }} + args : + - "--endpoint=$(CSI_ENDPOINT)" + - "--url=$(DIGITALOCEAN_API_URL)" + env: + - name: CSI_ENDPOINT + value: unix:///csi/csi.sock + - name: DIGITALOCEAN_API_URL + value: https://api.digitalocean.com/ + imagePullPolicy: "Always" + securityContext: + privileged: true + capabilities: + add: ["SYS_ADMIN"] + allowPrivilegeEscalation: true + volumeMounts: + - name: plugin-dir + mountPath: /csi + - name: pods-mount-dir + mountPath: /var/lib/kubelet + # needed so that any mounts setup inside this container are + # propagated back to the host machine. + mountPropagation: "Bidirectional" + - name: device-dir + mountPath: /dev + volumes: + - name: registration-dir + hostPath: + path: /var/lib/kubelet/plugins_registry/ + type: DirectoryOrCreate + - name: plugin-dir + hostPath: + path: /var/lib/kubelet/plugins/dobs.csi.digitalocean.com + type: DirectoryOrCreate + - name: pods-mount-dir + hostPath: + path: /var/lib/kubelet + type: Directory + - name: device-dir + hostPath: + path: /dev + - name: udev-rules-dir + hostPath: + path: /etc/udev/rules.d/ +--- + +apiVersion: v1 +kind: ServiceAccount +metadata: + name: csi-do-node-sa + namespace: kube-system + +--- + +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-do-node-driver-registrar-role + namespace: kube-system +rules: + - apiGroups: [""] + resources: ["events"] + verbs: ["get", "list", "watch", "create", "update", "patch"] + +--- + +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-do-node-driver-registrar-binding +subjects: + - kind: ServiceAccount + name: csi-do-node-sa + namespace: kube-system +roleRef: + kind: ClusterRole + name: csi-do-node-driver-registrar-role + apiGroup: rbac.authorization.k8s.io diff --git a/addons/csi-digitalocean/snapshot-controller.yaml b/addons/csi-digitalocean/snapshot-controller.yaml new file mode 100644 index 000000000..03a08322c --- /dev/null +++ b/addons/csi-digitalocean/snapshot-controller.yaml @@ -0,0 +1,98 @@ +# Copyright 2022 DigitalOcean +# +# 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. + + +# +# snapshotter controller +# source: # Source: https://github.com/kubernetes-csi/external-snapshotter +# + +kind: StatefulSet +apiVersion: apps/v1 +metadata: + name: snapshot-controller + namespace: kube-system +spec: + serviceName: "snapshot-controller" + replicas: 1 + selector: + matchLabels: + app: snapshot-controller + template: + metadata: + labels: + app: snapshot-controller + spec: + serviceAccount: snapshot-controller + containers: + - name: snapshot-controller + image: {{ .InternalImages.Get "DigitalOceanCSISnapshotController" }} + args: + - "--v=5" + imagePullPolicy: IfNotPresent + +--- + +apiVersion: v1 +kind: ServiceAccount +metadata: + name: snapshot-controller + namespace: kube-system + +--- + +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: snapshot-controller-role +rules: + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["persistentvolumeclaims"] + verbs: ["get", "list", "watch", "update"] + - apiGroups: ["storage.k8s.io"] + resources: ["storageclasses"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["events"] + verbs: ["list", "watch", "create", "update", "patch"] + - 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"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots"] + verbs: ["get", "list", "watch", "update"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots/status"] + verbs: ["update"] + +--- + +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: snapshot-controller-binding +subjects: + - kind: ServiceAccount + name: snapshot-controller + namespace: kube-system +roleRef: + kind: ClusterRole + name: snapshot-controller-role + apiGroup: rbac.authorization.k8s.io diff --git a/addons/csi-digitalocean/snapshot-validation-webhook.yaml b/addons/csi-digitalocean/snapshot-validation-webhook.yaml new file mode 100644 index 000000000..1993e2bc3 --- /dev/null +++ b/addons/csi-digitalocean/snapshot-validation-webhook.yaml @@ -0,0 +1,97 @@ +# Copyright 2022 DigitalOcean +# +# 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: Secret +metadata: + name: digitalocean-webhook-certs + namespace: kube-system +data: + "cert.pem": | +{{ .Certificates.DigitalOceanCSIWebhookCert | b64enc | indent 4 }} + "key.pem": | +{{ .Certificates.DigitalOceanCSIWebhookKey | b64enc | indent 4 }} +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + name: "validation-webhook.snapshot.storage.k8s.io" +webhooks: + - name: "validation-webhook.snapshot.storage.k8s.io" + rules: + - apiGroups: ["snapshot.storage.k8s.io"] + apiVersions: ["v1", "v1beta1"] + operations: ["CREATE", "UPDATE"] + resources: ["volumesnapshots", "volumesnapshotcontents"] + scope: "*" + clientConfig: + service: + namespace: "kube-system" + name: "snapshot-validation-service" + path: "/volumesnapshot" + caBundle: | +{{ .Certificates.KubernetesCA | b64enc | indent 8 }} + admissionReviewVersions: ["v1", "v1beta1"] + sideEffects: None + failurePolicy: Fail + timeoutSeconds: 5 + +--- + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: snapshot-validation + namespace: kube-system + labels: + app: snapshot-validation +spec: + replicas: 2 + selector: + matchLabels: + app: snapshot-validation + template: + metadata: + labels: + app: snapshot-validation + spec: + containers: + - name: snapshot-validation + image: {{ .InternalImages.Get "DigitalOceanCSISnapshotValidationWebhook" }} + imagePullPolicy: IfNotPresent + args: ['--tls-cert-file=/etc/snapshot-validation-webhook/certs/cert.pem', '--tls-private-key-file=/etc/snapshot-validation-webhook/certs/key.pem'] + ports: + - containerPort: 443 + volumeMounts: + - name: snapshot-validation-webhook-certs + mountPath: /etc/snapshot-validation-webhook/certs + readOnly: true + volumes: + - name: snapshot-validation-webhook-certs + secret: + secretName: digitalocean-webhook-certs + +--- + +apiVersion: v1 +kind: Service +metadata: + name: snapshot-validation-service + namespace: kube-system +spec: + selector: + app: snapshot-validation + ports: + - protocol: TCP + port: 443 diff --git a/addons/default-storage-class/storage-class.yaml b/addons/default-storage-class/storage-class.yaml index b314a43c5..79606f89a 100644 --- a/addons/default-storage-class/storage-class.yaml +++ b/addons/default-storage-class/storage-class.yaml @@ -172,3 +172,25 @@ provisioner: csi.hetzner.cloud volumeBindingMode: WaitForFirstConsumer allowVolumeExpansion: true {{ end }} + +{{ if eq .Config.CloudProvider.CloudProviderName "digitalocean" }} +{{ if .Config.CloudProvider.External }} +kind: StorageClass +apiVersion: storage.k8s.io/v1 +metadata: + name: do-block-storage + annotations: + storageclass.kubernetes.io/is-default-class: "true" +provisioner: dobs.csi.digitalocean.com +allowVolumeExpansion: true +--- +kind: VolumeSnapshotClass +apiVersion: snapshot.storage.k8s.io/v1beta1 +metadata: + name: do-block-storage + annotations: + snapshot.storage.kubernetes.io/is-default-class: "true" +driver: dobs.csi.digitalocean.com +deletionPolicy: Delete +{{ end }} +{{ end }} diff --git a/pkg/addons/applier.go b/pkg/addons/applier.go index e3e5670a4..85a3caaa9 100644 --- a/pkg/addons/applier.go +++ b/pkg/addons/applier.go @@ -208,8 +208,10 @@ func newAddonsApplier(s *state.State) (*applier, error) { Params: params, } + // Certs for CSI plugins + switch { // Certs for vsphere-csi-webhook (deployed only if CSIMigration is enabled) - if csiMigration && s.Cluster.CloudProvider.Vsphere != nil { + case csiMigration && s.Cluster.CloudProvider.Vsphere != nil: vsphereCSICertsMap, err := certificate.NewSignedTLSCert( resources.VsphereCSIWebhookName, resources.VsphereCSIWebhookNamespace, @@ -222,9 +224,7 @@ func newAddonsApplier(s *state.State) (*applier, error) { } data.Certificates["vSphereCSIWebhookCert"] = vsphereCSICertsMap[resources.TLSCertName] data.Certificates["vSphereCSIWebhookKey"] = vsphereCSICertsMap[resources.TLSKeyName] - } - - if s.Cluster.CloudProvider.Nutanix != nil { + case s.Cluster.CloudProvider.Nutanix != nil: nutanixCSICertsMap, err := certificate.NewSignedTLSCert( resources.NutanixCSIWebhookName, resources.NutanixCSIWebhookNamespace, @@ -237,6 +237,19 @@ func newAddonsApplier(s *state.State) (*applier, error) { } data.Certificates["NutanixCSIWebhookCert"] = nutanixCSICertsMap[resources.TLSCertName] data.Certificates["NutanixCSIWebhookKey"] = nutanixCSICertsMap[resources.TLSKeyName] + case s.Cluster.CloudProvider.DigitalOcean != nil && s.Cluster.CloudProvider.External: + digitaloceanCSICertsMap, err := certificate.NewSignedTLSCert( + resources.DigitalOceanCSIWebhookName, + resources.DigitalOceanCSIWebhookNamespace, + s.Cluster.ClusterNetwork.ServiceDomainName, + kubeCAPrivateKey, + kubeCACert, + ) + if err != nil { + return nil, err + } + data.Certificates["DigitalOceanCSIWebhookCert"] = digitaloceanCSICertsMap[resources.TLSCertName] + data.Certificates["DigitalOceanCSIWebhookKey"] = digitaloceanCSICertsMap[resources.TLSKeyName] } return &applier{ diff --git a/pkg/addons/ensure.go b/pkg/addons/ensure.go index 8cc5d4600..67c88c4e4 100644 --- a/pkg/addons/ensure.go +++ b/pkg/addons/ensure.go @@ -49,6 +49,7 @@ var ( resources.AddonCSIAwsEBS: "", resources.AddonCSIAzureDisk: "", resources.AddonCSIAzureFile: "", + resources.AddonCSIDigitalOcean: "", resources.AddonCSIHetzner: "", resources.AddonCSIOpenStackCinder: "", resources.AddonCSIVsphere: "", @@ -132,9 +133,14 @@ func collectAddons(s *state.State) (addonsToDeploy []addonAction) { }, ) case s.Cluster.CloudProvider.DigitalOcean != nil: - addonsToDeploy = append(addonsToDeploy, addonAction{ - name: resources.AddonCCMDigitalOcean, - }) + addonsToDeploy = append(addonsToDeploy, + addonAction{ + name: resources.AddonCCMDigitalOcean, + }, + addonAction{ + name: resources.AddonCSIDigitalOcean, + }, + ) case s.Cluster.CloudProvider.Hetzner != nil: addonsToDeploy = append(addonsToDeploy, addonAction{ diff --git a/pkg/templates/images/images.go b/pkg/templates/images/images.go index 9f9ec48a8..fde4f91ba 100644 --- a/pkg/templates/images/images.go +++ b/pkg/templates/images/images.go @@ -124,6 +124,17 @@ const ( NutanixCSIResizer NutanixCSISnapshotter + // DigitalOcean CSI + DigitalOceanCSI + DigitalOceanCSIAlpine + DigitalOceanCSIAttacher + DigitalOceanCSINodeDriverRegistar + DigitalOceanCSIProvisioner + DigitalOceanCSIResizer + DigitalOceanCSISnapshotController + DigitalOceanCSISnapshotValidationWebhook + DigitalOceanCSISnapshotter + // CCMs and CSI plugins DigitaloceanCCM HetznerCCM @@ -235,6 +246,16 @@ func optionalResources() map[Resource]map[string]string { // DigitalOcean CCM DigitaloceanCCM: {"*": "docker.io/digitalocean/digitalocean-cloud-controller-manager:v0.1.33"}, + DigitalOceanCSI: {"*": "docker.io/digitalocean/do-csi-plugin:v3.0.0"}, + DigitalOceanCSIAlpine: {"*": "docker.io/alpine:3"}, + DigitalOceanCSIAttacher: {"*": "k8s.gcr.io/sig-storage/csi-attacher:v3.3.0"}, + DigitalOceanCSINodeDriverRegistar: {"*": "k8s.gcr.io/sig-storage/csi-node-driver-registrar:v2.4.0"}, + DigitalOceanCSIProvisioner: {"*": "k8s.gcr.io/sig-storage/csi-provisioner:v2.2.2"}, + DigitalOceanCSIResizer: {"*": "k8s.gcr.io/sig-storage/csi-resizer:v1.3.0"}, + DigitalOceanCSISnapshotController: {"*": "k8s.gcr.io/sig-storage/snapshot-controller:v3.0.3"}, + DigitalOceanCSISnapshotValidationWebhook: {"*": "k8s.gcr.io/sig-storage/snapshot-validation-webhook:v3.0.3"}, + DigitalOceanCSISnapshotter: {"*": "k8s.gcr.io/sig-storage/csi-snapshotter:v3.0.3"}, + // Hetzner CCM HetznerCCM: {"*": "docker.io/hetznercloud/hcloud-cloud-controller-manager:v1.12.0"}, diff --git a/pkg/templates/images/resource_string.go b/pkg/templates/images/resource_string.go index 84256da1a..ca8405665 100644 --- a/pkg/templates/images/resource_string.go +++ b/pkg/templates/images/resource_string.go @@ -65,21 +65,30 @@ func _() { _ = x[NutanixCSIRegistrar-55] _ = x[NutanixCSIResizer-56] _ = x[NutanixCSISnapshotter-57] - _ = x[DigitaloceanCCM-58] - _ = x[HetznerCCM-59] - _ = x[HetznerCSI-60] - _ = x[OpenstackCCM-61] - _ = x[OpenstackCSI-62] - _ = x[EquinixMetalCCM-63] - _ = x[VsphereCCM-64] - _ = x[VsphereCSIDriver-65] - _ = x[VsphereCSISyncer-66] - _ = x[VsphereCSIProvisioner-67] + _ = x[DigitalOceanCSI-58] + _ = x[DigitalOceanCSIAlpine-59] + _ = x[DigitalOceanCSIAttacher-60] + _ = x[DigitalOceanCSINodeDriverRegistar-61] + _ = x[DigitalOceanCSIProvisioner-62] + _ = x[DigitalOceanCSIResizer-63] + _ = x[DigitalOceanCSISnapshotController-64] + _ = x[DigitalOceanCSISnapshotValidationWebhook-65] + _ = x[DigitalOceanCSISnapshotter-66] + _ = x[DigitaloceanCCM-67] + _ = x[HetznerCCM-68] + _ = x[HetznerCSI-69] + _ = x[OpenstackCCM-70] + _ = x[OpenstackCSI-71] + _ = x[EquinixMetalCCM-72] + _ = x[VsphereCCM-73] + _ = x[VsphereCSIDriver-74] + _ = x[VsphereCSISyncer-75] + _ = x[VsphereCSIProvisioner-76] } -const _Resource_name = "CalicoCNICalicoControllerCalicoNodeFlannelCiliumCiliumOperatorHubbleRelayHubbleUIHubbleUIBackendHubbleProxyWeaveNetCNIKubeWeaveNetCNINPCDNSNodeCacheMachineControllerMetricsServerClusterAutoscalerCSIAttacherCSINodeDriverRegistarCSIProvisionerCSISnapshotterCSIResizerCSILivenessProbeAwsCCMAzureCCMAzureCNMAwsEbsCSIAwsEbsCSIAttacherAwsEbsCSILivenessProbeAwsEbsCSINodeDriverRegistrarAwsEbsCSIProvisionerAwsEbsCSIResizerAwsEbsCSISnapshotterAwsEbsCSISnapshotControllerAzureFileCSIAzureFileCSIAttacherAzureFileCSILivenessProbeAzureFileCSINodeDriverRegistarAzureFileCSIProvisionerAzureFileCSIResizerAzureFileCSISnapshotterAzureFileCSISnapshotterControllerNutanixCSISnapshotControllerNutanixCSISnapshotValidationWebhookAzureDiskCSIAzureDiskCSIAttacherAzureDiskCSILivenessProbeAzureDiskCSINodeDriverRegistarAzureDiskCSIProvisionerAzureDiskCSIResizerAzureDiskCSISnapshotterAzureDiskCSISnapshotterControllerNutanixCSILivenessProbeNutanixCSINutanixCSIProvisionerNutanixCSIRegistrarNutanixCSIResizerNutanixCSISnapshotterDigitaloceanCCMHetznerCCMHetznerCSIOpenstackCCMOpenstackCSIEquinixMetalCCMVsphereCCMVsphereCSIDriverVsphereCSISyncerVsphereCSIProvisioner" +const _Resource_name = "CalicoCNICalicoControllerCalicoNodeFlannelCiliumCiliumOperatorHubbleRelayHubbleUIHubbleUIBackendHubbleProxyWeaveNetCNIKubeWeaveNetCNINPCDNSNodeCacheMachineControllerMetricsServerClusterAutoscalerCSIAttacherCSINodeDriverRegistarCSIProvisionerCSISnapshotterCSIResizerCSILivenessProbeAwsCCMAzureCCMAzureCNMAwsEbsCSIAwsEbsCSIAttacherAwsEbsCSILivenessProbeAwsEbsCSINodeDriverRegistrarAwsEbsCSIProvisionerAwsEbsCSIResizerAwsEbsCSISnapshotterAwsEbsCSISnapshotControllerAzureFileCSIAzureFileCSIAttacherAzureFileCSILivenessProbeAzureFileCSINodeDriverRegistarAzureFileCSIProvisionerAzureFileCSIResizerAzureFileCSISnapshotterAzureFileCSISnapshotterControllerNutanixCSISnapshotControllerNutanixCSISnapshotValidationWebhookAzureDiskCSIAzureDiskCSIAttacherAzureDiskCSILivenessProbeAzureDiskCSINodeDriverRegistarAzureDiskCSIProvisionerAzureDiskCSIResizerAzureDiskCSISnapshotterAzureDiskCSISnapshotterControllerNutanixCSILivenessProbeNutanixCSINutanixCSIProvisionerNutanixCSIRegistrarNutanixCSIResizerNutanixCSISnapshotterDigitalOceanCSIDigitalOceanCSIAlpineDigitalOceanCSIAttacherDigitalOceanCSINodeDriverRegistarDigitalOceanCSIProvisionerDigitalOceanCSIResizerDigitalOceanCSISnapshotControllerDigitalOceanCSISnapshotValidationWebhookDigitalOceanCSISnapshotterDigitaloceanCCMHetznerCCMHetznerCSIOpenstackCCMOpenstackCSIEquinixMetalCCMVsphereCCMVsphereCSIDriverVsphereCSISyncerVsphereCSIProvisioner" -var _Resource_index = [...]uint16{0, 9, 25, 35, 42, 48, 62, 73, 81, 96, 107, 122, 136, 148, 165, 178, 195, 206, 227, 241, 255, 265, 281, 287, 295, 303, 312, 329, 351, 379, 399, 415, 435, 462, 474, 494, 519, 549, 572, 591, 614, 647, 675, 710, 722, 742, 767, 797, 820, 839, 862, 895, 918, 928, 949, 968, 985, 1006, 1021, 1031, 1041, 1053, 1065, 1080, 1090, 1106, 1122, 1143} +var _Resource_index = [...]uint16{0, 9, 25, 35, 42, 48, 62, 73, 81, 96, 107, 122, 136, 148, 165, 178, 195, 206, 227, 241, 255, 265, 281, 287, 295, 303, 312, 329, 351, 379, 399, 415, 435, 462, 474, 494, 519, 549, 572, 591, 614, 647, 675, 710, 722, 742, 767, 797, 820, 839, 862, 895, 918, 928, 949, 968, 985, 1006, 1021, 1042, 1065, 1098, 1124, 1146, 1179, 1219, 1245, 1260, 1270, 1280, 1292, 1304, 1319, 1329, 1345, 1361, 1382} func (i Resource) String() string { i -= 1 diff --git a/pkg/templates/resources/resources.go b/pkg/templates/resources/resources.go index 18cf671c6..59c02b809 100644 --- a/pkg/templates/resources/resources.go +++ b/pkg/templates/resources/resources.go @@ -35,6 +35,7 @@ const ( AddonCSIAwsEBS = "csi-aws-ebs" AddonCSIAzureDisk = "csi-azuredisk" AddonCSIAzureFile = "csi-azurefile" + AddonCSIDigitalOcean = "csi-digitalocean" AddonCSIHetzner = "csi-hetzner" AddonCSIOpenStackCinder = "csi-openstack-cinder" AddonCSIVsphere = "csi-vsphere" @@ -64,6 +65,9 @@ const ( NutanixCSIWebhookName = "snapshot-validation-service" NutanixCSIWebhookNamespace = metav1.NamespaceSystem + + DigitalOceanCSIWebhookName = "snapshot-validation-service" + DigitalOceanCSIWebhookNamespace = metav1.NamespaceSystem ) const (