def __init__(self):

        self.module_arg_spec = dict(
            resource_group=dict(type='str', required=True),
            name=dict(type='str', required=True),
            file_path=dict(type='str', required=False),
            pool_name=dict(type='str', required=True),
            account_name=dict(type='str', required=True),
            location=dict(type='str', required=False),
            state=dict(choices=['present', 'absent'], default='present', type='str'),
            subnet_name=dict(type='str', required=False, aliases=['subnet_id']),
            virtual_network=dict(type='str', required=False),
            size=dict(type='int', required=False),
            vnet_resource_group_for_subnet=dict(type='str', required=False),
            service_level=dict(type='str', required=False, choices=['Premium', 'Standard', 'Ultra']),
            protocol_types=dict(type='list', elements='str')
        )
        self.module = AnsibleModule(
            argument_spec=self.module_arg_spec,
            required_if=[
                ('state', 'present', ['location', 'file_path', 'subnet_name', 'virtual_network']),
            ],
            supports_check_mode=True
        )
        self.na_helper = NetAppModule()
        self.parameters = self.na_helper.set_parameters(self.module.params)

        self.fail_when_import_errors(IMPORT_ERRORS, HAS_AZURE_MGMT_NETAPP)
        super(AzureRMNetAppVolume, self).__init__(derived_arg_spec=self.module_arg_spec, supports_check_mode=True)
Example #2
0
    def __init__(self):

        self.module_arg_spec = dict(resource_group=dict(type='str',
                                                        required=True),
                                    name=dict(type='str', required=True),
                                    volume_name=dict(type='str',
                                                     required=True),
                                    pool_name=dict(type='str', required=True),
                                    account_name=dict(type='str',
                                                      required=True),
                                    location=dict(type='str', required=False),
                                    state=dict(choices=['present', 'absent'],
                                               default='present',
                                               type='str'))
        self.module = AnsibleModule(argument_spec=self.module_arg_spec,
                                    required_if=[
                                        ('state', 'present', ['location']),
                                    ],
                                    supports_check_mode=True)
        self.na_helper = NetAppModule()
        self.parameters = self.na_helper.set_parameters(self.module.params)

        self.fail_when_import_errors(IMPORT_ERRORS, HAS_AZURE_MGMT_NETAPP)
        super(AzureRMNetAppSnapshot,
              self).__init__(derived_arg_spec=self.module_arg_spec,
                             supports_check_mode=True)
Example #3
0
    def __init__(self):

        self.module_arg_spec = dict(
            resource_group=dict(type='str', required=True),
            name=dict(type='str', required=True),
            account_name=dict(type='str', required=True),
            location=dict(type='str', required=False),
            state=dict(choices=['present', 'absent'], default='present', type='str'),
            size=dict(type='int', required=False, default=1),
            service_level=dict(type='str', required=False, choices=['Standard', 'Premium', 'Ultra']),
        )
        self.module = AnsibleModule(
            argument_spec=self.module_arg_spec,
            required_if=[
                ('state', 'present', ['location', 'service_level']),
            ],
            supports_check_mode=True
        )
        self.na_helper = NetAppModule()
        self.parameters = self.na_helper.set_parameters(self.module.params)

        if HAS_AZURE_MGMT_NETAPP is False:
            self.module.fail_json(msg="the python Azure-mgmt-NetApp module is required")
        super(AzureRMNetAppCapacityPool, self).__init__(derived_arg_spec=self.module_arg_spec,
                                                        supports_check_mode=True)
    def __init__(self):

        self.module_arg_spec = dict(
            resource_group=dict(type='str', required=True),
            name=dict(type='str', required=True),
            location=dict(type='str', required=False),
            state=dict(choices=['present', 'absent'],
                       default='present',
                       type='str'),
            tags=dict(type='dict', required=False),
            active_directories=dict(type='list',
                                    elements='dict',
                                    options=dict(
                                        active_directory_id=dict(type='str'),
                                        dns=dict(type='list', elements='str'),
                                        domain=dict(type='str'),
                                        site=dict(type='str'),
                                        smb_server_name=dict(type='str'),
                                        organizational_unit=dict(type='str'),
                                        username=dict(type='str'),
                                        password=dict(type='str', no_log=True),
                                        aes_encryption=dict(type='bool'),
                                        ldap_signing=dict(type='bool'),
                                    )),
            debug=dict(type='bool', default=False))
        self.module = AnsibleModule(argument_spec=self.module_arg_spec,
                                    required_if=[
                                        ('state', 'present', ['location']),
                                    ],
                                    supports_check_mode=True)
        self.na_helper = NetAppModule()
        self.parameters = self.na_helper.set_parameters(self.module.params)
        self.debug = list()
        self.warnings = list()

        if HAS_AZURE_MGMT_NETAPP is False:
            self.module.fail_json(
                msg="the python Azure-mgmt-NetApp module is required")
        super(AzureRMNetAppAccount,
              self).__init__(derived_arg_spec=self.module_arg_spec,
                             supports_check_mode=True)
    def __init__(self):

        self.module_arg_spec = dict(
            resource_group=dict(type='str', required=True),
            name=dict(type='str', required=True),
            location=dict(type='str'),
            state=dict(choices=['present', 'absent'],
                       default='present',
                       type='str'),
        )
        self.module = AnsibleModule(argument_spec=self.module_arg_spec,
                                    supports_check_mode=True)
        self.na_helper = NetAppModule()
        self.parameters = self.na_helper.set_parameters(self.module.params)

        if HAS_AZURE_MGMT_NETAPP is False:
            self.module.fail_json(
                msg="the python Azure-mgmt-NetApp module is required")
        super(AzureRMNetAppAccount,
              self).__init__(derived_arg_spec=self.module_arg_spec,
                             supports_check_mode=True)
Example #6
0
class AzureRMNetAppSnapshot(AzureRMNetAppModuleBase):
    """ crate or delete snapshots """
    def __init__(self):

        self.module_arg_spec = dict(resource_group=dict(type='str',
                                                        required=True),
                                    name=dict(type='str', required=True),
                                    volume_name=dict(type='str',
                                                     required=True),
                                    pool_name=dict(type='str', required=True),
                                    account_name=dict(type='str',
                                                      required=True),
                                    location=dict(type='str', required=False),
                                    state=dict(choices=['present', 'absent'],
                                               default='present',
                                               type='str'))
        self.module = AnsibleModule(argument_spec=self.module_arg_spec,
                                    required_if=[
                                        ('state', 'present', ['location']),
                                    ],
                                    supports_check_mode=True)
        self.na_helper = NetAppModule()
        self.parameters = self.na_helper.set_parameters(self.module.params)

        self.fail_when_import_errors(IMPORT_ERRORS, HAS_AZURE_MGMT_NETAPP)
        super(AzureRMNetAppSnapshot,
              self).__init__(derived_arg_spec=self.module_arg_spec,
                             supports_check_mode=True)

    def get_azure_netapp_snapshot(self):
        """
            Returns snapshot object for an existing snapshot
            Return None if snapshot does not exist
        """
        try:
            snapshot_get = self.netapp_client.snapshots.get(
                self.parameters['resource_group'],
                self.parameters['account_name'], self.parameters['pool_name'],
                self.parameters['volume_name'], self.parameters['name'])
        except (CloudError, ResourceNotFoundError):  # snapshot does not exist
            return None
        return snapshot_get

    def create_azure_netapp_snapshot(self):
        """
            Create a snapshot for the given Azure NetApp Account
            :return: None
        """
        kw_args = dict(resource_group_name=self.parameters['resource_group'],
                       account_name=self.parameters['account_name'],
                       pool_name=self.parameters['pool_name'],
                       volume_name=self.parameters['volume_name'],
                       snapshot_name=self.parameters['name'])
        if self.new_style:
            kw_args['body'] = Snapshot(location=self.parameters['location'])
        else:
            kw_args['location'] = self.parameters['location']
        try:
            self.get_method('snapshots', 'create')(**kw_args)
        except (CloudError, AzureError) as error:
            self.module.fail_json(
                msg='Error creating snapshot %s for Azure NetApp account %s: %s'
                % (self.parameters['name'], self.parameters['account_name'],
                   to_native(error)),
                exception=traceback.format_exc())

    def delete_azure_netapp_snapshot(self):
        """
            Delete a snapshot for the given Azure NetApp Account
            :return: None
        """
        try:
            self.get_method('snapshots', 'delete')(
                resource_group_name=self.parameters['resource_group'],
                account_name=self.parameters['account_name'],
                pool_name=self.parameters['pool_name'],
                volume_name=self.parameters['volume_name'],
                snapshot_name=self.parameters['name'])
        except (CloudError, AzureError) as error:
            self.module.fail_json(
                msg='Error deleting snapshot %s for Azure NetApp account %s: %s'
                % (self.parameters['name'], self.parameters['account_name'],
                   to_native(error)),
                exception=traceback.format_exc())

    def exec_module(self, **kwargs):
        current = self.get_azure_netapp_snapshot()
        cd_action = self.na_helper.get_cd_action(current, self.parameters)

        if self.na_helper.changed:
            if self.module.check_mode:
                pass
            else:
                if cd_action == 'create':
                    self.create_azure_netapp_snapshot()
                elif cd_action == 'delete':
                    self.delete_azure_netapp_snapshot()

        self.module.exit_json(changed=self.na_helper.changed)
Example #7
0
class AzureRMNetAppCapacityPool(AzureRMNetAppModuleBase):

    def __init__(self):

        self.module_arg_spec = dict(
            resource_group=dict(type='str', required=True),
            name=dict(type='str', required=True),
            account_name=dict(type='str', required=True),
            location=dict(type='str', required=False),
            state=dict(choices=['present', 'absent'], default='present', type='str'),
            size=dict(type='int', required=False, default=1),
            service_level=dict(type='str', required=False, choices=['Standard', 'Premium', 'Ultra']),
        )
        self.module = AnsibleModule(
            argument_spec=self.module_arg_spec,
            required_if=[
                ('state', 'present', ['location', 'service_level']),
            ],
            supports_check_mode=True
        )
        self.na_helper = NetAppModule()
        self.parameters = self.na_helper.set_parameters(self.module.params)

        if HAS_AZURE_MGMT_NETAPP is False:
            self.module.fail_json(msg="the python Azure-mgmt-NetApp module is required")
        super(AzureRMNetAppCapacityPool, self).__init__(derived_arg_spec=self.module_arg_spec,
                                                        supports_check_mode=True)

    def get_azure_netapp_capacity_pool(self):
        """
            Returns capacity pool object for an existing pool
            Return None if capacity pool does not exist
        """
        try:
            capacity_pool_get = self.netapp_client.pools.get(self.parameters['resource_group'],
                                                             self.parameters['account_name'], self.parameters['name'])
        except CloudError:  # capacity pool does not exist
            return None
        return capacity_pool_get

    def create_azure_netapp_capacity_pool(self):
        """
            Create a capacity pool for the given Azure NetApp Account
            :return: None
        """
        capacity_pool_body = CapacityPool(
            location=self.parameters['location'],
            size=self.parameters['size'] * SIZE_POOL,
            service_level=self.parameters['service_level']
        )
        try:
            self.netapp_client.pools.create_or_update(body=capacity_pool_body, resource_group_name=self.parameters['resource_group'],
                                                      account_name=self.parameters['account_name'],
                                                      pool_name=self.parameters['name'])
        except CloudError as error:
            self.module.fail_json(msg='Error creating capacity pool %s for Azure NetApp account %s: %s'
                                      % (self.parameters['name'], self.parameters['account_name'], to_native(error)),
                                  exception=traceback.format_exc())

    def modify_azure_netapp_capacity_pool(self, modify):
        """
            Modify a capacity pool for the given Azure NetApp Account
            :return: None
        """
        capacity_pool_body = CapacityPool(
            location=self.parameters['location'],
            service_level=self.parameters['service_level'],
            size=self.parameters['size'] * SIZE_POOL
        )
        try:
            self.netapp_client.pools.update(body=capacity_pool_body, resource_group_name=self.parameters['resource_group'],
                                            account_name=self.parameters['account_name'],
                                            pool_name=self.parameters['name'])
        except CloudError as error:
            self.module.fail_json(msg='Error modifying capacity pool %s for Azure NetApp account %s: %s'
                                      % (self.parameters['name'], self.parameters['account_name'], to_native(error)),
                                  exception=traceback.format_exc())

    def delete_azure_netapp_capacity_pool(self):
        """
            Delete a capacity pool for the given Azure NetApp Account
            :return: None
        """
        try:
            self.netapp_client.pools.delete(resource_group_name=self.parameters['resource_group'],
                                            account_name=self.parameters['account_name'], pool_name=self.parameters['name'])
        except CloudError as error:
            self.module.fail_json(msg='Error deleting capacity pool %s for Azure NetApp account %s: %s'
                                      % (self.parameters['name'], self.parameters['name'], to_native(error)),
                                  exception=traceback.format_exc())

    def exec_module(self, **kwargs):
        modify = {}
        current = self.get_azure_netapp_capacity_pool()
        cd_action = self.na_helper.get_cd_action(current, self.parameters)
        if cd_action is None and self.parameters['state'] == 'present':
            current = vars(current)
            # to match with the unit of size input
            current['size'] = int(current['size'] / SIZE_POOL)
            # get_azure_netapp_capacity_pool() returns pool name with account name appended in front of it like 'account/pool'
            current['name'] = self.parameters['name']
            modify = self.na_helper.get_modified_attributes(current, self.parameters)

        if self.na_helper.changed:
            if self.module.check_mode:
                pass
            else:
                if cd_action == 'create':
                    self.create_azure_netapp_capacity_pool()
                elif cd_action == 'delete':
                    self.delete_azure_netapp_capacity_pool()
                elif modify:
                    self.modify_azure_netapp_capacity_pool(modify)

        self.module.exit_json(changed=self.na_helper.changed)
Example #8
0
class AzureRMNetAppVolume(AzureRMNetAppModuleBase):
    ''' create or delete a volume '''
    def __init__(self):

        self.module_arg_spec = dict(
            resource_group=dict(type='str', required=True),
            name=dict(type='str', required=True),
            file_path=dict(type='str', required=False),
            pool_name=dict(type='str', required=True),
            account_name=dict(type='str', required=True),
            location=dict(type='str', required=False),
            state=dict(choices=['present', 'absent'],
                       default='present',
                       type='str'),
            subnet_name=dict(type='str', required=False,
                             aliases=['subnet_id']),
            virtual_network=dict(type='str', required=False),
            size=dict(type='int', required=False),
            vnet_resource_group_for_subnet=dict(type='str', required=False),
            service_level=dict(type='str',
                               required=False,
                               choices=['Premium', 'Standard', 'Ultra']),
            protocol_types=dict(type='list', elements='str'))
        self.module = AnsibleModule(argument_spec=self.module_arg_spec,
                                    required_if=[
                                        ('state', 'present', [
                                            'location', 'file_path',
                                            'subnet_name', 'virtual_network'
                                        ]),
                                    ],
                                    supports_check_mode=True)
        self.na_helper = NetAppModule()
        self.parameters = self.na_helper.set_parameters(self.module.params)

        if HAS_AZURE_MGMT_NETAPP is False:
            self.module.fail_json(
                msg="the python Azure-mgmt-NetApp module is required")
        super(AzureRMNetAppVolume,
              self).__init__(derived_arg_spec=self.module_arg_spec,
                             supports_check_mode=True)

    def get_azure_netapp_volume(self):
        """
            Returns volume object for an existing volume
            Return None if volume does not exist
        """
        try:
            volume_get = self.netapp_client.volumes.get(
                self.parameters['resource_group'],
                self.parameters['account_name'], self.parameters['pool_name'],
                self.parameters['name'])
        except CloudError:  # volume does not exist
            return None
        return volume_get

    def get_export_policy_rules(self):
        # ExportPolicyRule(rule_index: int=None, unix_read_only: bool=None, unix_read_write: bool=None,
        # kerberos5_read_only: bool=False, kerberos5_read_write: bool=False, kerberos5i_read_only: bool=False,
        # kerberos5i_read_write: bool=False, kerberos5p_read_only: bool=False, kerberos5p_read_write: bool=False,
        # cifs: bool=None, nfsv3: bool=None, nfsv41: bool=None, allowed_clients: str=None, has_root_access: bool=True
        ptypes = self.parameters.get('protocol_types')
        if ptypes is None:
            return None
        ptypes = [x.lower() for x in ptypes]
        if 'nfsv4.1' in ptypes:
            ptypes.append('nfsv41')
        else:
            return None
        # only create a policy when NFSv4 is used (for now)
        options = dict(rule_index=1,
                       allowed_clients='0.0.0.0/0',
                       unix_read_write=True)
        for protocol in ('cifs', 'nfsv3', 'nfsv41'):
            options[protocol] = protocol in ptypes
        if options:
            return VolumePropertiesExportPolicy(
                rules=[ExportPolicyRule(**options)])
        return None

    def create_azure_netapp_volume(self):
        """
            Create a volume for the given Azure NetApp Account
            :return: None
        """
        options = dict()
        for attr in ('protocol_types', 'service_level', 'size'):
            value = self.parameters.get(attr)
            if value is not None:
                if attr == 'size':
                    attr = 'usage_threshold'
                    value *= ONE_GIB
                options[attr] = value
        rules = self.get_export_policy_rules()
        if rules is not None:
            options['export_policy'] = rules
        subnet_id = '/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Network/virtualNetworks/%s/subnets/%s'\
                    % (self.netapp_client.config.subscription_id,
                       self.parameters['resource_group'] if self.parameters.get('vnet_resource_group_for_subnet') is None
                       else self.parameters['vnet_resource_group_for_subnet'],
                       self.parameters['virtual_network'],
                       self.parameters['subnet_name'])
        volume_body = Volume(location=self.parameters['location'],
                             creation_token=self.parameters['file_path'],
                             subnet_id=subnet_id,
                             **options)
        try:
            result = self.netapp_client.volumes.create_or_update(
                body=volume_body,
                resource_group_name=self.parameters['resource_group'],
                account_name=self.parameters['account_name'],
                pool_name=self.parameters['pool_name'],
                volume_name=self.parameters['name'])
            # waiting till the status turns Succeeded
            while result.done() is not True:
                result.result(10)
        except (CloudError, ValidationError) as error:
            self.module.fail_json(
                msg=
                'Error creating volume %s for Azure NetApp account %s and subnet ID %s: %s'
                % (self.parameters['name'], self.parameters['account_name'],
                   subnet_id, to_native(error)),
                exception=traceback.format_exc())

    def delete_azure_netapp_volume(self):
        """
            Delete a volume for the given Azure NetApp Account
            :return: None
        """
        try:
            result = self.netapp_client.volumes.delete(
                resource_group_name=self.parameters['resource_group'],
                account_name=self.parameters['account_name'],
                pool_name=self.parameters['pool_name'],
                volume_name=self.parameters['name'])
            # waiting till the status turns Succeeded
            while result.done() is not True:
                result.result(10)
        except CloudError as error:
            self.module.fail_json(
                msg='Error deleting volume %s for Azure NetApp account %s: %s'
                % (self.parameters['name'], self.parameters['account_name'],
                   to_native(error)),
                exception=traceback.format_exc())

    def exec_module(self, **kwargs):
        current = self.get_azure_netapp_volume()
        cd_action = self.na_helper.get_cd_action(current, self.parameters)

        if self.na_helper.changed:
            if self.module.check_mode:
                pass
            else:
                if cd_action == 'create':
                    self.create_azure_netapp_volume()
                elif cd_action == 'delete':
                    self.delete_azure_netapp_volume()

        return_info = ''
        if self.parameters['state'] == 'present':
            return_info = self.get_azure_netapp_volume()
            if return_info is None:
                self.module.fail_json(
                    msg=
                    'Error: volume %s was created successfully, but cannot be found.'
                    % self.parameters['name'])
            if return_info.mount_targets is None:
                self.module.fail_json(
                    msg=
                    'Error: volume %s was created successfully, but mount target(s) cannot be found - volume details: %s.'
                    % (self.parameters['name'], str(return_info)))
            return_info = '%s:/%s' % (return_info.mount_targets[0].ip_address,
                                      return_info.creation_token)
        self.module.exit_json(changed=self.na_helper.changed,
                              msg=str(return_info))
class AzureRMNetAppAccount(AzureRMNetAppModuleBase):
    def __init__(self):

        self.module_arg_spec = dict(
            resource_group=dict(type='str', required=True),
            name=dict(type='str', required=True),
            location=dict(type='str'),
            state=dict(choices=['present', 'absent'],
                       default='present',
                       type='str'),
        )
        self.module = AnsibleModule(argument_spec=self.module_arg_spec,
                                    supports_check_mode=True)
        self.na_helper = NetAppModule()
        self.parameters = self.na_helper.set_parameters(self.module.params)

        if HAS_AZURE_MGMT_NETAPP is False:
            self.module.fail_json(
                msg="the python Azure-mgmt-NetApp module is required")
        super(AzureRMNetAppAccount,
              self).__init__(derived_arg_spec=self.module_arg_spec,
                             supports_check_mode=True)

    def get_azure_netapp_account(self):
        """
            Returns NetApp Account object for an existing account
            Return None if account does not exist
        """
        try:
            account_get = self.netapp_client.accounts.get(
                self.parameters['resource_group'], self.parameters['name'])
        except CloudError:  # account does not exist
            return None
        return account_get

    def create_azure_netapp_account(self):
        """
            Create an Azure NetApp Account
            :return: None
        """
        account_body = NetAppAccount(location=self.parameters['location'])
        try:
            self.netapp_client.accounts.create_or_update(
                body=account_body,
                resource_group_name=self.parameters['resource_group'],
                account_name=self.parameters['name'])
        except CloudError as error:
            self.module.fail_json(
                msg='Error creating Azure NetApp account %s: %s' %
                (self.parameters['name'], to_native(error)),
                exception=traceback.format_exc())

    def delete_azure_netapp_account(self):
        """
            Delete an Azure NetApp Account
            :return: None
        """
        try:
            self.netapp_client.accounts.delete(
                resource_group_name=self.parameters['resource_group'],
                account_name=self.parameters['name'])
        except CloudError as error:
            self.module.fail_json(
                msg='Error deleting Azure NetApp account %s: %s' %
                (self.parameters['name'], to_native(error)),
                exception=traceback.format_exc())

    def exec_module(self, **kwargs):
        current = self.get_azure_netapp_account()
        cd_action = self.na_helper.get_cd_action(current, self.parameters)

        if self.na_helper.changed:
            if self.module.check_mode:
                pass
            else:
                if cd_action == 'create':
                    self.create_azure_netapp_account()
                elif cd_action == 'delete':
                    self.delete_azure_netapp_account()

        self.module.exit_json(changed=self.na_helper.changed)
class AzureRMNetAppVolume(AzureRMNetAppModuleBase):
    def __init__(self):

        self.module_arg_spec = dict(
            resource_group=dict(type='str', required=True),
            name=dict(type='str', required=True),
            file_path=dict(type='str', required=False),
            pool_name=dict(type='str', required=True),
            account_name=dict(type='str', required=True),
            location=dict(type='str', required=False),
            state=dict(choices=['present', 'absent'],
                       default='present',
                       type='str'),
            subnet_id=dict(type='str', required=False),
            virtual_network=dict(type='str', required=False),
            size=dict(type='int', required=False),
            vnet_resource_group_for_subnet=dict(type='str', required=False),
            service_level=dict(type='str',
                               required=False,
                               choices=['Premium', 'Standard', 'Ultra']))
        self.module = AnsibleModule(argument_spec=self.module_arg_spec,
                                    required_if=[
                                        ('state', 'present', [
                                            'location', 'file_path',
                                            'subnet_id', 'virtual_network'
                                        ]),
                                    ],
                                    supports_check_mode=True)
        self.na_helper = NetAppModule()
        self.parameters = self.na_helper.set_parameters(self.module.params)

        if HAS_AZURE_MGMT_NETAPP is False:
            self.module.fail_json(
                msg="the python Azure-mgmt-NetApp module is required")
        super(AzureRMNetAppVolume,
              self).__init__(derived_arg_spec=self.module_arg_spec,
                             supports_check_mode=True)

    def get_azure_netapp_volume(self):
        """
            Returns volume object for an existing volume
            Return None if volume does not exist
        """
        try:
            volume_get = self.netapp_client.volumes.get(
                self.parameters['resource_group'],
                self.parameters['account_name'], self.parameters['pool_name'],
                self.parameters['name'])
        except CloudError:  # volume does not exist
            return None
        return volume_get

    def create_azure_netapp_volume(self):
        """
            Create a volume for the given Azure NetApp Account
            :return: None
        """
        volume_body = Volume(
            location=self.parameters['location'],
            creation_token=self.parameters['file_path'],
            service_level=self.parameters['service_level']
            if self.parameters.get('service_level') is not None else 'Premium',
            usage_threshold=(self.parameters['size'] if self.parameters.get(
                'size') is not None else 100) * ONE_GIB,
            subnet_id=
            '/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Network/virtualNetworks/%s/subnets/%s'
            %
            (self.netapp_client.config.subscription_id,
             self.parameters['resource_group']
             if self.parameters.get('vnet_resource_group_for_subnet') is None
             else self.parameters['vnet_resource_group_for_subnet'],
             self.parameters['virtual_network'], self.parameters['subnet_id']))
        try:
            result = self.netapp_client.volumes.create_or_update(
                body=volume_body,
                resource_group_name=self.parameters['resource_group'],
                account_name=self.parameters['account_name'],
                pool_name=self.parameters['pool_name'],
                volume_name=self.parameters['name'])
            # waiting till the status turns Succeeded
            while result.done() is not True:
                result.result(10)
        except CloudError as error:
            self.module.fail_json(
                msg=
                'Error creating volume %s for Azure NetApp account %s and subnet ID %s: %s'
                % (self.parameters['name'], self.parameters['account_name'],
                   self.parameters['subnet_id'], to_native(error)),
                exception=traceback.format_exc())

    def delete_azure_netapp_volume(self):
        """
            Delete a volume for the given Azure NetApp Account
            :return: None
        """
        try:
            result = self.netapp_client.volumes.delete(
                resource_group_name=self.parameters['resource_group'],
                account_name=self.parameters['account_name'],
                pool_name=self.parameters['pool_name'],
                volume_name=self.parameters['name'])
            # waiting till the status turns Succeeded
            while result.done() is not True:
                result.result(10)
        except CloudError as error:
            self.module.fail_json(
                msg='Error deleting volume %s for Azure NetApp account %s: %s'
                % (self.parameters['name'], self.parameters['account_name'],
                   to_native(error)),
                exception=traceback.format_exc())

    def exec_module(self, **kwargs):
        current = self.get_azure_netapp_volume()
        cd_action = self.na_helper.get_cd_action(current, self.parameters)

        if self.na_helper.changed:
            if self.module.check_mode:
                pass
            else:
                if cd_action == 'create':
                    self.create_azure_netapp_volume()
                elif cd_action == 'delete':
                    self.delete_azure_netapp_volume()

        return_info = ''
        if self.parameters['state'] == 'present':
            return_info = self.get_azure_netapp_volume()
            return_info = ('%s:/%s' % (return_info.mount_targets[0].ip_address,
                                       return_info.creation_token)
                           ) if return_info is not None else ''
        self.module.exit_json(changed=self.na_helper.changed,
                              msg=str(return_info))
class AzureRMNetAppAccount(AzureRMNetAppModuleBase):
    ''' create, modify, delete account, including joining AD domain
    '''
    def __init__(self):

        self.module_arg_spec = dict(
            resource_group=dict(type='str', required=True),
            name=dict(type='str', required=True),
            location=dict(type='str', required=False),
            state=dict(choices=['present', 'absent'],
                       default='present',
                       type='str'),
            tags=dict(type='dict', required=False),
            active_directories=dict(type='list',
                                    elements='dict',
                                    options=dict(
                                        active_directory_id=dict(type='str'),
                                        dns=dict(type='list', elements='str'),
                                        domain=dict(type='str'),
                                        site=dict(type='str'),
                                        smb_server_name=dict(type='str'),
                                        organizational_unit=dict(type='str'),
                                        username=dict(type='str'),
                                        password=dict(type='str', no_log=True),
                                        aes_encryption=dict(type='bool'),
                                        ldap_signing=dict(type='bool'),
                                    )),
            debug=dict(type='bool', default=False))
        self.module = AnsibleModule(argument_spec=self.module_arg_spec,
                                    required_if=[
                                        ('state', 'present', ['location']),
                                    ],
                                    supports_check_mode=True)
        self.na_helper = NetAppModule()
        self.parameters = self.na_helper.set_parameters(self.module.params)
        self.debug = list()
        self.warnings = list()

        if HAS_AZURE_MGMT_NETAPP is False:
            self.module.fail_json(
                msg="the python Azure-mgmt-NetApp module is required")
        super(AzureRMNetAppAccount,
              self).__init__(derived_arg_spec=self.module_arg_spec,
                             supports_check_mode=True)

    def get_azure_netapp_account(self):
        """
            Returns NetApp Account object for an existing account
            Return None if account does not exist
        """
        try:
            account_get = self.netapp_client.accounts.get(
                self.parameters['resource_group'], self.parameters['name'])
        except CloudError:  # account does not exist
            return None
        account = vars(account_get)
        ads = None
        if account.get('active_directories') is not None:
            ads = list()
            for each_ad in account.get('active_directories'):
                ad_dict = vars(each_ad)
                dns = ad_dict.get('dns')
                if dns is not None:
                    ad_dict['dns'] = sorted(dns.split(','))
                ads.append(ad_dict)
        account['active_directories'] = ads
        return account

    def create_account_request_body(self, modify=None):
        """
            Create an Azure NetApp Account Request Body
            :return: None
        """
        options = dict()
        location = None
        for attr in ('location', 'tags', 'active_directories'):
            value = self.parameters.get(attr)
            if attr == 'location' and modify is None:
                location = value
                continue
            if value is not None:
                if modify is None or attr in modify:
                    if attr == 'active_directories':
                        ads = list()
                        for ad_dict in value:
                            if ad_dict.get('dns') is not None:
                                # API expects a string of comma separated elements
                                ad_dict['dns'] = ','.join(ad_dict['dns'])
                            ads.append(
                                ActiveDirectory(
                                    **self.na_helper.filter_out_none_entries(
                                        ad_dict)))
                        value = ads
                    options[attr] = value
        if modify is None:
            if location is None:
                self.module.fail_json(
                    msg="Error: 'location' is a required parameter")
            return NetAppAccount(location=location, **options)
        return NetAppAccountPatch(**options)

    def create_azure_netapp_account(self):
        """
            Create an Azure NetApp Account
            :return: None
        """
        account_body = self.create_account_request_body()
        try:
            self.netapp_client.accounts.create_or_update(
                body=account_body,
                resource_group_name=self.parameters['resource_group'],
                account_name=self.parameters['name'])
        except CloudError as error:
            self.module.fail_json(
                msg='Error creating Azure NetApp account %s: %s' %
                (self.parameters['name'], to_native(error)),
                exception=traceback.format_exc())

    def update_azure_netapp_account(self, modify):
        """
            Create an Azure NetApp Account
            :return: None
        """
        account_body = self.create_account_request_body(modify)
        try:
            self.netapp_client.accounts.update(
                body=account_body,
                resource_group_name=self.parameters['resource_group'],
                account_name=self.parameters['name'])
        except CloudError as error:
            self.module.fail_json(
                msg='Error creating Azure NetApp account %s: %s' %
                (self.parameters['name'], to_native(error)),
                exception=traceback.format_exc())

    def delete_azure_netapp_account(self):
        """
            Delete an Azure NetApp Account
            :return: None
        """
        try:
            self.netapp_client.accounts.delete(
                resource_group_name=self.parameters['resource_group'],
                account_name=self.parameters['name'])
        except CloudError as error:
            self.module.fail_json(
                msg='Error deleting Azure NetApp account %s: %s' %
                (self.parameters['name'], to_native(error)),
                exception=traceback.format_exc())

    def get_changes_in_ads(self, current, desired):
        c_ads = current.get('active_directories')
        d_ads = desired.get('active_directories')
        if not c_ads:
            return desired.get('active_directories'), None
        if not d_ads:
            return None, current.get('active_directories')
        if len(c_ads) > 1 or len(d_ads) > 1:
            msg = 'Error checking for AD, currently only one AD is supported.'
            if len(c_ads) > 1:
                msg += '  Current: %s.' % str(c_ads)
            if len(d_ads) > 1:
                msg += '  Desired: %s.' % str(d_ads)
            self.module.fail_json(
                msg='Error checking for AD, currently only one AD is supported'
            )
        changed = False
        d_ad = d_ads[0]
        c_ad = c_ads[0]
        for key, value in c_ad.items():
            if key == 'password':
                if d_ad.get(key) is None:
                    continue
                self.warnings.append(
                    "module is not idempotent if 'password:'******'current: %s' % str(current))
        if current is not None and cd_action is None:
            ads_to_add, ads_to_delete = self.get_changes_in_ads(
                current, self.parameters)
            self.parameters.pop('active_directories', None)
            if ads_to_add:
                self.parameters['active_directories'] = ads_to_add
            if ads_to_delete:
                self.module.fail_json(
                    msg="Error: API does not support unjoining an AD",
                    debug=self.debug)
            modify = self.na_helper.get_modified_attributes(
                current, self.parameters)

        if self.na_helper.changed:
            if self.module.check_mode:
                pass
            else:
                if cd_action == 'create':
                    self.create_azure_netapp_account()
                elif cd_action == 'delete':
                    self.delete_azure_netapp_account()
                elif modify:
                    self.update_azure_netapp_account(modify)
        results = dict(changed=self.na_helper.changed, modify=modify)
        if self.warnings:
            results['warnings'] = self.warnings
        if self.parameters['debug']:
            results['debug'] = self.debug
        self.module.exit_json(**results)