Dre4m Shell
Server IP : 85.214.239.14  /  Your IP : 3.14.249.191
Web Server : Apache/2.4.62 (Debian)
System : Linux h2886529.stratoserver.net 4.9.0 #1 SMP Tue Jan 9 19:45:01 MSK 2024 x86_64
User : www-data ( 33)
PHP Version : 7.4.18
Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
MySQL : OFF  |  cURL : OFF  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : ON  |  Pkexec : OFF
Directory :  /lib/python3/dist-packages/ansible_collections/dellemc/powerflex/plugins/modules/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ HOME SHELL ]     

Current File : /lib/python3/dist-packages/ansible_collections/dellemc/powerflex/plugins/modules/storagepool.py
#!/usr/bin/python

# Copyright: (c) 2021, Dell Technologies
# Apache License version 2.0 (see MODULE-LICENSE or http://www.apache.org/licenses/LICENSE-2.0.txt)

"""Ansible module for managing Dell Technologies (Dell) PowerFlex storage pool"""

from __future__ import absolute_import, division, print_function

__metaclass__ = type

DOCUMENTATION = r'''
---
module: storagepool

version_added: '1.0.0'

short_description: Managing Dell PowerFlex storage pool

description:
- Dell PowerFlex storage pool module includes getting the details of
  storage pool, creating a new storage pool, and modifying the attribute of
  a storage pool.

extends_documentation_fragment:
  - dellemc.powerflex.powerflex

author:
- Arindam Datta (@dattaarindam) <ansible.team@dell.com>
- P Srinivas Rao (@srinivas-rao5) <ansible.team@dell.com>

options:
  storage_pool_name:
    description:
    - The name of the storage pool.
    - If more than one storage pool is found with the same name then
      protection domain id/name is required to perform the task.
    - Mutually exclusive with I(storage_pool_id).
    type: str
  storage_pool_id:
    description:
    - The id of the storage pool.
    - It is auto generated, hence should not be provided during
      creation of a storage pool.
    - Mutually exclusive with I(storage_pool_name).
    type: str
  protection_domain_name:
    description:
    - The name of the protection domain.
    - During creation of a pool, either protection domain name or id must be
      mentioned.
    - Mutually exclusive with I(protection_domain_id).
    type: str
  protection_domain_id:
    description:
    - The id of the protection domain.
    - During creation of a pool, either protection domain name or id must
      be mentioned.
    - Mutually exclusive with I(protection_domain_name).
    type: str
  media_type:
    description:
    - Type of devices in the storage pool.
    type: str
    choices: ['HDD', 'SSD', 'TRANSITIONAL']
  storage_pool_new_name:
    description:
    - New name for the storage pool can be provided.
    - This parameter is used for renaming the storage pool.
    type: str
  use_rfcache:
    description:
    - Enable/Disable RFcache on a specific storage pool.
    type: bool
  use_rmcache:
    description:
    - Enable/Disable RMcache on a specific storage pool.
    type: bool
  state:
    description:
    - State of the storage pool.
    type: str
    choices: ["present", "absent"]
    required: true
notes:
  - TRANSITIONAL media type is supported only during modification.
  - The I(check_mode) is not supported.
'''

EXAMPLES = r'''

- name: Get the details of storage pool by name
  dellemc.powerflex.storagepool:
    hostname: "{{hostname}}"
    username: "{{username}}"
    password: "{{password}}"
    validate_certs: "{{validate_certs}}"
    storage_pool_name: "sample_pool_name"
    protection_domain_name: "sample_protection_domain"
    state: "present"

- name: Get the details of storage pool by id
  dellemc.powerflex.storagepool:
    hostname: "{{hostname}}"
    username: "{{username}}"
    password: "{{password}}"
    validate_certs: "{{validate_certs}}"
    storage_pool_id: "abcd1234ab12r"
    state: "present"

- name: Create a new storage pool by name
  dellemc.powerflex.storagepool:
    hostname: "{{hostname}}"
    username: "{{username}}"
    password: "{{password}}"
    validate_certs: "{{validate_certs}}"
    storage_pool_name: "ansible_test_pool"
    protection_domain_id: "1c957da800000000"
    media_type: "HDD"
    state: "present"

- name: Modify a storage pool by name
  dellemc.powerflex.storagepool:
    hostname: "{{hostname}}"
    username: "{{username}}"
    password: "{{password}}"
    validate_certs: "{{validate_certs}}"
    storage_pool_name: "ansible_test_pool"
    protection_domain_id: "1c957da800000000"
    use_rmcache: True
    use_rfcache: True
    state: "present"

- name: Rename storage pool by id
  dellemc.powerflex.storagepool:
    hostname: "{{hostname}}"
    username: "{{username}}"
    password: "{{password}}"
    validate_certs: "{{validate_certs}}"
    storage_pool_id: "abcd1234ab12r"
    storage_pool_new_name: "new_ansible_pool"
    state: "present"
'''

RETURN = r'''
changed:
    description: Whether or not the resource has changed.
    returned: always
    type: bool
    sample: 'false'
storage_pool_details:
    description: Details of the storage pool.
    returned: When storage pool exists
    type: dict
    contains:
        mediaType:
            description: Type of devices in the storage pool.
            type: str
        useRfcache:
            description: Enable/Disable RFcache on a specific storage pool.
            type: bool
        useRmcache:
            description: Enable/Disable RMcache on a specific storage pool.
            type: bool
        id:
            description: ID of the storage pool under protection domain.
            type: str
        name:
            description: Name of the storage pool under protection domain.
            type: str
        protectionDomainId:
            description: ID of the protection domain in which pool resides.
            type: str
        protectionDomainName:
            description: Name of the protection domain in which pool resides.
            type: str
        "statistics":
            description: Statistics details of the storage pool.
            type: dict
            contains:
                "capacityInUseInKb":
                    description: Total capacity of the storage pool.
                    type: str
                "unusedCapacityInKb":
                    description: Unused capacity of the storage pool.
                    type: str
                "deviceIds":
                    description: Device Ids of the storage pool.
                    type: list
    sample: {
        "addressSpaceUsage": "Normal",
        "addressSpaceUsageType": "DeviceCapacityLimit",
        "backgroundScannerBWLimitKBps": 3072,
        "backgroundScannerMode": "DataComparison",
        "bgScannerCompareErrorAction": "ReportAndFix",
        "bgScannerReadErrorAction": "ReportAndFix",
        "capacityAlertCriticalThreshold": 90,
        "capacityAlertHighThreshold": 80,
        "capacityUsageState": "Normal",
        "capacityUsageType": "NetCapacity",
        "checksumEnabled": false,
        "compressionMethod": "Invalid",
        "dataLayout": "MediumGranularity",
        "externalAccelerationType": "None",
        "fglAccpId": null,
        "fglExtraCapacity": null,
        "fglMaxCompressionRatio": null,
        "fglMetadataSizeXx100": null,
        "fglNvdimmMetadataAmortizationX100": null,
        "fglNvdimmWriteCacheSizeInMb": null,
        "fglOverProvisioningFactor": null,
        "fglPerfProfile": null,
        "fglWriteAtomicitySize": null,
        "fragmentationEnabled": true,
        "id": "e0d8f6c900000000",
        "links": [
            {
                "href": "/api/instances/StoragePool::e0d8f6c900000000",
                "rel": "self"
            },
            {
                "href": "/api/instances/StoragePool::e0d8f6c900000000
                        /relationships/Statistics",
                "rel": "/api/StoragePool/relationship/Statistics"
            },
            {
                "href": "/api/instances/StoragePool::e0d8f6c900000000
                        /relationships/SpSds",
                "rel": "/api/StoragePool/relationship/SpSds"
            },
            {
                "href": "/api/instances/StoragePool::e0d8f6c900000000
                        /relationships/Volume",
                "rel": "/api/StoragePool/relationship/Volume"
            },
            {
                "href": "/api/instances/StoragePool::e0d8f6c900000000
                        /relationships/Device",
                "rel": "/api/StoragePool/relationship/Device"
            },
            {
                "href": "/api/instances/StoragePool::e0d8f6c900000000
                        /relationships/VTree",
                "rel": "/api/StoragePool/relationship/VTree"
            },
            {
                "href": "/api/instances/ProtectionDomain::9300c1f900000000",
                "rel": "/api/parent/relationship/protectionDomainId"
            }
        ],
        "statistics": {
                "BackgroundScannedInMB": 3466920,
                "activeBckRebuildCapacityInKb": 0,
                "activeEnterProtectedMaintenanceModeCapacityInKb": 0,
                "aggregateCompressionLevel": "Uncompressed",
                "atRestCapacityInKb": 1248256,
                "backgroundScanCompareErrorCount": 0,
                "backgroundScanFixedCompareErrorCount": 0,
                "bckRebuildReadBwc": {
                    "numOccured": 0,
                    "numSeconds": 0,
                    "totalWeightInKb": 0
                },
                "bckRebuildWriteBwc": {
                    "numOccured": 0,
                    "numSeconds": 0,
                    "totalWeightInKb": 0
                },
                "capacityAvailableForVolumeAllocationInKb": 369098752,
                "capacityInUseInKb": 2496512,
                "capacityInUseNoOverheadInKb": 2496512,
                "capacityLimitInKb": 845783040,
                "compressedDataCompressionRatio": 0.0,
                "compressionRatio": 1.0,
                "currentFglMigrationSizeInKb": 0,
                "deviceIds": [
                ],
                "enterProtectedMaintenanceModeCapacityInKb": 0,
                "enterProtectedMaintenanceModeReadBwc": {
                    "numOccured": 0,
                    "numSeconds": 0,
                    "totalWeightInKb": 0
                },
                "enterProtectedMaintenanceModeWriteBwc": {
                    "numOccured": 0,
                    "numSeconds": 0,
                    "totalWeightInKb": 0
                },
                "exitProtectedMaintenanceModeReadBwc": {
                    "numOccured": 0,
                    "numSeconds": 0,
                    "totalWeightInKb": 0
                },
                "exitProtectedMaintenanceModeWriteBwc": {
                    "numOccured": 0,
                    "numSeconds": 0,
                    "totalWeightInKb": 0
                },
                "exposedCapacityInKb": 0,
                "failedCapacityInKb": 0,
                "fwdRebuildReadBwc": {
                    "numOccured": 0,
                    "numSeconds": 0,
                    "totalWeightInKb": 0
                },
                "fwdRebuildWriteBwc": {
                    "numOccured": 0,
                    "numSeconds": 0,
                    "totalWeightInKb": 0
                },
                "inMaintenanceCapacityInKb": 0,
                "inMaintenanceVacInKb": 0,
                "inUseVacInKb": 184549376,
                "inaccessibleCapacityInKb": 0,
                "logWrittenBlocksInKb": 0,
                "maxCapacityInKb": 845783040,
                "migratingVolumeIds": [
                ],
                "migratingVtreeIds": [
                ],
                "movingCapacityInKb": 0,
                "netCapacityInUseInKb": 1248256,
                "normRebuildCapacityInKb": 0,
                "normRebuildReadBwc": {
                    "numOccured": 0,
                    "numSeconds": 0,
                    "totalWeightInKb": 0
                },
                "normRebuildWriteBwc": {
                    "numOccured": 0,
                    "numSeconds": 0,
                    "totalWeightInKb": 0
                },
                "numOfDeviceAtFaultRebuilds": 0,
                "numOfDevices": 3,
                "numOfIncomingVtreeMigrations": 0,
                "numOfVolumes": 8,
                "numOfVolumesInDeletion": 0,
                "numOfVtrees": 8,
                "overallUsageRatio": 73.92289,
                "pendingBckRebuildCapacityInKb": 0,
                "pendingEnterProtectedMaintenanceModeCapacityInKb": 0,
                "pendingExitProtectedMaintenanceModeCapacityInKb": 0,
                "pendingFwdRebuildCapacityInKb": 0,
                "pendingMovingCapacityInKb": 0,
                "pendingMovingInBckRebuildJobs": 0,
                "persistentChecksumBuilderProgress": 100.0,
                "persistentChecksumCapacityInKb": 414720,
                "primaryReadBwc": {
                    "numOccured": 0,
                    "numSeconds": 0,
                    "totalWeightInKb": 0
                },
                "primaryReadFromDevBwc": {
                    "numOccured": 0,
                    "numSeconds": 0,
                    "totalWeightInKb": 0
                },
                "primaryReadFromRmcacheBwc": {
                    "numOccured": 0,
                    "numSeconds": 0,
                    "totalWeightInKb": 0
                },
                "primaryVacInKb": 92274688,
                "primaryWriteBwc": {
                    "numOccured": 0,
                    "numSeconds": 0,
                    "totalWeightInKb": 0
                },
                "protectedCapacityInKb": 2496512,
                "protectedVacInKb": 184549376,
                "provisionedAddressesInKb": 2496512,
                "rebalanceCapacityInKb": 0,
                "rebalanceReadBwc": {
                    "numOccured": 0,
                    "numSeconds": 0,
                    "totalWeightInKb": 0
                },
                "rebalanceWriteBwc": {
                    "numOccured": 0,
                    "numSeconds": 0,
                    "totalWeightInKb": 0
                },
                "rfacheReadHit": 0,
                "rfacheWriteHit": 0,
                "rfcacheAvgReadTime": 0,
                "rfcacheAvgWriteTime": 0,
                "rfcacheIoErrors": 0,
                "rfcacheIosOutstanding": 0,
                "rfcacheIosSkipped": 0,
                "rfcacheReadMiss": 0,
                "rmPendingAllocatedInKb": 0,
                "rmPendingThickInKb": 0,
                "rplJournalCapAllowed": 0,
                "rplTotalJournalCap": 0,
                "rplUsedJournalCap": 0,
                "secondaryReadBwc": {
                    "numOccured": 0,
                    "numSeconds": 0,
                    "totalWeightInKb": 0
                },
                "secondaryReadFromDevBwc": {
                    "numOccured": 0,
                    "numSeconds": 0,
                    "totalWeightInKb": 0
                },
                "secondaryReadFromRmcacheBwc": {
                    "numOccured": 0,
                    "numSeconds": 0,
                    "totalWeightInKb": 0
                },
                "secondaryVacInKb": 92274688,
                "secondaryWriteBwc": {
                    "numOccured": 0,
                    "numSeconds": 0,
                    "totalWeightInKb": 0
                },
                "semiProtectedCapacityInKb": 0,
                "semiProtectedVacInKb": 0,
                "snapCapacityInUseInKb": 0,
                "snapCapacityInUseOccupiedInKb": 0,
                "snapshotCapacityInKb": 0,
                "spSdsIds": [
                    "abdfe71b00030001",
                    "abdce71d00040001",
                    "abdde71e00050001"
                ],
                "spareCapacityInKb": 84578304,
                "targetOtherLatency": {
                    "numOccured": 0,
                    "numSeconds": 0,
                    "totalWeightInKb": 0
                },
                "targetReadLatency": {
                    "numOccured": 0,
                    "numSeconds": 0,
                    "totalWeightInKb": 0
                },
                "targetWriteLatency": {
                    "numOccured": 0,
                    "numSeconds": 0,
                    "totalWeightInKb": 0
                },
                "tempCapacityInKb": 0,
                "tempCapacityVacInKb": 0,
                "thickCapacityInUseInKb": 0,
                "thinAndSnapshotRatio": 73.92289,
                "thinCapacityAllocatedInKm": 184549376,
                "thinCapacityInUseInKb": 0,
                "thinUserDataCapacityInKb": 2496512,
                "totalFglMigrationSizeInKb": 0,
                "totalReadBwc": {
                    "numOccured": 0,
                    "numSeconds": 0,
                    "totalWeightInKb": 0
                },
                "totalWriteBwc": {
                    "numOccured": 0,
                    "numSeconds": 0,
                    "totalWeightInKb": 0
                },
                "trimmedUserDataCapacityInKb": 0,
                "unreachableUnusedCapacityInKb": 0,
                "unusedCapacityInKb": 758708224,
                "userDataCapacityInKb": 2496512,
                "userDataCapacityNoTrimInKb": 2496512,
                "userDataReadBwc": {
                    "numOccured": 0,
                    "numSeconds": 0,
                    "totalWeightInKb": 0
                },
                "userDataSdcReadLatency": {
                    "numOccured": 0,
                    "numSeconds": 0,
                    "totalWeightInKb": 0
                },
                "userDataSdcTrimLatency": {
                    "numOccured": 0,
                    "numSeconds": 0,
                    "totalWeightInKb": 0
                },
                "userDataSdcWriteLatency": {
                    "numOccured": 0,
                    "numSeconds": 0,
                    "totalWeightInKb": 0
                },
                "userDataTrimBwc": {
                    "numOccured": 0,
                    "numSeconds": 0,
                    "totalWeightInKb": 0
                },
                "userDataWriteBwc": {
                    "numOccured": 0,
                    "numSeconds": 0,
                    "totalWeightInKb": 0
                },
                "volMigrationReadBwc": {
                    "numOccured": 0,
                    "numSeconds": 0,
                    "totalWeightInKb": 0
                },
                "volMigrationWriteBwc": {
                    "numOccured": 0,
                    "numSeconds": 0,
                    "totalWeightInKb": 0
                },
                "volumeAddressSpaceInKb": 922XXXXX,
                "volumeAllocationLimitInKb": 3707XXXXX,
                "volumeIds": [
                    "456afc7900XXXXXXXX"
                ],
                "vtreeAddresSpaceInKb": 92274688,
                "vtreeIds": [
                    "32b1681bXXXXXXXX",
                ]
        },
        "mediaType": "HDD",
        "name": "pool1",
        "numOfParallelRebuildRebalanceJobsPerDevice": 2,
        "persistentChecksumBuilderLimitKb": 3072,
        "persistentChecksumEnabled": true,
        "persistentChecksumState": "Protected",
        "persistentChecksumValidateOnRead": false,
        "protectedMaintenanceModeIoPriorityAppBwPerDeviceThresholdInKbps": null,
        "protectedMaintenanceModeIoPriorityAppIopsPerDeviceThreshold": null,
        "protectedMaintenanceModeIoPriorityBwLimitPerDeviceInKbps": 10240,
        "protectedMaintenanceModeIoPriorityNumOfConcurrentIosPerDevice": 1,
        "protectedMaintenanceModeIoPriorityPolicy": "limitNumOfConcurrentIos",
        "protectedMaintenanceModeIoPriorityQuietPeriodInMsec": null,
        "protectionDomainId": "9300c1f900000000",
        "protectionDomainName": "domain1",
        "rebalanceEnabled": true,
        "rebalanceIoPriorityAppBwPerDeviceThresholdInKbps": null,
        "rebalanceIoPriorityAppIopsPerDeviceThreshold": null,
        "rebalanceIoPriorityBwLimitPerDeviceInKbps": 10240,
        "rebalanceIoPriorityNumOfConcurrentIosPerDevice": 1,
        "rebalanceIoPriorityPolicy": "favorAppIos",
        "rebalanceIoPriorityQuietPeriodInMsec": null,
        "rebuildEnabled": true,
        "rebuildIoPriorityAppBwPerDeviceThresholdInKbps": null,
        "rebuildIoPriorityAppIopsPerDeviceThreshold": null,
        "rebuildIoPriorityBwLimitPerDeviceInKbps": 10240,
        "rebuildIoPriorityNumOfConcurrentIosPerDevice": 1,
        "rebuildIoPriorityPolicy": "limitNumOfConcurrentIos",
        "rebuildIoPriorityQuietPeriodInMsec": null,
        "replicationCapacityMaxRatio": 32,
        "rmcacheWriteHandlingMode": "Cached",
        "sparePercentage": 10,
        "useRfcache": false,
        "useRmcache": false,
        "vtreeMigrationIoPriorityAppBwPerDeviceThresholdInKbps": null,
        "vtreeMigrationIoPriorityAppIopsPerDeviceThreshold": null,
        "vtreeMigrationIoPriorityBwLimitPerDeviceInKbps": 10240,
        "vtreeMigrationIoPriorityNumOfConcurrentIosPerDevice": 1,
        "vtreeMigrationIoPriorityPolicy": "favorAppIos",
        "vtreeMigrationIoPriorityQuietPeriodInMsec": null,
        "zeroPaddingEnabled": true
    }
'''

from ansible.module_utils.basic import AnsibleModule
from ansible_collections.dellemc.powerflex.plugins.module_utils.storage.dell\
    import utils

LOG = utils.get_logger('storagepool')


class PowerFlexStoragePool(object):
    """Class with StoragePool operations"""

    def __init__(self):
        """ Define all parameters required by this module"""

        self.module_params = utils.get_powerflex_gateway_host_parameters()
        self.module_params.update(get_powerflex_storagepool_parameters())

        """ initialize the ansible module """
        mut_ex_args = [['storage_pool_name', 'storage_pool_id'],
                       ['protection_domain_name', 'protection_domain_id'],
                       ['storage_pool_id', 'protection_domain_name'],
                       ['storage_pool_id', 'protection_domain_id']]

        required_one_of_args = [['storage_pool_name', 'storage_pool_id']]
        self.module = AnsibleModule(argument_spec=self.module_params,
                                    supports_check_mode=False,
                                    mutually_exclusive=mut_ex_args,
                                    required_one_of=required_one_of_args)

        utils.ensure_required_libs(self.module)

        try:
            self.powerflex_conn = utils.get_powerflex_gateway_host_connection(
                self.module.params)
            LOG.info('Got the PowerFlex system connection object instance')
        except Exception as e:
            LOG.error(str(e))
            self.module.fail_json(msg=str(e))

    def get_protection_domain(self, protection_domain_name=None,
                              protection_domain_id=None):
        """Get protection domain details
            :param protection_domain_name: Name of the protection domain
            :param protection_domain_id: ID of the protection domain
            :return: Protection domain details
        """
        name_or_id = protection_domain_id if protection_domain_id \
            else protection_domain_name
        try:
            filter_fields = {}
            if protection_domain_id:
                filter_fields = {'id': protection_domain_id}
            if protection_domain_name:
                filter_fields = {'name': protection_domain_name}

            pd_details = self.powerflex_conn.protection_domain.get(
                filter_fields=filter_fields)
            if pd_details:
                return pd_details[0]

            if not pd_details:
                err_msg = "Unable to find the protection domain with {0}. " \
                          "Please enter a valid protection domain" \
                          " name/id.".format(name_or_id)
                self.module.fail_json(msg=err_msg)

        except Exception as e:
            errormsg = "Failed to get the protection domain {0} with" \
                       " error {1}".format(name_or_id, str(e))
            LOG.error(errormsg)
            self.module.fail_json(msg=errormsg)

    def get_storage_pool(self, storage_pool_id=None, storage_pool_name=None,
                         pd_id=None):
        """Get storage pool details
            :param pd_id: ID of the protection domain
            :param storage_pool_name: The name of the storage pool
            :param storage_pool_id: The storage pool id
            :return: Storage pool details
        """
        name_or_id = storage_pool_id if storage_pool_id \
            else storage_pool_name
        try:
            filter_fields = {}
            if storage_pool_id:
                filter_fields = {'id': storage_pool_id}
            if storage_pool_name:
                filter_fields.update({'name': storage_pool_name})
            if pd_id:
                filter_fields.update({'protectionDomainId': pd_id})
            pool_details = self.powerflex_conn.storage_pool.get(
                filter_fields=filter_fields)
            if pool_details:
                if len(pool_details) > 1:

                    err_msg = "More than one storage pool found with {0}," \
                              " Please provide protection domain Name/Id" \
                              " to fetch the unique" \
                              " storage pool".format(storage_pool_name)
                    LOG.error(err_msg)
                    self.module.fail_json(msg=err_msg)
                elif len(pool_details) == 1:
                    pool_details = pool_details[0]
                    statistics = self.powerflex_conn.storage_pool.get_statistics(pool_details['id'])
                    pool_details['statistics'] = statistics if statistics else {}
                    pd_id = pool_details['protectionDomainId']
                    pd_name = self.get_protection_domain(
                        protection_domain_id=pd_id)['name']
                    # adding protection domain name in the pool details
                    pool_details['protectionDomainName'] = pd_name
                else:
                    pool_details = None

            return pool_details

        except Exception as e:
            errormsg = "Failed to get the storage pool {0} with error " \
                       "{1}".format(name_or_id, str(e))
            LOG.error(errormsg)
            self.module.fail_json(msg=errormsg)

    def create_storage_pool(self, pool_name, pd_id, media_type,
                            use_rfcache=None, use_rmcache=None):
        """
        Create a storage pool
        :param pool_name: Name of the storage pool
        :param pd_id: ID of the storage pool
        :param media_type: Type of storage device in the pool
        :param use_rfcache: Enable/Disable RFcache on pool
        :param use_rmcache: Enable/Disable RMcache on pool
        :return: True, if the operation is successful
        """
        try:
            if media_type == "Transitional":
                self.module.fail_json(msg="TRANSITIONAL media type is not"
                                          " supported during creation."
                                          " Please enter a valid media type")

            if pd_id is None:
                self.module.fail_json(
                    msg="Please provide protection domain details for "
                        "creation of a storage pool")
            self.powerflex_conn.storage_pool.create(
                media_type=media_type,
                protection_domain_id=pd_id, name=pool_name,
                use_rfcache=use_rfcache, use_rmcache=use_rmcache)

            return True
        except Exception as e:
            errormsg = "Failed to create the storage pool {0} with error " \
                       "{1}".format(pool_name, str(e))
            LOG.error(errormsg)
            self.module.fail_json(msg=errormsg)

    def modify_storage_pool(self, pool_id, modify_dict):
        """
        Modify the parameters of the storage pool.
        :param modify_dict: Dict containing parameters which are to be
         modified
        :param pool_id: Id of the pool.
        :return: True, if the operation is successful.
        """

        try:

            if 'new_name' in modify_dict:
                self.powerflex_conn.storage_pool.rename(
                    pool_id, modify_dict['new_name'])
            if 'use_rmcache' in modify_dict:
                self.powerflex_conn.storage_pool.set_use_rmcache(
                    pool_id, modify_dict['use_rmcache'])
            if 'use_rfcache' in modify_dict:
                self.powerflex_conn.storage_pool.set_use_rfcache(
                    pool_id, modify_dict['use_rfcache'])
            if 'media_type' in modify_dict:
                self.powerflex_conn.storage_pool.set_media_type(
                    pool_id, modify_dict['media_type'])
            return True

        except Exception as e:
            err_msg = "Failed to update the storage pool {0} with error " \
                      "{1}".format(pool_id, str(e))
            LOG.error(err_msg)
            self.module.fail_json(msg=err_msg)

    def verify_params(self, pool_details, pd_name, pd_id):
        """
        :param pool_details: Details of the storage pool
        :param pd_name: Name of the protection domain
        :param pd_id: Id of the protection domain
        """
        if pd_id and pd_id != pool_details['protectionDomainId']:
            self.module.fail_json(msg="Entered protection domain id does not"
                                      " match with the storage pool's "
                                      "protection domain id. Please enter "
                                      "a correct protection domain id.")

        if pd_name and pd_name != pool_details['protectionDomainName']:
            self.module.fail_json(msg="Entered protection domain name does"
                                      " not match with the storage pool's "
                                      "protection domain name. Please enter"
                                      " a correct protection domain name.")

    def perform_module_operation(self):
        """ Perform different actions on Storage Pool based on user input
            in the playbook """

        pool_name = self.module.params['storage_pool_name']
        pool_id = self.module.params['storage_pool_id']
        pool_new_name = self.module.params['storage_pool_new_name']
        state = self.module.params['state']
        pd_name = self.module.params['protection_domain_name']
        pd_id = self.module.params['protection_domain_id']
        use_rmcache = self.module.params['use_rmcache']
        use_rfcache = self.module.params['use_rfcache']
        media_type = self.module.params['media_type']
        if media_type == "TRANSITIONAL":
            media_type = 'Transitional'

        result = dict(
            storage_pool_details={}
        )
        changed = False
        pd_details = None
        if pd_name or pd_id:
            pd_details = self.get_protection_domain(
                protection_domain_id=pd_id,
                protection_domain_name=pd_name)
        if pd_details:
            pd_id = pd_details['id']

        if pool_name is not None and (len(pool_name.strip()) == 0):
            self.module.fail_json(
                msg="Empty or white spaced string provided in "
                    "storage_pool_name. Please provide valid storage"
                    " pool name.")

        # Get the details of the storage pool.
        pool_details = self.get_storage_pool(storage_pool_id=pool_id,
                                             storage_pool_name=pool_name,
                                             pd_id=pd_id)
        if pool_name and pool_details:
            pool_id = pool_details['id']
            self.verify_params(pool_details, pd_name, pd_id)

        # create a storage pool
        if state == 'present' and not pool_details:
            LOG.info("Creating new storage pool")
            if pool_id:
                self.module.fail_json(
                    msg="storage_pool_name is missing & name required to "
                        "create a storage pool. Please enter a valid "
                        "storage_pool_name.")
            if pool_new_name is not None:
                self.module.fail_json(
                    msg="storage_pool_new_name is passed during creation. "
                        "storage_pool_new_name is not allowed during "
                        "creation of a storage pool.")
            changed = self.create_storage_pool(
                pool_name, pd_id, media_type, use_rfcache, use_rmcache)
            if changed:
                pool_id = self.get_storage_pool(storage_pool_id=pool_id,
                                                storage_pool_name=pool_name,
                                                pd_id=pd_id)['id']

        # modify the storage pool parameters
        if state == 'present' and pool_details:
            # check if the parameters are to be updated or not
            if pool_new_name is not None and len(pool_new_name.strip()) == 0:
                self.module.fail_json(
                    msg="Empty/White spaced name is not allowed during "
                        "renaming of a storage pool. Please enter a valid "
                        "storage pool new name.")
            modify_dict = to_modify(pool_details, use_rmcache, use_rfcache,
                                    pool_new_name, media_type)
            if bool(modify_dict):
                LOG.info("Modify attributes of storage pool")
                changed = self.modify_storage_pool(pool_id, modify_dict)

        # Delete a storage pool
        if state == 'absent' and pool_details:
            msg = "Deleting storage pool is not supported through" \
                  " ansible module."
            LOG.error(msg)
            self.module.fail_json(msg=msg)

        # Show the updated storage pool details
        if state == 'present':
            pool_details = self.get_storage_pool(storage_pool_id=pool_id)
            # fetching Id from pool details to address a case where
            # protection domain is not passed
            pd_id = pool_details['protectionDomainId']
            pd_name = self.get_protection_domain(
                protection_domain_id=pd_id)['name']
            # adding protection domain name in the pool details
            pool_details['protectionDomainName'] = pd_name
            result['storage_pool_details'] = pool_details
        result['changed'] = changed

        self.module.exit_json(**result)


def to_modify(pool_details, use_rmcache, use_rfcache, new_name, media_type):
    """
    Check whether a parameter is required to be updated.

    :param media_type:  Type of the media supported by the pool.
    :param pool_details: Details of the storage pool
    :param use_rmcache: Enable/Disable RMcache on pool
    :param use_rfcache: Enable/Disable RFcache on pool
    :param new_name: New name for the storage pool
    :return: dict, containing parameters to be modified
    """
    pool_name = pool_details['name']
    pool_use_rfcache = pool_details['useRfcache']
    pool_use_rmcache = pool_details['useRmcache']
    pool_media_type = pool_details['mediaType']
    modify_params = {}

    if new_name is not None and pool_name != new_name:
        modify_params['new_name'] = new_name
    if use_rfcache is not None and pool_use_rfcache != use_rfcache:
        modify_params['use_rfcache'] = use_rfcache
    if use_rmcache is not None and pool_use_rmcache != use_rmcache:
        modify_params['use_rmcache'] = use_rmcache
    if media_type is not None and media_type != pool_media_type:
        modify_params['media_type'] = media_type
    return modify_params


def get_powerflex_storagepool_parameters():
    """This method provides parameters required for the ansible
    Storage Pool module on powerflex"""
    return dict(
        storage_pool_name=dict(required=False, type='str'),
        storage_pool_id=dict(required=False, type='str'),
        protection_domain_name=dict(required=False, type='str'),
        protection_domain_id=dict(required=False, type='str'),
        media_type=dict(required=False, type='str',
                        choices=['HDD', 'SSD', 'TRANSITIONAL']),
        use_rfcache=dict(required=False, type='bool'),
        use_rmcache=dict(required=False, type='bool'),
        storage_pool_new_name=dict(required=False, type='str'),
        state=dict(required=True, type='str', choices=['present', 'absent']))


def main():
    """ Create PowerFlex Storage Pool object and perform action on it
        based on user input from playbook"""
    obj = PowerFlexStoragePool()
    obj.perform_module_operation()


if __name__ == '__main__':
    main()

Anon7 - 2022
AnonSec Team