diff --git a/docs/labels.md b/docs/labels.md index 07b08db3..c7ee61f1 100644 --- a/docs/labels.md +++ b/docs/labels.md @@ -62,6 +62,21 @@ Default value: `v1.25.3` +### Manila + +* `manila_csi_plugin_tag` + + The version of the Manila CSI container image to use when bootstrapping the + cluster. + + Default value: `v1.25.3` + +* `manila_csi_share_network_id` + + Manila [share network](https://wiki.openstack.org/wiki/Manila/Concepts#share_network) ID. + + Default value: `None` + ## Kubernetes * `auto_healing_enabled` diff --git a/hack/stack.sh b/hack/stack.sh index d175d271..6fe09f31 100755 --- a/hack/stack.sh +++ b/hack/stack.sh @@ -66,6 +66,22 @@ enable_service octavia o-api o-cw o-hm o-hk o-da # Magnum enable_plugin magnum https://opendev.org/openstack/magnum +# Manila +LIBS_FROM_GIT=python-manilaclient +enable_plugin manila https://opendev.org/openstack/manila +enable_plugin manila-ui https://opendev.org/openstack/manila-ui +enable_plugin manila-tempest-plugin https://opendev.org/openstack/manila-tempest-plugin + +SHARE_DRIVER=manila.share.drivers.generic.GenericShareDriver +MANILA_ENABLED_BACKENDS=generic +MANILA_OPTGROUP_generic_driver_handles_share_servers=True +MANILA_OPTGROUP_generic_connect_share_server_to_tenant_network=True +MANILA_DEFAULT_SHARE_TYPE_EXTRA_SPECS='snapshot_support=True create_share_from_snapshot_support=True' +MANILA_CONFIGURE_DEFAULT_TYPES=True + +MANILA_SERVICE_IMAGE_ENABLED=True +MANILA_USE_SERVICE_INSTANCE_PASSWORD=True + [[post-config|/etc/magnum/magnum.conf]] [cluster_template] kubernetes_allowed_network_drivers = calico diff --git a/magnum_cluster_api/clients.py b/magnum_cluster_api/clients.py index eb609b06..c91ec4d7 100644 --- a/magnum_cluster_api/clients.py +++ b/magnum_cluster_api/clients.py @@ -13,12 +13,42 @@ # under the License. import pykube -from magnum.common import clients +from magnum.common import clients, exception +from manilaclient.v2 import client as manilaclient + + +class OpenStackClients(clients.OpenStackClients): + """Convenience class to create and cache client instances.""" + + def __init__(self, context): + super(OpenStackClients, self).__init__(context) + self._manila = None + + @exception.wrap_keystone_exception + def manila(self): + if self._manila: + return self._manila + endpoint_type = self._get_client_option("manila", "endpoint_type") + region_name = self._get_client_option("manila", "region_name") + manilaclient_version = self._get_client_option("manila", "api_version") + endpoint = self.url_for( + service_type="sharev2", interface=endpoint_type, region_name=region_name + ) + args = { + "cacert": self._get_client_option("manila", "ca_file"), + "insecure": self._get_client_option("manila", "insecure"), + } + + session = self.keystone().session + self._manila = manilaclient.Client( + manilaclient_version, session=session, service_catalog_url=endpoint, **args + ) + return self._manila def get_pykube_api() -> pykube.HTTPClient: return pykube.HTTPClient(pykube.KubeConfig.from_env()) -def get_openstack_api(context) -> clients.OpenStackClients: - return clients.OpenStackClients(context) +def get_openstack_api(context) -> OpenStackClients: + return OpenStackClients(context) diff --git a/magnum_cluster_api/cmd/image_loader.py b/magnum_cluster_api/cmd/image_loader.py index e9f8c4ae..1ff9d038 100644 --- a/magnum_cluster_api/cmd/image_loader.py +++ b/magnum_cluster_api/cmd/image_loader.py @@ -27,7 +27,9 @@ "docker.io/calico/kube-controllers:v3.24.2", "docker.io/calico/node:v3.24.2", "docker.io/k8scloudprovider/cinder-csi-plugin:v1.25.3", + "docker.io/k8scloudprovider/manila-csi-plugin:v1.25.3", "docker.io/k8scloudprovider/openstack-cloud-controller-manager:v1.25.3", + "registry.k8s.io/sig-storage/nfsplugin:v4.2.0", "registry.k8s.io/coredns/coredns:v1.8.6", "registry.k8s.io/coredns/coredns:v1.9.3", CONF.auto_scaling.v1_22_image, @@ -62,11 +64,18 @@ "registry.k8s.io/kube-scheduler:v1.26.2", images.PAUSE, "registry.k8s.io/sig-storage/csi-attacher:v3.4.0", + "registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.4.0", "registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.5.1", + "registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.6.2", + "registry.k8s.io/sig-storage/csi-provisioner:v3.0.0", "registry.k8s.io/sig-storage/csi-provisioner:v3.1.0", + "registry.k8s.io/sig-storage/csi-provisioner:v3.3.0", "registry.k8s.io/sig-storage/csi-resizer:v1.4.0", + "registry.k8s.io/sig-storage/csi-resizer:v1.8.0", + "registry.k8s.io/sig-storage/csi-snapshotter:v5.0.1", "registry.k8s.io/sig-storage/csi-snapshotter:v6.0.1", "registry.k8s.io/sig-storage/livenessprobe:v2.7.0", + "registry.k8s.io/sig-storage/livenessprobe:v2.8.0", ] diff --git a/magnum_cluster_api/conf.py b/magnum_cluster_api/conf.py index f77bc3b3..e10b4c79 100644 --- a/magnum_cluster_api/conf.py +++ b/magnum_cluster_api/conf.py @@ -12,8 +12,16 @@ # License for the specific language governing permissions and limitations # under the License. +from magnum.i18n import _ from oslo_config import cfg +auto_scaling_group = cfg.OptGroup(name="auto_scaling", title="Options for auto scaling") + +manila_client_group = cfg.OptGroup( + name="manila_client", title="Options for the Manila client" +) + + auto_scaling_opts = [ cfg.StrOpt( "image_repository", @@ -47,5 +55,47 @@ ), ] + +manila_client_opts = [ + cfg.StrOpt( + "region_name", + help=_( + "Region in Identity service catalog to use for " + "communication with the OpenStack service." + ), + ), + cfg.StrOpt( + "endpoint_type", + default="publicURL", + help=_( + "Type of endpoint in Identity service catalog to use " + "for communication with the OpenStack service." + ), + ), + cfg.StrOpt( + "api_version", + default="3", + help=_("Version of Manila API to use in manilaclient."), + ), +] + +common_security_opts = [ + cfg.StrOpt("ca_file", help=_("Optional CA cert file to use in SSL connections.")), + cfg.StrOpt("cert_file", help=_("Optional PEM-formatted certificate chain file.")), + cfg.StrOpt( + "key_file", + help=_("Optional PEM-formatted file that contains the " "private key."), + ), + cfg.BoolOpt( + "insecure", + default=False, + help=_("If set, then the server's certificate will not " "be verified."), + ), +] + CONF = cfg.CONF -CONF.register_opts(auto_scaling_opts, "auto_scaling") +CONF.register_group(auto_scaling_group) +CONF.register_group(manila_client_group) +CONF.register_opts(auto_scaling_opts, group=auto_scaling_group) +CONF.register_opts(manila_client_opts, group=manila_client_group) +CONF.register_opts(common_security_opts, group=manila_client_group) diff --git a/magnum_cluster_api/image_utils.py b/magnum_cluster_api/image_utils.py index efc795ea..ab695452 100644 --- a/magnum_cluster_api/image_utils.py +++ b/magnum_cluster_api/image_utils.py @@ -24,7 +24,7 @@ def update_manifest_images(cluster_uuid: str, file, repository=None, replacement docs = [] for doc in yaml.safe_load_all(data): # Fix container image paths - if doc["kind"] in ("DaemonSet", "Deployment"): + if doc["kind"] in ("DaemonSet", "Deployment", "StatefulSet"): for container in itertools.chain( doc["spec"]["template"]["spec"].get("initContainers", []), doc["spec"]["template"]["spec"]["containers"], @@ -63,6 +63,10 @@ def get_image(name: str, repository: str = None): new_image_name = name.replace("docker.io/k8scloudprovider", repository) if name.startswith("registry.k8s.io/sig-storage"): new_image_name = name.replace("registry.k8s.io/sig-storage", repository) + if name.startswith("registry.k8s.io/provider-os"): + new_image_name = name.replace("registry.k8s.io/provider-os", repository) + if name.startswith("gcr.io/k8s-staging-sig-storage"): + new_image_name = name.replace("gcr.io/k8s-staging-sig-storage", repository) if new_image_name.startswith(f"{repository}/livenessprobe"): return new_image_name.replace("livenessprobe", "csi-livenessprobe") if new_image_name.startswith("registry.k8s.io/coredns"): diff --git a/magnum_cluster_api/manifests/csi/cinder-csi-controllerplugin-rbac.yaml b/magnum_cluster_api/manifests/cinder-csi/cinder-csi-controllerplugin-rbac.yaml similarity index 100% rename from magnum_cluster_api/manifests/csi/cinder-csi-controllerplugin-rbac.yaml rename to magnum_cluster_api/manifests/cinder-csi/cinder-csi-controllerplugin-rbac.yaml diff --git a/magnum_cluster_api/manifests/csi/cinder-csi-controllerplugin.yaml b/magnum_cluster_api/manifests/cinder-csi/cinder-csi-controllerplugin.yaml similarity index 100% rename from magnum_cluster_api/manifests/csi/cinder-csi-controllerplugin.yaml rename to magnum_cluster_api/manifests/cinder-csi/cinder-csi-controllerplugin.yaml diff --git a/magnum_cluster_api/manifests/csi/cinder-csi-nodeplugin-rbac.yaml b/magnum_cluster_api/manifests/cinder-csi/cinder-csi-nodeplugin-rbac.yaml similarity index 100% rename from magnum_cluster_api/manifests/csi/cinder-csi-nodeplugin-rbac.yaml rename to magnum_cluster_api/manifests/cinder-csi/cinder-csi-nodeplugin-rbac.yaml diff --git a/magnum_cluster_api/manifests/csi/cinder-csi-nodeplugin.yaml b/magnum_cluster_api/manifests/cinder-csi/cinder-csi-nodeplugin.yaml similarity index 100% rename from magnum_cluster_api/manifests/csi/cinder-csi-nodeplugin.yaml rename to magnum_cluster_api/manifests/cinder-csi/cinder-csi-nodeplugin.yaml diff --git a/magnum_cluster_api/manifests/csi/csi-cinder-driver.yaml b/magnum_cluster_api/manifests/cinder-csi/csi-cinder-driver.yaml similarity index 100% rename from magnum_cluster_api/manifests/csi/csi-cinder-driver.yaml rename to magnum_cluster_api/manifests/cinder-csi/csi-cinder-driver.yaml diff --git a/magnum_cluster_api/manifests/manila-csi/csi-controllerplugin-rbac.yaml b/magnum_cluster_api/manifests/manila-csi/csi-controllerplugin-rbac.yaml new file mode 100644 index 00000000..968e7a59 --- /dev/null +++ b/magnum_cluster_api/manifests/manila-csi/csi-controllerplugin-rbac.yaml @@ -0,0 +1,196 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app: openstack-manila-csi + component: controllerplugin + name: openstack-manila-csi-controllerplugin + namespace: kube-system +--- +aggregationRule: + clusterRoleSelectors: + - matchLabels: + rbac.manila.csi.openstack.org/aggregate-to-openstack-manila-csi-controllerplugin: 'true' +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app: openstack-manila-csi + component: controllerplugin + name: openstack-manila-csi-controllerplugin +rules: [] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app: openstack-manila-csi + component: controllerplugin + rbac.manila.csi.openstack.org/aggregate-to-openstack-manila-csi-controllerplugin: 'true' + name: openstack-manila-csi-controllerplugin-rules +rules: +- apiGroups: + - '' + resources: + - nodes + verbs: + - get + - list + - watch +- apiGroups: + - '' + resources: + - secrets + verbs: + - get + - list +- apiGroups: + - '' + resources: + - persistentvolumes + verbs: + - get + - list + - watch + - create + - delete + - patch +- apiGroups: + - '' + resources: + - persistentvolumeclaims + verbs: + - get + - list + - watch + - update +- apiGroups: + - '' + resources: + - persistentvolumeclaims/status + verbs: + - patch +- apiGroups: + - '' + resources: + - events + verbs: + - list + - watch + - create + - update + - patch +- apiGroups: + - storage.k8s.io + resources: + - storageclasses + verbs: + - get + - list + - watch +- apiGroups: + - storage.k8s.io + resources: + - csinodes + verbs: + - get + - list + - watch +- apiGroups: + - snapshot.storage.k8s.io + resources: + - volumesnapshotclasses + verbs: + - get + - list + - watch +- apiGroups: + - snapshot.storage.k8s.io + resources: + - volumesnapshots + verbs: + - get + - list +- 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 +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app: openstack-manila-csi + component: controllerplugin + name: openstack-manila-csi-controllerplugin +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: openstack-manila-csi-controllerplugin +subjects: +- kind: ServiceAccount + name: openstack-manila-csi-controllerplugin + namespace: kube-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app: openstack-manila-csi + component: controllerplugin + name: openstack-manila-csi-controllerplugin + namespace: kube-system +rules: +- apiGroups: + - '' + resources: + - endpoints + verbs: + - get + - watch + - list + - delete + - update + - create +- apiGroups: + - '' + resources: + - configmaps + verbs: + - get + - list + - watch + - create + - delete +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app: openstack-manila-csi + component: controllerplugin + name: openstack-manila-csi-controllerplugin + namespace: kube-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: openstack-manila-csi-controllerplugin +subjects: +- kind: ServiceAccount + name: openstack-manila-csi-controllerplugin + namespace: kube-system diff --git a/magnum_cluster_api/manifests/manila-csi/csi-controllerplugin.yaml b/magnum_cluster_api/manifests/manila-csi/csi-controllerplugin.yaml new file mode 100644 index 00000000..338ec7ba --- /dev/null +++ b/magnum_cluster_api/manifests/manila-csi/csi-controllerplugin.yaml @@ -0,0 +1,121 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app: openstack-manila-csi + component: controllerplugin + name: openstack-manila-csi-controllerplugin + namespace: kube-system +spec: + ports: + - name: dummy + port: 12345 + selector: + app: openstack-manila-csi + component: controllerplugin +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + labels: + app: openstack-manila-csi + component: controllerplugin + name: openstack-manila-csi-controllerplugin + namespace: kube-system +spec: + replicas: 1 + selector: + matchLabels: + app: openstack-manila-csi + component: controllerplugin + serviceName: openstack-manila-csi-controllerplugin + template: + metadata: + labels: + app: openstack-manila-csi + component: controllerplugin + spec: + containers: + - args: + - --csi-address=$(ADDRESS) + env: + - name: ADDRESS + value: unix:///var/lib/kubelet/plugins/manila.csi.openstack.org/csi-controllerplugin.sock + image: registry.k8s.io/sig-storage/csi-provisioner:v3.0.0 + imagePullPolicy: IfNotPresent + name: provisioner + volumeMounts: + - mountPath: /var/lib/kubelet/plugins/manila.csi.openstack.org + name: plugin-dir + - args: + - --csi-address=$(ADDRESS) + env: + - name: ADDRESS + value: unix:///var/lib/kubelet/plugins/manila.csi.openstack.org/csi-controllerplugin.sock + image: registry.k8s.io/sig-storage/csi-snapshotter:v5.0.1 + imagePullPolicy: IfNotPresent + name: snapshotter + volumeMounts: + - mountPath: /var/lib/kubelet/plugins/manila.csi.openstack.org + name: plugin-dir + - args: + - --csi-address=$(ADDRESS) + - --handle-volume-inuse-error=false + env: + - name: ADDRESS + value: unix:///var/lib/kubelet/plugins/manila.csi.openstack.org/csi-controllerplugin.sock + image: registry.k8s.io/sig-storage/csi-resizer:v1.8.0 + imagePullPolicy: IfNotPresent + name: resizer + volumeMounts: + - mountPath: /var/lib/kubelet/plugins/manila.csi.openstack.org + name: plugin-dir + - command: + - /bin/sh + - -c + - /bin/manila-csi-plugin --nodeid=$(NODE_ID) --endpoint=$(CSI_ENDPOINT) --drivername=$(DRIVER_NAME) + --share-protocol-selector=$(MANILA_SHARE_PROTO) --fwdendpoint=$(FWD_CSI_ENDPOINT) + env: + - name: DRIVER_NAME + value: manila.csi.openstack.org + - name: NODE_ID + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: CSI_ENDPOINT + value: unix:///var/lib/kubelet/plugins/manila.csi.openstack.org/csi-controllerplugin.sock + - name: FWD_CSI_ENDPOINT + value: unix:///var/lib/kubelet/plugins/csi-nfsplugin/csi.sock + - name: MANILA_SHARE_PROTO + value: NFS + image: registry.k8s.io/provider-os/manila-csi-plugin:latest + imagePullPolicy: IfNotPresent + name: nodeplugin + securityContext: + allowPrivilegeEscalation: true + capabilities: + add: + - SYS_ADMIN + privileged: true + volumeMounts: + - mountPath: /var/lib/kubelet/plugins/manila.csi.openstack.org + name: plugin-dir + - mountPath: /var/lib/kubelet/plugins/csi-nfsplugin + name: fwd-plugin-dir + - mountPath: /var/lib/kubelet/pods + mountPropagation: Bidirectional + name: pod-mounts + serviceAccountName: openstack-manila-csi-controllerplugin + volumes: + - hostPath: + path: /var/lib/kubelet/plugins/manila.csi.openstack.org + type: DirectoryOrCreate + name: plugin-dir + - hostPath: + path: /var/lib/kubelet/plugins/csi-nfsplugin + type: Directory + name: fwd-plugin-dir + - hostPath: + path: /var/lib/kubelet/pods + type: Directory + name: pod-mounts diff --git a/magnum_cluster_api/manifests/manila-csi/csi-nodeplugin-rbac.yaml b/magnum_cluster_api/manifests/manila-csi/csi-nodeplugin-rbac.yaml new file mode 100644 index 00000000..f946e6a3 --- /dev/null +++ b/magnum_cluster_api/manifests/manila-csi/csi-nodeplugin-rbac.yaml @@ -0,0 +1,78 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app: openstack-manila-csi + component: nodeplugin + name: openstack-manila-csi-nodeplugin + namespace: kube-system +--- +aggregationRule: + clusterRoleSelectors: + - matchLabels: + rbac.manila.csi.openstack.org/aggregate-to-openstack-manila-csi-nodeplugin: 'true' +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app: openstack-manila-csi + component: nodeplugin + name: openstack-manila-csi-nodeplugin +rules: [] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app: openstack-manila-csi + component: nodeplugin + rbac.manila.csi.openstack.org/aggregate-to-openstack-manila-csi-nodeplugin: 'true' + name: openstack-manila-csi-nodeplugin-rules +rules: +- apiGroups: + - '' + resources: + - configmaps + verbs: + - get + - list +- apiGroups: + - '' + resources: + - nodes + verbs: + - get + - list + - update +- apiGroups: + - '' + resources: + - namespaces + verbs: + - get + - list +- apiGroups: + - '' + resources: + - persistentvolumes + verbs: + - get + - list + - watch + - update +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app: openstack-manila-csi + component: nodeplugin + name: openstack-manila-csi-nodeplugin +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: openstack-manila-csi-nodeplugin +subjects: +- kind: ServiceAccount + name: openstack-manila-csi-nodeplugin + namespace: kube-system diff --git a/magnum_cluster_api/manifests/manila-csi/csi-nodeplugin.yaml b/magnum_cluster_api/manifests/manila-csi/csi-nodeplugin.yaml new file mode 100644 index 00000000..cbe0a532 --- /dev/null +++ b/magnum_cluster_api/manifests/manila-csi/csi-nodeplugin.yaml @@ -0,0 +1,93 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + labels: + app: openstack-manila-csi + component: nodeplugin + name: openstack-manila-csi-nodeplugin + namespace: kube-system +spec: + selector: + matchLabels: + app: openstack-manila-csi + component: nodeplugin + template: + metadata: + labels: + app: openstack-manila-csi + component: nodeplugin + spec: + containers: + - args: + - --csi-address=/csi/csi.sock + - --kubelet-registration-path=/var/lib/kubelet/plugins/manila.csi.openstack.org/csi.sock + env: + - name: KUBE_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + image: registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.4.0 + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + exec: + command: + - /bin/sh + - -c + - rm -rf /registration/manila.csi.openstack.org /registration/manila.csi.openstack.org-reg.sock + name: registrar + volumeMounts: + - mountPath: /csi + name: plugin-dir + - mountPath: /registration + name: registration-dir + - command: + - /bin/sh + - -c + - /bin/manila-csi-plugin --nodeid=$(NODE_ID) --endpoint=$(CSI_ENDPOINT) --drivername=$(DRIVER_NAME) + --share-protocol-selector=$(MANILA_SHARE_PROTO) --fwdendpoint=$(FWD_CSI_ENDPOINT) + env: + - name: DRIVER_NAME + value: manila.csi.openstack.org + - name: NODE_ID + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: CSI_ENDPOINT + value: unix:///var/lib/kubelet/plugins/manila.csi.openstack.org/csi.sock + - name: FWD_CSI_ENDPOINT + value: unix:///var/lib/kubelet/plugins/csi-nfsplugin/csi.sock + - name: MANILA_SHARE_PROTO + value: NFS + image: registry.k8s.io/provider-os/manila-csi-plugin:latest + imagePullPolicy: IfNotPresent + name: nodeplugin + securityContext: + allowPrivilegeEscalation: true + capabilities: + add: + - SYS_ADMIN + privileged: true + volumeMounts: + - mountPath: /var/lib/kubelet/plugins/manila.csi.openstack.org + name: plugin-dir + - mountPath: /var/lib/kubelet/plugins/csi-nfsplugin + name: fwd-plugin-dir + dnsPolicy: ClusterFirstWithHostNet + hostNetwork: true + serviceAccountName: openstack-manila-csi-nodeplugin + tolerations: + - operator: Exists + volumes: + - hostPath: + path: /var/lib/kubelet/plugins_registry + type: Directory + name: registration-dir + - hostPath: + path: /var/lib/kubelet/plugins/manila.csi.openstack.org + type: DirectoryOrCreate + name: plugin-dir + - hostPath: + path: /var/lib/kubelet/plugins/csi-nfsplugin + type: DirectoryOrCreate + name: fwd-plugin-dir diff --git a/magnum_cluster_api/manifests/manila-csi/csidriver.yaml b/magnum_cluster_api/manifests/manila-csi/csidriver.yaml new file mode 100644 index 00000000..6bbbf48d --- /dev/null +++ b/magnum_cluster_api/manifests/manila-csi/csidriver.yaml @@ -0,0 +1,7 @@ +apiVersion: storage.k8s.io/v1 +kind: CSIDriver +metadata: + name: manila.csi.openstack.org +spec: + attachRequired: false + podInfoOnMount: false diff --git a/magnum_cluster_api/manifests/nfs-csi/csi-nfs-controller.yaml b/magnum_cluster_api/manifests/nfs-csi/csi-nfs-controller.yaml new file mode 100644 index 00000000..1ca83423 --- /dev/null +++ b/magnum_cluster_api/manifests/nfs-csi/csi-nfs-controller.yaml @@ -0,0 +1,119 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: csi-nfs-controller + namespace: kube-system +spec: + replicas: 1 + selector: + matchLabels: + app: csi-nfs-controller + template: + metadata: + labels: + app: csi-nfs-controller + spec: + containers: + - args: + - -v=2 + - --csi-address=$(ADDRESS) + - --leader-election + - --leader-election-namespace=kube-system + - --extra-create-metadata=true + env: + - name: ADDRESS + value: /csi/csi.sock + image: registry.k8s.io/sig-storage/csi-provisioner:v3.3.0 + name: csi-provisioner + resources: + limits: + memory: 400Mi + requests: + cpu: 10m + memory: 20Mi + volumeMounts: + - mountPath: /csi + name: socket-dir + - args: + - --csi-address=/csi/csi.sock + - --probe-timeout=3s + - --health-port=29652 + - --v=2 + image: registry.k8s.io/sig-storage/livenessprobe:v2.8.0 + name: liveness-probe + resources: + limits: + memory: 100Mi + requests: + cpu: 10m + memory: 20Mi + volumeMounts: + - mountPath: /csi + name: socket-dir + - args: + - -v=5 + - --nodeid=$(NODE_ID) + - --endpoint=$(CSI_ENDPOINT) + env: + - name: NODE_ID + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: CSI_ENDPOINT + value: unix:///csi/csi.sock + image: registry.k8s.io/sig-storage/nfsplugin:v4.2.0 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 5 + httpGet: + path: /healthz + port: healthz + initialDelaySeconds: 30 + periodSeconds: 30 + timeoutSeconds: 10 + name: nfs + ports: + - containerPort: 29652 + name: healthz + protocol: TCP + resources: + limits: + memory: 200Mi + requests: + cpu: 10m + memory: 20Mi + securityContext: + allowPrivilegeEscalation: true + capabilities: + add: + - SYS_ADMIN + privileged: true + volumeMounts: + - mountPath: /var/lib/kubelet/pods + mountPropagation: Bidirectional + name: pods-mount-dir + - mountPath: /csi + name: socket-dir + dnsPolicy: Default + hostNetwork: true + nodeSelector: + kubernetes.io/os: linux + priorityClassName: system-cluster-critical + serviceAccountName: csi-nfs-controller-sa + tolerations: + - effect: NoSchedule + key: node-role.kubernetes.io/master + operator: Exists + - effect: NoSchedule + key: node-role.kubernetes.io/controlplane + operator: Exists + - effect: NoSchedule + key: node-role.kubernetes.io/control-plane + operator: Exists + volumes: + - hostPath: + path: /var/lib/kubelet/pods + type: Directory + name: pods-mount-dir + - emptyDir: {} + name: socket-dir diff --git a/magnum_cluster_api/manifests/nfs-csi/csi-nfs-driverinfo.yaml b/magnum_cluster_api/manifests/nfs-csi/csi-nfs-driverinfo.yaml new file mode 100644 index 00000000..fc933360 --- /dev/null +++ b/magnum_cluster_api/manifests/nfs-csi/csi-nfs-driverinfo.yaml @@ -0,0 +1,9 @@ +apiVersion: storage.k8s.io/v1 +kind: CSIDriver +metadata: + name: nfs.csi.k8s.io +spec: + attachRequired: false + fsGroupPolicy: File + volumeLifecycleModes: + - Persistent diff --git a/magnum_cluster_api/manifests/nfs-csi/csi-nfs-node.yaml b/magnum_cluster_api/manifests/nfs-csi/csi-nfs-node.yaml new file mode 100644 index 00000000..9a543c94 --- /dev/null +++ b/magnum_cluster_api/manifests/nfs-csi/csi-nfs-node.yaml @@ -0,0 +1,131 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: csi-nfs-node + namespace: kube-system +spec: + selector: + matchLabels: + app: csi-nfs-node + template: + metadata: + labels: + app: csi-nfs-node + spec: + containers: + - args: + - --csi-address=/csi/csi.sock + - --probe-timeout=3s + - --health-port=29653 + - --v=2 + image: registry.k8s.io/sig-storage/livenessprobe:v2.8.0 + name: liveness-probe + resources: + limits: + memory: 100Mi + requests: + cpu: 10m + memory: 20Mi + volumeMounts: + - mountPath: /csi + name: socket-dir + - args: + - --v=2 + - --csi-address=/csi/csi.sock + - --kubelet-registration-path=$(DRIVER_REG_SOCK_PATH) + env: + - name: DRIVER_REG_SOCK_PATH + value: /var/lib/kubelet/plugins/csi-nfsplugin/csi.sock + - name: KUBE_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + image: registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.6.2 + livenessProbe: + exec: + command: + - /csi-node-driver-registrar + - --kubelet-registration-path=$(DRIVER_REG_SOCK_PATH) + - --mode=kubelet-registration-probe + initialDelaySeconds: 30 + timeoutSeconds: 15 + name: node-driver-registrar + resources: + limits: + memory: 100Mi + requests: + cpu: 10m + memory: 20Mi + volumeMounts: + - mountPath: /csi + name: socket-dir + - mountPath: /registration + name: registration-dir + - args: + - -v=5 + - --nodeid=$(NODE_ID) + - --endpoint=$(CSI_ENDPOINT) + env: + - name: NODE_ID + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: CSI_ENDPOINT + value: unix:///csi/csi.sock + image: registry.k8s.io/sig-storage/nfsplugin:v4.2.0 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 5 + httpGet: + path: /healthz + port: healthz + initialDelaySeconds: 30 + periodSeconds: 30 + timeoutSeconds: 10 + name: nfs + ports: + - containerPort: 29653 + name: healthz + protocol: TCP + resources: + limits: + memory: 300Mi + requests: + cpu: 10m + memory: 20Mi + securityContext: + allowPrivilegeEscalation: true + capabilities: + add: + - SYS_ADMIN + privileged: true + volumeMounts: + - mountPath: /csi + name: socket-dir + - mountPath: /var/lib/kubelet/pods + mountPropagation: Bidirectional + name: pods-mount-dir + dnsPolicy: Default + hostNetwork: true + nodeSelector: + kubernetes.io/os: linux + serviceAccountName: csi-nfs-node-sa + tolerations: + - operator: Exists + volumes: + - hostPath: + path: /var/lib/kubelet/plugins/csi-nfsplugin + type: DirectoryOrCreate + name: socket-dir + - hostPath: + path: /var/lib/kubelet/pods + type: Directory + name: pods-mount-dir + - hostPath: + path: /var/lib/kubelet/plugins_registry + type: Directory + name: registration-dir + updateStrategy: + rollingUpdate: + maxUnavailable: 1 + type: RollingUpdate diff --git a/magnum_cluster_api/manifests/nfs-csi/rbac-csi-nfs.yaml b/magnum_cluster_api/manifests/nfs-csi/rbac-csi-nfs.yaml new file mode 100644 index 00000000..2c304a17 --- /dev/null +++ b/magnum_cluster_api/manifests/nfs-csi/rbac-csi-nfs.yaml @@ -0,0 +1,101 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: csi-nfs-controller-sa + namespace: kube-system +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: csi-nfs-node-sa + namespace: kube-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: nfs-external-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: + - get + - list + - watch + - create + - update + - patch +- apiGroups: + - storage.k8s.io + resources: + - csinodes + verbs: + - get + - list + - watch +- apiGroups: + - '' + resources: + - nodes + verbs: + - get + - list + - watch +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - list + - watch + - create + - update + - patch +- apiGroups: + - '' + resources: + - secrets + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: nfs-csi-provisioner-binding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: nfs-external-provisioner-role +subjects: +- kind: ServiceAccount + name: csi-nfs-controller-sa + namespace: kube-system diff --git a/magnum_cluster_api/resources.py b/magnum_cluster_api/resources.py index 5ea5cde0..844dbc2b 100644 --- a/magnum_cluster_api/resources.py +++ b/magnum_cluster_api/resources.py @@ -35,7 +35,8 @@ CONF = cfg.CONF CLOUD_PROVIDER_TAG = "v1.25.3" CALICO_TAG = "v3.24.2" -CSI_TAG = "v1.25.3" +CINDER_CSI_TAG = "v1.25.3" +MANILA_CSI_TAG = "v1.25.3" CLUSTER_CLASS_VERSION = pkg_resources.require("magnum_cluster_api")[0].version CLUSTER_CLASS_NAME = f"magnum-v{CLUSTER_CLASS_VERSION}" @@ -163,93 +164,183 @@ def get_object(self) -> pykube.ConfigMap: ccm_version = utils.get_cluster_label( self.cluster, "cloud_provider_tag", CLOUD_PROVIDER_TAG ) - csi_version = utils.get_cluster_label( - self.cluster, "cinder_csi_plugin_tag", CSI_TAG - ) repository = utils.get_cluster_container_infra_prefix(self.cluster) osc = clients.get_openstack_api(self.context) - volume_types = osc.cinder().volume_types.list() - default_volume_type = osc.cinder().volume_types.default() - return pykube.ConfigMap( - self.api, - { - "apiVersion": pykube.ConfigMap.version, - "kind": pykube.ConfigMap.kind, - "metadata": { - "name": self.cluster.uuid, - "namespace": "magnum-system", + data = { + **{ + os.path.basename(manifest): image_utils.update_manifest_images( + self.cluster.uuid, + manifest, + repository=repository, + replacements=[ + ( + "docker.io/k8scloudprovider/openstack-cloud-controller-manager:latest", + f"docker.io/k8scloudprovider/openstack-cloud-controller-manager:{ccm_version}", + ), + ], + ) + for manifest in glob.glob(os.path.join(manifests_path, "ccm/*.yaml")) + }, + **{ + "calico.yml": image_utils.update_manifest_images( + self.cluster.uuid, + os.path.join(manifests_path, f"calico/{calico_version}.yaml"), + repository=repository, + ) + }, + } + + if utils.is_cinder_csi_enabled(self.cluster): + volume_types = osc.cinder().volume_types.list() + default_volume_type = osc.cinder().volume_types.default() + csi_version = utils.get_cluster_label( + self.cluster, "cinder_csi_plugin_tag", CINDER_CSI_TAG + ) + data = { + **data, + **{ + os.path.basename(manifest): image_utils.update_manifest_images( + self.cluster.uuid, + manifest, + repository=repository, + replacements=[ + ( + "docker.io/k8scloudprovider/cinder-csi-plugin:latest", + f"docker.io/k8scloudprovider/cinder-csi-plugin:{csi_version}", + ), + ], + ) + for manifest in glob.glob( + os.path.join(manifests_path, "cinder-csi/*.yaml") + ) }, - "data": { - **{ - os.path.basename(manifest): image_utils.update_manifest_images( - self.cluster.uuid, - manifest, - repository=repository, - replacements=[ - ( - "docker.io/k8scloudprovider/openstack-cloud-controller-manager:latest", - f"docker.io/k8scloudprovider/openstack-cloud-controller-manager:{ccm_version}", - ), - ], - ) - for manifest in glob.glob( - os.path.join(manifests_path, "ccm/*.yaml") - ) - }, - **{ - os.path.basename(manifest): image_utils.update_manifest_images( - self.cluster.uuid, - manifest, - repository=repository, - replacements=[ - ( - "docker.io/k8scloudprovider/cinder-csi-plugin:latest", - f"docker.io/k8scloudprovider/cinder-csi-plugin:{csi_version}", - ), - ], - ) - for manifest in glob.glob( - os.path.join(manifests_path, "csi/*.yaml") - ) - }, - **{ - "calico.yml": image_utils.update_manifest_images( - self.cluster.uuid, - os.path.join( - manifests_path, f"calico/{calico_version}.yaml" + **{ + f"storageclass-cinder-{vt.name}.yaml": yaml.dump( + { + "apiVersion": objects.StorageClass.version, + "allowVolumeExpansion": True, + "kind": objects.StorageClass.kind, + "metadata": { + "annotations": { + "storageclass.kubernetes.io/is-default-class": "true" + } + if default_volume_type.name == vt.name + else {}, + "name": "cinder-%s" % vt.name.lower(), + }, + "provisioner": "kubernetes.io/cinder", + "parameters": { + "type": vt.name, + }, + "reclaimPolicy": "Delete", + "volumeBindingMode": "Immediate", + } + ) + for vt in volume_types + if vt.name != "__DEFAULT__" + }, + } + + if utils.is_manila_csi_enabled(self.cluster): + share_types = osc.manila().share_types.list() + csi_version = utils.get_cluster_label( + self.cluster, "manila_csi_plugin_tag", MANILA_CSI_TAG + ) + share_network_id = utils.get_cluster_label( + self.cluster, "manila_csi_share_network_id", None + ) + data = { + **data, + **{ + "manila-csi-secret.yaml": yaml.dump( + { + "apiVersion": pykube.Secret.version, + "kind": pykube.Secret.kind, + "metadata": { + "name": "csi-manila-secrets", + "namespace": "kube-system", + }, + "stringData": utils.generate_manila_csi_cloud_config( + self.api, + self.cluster, ), - repository=repository, - ) - }, + }, + ) + }, + **{ + os.path.basename(manifest): image_utils.update_manifest_images( + self.cluster.uuid, + manifest, + repository=repository, + ) + for manifest in glob.glob( + os.path.join(manifests_path, "nfs-csi/*.yaml") + ) + }, + **{ + os.path.basename(manifest): image_utils.update_manifest_images( + self.cluster.uuid, + manifest, + repository=repository, + replacements=[ + ( + "registry.k8s.io/provider-os/manila-csi-plugin:latest", + f"registry.k8s.io/provider-os/manila-csi-plugin:{csi_version}", + ), + ], + ) + for manifest in glob.glob( + os.path.join(manifests_path, "manila-csi/*.yaml") + ) + }, + } + # NOTE: We only create StorageClasses if share_network_id specified. + if share_network_id: + data = { + **data, **{ - f"storageclass-{vt.name}.yaml": yaml.dump( + f"storageclass-manila-{st.name}.yaml": yaml.dump( { "apiVersion": objects.StorageClass.version, "allowVolumeExpansion": True, "kind": objects.StorageClass.kind, "metadata": { - "annotations": { - "storageclass.kubernetes.io/is-default-class": "true" - } - if default_volume_type.name == vt.name - else {}, - "name": vt.name.lower(), + "name": "manila-%s" % st.name.lower(), }, - "provisioner": "kubernetes.io/cinder", + "provisioner": "manila.csi.openstack.org", "parameters": { - "type": vt.name, + "type": st.name, + "shareNetworkID": share_network_id, + "csi.storage.k8s.io/provisioner-secret-name": "csi-manila-secrets", + "csi.storage.k8s.io/provisioner-secret-namespace": "kube-system", + "csi.storage.k8s.io/controller-expand-secret-name": "csi-manila-secrets", + "csi.storage.k8s.io/controller-expand-secret-namespace": "kube-system", + "csi.storage.k8s.io/node-stage-secret-name": "csi-manila-secrets", + "csi.storage.k8s.io/node-stage-secret-namespace": "kube-system", + "csi.storage.k8s.io/node-publish-secret-name": "csi-manila-secrets", + "csi.storage.k8s.io/node-publish-secret-namespace": "kube-system", }, "reclaimPolicy": "Delete", "volumeBindingMode": "Immediate", } ) - for vt in volume_types - if vt.name != "__DEFAULT__" + for st in share_types }, + } + + return pykube.ConfigMap( + self.api, + { + "apiVersion": pykube.ConfigMap.version, + "kind": pykube.ConfigMap.kind, + "metadata": { + "name": self.cluster.uuid, + "namespace": "magnum-system", }, + "data": data, }, ) @@ -1334,13 +1425,19 @@ def labels(self) -> dict: "ccm": f"openstack-cloud-controller-manager-{ccm_version}", } - if utils.get_cluster_label_as_bool(self.cluster, "cinder_csi_enabled", True): + if utils.is_cinder_csi_enabled(self.cluster): csi_version = utils.get_cluster_label( - self.cluster, "cinder_csi_plugin_tag", CSI_TAG + self.cluster, "cinder_csi_plugin_tag", CINDER_CSI_TAG ) labels["csi"] = "cinder" labels["cinder-csi-version"] = csi_version + if utils.is_manila_csi_enabled(self.cluster): + manila_version = utils.get_cluster_label( + self.cluster, "manila_csi_plugin_tag", MANILA_CSI_TAG + ) + labels["manila-csi-version"] = manila_version + return {**super().labels, **labels} def get_or_none(self) -> objects.Cluster: diff --git a/magnum_cluster_api/utils.py b/magnum_cluster_api/utils.py index fae46002..d2ef9d43 100644 --- a/magnum_cluster_api/utils.py +++ b/magnum_cluster_api/utils.py @@ -21,12 +21,16 @@ import yaml from magnum import objects as magnum_objects from magnum.common import context, exception, octavia +from magnum.common.keystone import KeystoneClientV3 +from oslo_log import log as logging from oslo_serialization import base64 from oslo_utils import strutils from tenacity import retry, retry_if_exception_type from magnum_cluster_api import clients, image_utils, images, objects +LOG = logging.getLogger(__name__) + def get_or_generate_cluster_api_cloud_config_secret_name( api: pykube.HTTPClient, cluster: magnum_objects.Cluster @@ -90,6 +94,34 @@ def generate_cloud_controller_manager_config( ) +def generate_manila_csi_cloud_config( + api: pykube.HTTPClient, + cluster: magnum_objects.Cluster, +) -> str: + """ + Generate coniguration of Openstack authentication for manila csi + """ + data = pykube.Secret.objects(api, namespace="magnum-system").get_by_name( + get_or_generate_cluster_api_cloud_config_secret_name(api, cluster) + ) + clouds_yaml = base64.decode_as_text(data.obj["data"]["clouds.yaml"]) + cloud_config = yaml.safe_load(clouds_yaml) + + return { + "os-authURL": cloud_config["clouds"]["default"]["auth"]["auth_url"], + "os-region": cloud_config["clouds"]["default"]["region_name"], + "os-applicationCredentialID": cloud_config["clouds"]["default"]["auth"][ + "application_credential_id" + ], + "os-applicationCredentialSecret": cloud_config["clouds"]["default"]["auth"][ + "application_credential_secret" + ], + "os-TLSInsecure": "false" + if cloud_config["clouds"]["default"]["verify"] + else "true", + } + + def get_kube_tag(cluster: magnum_objects.Cluster) -> str: return get_cluster_label(cluster, "kube_tag", "v1.25.3") @@ -233,3 +265,56 @@ def delete_loadbalancers(ctx, cluster): octavia.wait_for_lb_deleted(octavia_client, candidates) except Exception as e: raise exception.PreDeletionFailed(cluster_uuid=cluster.uuid, msg=str(e)) + + +def is_cinder_enabled(): + """Check if Cinder service is deployed in the cloud.""" + + admin_context = context.make_admin_context() + keystone = KeystoneClientV3(admin_context) + + try: + cinder_svc = keystone.client.services.list(type="volumev3") + except Exception: + LOG.exception("Failed to list services") + raise exception.ServicesListFailed() + + # Always assume there is only one load balancing service configured. + if cinder_svc and cinder_svc[0].enabled: + return True + + LOG.info("There is no volumev3 service enabled in the cloud.") + return False + + +def is_manila_enabled(): + """Check if Manila service is deployed in the cloud.""" + + admin_context = context.make_admin_context() + keystone = KeystoneClientV3(admin_context) + + try: + manila_svc = keystone.client.services.list(type="sharev2") + except Exception: + LOG.exception("Failed to list services") + raise exception.ServicesListFailed() + + if manila_svc and manila_svc[0].enabled: + return True + + LOG.info("There is no sharev2 service enabled in the cloud.") + return False + + +def is_cinder_csi_enabled(cluster: magnum_objects.Cluster) -> bool: + return ( + get_cluster_label_as_bool(cluster, "cinder_csi_enabled", True) + and is_cinder_enabled() + ) + + +def is_manila_csi_enabled(cluster: magnum_objects.Cluster) -> bool: + return ( + get_cluster_label_as_bool(cluster, "manila_csi_enabled", True) + and is_manila_enabled() + ) diff --git a/poetry.lock b/poetry.lock index e0a7958e..3d579fd5 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1828,23 +1828,17 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "prettytable" -version = "2.5.0" -description = "A simple Python library for easily displaying tabular data in a visually appealing ASCII table format" +version = "0.7.2" +description = "A simple Python library for easily displaying tabular data in a visually appealing ASCII table format." category = "main" optional = false -python-versions = ">=3.6" +python-versions = "*" files = [ - {file = "prettytable-2.5.0-py3-none-any.whl", hash = "sha256:1411c65d21dca9eaa505ba1d041bed75a6d629ae22f5109a923f4e719cfecba4"}, - {file = "prettytable-2.5.0.tar.gz", hash = "sha256:f7da57ba63d55116d65e5acb147bfdfa60dceccabf0d607d6817ee2888a05f2c"}, + {file = "prettytable-0.7.2.tar.bz2", hash = "sha256:853c116513625c738dc3ce1aee148b5b5757a86727e67eff6502c7ca59d43c36"}, + {file = "prettytable-0.7.2.tar.gz", hash = "sha256:2d5460dc9db74a32bcc8f9f67de68b2c4f4d2f01fa3bd518764c69156d9cacd9"}, + {file = "prettytable-0.7.2.zip", hash = "sha256:a53da3b43d7a5c229b5e3ca2892ef982c46b7923b51e98f0db49956531211c4f"}, ] -[package.dependencies] -importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} -wcwidth = "*" - -[package.extras] -tests = ["pytest", "pytest-cov", "pytest-lazy-fixture"] - [[package]] name = "prometheus-client" version = "0.16.0" @@ -2259,6 +2253,32 @@ requests = ">=2.14.2" six = ">=1.10.0" stevedore = ">=1.20.0" +[[package]] +name = "python-manilaclient" +version = "3.4.0" +description = "Client library for OpenStack Manila API." +category = "main" +optional = false +python-versions = ">=3.6" +files = [ + {file = "python-manilaclient-3.4.0.tar.gz", hash = "sha256:178d7f93b3498a0c05370dbde3ab23ddd6432831fe3e480e8e49a5f6ddcc82dc"}, + {file = "python_manilaclient-3.4.0-py3-none-any.whl", hash = "sha256:0ce99a63922d5c91a4380cc77135295bce8fbadaff3b01b694d21caa4698723d"}, +] + +[package.dependencies] +Babel = ">=2.3.4,<2.4.0 || >2.4.0" +debtcollector = ">=1.2.0" +osc-lib = ">=1.10.0" +"oslo.config" = ">=5.2.0" +"oslo.log" = ">=3.36.0" +"oslo.serialization" = ">=2.18.0,<2.19.1 || >2.19.1" +"oslo.utils" = ">=3.33.0" +pbr = ">=2.0.0,<2.1.0 || >2.1.0" +PrettyTable = ">=0.7.1" +python-keystoneclient = ">=3.8.0" +requests = ">=2.14.2" +simplejson = ">=3.5.1" + [[package]] name = "python-neutronclient" version = "7.8.0" @@ -3298,4 +3318,4 @@ testing = ["func-timeout", "jaraco.itertools", "pytest (>=4.6)", "pytest-black ( [metadata] lock-version = "2.0" python-versions = "^3.6" -content-hash = "425ba2d0c191127787a20b8d902e6b5567bb293f57e2fbc2a18a5b9c15d6f87a" +content-hash = "28731eafe7a19ea37e086bc04e61a0f42cea95caabf23565f5e93e902598c9a1" diff --git a/pyproject.toml b/pyproject.toml index e3410f46..f2bed036 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,6 +20,7 @@ magnum = ">=14.0.0" pykube-ng = "*" pyroute2 = ">=0.3.4" python = "^3.6" +"python-manilaclient" = ">=3.3.2" requests = ">=2.27.1" semver = "^2.0.0" shortuuid = "*" diff --git a/tools/sync-csi-manifests b/tools/sync-cinder-csi-manifests old mode 100755 new mode 100644 similarity index 97% rename from tools/sync-csi-manifests rename to tools/sync-cinder-csi-manifests index ef8ee959..30819f24 --- a/tools/sync-csi-manifests +++ b/tools/sync-cinder-csi-manifests @@ -82,5 +82,5 @@ for manifest in MANIFESTS: else: docs.append(doc) - with open(f"magnum_cluster_api/manifests/csi/{manifest}", "w") as fd: + with open(f"magnum_cluster_api/manifests/cinder-csi/{manifest}", "w") as fd: yaml.dump_all(docs, fd, default_flow_style=False) diff --git a/tools/sync-manila-csi-manifests b/tools/sync-manila-csi-manifests new file mode 100644 index 00000000..d3b7f56c --- /dev/null +++ b/tools/sync-manila-csi-manifests @@ -0,0 +1,90 @@ +#!/usr/bin/env python3 + +# Copyright (c) 2023 VEXXHOST, Inc. +# +# 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. + +# This script is used to sync the CCM manifests from the CCM repo to the +# manifests folder. + +import requests +import yaml + +MANIFESTS = set( + [ + "csi-controllerplugin-rbac.yaml", + "csi-controllerplugin.yaml", + "csi-nodeplugin-rbac.yaml", + "csi-nodeplugin.yaml", + "csidriver.yaml", + ] +) + + +def set_namespace(doc, namespace="kube-system"): + cluster_scope_kinds = [ + "ClusterRole", + "ClusterRoleBinding", + "CSIDriver", + "List", + ] + binding_kinds = [ + "ClusterRoleBinding", + "RoleBinding", + ] + if doc["kind"] not in cluster_scope_kinds: + doc["metadata"]["namespace"] = namespace + + if doc["kind"] in binding_kinds: + for item in doc["subjects"]: + item["namespace"] = namespace + return doc + + +for manifest in MANIFESTS: + url = f"https://raw.githubusercontent.com/kubernetes/cloud-provider-openstack/master/manifests/manila-csi-plugin/{manifest}" # noqa E501 + + docs = [] + r = requests.get(url) + + for doc in yaml.safe_load_all(r.text): + if doc["kind"] == "StatefulSet": + doc["spec"]["template"]["spec"]["containers"][3]["env"][3][ + "value" + ] = "unix:///var/lib/kubelet/plugins/csi-nfsplugin/csi.sock" + doc["spec"]["template"]["spec"]["containers"][3]["env"][4]["value"] = "NFS" + doc["spec"]["template"]["spec"]["containers"][3]["image"] = "registry.k8s.io/provider-os/manila-csi-plugin:latest" + doc["spec"]["template"]["spec"]["containers"][3]["volumeMounts"][1]["mountPath"] = "/var/lib/kubelet/plugins/csi-nfsplugin" + doc["spec"]["template"]["spec"]["volumes"][1]["hostPath"]["path"] = "/var/lib/kubelet/plugins/csi-nfsplugin" + + + if doc["kind"] == "DaemonSet": + doc["spec"]["template"]["spec"]["containers"][1]["env"][3][ + "value" + ] = "unix:///var/lib/kubelet/plugins/csi-nfsplugin/csi.sock" + doc["spec"]["template"]["spec"]["containers"][1]["env"][4]["value"] = "NFS" + doc["spec"]["template"]["spec"]["containers"][1]["image"] = "registry.k8s.io/provider-os/manila-csi-plugin:latest" + # Set FWD plugin + doc["spec"]["template"]["spec"]["containers"][1]["volumeMounts"][1]["mountPath"] = "/var/lib/kubelet/plugins/csi-nfsplugin" + doc["spec"]["template"]["spec"]["volumes"][2]["hostPath"]["path"] = "/var/lib/kubelet/plugins/csi-nfsplugin" + # Set toleration + doc["spec"]["template"]["spec"]["tolerations"] = [{"operator": "Exists"}] + + if doc["kind"] == "List": + for item in doc["items"]: + docs.append(set_namespace(item)) + else: + docs.append(set_namespace(doc)) + + with open(f"magnum_cluster_api/manifests/manila-csi/{manifest}", "w") as fd: + yaml.dump_all(docs, fd, default_flow_style=False) diff --git a/tools/sync-nfs-csi-manifests b/tools/sync-nfs-csi-manifests new file mode 100644 index 00000000..6eb97adc --- /dev/null +++ b/tools/sync-nfs-csi-manifests @@ -0,0 +1,48 @@ +#!/usr/bin/env python3 + +# Copyright (c) 2023 VEXXHOST, Inc. +# +# 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. + +# This script is used to sync the CCM manifests from the CCM repo to the +# manifests folder. + +import requests +import yaml + +MANIFESTS = set( + [ + "csi-nfs-node.yaml", + "csi-nfs-controller.yaml", + "csi-nfs-driverinfo.yaml", + "rbac-csi-nfs.yaml", + ] +) +NFS_CSI_TAG = "v4.2.0" + + +for manifest in MANIFESTS: + url = f"https://raw.githubusercontent.com/kubernetes-csi/csi-driver-nfs/master/deploy/{NFS_CSI_TAG}/{manifest}" # noqa E501 + + docs = [] + r = requests.get(url) + + for doc in yaml.safe_load_all(r.text): + if doc["kind"] == "List": + for item in doc["items"]: + docs.append(item) + else: + docs.append(doc) + + with open(f"magnum_cluster_api/manifests/nfs-csi/{manifest}", "w") as fd: + yaml.dump_all(docs, fd, default_flow_style=False)