Browse Source

Merge pull request #8700 from abn/lib_openshift/oc_storageclass

lib_openshift/oc_storageclass: support mountOptions and reclaimPolicy
OpenShift Merge Robot 6 years ago
parent
commit
67a6ddc79b

+ 2 - 0
inventory/hosts.example

@@ -612,6 +612,8 @@ debug_level=2
 # StorageClass
 # openshift_storageclass_name=gp2
 # openshift_storageclass_parameters={'type': 'gp2', 'encrypted': 'false'}
+# openshift_storageclass_mount_options=['dir_mode=0777', 'file_mode=0777']
+# openshift_storageclass_reclaim_policy="Delete"
 #
 # PersistentLocalStorage
 # If Persistent Local Storage is wanted, this boolean can be defined to True.

+ 44 - 1
roles/lib_openshift/library/oc_storageclass.py

@@ -110,6 +110,18 @@ options:
     required: false
     default: v1
     aliases: []
+  mount_options:
+    description:
+    - A list of mount options to pass when mounting volumes of this storage class.
+    required: false
+    default: None
+    aliases: []
+  reclaim_policy:
+    description:
+    - The reclaim policy to use for this storage class.
+    required: false
+    default: None
+    aliases: []
 author:
 - "Kenny Woodson <kwoodson@redhat.com>"
 extends_documentation_fragment: []
@@ -1488,7 +1500,9 @@ class StorageClassConfig(object):
                  annotations=None,
                  default_storage_class="false",
                  api_version='v1',
-                 kubeconfig='/etc/origin/master/admin.kubeconfig'):
+                 kubeconfig='/etc/origin/master/admin.kubeconfig',
+                 mount_options=None,
+                 reclaim_policy=None):
         ''' constructor for handling storageclass options '''
         self.name = name
         self.parameters = parameters
@@ -1497,6 +1511,8 @@ class StorageClassConfig(object):
         self.api_version = api_version
         self.default_storage_class = str(default_storage_class).lower()
         self.kubeconfig = kubeconfig
+        self.mount_options = mount_options
+        self.reclaim_policy = reclaim_policy
         self.data = {}
 
         self.create_dict()
@@ -1525,6 +1541,11 @@ class StorageClassConfig(object):
         else:
             self.data['parameters']['type'] = 'gp2'
 
+        self.data['mountOptions'] = self.mount_options or []
+
+        if self.reclaim_policy is not None:
+            self.data['reclaimPolicy'] = self.reclaim_policy
+
 
 
 # pylint: disable=too-many-instance-attributes,too-many-public-methods
@@ -1533,6 +1554,8 @@ class StorageClass(Yedit):
     annotations_path = "metadata.annotations"
     provisioner_path = "provisioner"
     parameters_path = "parameters"
+    mount_options_path = "mountOptions"
+    reclaim_policy_path = "reclaimPolicy"
     kind = 'StorageClass'
 
     def __init__(self, content):
@@ -1547,6 +1570,14 @@ class StorageClass(Yedit):
         ''' get the service selector'''
         return self.get(StorageClass.parameters_path) or {}
 
+    def get_mount_options(self):
+        ''' get mount options'''
+        return self.get(StorageClass.mount_options_path) or []
+
+    def get_reclaim_policy(self):
+        ''' get reclaim policy'''
+        return self.get(StorageClass.reclaim_policy_path)
+
 # -*- -*- -*- End included fragment: lib/storageclass.py -*- -*- -*-
 
 # -*- -*- -*- Begin included fragment: class/oc_storageclass.py -*- -*- -*-
@@ -1611,6 +1642,14 @@ class OCStorageClass(OpenShiftCLI):
             if 'is-default-class' in anno_key and anno_value != self.config.default_storage_class:
                 return True
 
+        # check if mount options have updated
+        if set(self.storage_class.get_mount_options()) != set(self.config.mount_options):
+            return True
+
+        # check if reclaim policy has been updated
+        if self.storage_class.get_reclaim_policy() != self.config.reclaim_policy:
+            return True
+
         return False
 
     @staticmethod
@@ -1640,6 +1679,8 @@ class OCStorageClass(OpenShiftCLI):
                                      api_version="storage.k8s.io/{}".format(params['api_version']),
                                      default_storage_class=params.get('default_storage_class', 'false'),
                                      kubeconfig=params['kubeconfig'],
+                                     mount_options=params['mount_options'],
+                                     reclaim_policy=params['reclaim_policy']
                                     )
 
         oc_sc = OCStorageClass(rconfig, verbose=params['debug'])
@@ -1737,6 +1778,8 @@ def main():
             provisioner=dict(required=True, type='str'),
             api_version=dict(default='v1', type='str'),
             default_storage_class=dict(default="false", type='str'),
+            mount_options=dict(default=None, type='list'),
+            reclaim_policy=dict(default=None, type='str'),
         ),
         supports_check_mode=True,
     )

+ 2 - 0
roles/lib_openshift/src/ansible/oc_storageclass.py

@@ -17,6 +17,8 @@ def main():
             provisioner=dict(required=True, type='str'),
             api_version=dict(default='v1', type='str'),
             default_storage_class=dict(default="false", type='str'),
+            mount_options=dict(default=None, type='list'),
+            reclaim_policy=dict(default=None, type='str'),
         ),
         supports_check_mode=True,
     )

+ 10 - 0
roles/lib_openshift/src/class/oc_storageclass.py

@@ -61,6 +61,14 @@ class OCStorageClass(OpenShiftCLI):
             if 'is-default-class' in anno_key and anno_value != self.config.default_storage_class:
                 return True
 
+        # check if mount options have updated
+        if set(self.storage_class.get_mount_options()) != set(self.config.mount_options):
+            return True
+
+        # check if reclaim policy has been updated
+        if self.storage_class.get_reclaim_policy() != self.config.reclaim_policy:
+            return True
+
         return False
 
     @staticmethod
@@ -90,6 +98,8 @@ class OCStorageClass(OpenShiftCLI):
                                      api_version="storage.k8s.io/{}".format(params['api_version']),
                                      default_storage_class=params.get('default_storage_class', 'false'),
                                      kubeconfig=params['kubeconfig'],
+                                     mount_options=params['mount_options'],
+                                     reclaim_policy=params['reclaim_policy']
                                     )
 
         oc_sc = OCStorageClass(rconfig, verbose=params['debug'])

+ 12 - 0
roles/lib_openshift/src/doc/storageclass

@@ -57,6 +57,18 @@ options:
     required: false
     default: v1
     aliases: []
+  mount_options:
+    description:
+    - A list of mount options to pass when mounting volumes of this storage class.
+    required: false
+    default: None
+    aliases: []
+  reclaim_policy:
+    description:
+    - The reclaim policy to use for this storage class.
+    required: false
+    default: None
+    aliases: []
 author:
 - "Kenny Woodson <kwoodson@redhat.com>"
 extends_documentation_fragment: []

+ 20 - 1
roles/lib_openshift/src/lib/storageclass.py

@@ -13,7 +13,9 @@ class StorageClassConfig(object):
                  annotations=None,
                  default_storage_class="false",
                  api_version='v1',
-                 kubeconfig='/etc/origin/master/admin.kubeconfig'):
+                 kubeconfig='/etc/origin/master/admin.kubeconfig',
+                 mount_options=None,
+                 reclaim_policy=None):
         ''' constructor for handling storageclass options '''
         self.name = name
         self.parameters = parameters
@@ -22,6 +24,8 @@ class StorageClassConfig(object):
         self.api_version = api_version
         self.default_storage_class = str(default_storage_class).lower()
         self.kubeconfig = kubeconfig
+        self.mount_options = mount_options
+        self.reclaim_policy = reclaim_policy
         self.data = {}
 
         self.create_dict()
@@ -50,6 +54,11 @@ class StorageClassConfig(object):
         else:
             self.data['parameters']['type'] = 'gp2'
 
+        self.data['mountOptions'] = self.mount_options or []
+
+        if self.reclaim_policy is not None:
+            self.data['reclaimPolicy'] = self.reclaim_policy
+
 
 
 # pylint: disable=too-many-instance-attributes,too-many-public-methods
@@ -58,6 +67,8 @@ class StorageClass(Yedit):
     annotations_path = "metadata.annotations"
     provisioner_path = "provisioner"
     parameters_path = "parameters"
+    mount_options_path = "mountOptions"
+    reclaim_policy_path = "reclaimPolicy"
     kind = 'StorageClass'
 
     def __init__(self, content):
@@ -71,3 +82,11 @@ class StorageClass(Yedit):
     def get_parameters(self):
         ''' get the service selector'''
         return self.get(StorageClass.parameters_path) or {}
+
+    def get_mount_options(self):
+        ''' get mount options'''
+        return self.get(StorageClass.mount_options_path) or []
+
+    def get_reclaim_policy(self):
+        ''' get reclaim policy'''
+        return self.get(StorageClass.reclaim_policy_path)

+ 11 - 0
roles/lib_openshift/src/test/integration/oc_storageclass.yml

@@ -54,12 +54,23 @@
         type: gp2
         encrypted: "true"
       default_storage_class: "true"
+      mount_options:
+      - debug
+      reclaim_policy: Delete
     register: sc_out
 
   - assert:
       that: "sc_out.results.results[0]['parameters']['encrypted'] == 'true'"
       msg: storageclass update failed
 
+  - assert:
+      that: "sc_out.results.results[0]['reclaimPolicy'] == 'Delete'"
+      msg: storageclass update failed
+
+  - assert:
+      that: "sc_out.results.results[0]['mountOptions'] == ['debug']"
+      msg: storageclass update failed
+
   - name: oc delete storageclass
     oc_storageclass:
       name: testsc

+ 12 - 4
roles/lib_openshift/src/test/unit/test_oc_storageclass.py

@@ -44,7 +44,9 @@ class OCStorageClassTest(unittest.TestCase):
             'annotations': {'storageclass.beta.kubernetes.io/is-default-class': "true"},
             'parameters': {'type': 'gp2'},
             'api_version': 'v1',
-            'default_storage_class': 'true'
+            'default_storage_class': 'true',
+            'mount_options': ['debug'],
+            'reclaim_policy': 'Delete'
         }
 
         valid_result_json = '''{
@@ -59,7 +61,9 @@ class OCStorageClassTest(unittest.TestCase):
                 "annotations": {"storageclass.beta.kubernetes.io/is-default-class": "true"}
             },
             "provisioner": "kubernetes.io/aws-ebs",
-            "parameters": {"type": "gp2"}
+            "parameters": {"type": "gp2"},
+            "mountOptions": ['debug'],
+            "reclaimPolicy": "Delete"
         }'''
 
         # Return values of our mocked function call. These get returned once per call.
@@ -127,7 +131,9 @@ class OCStorageClassTest(unittest.TestCase):
             'annotations': {'storageclass.beta.kubernetes.io/is-default-class': "true"},
             'parameters': {'type': 'gp2'},
             'api_version': 'v1',
-            'default_storage_class': 'true'
+            'default_storage_class': 'true',
+            'mount_options': ['debug'],
+            'reclaim_policy': 'Delete'
         }
 
         valid_result_json = '''{
@@ -142,7 +148,9 @@ class OCStorageClassTest(unittest.TestCase):
                 "annotations": {"storageclass.beta.kubernetes.io/is-default-class": "true"}
             },
             "provisioner": "kubernetes.io/aws-ebs",
-            "parameters": {"type": "gp2"}
+            "parameters": {"type": "gp2"},
+            "mountOptions": ['debug'],
+            "reclaimPolicy": "Delete"
         }'''
 
         # Return values of our mocked function call. These get returned once per call.

+ 2 - 0
roles/openshift_default_storage_class/defaults/main.yml

@@ -40,3 +40,5 @@ openshift_storageclass_default: "true"
 openshift_storageclass_name: "{{ openshift_storageclass_defaults[openshift_cloudprovider_kind]['name'] }}"
 openshift_storageclass_provisioner: "{{ openshift_storageclass_defaults[openshift_cloudprovider_kind]['provisioner'] }}"
 openshift_storageclass_parameters: "{{ openshift_storageclass_defaults[openshift_cloudprovider_kind]['parameters'] }}"
+openshift_storageclass_mount_options: []
+openshift_storageclass_reclaim_policy: ""

+ 19 - 0
roles/openshift_default_storage_class/tasks/azure.yml

@@ -0,0 +1,19 @@
+---
+# this is required for when using azure-file, should probably go to defaults upstream
+- block:
+    - name: Add azure provider cluster role
+      command: >
+        oc create clusterrole system:azure-cloud-provider
+        --verb=get,create --resource=secrets
+      register: cr_result
+      failed_when: cr_result.rc != 0 and 'AlreadyExists' not in cr_result.stderr
+      changed_when: "'AlreadyExists' not in cr_result.stderr"
+
+    - name: Bind azure provider cluster role to pv binder sa
+      command: >
+        oc create clusterrolebinding system:azure-cloud-provider
+        --clusterrole=system:azure-cloud-provider
+        --serviceaccount=kube-system:persistent-volume-binder
+      register: crb_result
+      failed_when: crb_result.rc != 0 and 'AlreadyExists' not in crb_result.stderr
+      changed_when: "'AlreadyExists' not in crb_result.stderr"

+ 6 - 0
roles/openshift_default_storage_class/tasks/main.yml

@@ -6,4 +6,10 @@
     default_storage_class: "{{ openshift_storageclass_default | default('true') | string}}"
     parameters: "{{ openshift_storageclass_parameters }}"
     provisioner: "{{ openshift_storageclass_provisioner }}"
+    mount_options: "{{ openshift_storageclass_mount_options }}"
+    reclaim_policy: "{{ openshift_storageclass_reclaim_policy | default(None) }}"
+  run_once: true
+
+- when: openshift_cloudprovider_kind == 'azure'
+  include_tasks: azure.yml
   run_once: true