From 48625ad984034cf104eaa6fa68db9a841b1998dd Mon Sep 17 00:00:00 2001
From: "Vladimir Sigunov (vs422h)" <vs422h@att.com>
Date: Wed, 20 Apr 2022 18:18:05 -0400
Subject: [PATCH] [Cinder] Add visibilty settings to volume types

This is to add public/private  visibility option
and project level access list to a volume type while creating.

Change-Id: Id33c8c9f10e60fcdb4b6c49e69f3b5d8f11850c6
---
 cinder/Chart.yaml                         |   2 +-
 cinder/templates/bin/_bootstrap.sh.tpl    | 108 +++++++++++++---------
 cinder/values.yaml                        |  13 +++
 cinder/values_overrides/backend_pure.yaml |   4 +
 releasenotes/notes/cinder.yaml            |   1 +
 5 files changed, 84 insertions(+), 44 deletions(-)

diff --git a/cinder/Chart.yaml b/cinder/Chart.yaml
index c5a2abf8b8..671470f199 100644
--- a/cinder/Chart.yaml
+++ b/cinder/Chart.yaml
@@ -14,7 +14,7 @@ apiVersion: v1
 appVersion: v1.0.0
 description: OpenStack-Helm Cinder
 name: cinder
-version: 0.2.18
+version: 0.2.19
 home: https://docs.openstack.org/cinder/latest/
 icon: https://www.openstack.org/themes/openstack/images/project-mascots/Cinder/OpenStack_Project_Cinder_vertical.png
 sources:
diff --git a/cinder/templates/bin/_bootstrap.sh.tpl b/cinder/templates/bin/_bootstrap.sh.tpl
index be74cfc126..49d99c5236 100644
--- a/cinder/templates/bin/_bootstrap.sh.tpl
+++ b/cinder/templates/bin/_bootstrap.sh.tpl
@@ -22,30 +22,53 @@ export HOME=/tmp
   {{- /* Create volume types defined in Values.bootstrap */}}
   {{- /* Types can only be created for backends defined in Values.conf */}}
   {{- $volumeTypes := .Values.bootstrap.volume_types }}
+  {{- /* Generating list of backends listed in .Values.conf.backends */}}
+  {{- $backendsList := list}}
   {{- range $backend_name, $backend_properties := .Values.conf.backends }}
-    {{- if $backend_properties }}
-      {{- range $name, $properties := $volumeTypes }}
-        {{- if $properties.volume_backend_name }}
-          {{- if (eq $properties.volume_backend_name $backend_properties.volume_backend_name) }}
-if [[ $(openstack volume type list -f value -c Name | grep -w {{ $name }}) ]]; then
-  if [[ ! $(openstack volume type show {{ $name }} | grep volume_backend_name) ]]; then
-    openstack volume type set \
-      {{- range $key, $value := $properties }}
-      --property {{ $key }}={{ $value }} \
-      {{- end }}
+    {{- if and $backend_properties $backend_properties.volume_backend_name }}
+    {{- $backendsList = append $backendsList $backend_properties.volume_backend_name }}
+    {{- end }}
+  {{- end }}
+
+  {{- range $name, $properties := $volumeTypes }}
+    {{- if and $properties.volume_backend_name (has $properties.volume_backend_name $backendsList) }}
+      {{- $access_type := $properties.access_type | default "public"}}
+      # Create a volume type if it doesn't exist.
+      # Assumption: the volume type name is unique.
+      openstack volume type show {{ $name }} || \
+      openstack volume type create \
+        --{{ $access_type }} \
       {{ $name }}
-  fi
-else
-  openstack volume type create \
-    --public \
-      {{- range $key, $value := $properties }}
-    --property {{ $key }}={{ $value }} \
-      {{- end }}
-    {{ $name }}
-fi
-          {{- end }}
+      {{/*
+        We will try to set or update volume type properties.
+        To update properties, the volume type MUST NOT BE IN USE,
+        and projects and domains with access to the volume type
+        MUST EXIST, as well.
+      */}}
+      is_in_use=$(openstack volume list --long --all-projects -c Type -f value | grep -E "^{{ $name }}\s*$" || true)
+      if [[ -z ${is_in_use} ]]; then
+        {{- if (eq $access_type "private") }}
+        volumeTypeID=$(openstack volume type show {{ $name }} -f value -c id)
+        cinder type-update --is-public false ${volumeTypeID}
         {{- end }}
-      {{- end }}
+
+        {{- if and $properties.grant_access (eq $access_type "private") }}
+        {{- range $domain, $domainProjects := $properties.grant_access }}
+        {{- range $project := $domainProjects }}
+        project_id=$(openstack project show --domain {{ $domain }} -c id -f value {{ $project }})
+        if [[ -z  $(openstack volume type show {{ $name }} -c access_project_ids -f value | grep ${project_id} || true) ]]; then
+          openstack volume type set --project-domain {{ $domain }} --project {{ $project }} {{ $name }}
+        fi
+        {{- end }}
+        {{- end }}
+        {{- end }}
+
+        {{- range $key, $value := $properties }}
+        {{- if and (ne $key "access_type") (ne $key "grant_access") $value }}
+        openstack volume type set --property {{ $key }}={{ $value }} {{ $name }}
+        {{- end }}
+        {{- end }}
+      fi
     {{- end }}
   {{- end }}
 
@@ -53,11 +76,11 @@ fi
   {{- if .Values.bootstrap.bootstrap_conf_backends }}
     {{- range $name, $properties := .Values.conf.backends }}
       {{- if $properties }}
-openstack volume type show {{ $name }} || \
-  openstack volume type create \
-    --public \
-    --property volume_backend_name={{ $properties.volume_backend_name }} \
-    {{ $name }}
+        openstack volume type show {{ $name }} || \
+        openstack volume type create \
+        --public \
+        --property volume_backend_name={{ $properties.volume_backend_name }} \
+        {{ $name }}
       {{- end }}
     {{- end }}
   {{- end }}
@@ -65,32 +88,31 @@ openstack volume type show {{ $name }} || \
   {{- /* Create and associate volume QoS if defined */}}
   {{- if .Values.bootstrap.volume_qos}}
     {{- range $qos_name, $qos_properties := .Values.bootstrap.volume_qos }}
-type_defined=true
+      type_defined=true
       {{- /* If the volume type to associate with is not defined, skip the qos */}}
       {{- range $qos_properties.associates }}
-if ! openstack volume type show {{ . }}; then
-  type_defined=false
-fi
+        if ! openstack volume type show {{ . }}; then
+          type_defined=false
+        fi
       {{- end }}
-if $type_defined; then
-  openstack volume qos show {{ $qos_name }} || \
-    openstack volume qos create \
-      --consumer {{ $qos_properties.consumer }} \
-      {{- range $key, $value := $qos_properties.properties }}
-      --property {{ $key }}={{ $value }} \
-      {{- end }}
-      {{ $qos_name }}
-      {{- range $qos_properties.associates }}
-  openstack volume qos associate {{ $qos_name }} {{ . }}
-      {{- end }}
-fi
+      if [[ ${type_defined} ]]; then
+        openstack volume qos show {{ $qos_name }} || \
+          openstack volume qos create \
+          --consumer {{ $qos_properties.consumer }} \
+          {{- range $key, $value := $qos_properties.properties }}
+            --property {{ $key }}={{ $value }} \
+          {{- end }}
+          {{ $qos_name }}
+          {{- range $qos_properties.associates }}
+            openstack volume qos associate {{ $qos_name }} {{ . }}
+          {{- end }}
+      fi
     {{- end }}
   {{- end }}
 
 {{- /* Check volume type and properties were added */}}
 openstack volume type list --long
 openstack volume qos list
-
 {{- end }}
 
 exit 0
diff --git a/cinder/values.yaml b/cinder/values.yaml
index b84e220751..70ddc817f9 100644
--- a/cinder/values.yaml
+++ b/cinder/values.yaml
@@ -368,6 +368,19 @@ bootstrap:
     name:
       group:
       volume_backend_name:
+      # access_type: "private"
+      # If you set up access_type to private, only the creator
+      # will get an access to the volume type. You can extend
+      # the access to your volume type by providing a list of
+      # domain names and projects as shown below
+      # grant_access:
+      #   <domain name 1>:
+      #     - <project name 1>
+      #     - <project name 2>
+      #     <...>
+      #   <domain name 2>:
+      #     - <project name 1>
+      #     <...>
   # Volume QoS if any. By default, None QoS is created.
   # Below values with a number at the end need to be replaced
   # with real names.
diff --git a/cinder/values_overrides/backend_pure.yaml b/cinder/values_overrides/backend_pure.yaml
index 9e0aaa2a67..40a6a6521d 100644
--- a/cinder/values_overrides/backend_pure.yaml
+++ b/cinder/values_overrides/backend_pure.yaml
@@ -22,6 +22,10 @@ bootstrap:
     PURE-MULTIATTACH:
       multiattach: "\"<is> True\""
       volume_backend_name: "PURE_BE"
+      access_type: "private"
+      grant_access:
+        default:
+          - admin
 conf:
   cinder:
     DEFAULT:
diff --git a/releasenotes/notes/cinder.yaml b/releasenotes/notes/cinder.yaml
index dae8c0722b..d6d986c195 100644
--- a/releasenotes/notes/cinder.yaml
+++ b/releasenotes/notes/cinder.yaml
@@ -35,4 +35,5 @@ cinder:
   - 0.2.16 Enable taint toleration for Openstack services
   - 0.2.17 Remove unsupported values overrides
   - 0.2.18 Add helm hook in bootstrap job
+  - 0.2.19 Add volume types visibility (public/private)
 ...