From 37fde2d2d0189d74163eb834747bb7a9b951ac48 Mon Sep 17 00:00:00 2001 From: Simon Dodsley Date: Mon, 28 Jun 2021 11:41:37 -0400 Subject: [PATCH] Add config options for all supported features Change-Id: If75aab5d8a0aeb4492a8aa029494abea4a362085 Co-authored-by: Aurelien Lourot --- src/config.yaml | 117 ++++++++++++++++++ src/lib/charm/openstack/cinder_purestorage.py | 63 +++++++++- ..._lib_charm_openstack_cinder_purestorage.py | 5 + 3 files changed, 184 insertions(+), 1 deletion(-) diff --git a/src/config.yaml b/src/config.yaml index f905223..37ccfd3 100644 --- a/src/config.yaml +++ b/src/config.yaml @@ -51,3 +51,120 @@ options: type: string description: Service name to present to Cinder default: !!null "" + eradicate-on-delete: + type: boolean + description: | + When enabled, all Pure volumes, snapshots, and protection groups will + be eradicated at the time of deletion in Cinder. Data will NOT be + recoverable after a delete with this set to True! When disabled, volumes + and snapshots will go into pending eradication state and can be recovered. + default: !!bool false + automatic-max-oversubscription: + type: boolean + description: | + Automatically determine an oversubscription ratio based on the current total + data reduction values. If used this calculated value will override the + max_over_subscription_ratio config option. + default: !!bool true + use-multipath: + type: boolean + description: | + Determine if we attach/detach volumes in cinder using multipath for volume to + image and image to volume transfer + default: !!bool true + use-replication: + type: boolean + description: When set this will enable Cinder Replication v2. + default: !!bool false + replication-target-name: + type: string + description: | + The name of the backend array to which replication should be performed. + default: !!null "" + replication-target-address: + type: string + description: | + The IP address, or FQDN, of the replication target array + default: !!null "" + replication-target-api-token: + type: string + description: | + The API token for the replication target array + default: !!null "" + replication-type: + type: string + description: | + The replication to be used. Options are async and sync. If not specified + the default is async. + default: !!null "" + replication-sync-uniform: + type: boolean + description: | + If the replication-type is set as sync, this defines that data paths are + uniform between arrays in the cluster and data connections should be + made to both when attaching. If not specified, defaults to False + default: !!null "" + replica-interval: + type: int + description: | + Snapshot replication interval in seconds. If not specified, defaults to 3600. + default: !!null "" + replica-retention-short: + type: int + description: | + Retain all snapshots on target for this time (in seconds). If not specified, + defaults to 14400 + default: !!null "" + replica-retention-per-day: + type: int + description: | + Retain how many snapshots for each day. If not specified, defaults to 3. + default: !!null "" + replica-retention-long: + type: int + description: | + Retain snapshots per day on target for this time (in days). If not specified, + defaults to 7. + default: !!null "" + use-image-cache: + type: boolean + description: | + If set to True the Glance Image Cache for Cinder will be enabled on the backend. + default: !!bool false + image-volume-cache-max-size-gb: + type: int + description: | + If use-image-cache is true this sets the maximum size of the cache. If not set + this default to unlimited. + default: !!null "" + image-volume-cache-max-count: + type: int + description: | + If use-image-cache is true this sets the maximum number of cache entries. + If not set this default to unlimited. + default: !!null "" + replication-pgname: + type: string + description: | + Pure Protection Group name to use for async replication (will be created if it + does not exist). If not specified, defaults to cinder-group. Available from Stein. + default: !!null "" + replication-pod: + type: string + description: | + Pure Pod name to use for sync replication (will be created if it + does not exist). If not specified, defaults to cinder-pod. Available from Stein. + default: !!null "" + iscsi-cidr: + type: string + description: | + If protocol is iscsi, this parameter provides the CIDR of FlashArray iSCSI + targets hosts are allowed to connect to. If not specified, defaults to all + IPv4 address. Available from Train. + default: !!null "" + use-chap: + type: boolean + description: | + If protocol is iscsi, this parameter defines whether to use CHAP + authentication for Cinder created hosts. + default: !!bool false diff --git a/src/lib/charm/openstack/cinder_purestorage.py b/src/lib/charm/openstack/cinder_purestorage.py index 85e18c7..8ad403e 100644 --- a/src/lib/charm/openstack/cinder_purestorage.py +++ b/src/lib/charm/openstack/cinder_purestorage.py @@ -23,12 +23,73 @@ class CinderpurestorageCharm( } service = self.config.get('volume-backend-name') volumedriver = drivers.get(self.config.get('protocol')) + image_cache = [] + iscsi = [] + repl = [] driver_options = [ ('san_ip', self.config.get('san-ip')), ('pure_api_token', self.config.get('pure-api-token')), + ('use_multipath_for_image_xfer', self.config.get('use-multipath')), + ('image_volume_cache_enabled', + self.config.get('use-image-cache')), + ('pure_eradicate_on_delete', + self.config.get('eradicate-on-delete')), + ('pure_automatic_max_oversubscription_ratio', + self.config.get('automatic-max-oversubscription')), ('volume_driver', volumedriver), ('volume_backend_name', service)] - return driver_options + + if self.config.get('protocol') == 'iscsi': + if self.config.get('iscsi-cidr'): + iscsi.extend([('pure_iscsi_cidr', + self.config.get('iscsi-cidr'))]) + if self.config.get('use-chap'): + iscsi.extend([('use_chap_auth', + self.config.get('use-chap'))]) + + if self.config.get('use-image-cache'): + image_cache = [ + ('image_volume_cache_max_size_gb', + self.config.get('image-volume-cache-max-size-gb', 0)), + ('image_volume_cache_max_count', + self.config.get('image-volume-cache-max-count', 0))] + + if self.config.get('use-replication'): + replication_device = 'backend_id:' + \ + self.config.get('replication-target-name') + \ + ',san_ip:' + \ + self.config.get('replication-target-address') + \ + ',api_token:' + \ + self.config.get('replication-target-api-token') + if self.config.get('replication-type') == 'sync': + replication_device += ',type:sync' + if self.config.get('replication-sync-uniform', False): + replication_device += ',uniform:true' + repl = [('replication_device', + replication_device)] + if self.config.get('replica-interval'): + repl.extend([('pure_replica_interval_default', + self.config.get('replica-interval'))]) + if self.config.get('pure-replica-retention-short'): + repl.extend([('pure_replica_retention_short_term_default', + self.config.get('pure-replica-retention-short'))]) + if self.config.get('replica-retention-per-day'): + # required for pep8 max line length compliance + TEMP_VAR = 'pure_replica_retention_long_term_per_day_default' + repl.extend([(TEMP_VAR, + self.config.get('replica-retention-per-day'))]) + if self.config.get('replica-retention-long'): + repl.extend([('pure_replica_retention_long_term_default', + self.config.get('replica-retention-long'))]) + if self.config.get('replication-pgname'): + repl.extend([('pure_replication_pg_name', + self.config.get('replication-pgname'))]) + if self.config.get('replication-pod'): + repl.extend([('pure_replication_pod_name', + self.config.get('replication-pod'))]) + + final_options = driver_options + image_cache + repl + iscsi + return final_options class CinderpurestorageCharmRocky(CinderpurestorageCharm): diff --git a/unit_tests/test_lib_charm_openstack_cinder_purestorage.py b/unit_tests/test_lib_charm_openstack_cinder_purestorage.py index ef5a6c4..af1c6f1 100644 --- a/unit_tests/test_lib_charm_openstack_cinder_purestorage.py +++ b/unit_tests/test_lib_charm_openstack_cinder_purestorage.py @@ -45,5 +45,10 @@ class TestCinderpurestorageCharm(test_utils.PatchHelper): # Add check here that configuration is as expected. self.assertEqual(config, [('san_ip', None), ('pure_api_token', None), + ('use_multipath_for_image_xfer', None), + ('image_volume_cache_enabled', None), + ('pure_eradicate_on_delete', None), + ('pure_automatic_max_oversubscription_ratio', + None), ('volume_driver', None), ('volume_backend_name', None)])