示例#1
0
    def __init__(self):
        """
        Parse arguments, setup state variables,
        check parameters and ensure request module is installed
        """
        self.argument_spec = netapp_utils.na_storagegrid_host_argument_spec()
        self.argument_spec.update(
            dict(
                state=dict(required=False, type="str", choices=["present"], default="present"),
                dns_servers=dict(required=True, type="list", elements="str"),
            )
        )

        self.module = AnsibleModule(
            argument_spec=self.argument_spec,
            # required_if=[("state", "present", ["state", "name", "protocol"])],
            supports_check_mode=True,
        )

        self.na_helper = NetAppModule()

        # set up state variables
        self.parameters = self.na_helper.set_parameters(self.module.params)
        # Calling generic SG rest_api class
        self.rest_api = SGRestAPI(self.module)
        # Checking for the parameters passed and create new parameters list
        self.data = self.parameters["dns_servers"]
示例#2
0
    def __init__(self):
        """
        Parse arguments, setup state variables,
        check parameters and ensure request module is installed
        """
        self.argument_spec = netapp_utils.na_storagegrid_host_argument_spec()
        self.argument_spec.update(
            dict(
                state=dict(required=False,
                           type="str",
                           choices=["present", "absent"],
                           default="present"),
                full_name=dict(required=False, type="str"),
                unique_name=dict(required=True, type="str"),
                member_of=dict(required=False, type="list", elements="str"),
                disable=dict(required=False, type="bool"),
                password=dict(required=False, type="str", no_log=True),
                update_password=dict(default="on_create",
                                     choices=["on_create", "always"]),
            ))

        self.module = AnsibleModule(
            argument_spec=self.argument_spec,
            required_if=[("state", "present", ["full_name", "unique_name"])],
            supports_check_mode=True,
        )

        self.na_helper = NetAppModule()

        # set up state variables
        self.parameters = self.na_helper.set_parameters(self.module.params)
        # Calling generic SG rest_api class
        self.rest_api = SGRestAPI(self.module)
        # Checking for the parameters passed and create new parameters list
        self.data = {}
        self.data["memberOf"] = []
        if self.parameters.get("full_name"):
            self.data["fullName"] = self.parameters["full_name"]
        if self.parameters.get("unique_name"):
            self.data["uniqueName"] = self.parameters["unique_name"]

        if self.parameters.get("disable") is not None:
            self.data["disable"] = self.parameters["disable"]

        re_local_user = re.compile("^user/")
        re_fed_user = re.compile("^federated-user/")

        if (re_local_user.match(self.parameters["unique_name"]) is None
                and re_fed_user.match(self.parameters["unique_name"]) is None):
            self.module.fail_json(
                msg="unique_name must begin with 'user/' or 'federated-user/'")

        self.pw_change = {}
        if self.parameters.get("password") is not None:
            if re_fed_user.match(self.parameters["unique_name"]):
                self.module.fail_json(
                    msg="password cannot be set for a federated user")
            self.pw_change["password"] = self.parameters["password"]
    def __init__(self):
        """
        Parse arguments, setup state variables,
        check parameters and ensure request module is installed
        """
        self.argument_spec = netapp_utils.na_storagegrid_host_argument_spec()
        self.argument_spec.update(
            dict(
                state=dict(required=False, type="str", choices=["present"], default="present"),
                name=dict(required=True, type="str"),
                region=dict(required=False, type="str"),
                compliance=dict(
                    required=False,
                    type="dict",
                    options=dict(
                        auto_delete=dict(required=False, type="bool"),
                        legal_hold=dict(required=False, type="bool"),
                        retention_period_minutes=dict(required=False, type="int"),
                    ),
                ),
            )
        )
        parameter_map = {
            "auto_delete": "autoDelete",
            "legal_hold": "legalHold",
            "retention_period_minutes": "retentionPeriodMinutes",
        }
        self.module = AnsibleModule(
            argument_spec=self.argument_spec,
            # required_if=[("state", "present", ["state", "name", "protocol"])],
            supports_check_mode=True,
        )

        self.na_helper = NetAppModule()

        # set up state variables
        self.parameters = self.na_helper.set_parameters(self.module.params)
        # Calling generic SG rest_api class
        self.rest_api = SGRestAPI(self.module)
        # Checking for the parameters passed and create new parameters list
        self.data = {}
        self.data["name"] = self.parameters["name"]
        self.data["region"] = self.parameters.get("region")
        if self.parameters.get("compliance"):
            # self.data["compliance"] = {
            #     parameter_map[k]: v
            #     for (k, v) in self.parameters["compliance"].items()
            #     if v
            # }
            self.data["compliance"] = dict(
                (parameter_map[k], v)
                for (k, v) in self.parameters["compliance"].items()
                if v
            )
示例#4
0
    def __init__(self):
        """
        Parse arguments, setup variables, check parameters and ensure
        request module is installed.
        """
        self.argument_spec = netapp_utils.na_storagegrid_host_argument_spec()
        self.argument_spec.update(dict(
            gather_subset=dict(default=['all'], type='list', elements='str', required=False),
            parameters=dict(type='dict', required=False)
        ))

        self.module = AnsibleModule(
            argument_spec=self.argument_spec,
            supports_check_mode=True
        )

        # set up variables
        self.na_helper = NetAppModule()
        self.parameters = self.na_helper.set_parameters(self.module.params)
        self.rest_api = SGRestAPI(self.module)
示例#5
0
class SgGridDns(object):
    """
    Create, modify and delete DNS entries for StorageGRID
    """

    def __init__(self):
        """
        Parse arguments, setup state variables,
        check parameters and ensure request module is installed
        """
        self.argument_spec = netapp_utils.na_storagegrid_host_argument_spec()
        self.argument_spec.update(
            dict(
                state=dict(required=False, type="str", choices=["present"], default="present"),
                dns_servers=dict(required=True, type="list", elements="str"),
            )
        )

        self.module = AnsibleModule(
            argument_spec=self.argument_spec,
            # required_if=[("state", "present", ["state", "name", "protocol"])],
            supports_check_mode=True,
        )

        self.na_helper = NetAppModule()

        # set up state variables
        self.parameters = self.na_helper.set_parameters(self.module.params)
        # Calling generic SG rest_api class
        self.rest_api = SGRestAPI(self.module)
        # Checking for the parameters passed and create new parameters list
        self.data = self.parameters["dns_servers"]

    def get_grid_dns(self):
        # Check if tenant account exists
        # Return tenant account info if found, or None
        api = "api/v3/grid/dns-servers"

        response, error = self.rest_api.get(api)

        if error:
            self.module.fail_json(msg=error)

        return response["data"]

    def update_grid_dns(self):
        api = "api/v3/grid/dns-servers"

        response, error = self.rest_api.put(api, self.data)
        if error:
            self.module.fail_json(msg=error)

        return response["data"]

    def apply(self):
        """
        Perform pre-checks, call functions and exit
        """
        grid_dns = self.get_grid_dns()

        cd_action = self.na_helper.get_cd_action(
            grid_dns, self.parameters["dns_servers"]
        )

        if cd_action is None and self.parameters["state"] == "present":
            # let's see if we need to update parameters
            update = False

            dns_diff = [
                i
                for i in self.data + grid_dns
                if i not in self.data or i not in grid_dns
            ]
            if dns_diff:
                update = True

            if update:
                self.na_helper.changed = True
        # ### DEBUG self.module.fail_json(msg=tenant_account, action=cd_action)
        result_message = ""
        resp_data = grid_dns
        if self.na_helper.changed:
            if self.module.check_mode:
                pass
            else:
                resp_data = self.update_grid_dns()
                result_message = "Grid DNS updated"

        self.module.exit_json(
            changed=self.na_helper.changed, msg=result_message, resp=resp_data
        )
示例#6
0
    def __init__(self):
        """
        Parse arguments, setup state variables,
        check parameters and ensure request module is installed
        """
        self.argument_spec = netapp_utils.na_storagegrid_host_argument_spec()
        self.argument_spec.update(
            dict(
                state=dict(required=False,
                           type="str",
                           choices=["present", "absent"],
                           default="present"),
                name=dict(required=False, type="str"),
                account_id=dict(required=False, type="str"),
                protocol=dict(required=False, choices=["s3", "swift"]),
                management=dict(required=False, type="bool", default=True),
                use_own_identity_source=dict(required=False, type="bool"),
                allow_platform_services=dict(required=False, type="bool"),
                root_access_group=dict(required=False, type="str"),
                quota_size=dict(required=False, type="int", default=0),
                quota_size_unit=dict(
                    default="gb",
                    choices=[
                        "bytes",
                        "b",
                        "kb",
                        "mb",
                        "gb",
                        "tb",
                        "pb",
                        "eb",
                        "zb",
                        "yb",
                    ],
                    type="str",
                ),
                password=dict(required=False, type="str", no_log=True),
                update_password=dict(default="on_create",
                                     choices=["on_create", "always"]),
            ))

        self.module = AnsibleModule(
            argument_spec=self.argument_spec,
            required_if=[(
                "state",
                "present",
                [
                    "name",
                    "protocol",
                    "use_own_identity_source",
                    "allow_platform_services",
                ],
            )],
            supports_check_mode=True,
        )

        self.na_helper = NetAppModule()

        # set up state variables
        self.parameters = self.na_helper.set_parameters(self.module.params)
        # Calling generic SG rest_api class
        self.rest_api = SGRestAPI(self.module)

        # Checking for the parameters passed and create new parameters list
        self.data = {}
        self.data["name"] = self.parameters["name"]
        self.data["capabilities"] = [self.parameters["protocol"]]

        if self.parameters.get("password") is not None:
            self.data["password"] = self.parameters["password"]

        # Append "management" to the capability list only if parameter is True
        if self.parameters.get("management"):
            self.data["capabilities"].append("management")

        self.data["policy"] = {}

        if "use_own_identity_source" in self.parameters:
            self.data["policy"]["useAccountIdentitySource"] = self.parameters[
                "use_own_identity_source"]

        if "allow_platform_services" in self.parameters:
            self.data["policy"]["allowPlatformServices"] = self.parameters[
                "allow_platform_services"]

        if self.parameters.get("root_access_group") is not None:
            self.data["grantRootAccessToGroup"] = self.parameters[
                "root_access_group"]

        if self.parameters["quota_size"] > 0:
            self.parameters["quota_size"] = (
                self.parameters["quota_size"] *
                netapp_utils.POW2_BYTE_MAP[self.parameters["quota_size_unit"]])
            self.data["policy"]["quotaObjectBytes"] = self.parameters[
                "quota_size"]
        elif self.parameters["quota_size"] == 0:
            self.data["policy"]["quotaObjectBytes"] = None

        self.pw_change = {}
        if self.parameters.get("password") is not None:
            self.pw_change["password"] = self.parameters["password"]
示例#7
0
class SgGridAccount(object):
    """
    Create, modify and delete StorageGRID Tenant Account
    """
    def __init__(self):
        """
        Parse arguments, setup state variables,
        check parameters and ensure request module is installed
        """
        self.argument_spec = netapp_utils.na_storagegrid_host_argument_spec()
        self.argument_spec.update(
            dict(
                state=dict(required=False,
                           type="str",
                           choices=["present", "absent"],
                           default="present"),
                name=dict(required=False, type="str"),
                account_id=dict(required=False, type="str"),
                protocol=dict(required=False, choices=["s3", "swift"]),
                management=dict(required=False, type="bool", default=True),
                use_own_identity_source=dict(required=False, type="bool"),
                allow_platform_services=dict(required=False, type="bool"),
                root_access_group=dict(required=False, type="str"),
                quota_size=dict(required=False, type="int", default=0),
                quota_size_unit=dict(
                    default="gb",
                    choices=[
                        "bytes",
                        "b",
                        "kb",
                        "mb",
                        "gb",
                        "tb",
                        "pb",
                        "eb",
                        "zb",
                        "yb",
                    ],
                    type="str",
                ),
                password=dict(required=False, type="str", no_log=True),
                update_password=dict(default="on_create",
                                     choices=["on_create", "always"]),
            ))

        self.module = AnsibleModule(
            argument_spec=self.argument_spec,
            required_if=[(
                "state",
                "present",
                [
                    "name",
                    "protocol",
                    "use_own_identity_source",
                    "allow_platform_services",
                ],
            )],
            supports_check_mode=True,
        )

        self.na_helper = NetAppModule()

        # set up state variables
        self.parameters = self.na_helper.set_parameters(self.module.params)
        # Calling generic SG rest_api class
        self.rest_api = SGRestAPI(self.module)

        # Checking for the parameters passed and create new parameters list
        self.data = {}
        self.data["name"] = self.parameters["name"]
        self.data["capabilities"] = [self.parameters["protocol"]]

        if self.parameters.get("password") is not None:
            self.data["password"] = self.parameters["password"]

        # Append "management" to the capability list only if parameter is True
        if self.parameters.get("management"):
            self.data["capabilities"].append("management")

        self.data["policy"] = {}

        if "use_own_identity_source" in self.parameters:
            self.data["policy"]["useAccountIdentitySource"] = self.parameters[
                "use_own_identity_source"]

        if "allow_platform_services" in self.parameters:
            self.data["policy"]["allowPlatformServices"] = self.parameters[
                "allow_platform_services"]

        if self.parameters.get("root_access_group") is not None:
            self.data["grantRootAccessToGroup"] = self.parameters[
                "root_access_group"]

        if self.parameters["quota_size"] > 0:
            self.parameters["quota_size"] = (
                self.parameters["quota_size"] *
                netapp_utils.POW2_BYTE_MAP[self.parameters["quota_size_unit"]])
            self.data["policy"]["quotaObjectBytes"] = self.parameters[
                "quota_size"]
        elif self.parameters["quota_size"] == 0:
            self.data["policy"]["quotaObjectBytes"] = None

        self.pw_change = {}
        if self.parameters.get("password") is not None:
            self.pw_change["password"] = self.parameters["password"]

    def get_tenant_account_id(self):
        # Check if tenant account exists
        # Return tenant account info if found, or None
        api = "api/v3/grid/accounts?limit=350"

        list_accounts, error = self.rest_api.get(api)

        if error:
            self.module.fail_json(msg=error)

        for account in list_accounts.get("data"):
            if account["name"] == self.parameters["name"]:
                return account["id"]

        return None

    def get_tenant_account(self, account_id):
        api = "api/v3/grid/accounts/%s" % account_id
        account, error = self.rest_api.get(api)

        if error:
            self.module.fail_json(msg=error)
        else:
            return account["data"]
        return None

    def create_tenant_account(self):
        api = "api/v3/grid/accounts"

        response, error = self.rest_api.post(api, self.data)

        if error:
            self.module.fail_json(msg=error)

        return response["data"]

    def delete_tenant_account(self, account_id):
        api = "api/v3/grid/accounts/" + account_id

        self.data = None
        response, error = self.rest_api.delete(api, self.data)
        if error:
            self.module.fail_json(msg=error)

    def update_tenant_account(self, account_id):
        api = "api/v3/grid/accounts/" + account_id

        if "password" in self.data:
            del self.data["password"]

        if "grantRootAccessToGroup" in self.data:
            del self.data["grantRootAccessToGroup"]

        response, error = self.rest_api.put(api, self.data)
        if error:
            self.module.fail_json(msg=error)

        return response["data"]

    def set_tenant_root_password(self, account_id):
        api = "api/v3/grid/accounts/%s/change-password" % account_id
        response, error = self.rest_api.post(api, self.pw_change)

        if error:
            self.module.fail_json(msg=error["text"])

    def apply(self):
        """
        Perform pre-checks, call functions and exit
        """

        tenant_account = None

        if self.parameters.get("account_id"):
            tenant_account = self.get_tenant_account(
                self.parameters["account_id"])

        else:
            tenant_account_id = self.get_tenant_account_id()
            if tenant_account_id:
                tenant_account = self.get_tenant_account(tenant_account_id)

        cd_action = self.na_helper.get_cd_action(tenant_account,
                                                 self.parameters)

        if cd_action is None and self.parameters["state"] == "present":
            # let's see if we need to update parameters
            update = False

            capability_diff = [
                i for i in self.data["capabilities"] +
                tenant_account["capabilities"]
                if i not in self.data["capabilities"]
                or i not in tenant_account["capabilities"]
            ]

            if self.parameters["quota_size"] > 0:
                if (tenant_account["policy"]["quotaObjectBytes"] !=
                        self.parameters["quota_size"]):
                    update = True
            elif (self.parameters["quota_size"] == 0 and
                  tenant_account["policy"]["quotaObjectBytes"] is not None):
                update = True

            if ("use_own_identity_source" in self.parameters
                    and tenant_account["policy"]["useAccountIdentitySource"] !=
                    self.parameters["use_own_identity_source"]):
                update = True

            elif ("allow_platform_services" in self.parameters
                  and tenant_account["policy"]["allowPlatformServices"] !=
                  self.parameters["allow_platform_services"]):
                update = True

            elif capability_diff:
                update = True

            if update:
                self.na_helper.changed = True

        result_message = ""
        resp_data = tenant_account
        if self.na_helper.changed:
            if self.module.check_mode:
                pass
            else:
                if cd_action == "delete":
                    self.delete_tenant_account(tenant_account["id"])
                    result_message = "Tenant Account deleted"
                    resp_data = None

                elif cd_action == "create":
                    resp_data = self.create_tenant_account()
                    result_message = "Tenant Account created"

                else:
                    resp_data = self.update_tenant_account(
                        tenant_account["id"])
                    result_message = "Tenant Account updated"

        # If a password has been set
        if self.pw_change:
            if self.module.check_mode:
                pass
            else:
                # Only update the password if update_password is always
                # On a create action, the password is set directly by the POST /grid/accounts method
                if self.parameters[
                        "update_password"] == "always" and cd_action != "create":
                    self.set_tenant_root_password(tenant_account["id"])
                    self.na_helper.changed = True

                    results = [
                        result_message, "Tenant Account root password updated"
                    ]
                    result_message = "; ".join(filter(None, results))

        self.module.exit_json(changed=self.na_helper.changed,
                              msg=result_message,
                              resp=resp_data)
示例#8
0
class NetAppSgGatherInfo(object):
    """ Class with gather info methods """

    def __init__(self):
        """
        Parse arguments, setup variables, check parameters and ensure
        request module is installed.
        """
        self.argument_spec = netapp_utils.na_storagegrid_host_argument_spec()
        self.argument_spec.update(dict(
            gather_subset=dict(default=['all'], type='list', elements='str', required=False),
            parameters=dict(type='dict', required=False)
        ))

        self.module = AnsibleModule(
            argument_spec=self.argument_spec,
            supports_check_mode=True
        )

        # set up variables
        self.na_helper = NetAppModule()
        self.parameters = self.na_helper.set_parameters(self.module.params)
        self.rest_api = SGRestAPI(self.module)

    def get_subset_info(self, gather_subset_info):
        """
        Gather StorageGRID information for the given subset using REST APIs
        Input for REST APIs call : (api, data)
        return gathered_sg_info
        """

        api = gather_subset_info['api_call']
        data = {}
        # allow for passing in any additional rest api parameters
        if self.parameters.get('parameters'):
            for each in self.parameters['parameters']:
                data[each] = self.parameters['parameters'][each]

        gathered_sg_info, error = self.rest_api.get(api, data)

        if error:
            self.module.fail_json(msg=error)
        else:
            return gathered_sg_info

        return None

    def convert_subsets(self):
        """ Convert an info to the REST API """
        info_to_rest_mapping = {
            'grid_accounts_info': 'grid/accounts',
            'grid_alarms_info': 'grid/alarms',
            'grid_audit_info': 'grid/audit',
            'grid_compliance_global_info': 'grid/compliance-global',
            'grid_config_info': 'grid/config',
            'grid_config_management_info': 'grid/config/management',
            'grid_config_product_version_info': 'grid/config/product-version',
            'grid_deactivated_features_info': 'grid/deactivated-features',
            'grid_dns_servers_info': 'grid/dns-servers',
            'grid_domain_names_info': 'grid/domain-names',
            'grid_ec_profiles_info': 'grid/ec-profiles',
            'grid_expansion_info': 'grid/expansion',
            'grid_expansion_nodes_info': 'grid/expansion/nodes',
            'grid_expansion_sites_info': 'grid/expansion/sites',
            'grid_grid_networks_info': 'grid/grid-networks',
            'grid_groups_info': 'grid/groups',
            'grid_health_info': 'grid/health',
            'grid_health_topology_info': 'grid/health/topology',
            'grid_identity_source_info': 'grid/identity-source',
            'grid_ilm_criteria_info': 'grid/ilm-criteria',
            'grid_ilm_policies_info': 'grid/ilm-policies',
            'grid_ilm_rules_info': 'grid/ilm-rules',
            'grid_license_info': 'grid/license',
            'grid_management_certificate_info': 'grid/management-certificate',
            'grid_ntp_servers_info': 'grid/ntp-servers',
            'grid_recovery_available_nodes_info': 'grid/recovery/available-nodes',
            'grid_recovery_info': 'grid/recovery',
            'grid_regions_info': 'grid/regions',
            'grid_schemes_info': 'grid/schemes',
            'grid_snmp_info': 'grid/snmp',
            'grid_storage_api_certificate_info': 'grid/storage-api-certificate',
            'grid_untrusted_client_network_info': 'grid/untrusted-client-network',
            'grid_users_info': 'grid/users',
            'grid_users_root_info': 'grid/users/root',
            'versions_info': 'versions',
        }
        # Add rest API names as there info version, also make sure we don't add a duplicate
        subsets = []
        for subset in self.parameters['gather_subset']:
            if subset in info_to_rest_mapping:
                if info_to_rest_mapping[subset] not in subsets:
                    subsets.append(info_to_rest_mapping[subset])
            else:
                if subset not in subsets:
                    subsets.append(subset)
        return subsets

    def apply(self):
        """ Perform pre-checks, call functions and exit """

        result_message = dict()

        # Defining gather_subset and appropriate api_call
        get_sg_subset_info = {
            'grid/accounts': {
                'api_call': 'api/v3/grid/accounts',
            },
            'grid/alarms': {
                'api_call': 'api/v3/grid/alarms',
            },
            'grid/audit': {
                'api_call': 'api/v3/grid/audit',
            },
            'grid/compliance-global': {
                'api_call': 'api/v3/grid/compliance-global',
            },
            'grid/config': {
                'api_call': 'api/v3/grid/config',
            },
            'grid/config/management': {
                'api_call': 'api/v3/grid/config/management',
            },
            'grid/config/product-version': {
                'api_call': 'api/v3/grid/config/product-version',
            },
            'grid/deactivated-features': {
                'api_call': 'api/v3/grid/deactivated-features',
            },
            'grid/dns-servers': {
                'api_call': 'api/v3/grid/dns-servers',
            },
            'grid/domain-names': {
                'api_call': 'api/v3/grid/domain-names',
            },
            'grid/ec-profiles': {
                'api_call': 'api/v3/grid/ec-profiles',
            },
            'grid/expansion': {
                'api_call': 'api/v3/grid/expansion',
            },
            'grid/expansion/nodes': {
                'api_call': 'api/v3/grid/expansion/nodes',
            },
            'grid/expansion/sites': {
                'api_call': 'api/v3/grid/expansion/sites',
            },
            'grid/grid-networks': {
                'api_call': 'api/v3/grid/grid-networks',
            },
            'grid/groups': {
                'api_call': 'api/v3/grid/groups',
            },
            'grid/health': {
                'api_call': 'api/v3/grid/health',
            },
            'grid/health/topology': {
                'api_call': 'api/v3/grid/health/topology',
            },
            'grid/identity-source': {
                'api_call': 'api/v3/grid/identity-source',
            },
            'grid/ilm-criteria': {
                'api_call': 'api/v3/grid/ilm-criteria',
            },
            'grid/ilm-policies': {
                'api_call': 'api/v3/grid/ilm-policies',
            },
            'grid/ilm-rules': {
                'api_call': 'api/v3/grid/ilm-rules',
            },
            'grid/license': {
                'api_call': 'api/v3/grid/license',
            },
            'grid/management-certificate': {
                'api_call': 'api/v3/grid/management-certificate',
            },
            'grid/ntp-servers': {
                'api_call': 'api/v3/grid/ntp-servers',
            },
            'grid/recovery/available-nodes': {
                'api_call': 'api/v3/grid/recovery/available-nodes',
            },
            'grid/recovery': {
                'api_call': 'api/v3/grid/recovery',
            },
            'grid/regions': {
                'api_call': 'api/v3/grid/regions',
            },
            'grid/schemes': {
                'api_call': 'api/v3/grid/schemes',
            },
            'grid/snmp': {
                'api_call': 'api/v3/grid/snmp',
            },
            'grid/storage-api-certificate': {
                'api_call': 'api/v3/grid/storage-api-certificate',
            },
            'grid/untrusted-client-network': {
                'api_call': 'api/v3/grid/untrusted-client-network',
            },
            'grid/users': {
                'api_call': 'api/v3/grid/users',
            },
            'grid/users/root': {
                'api_call': 'api/v3/grid/users/root',
            },
            'versions': {
                'api_call': 'api/v3/versions',
            },
        }

        if 'all' in self.parameters['gather_subset']:
            # If all in subset list, get the information of all subsets
            self.parameters['gather_subset'] = sorted(get_sg_subset_info.keys())

        converted_subsets = self.convert_subsets()

        for subset in converted_subsets:
            try:
                # Verify whether the supported subset passed
                specified_subset = get_sg_subset_info[subset]
            except KeyError:
                self.module.fail_json(msg="Specified subset %s not found, supported subsets are %s" %
                                      (subset, list(get_sg_subset_info.keys())))

            result_message[subset] = self.get_subset_info(specified_subset)

        self.module.exit_json(changed='False', sg_info=result_message)
示例#9
0
class SgOrgUser(object):
    """
    Create, modify and delete user within a StorageGRID Tenant Account
    """
    def __init__(self):
        """
        Parse arguments, setup state variables,
        check parameters and ensure request module is installed
        """
        self.argument_spec = netapp_utils.na_storagegrid_host_argument_spec()
        self.argument_spec.update(
            dict(
                state=dict(required=False,
                           type="str",
                           choices=["present", "absent"],
                           default="present"),
                full_name=dict(required=False, type="str"),
                unique_name=dict(required=True, type="str"),
                member_of=dict(required=False, type="list", elements="str"),
                disable=dict(required=False, type="bool"),
                password=dict(required=False, type="str", no_log=True),
                update_password=dict(default="on_create",
                                     choices=["on_create", "always"]),
            ))

        self.module = AnsibleModule(
            argument_spec=self.argument_spec,
            required_if=[("state", "present", ["full_name", "unique_name"])],
            supports_check_mode=True,
        )

        self.na_helper = NetAppModule()

        # set up state variables
        self.parameters = self.na_helper.set_parameters(self.module.params)
        # Calling generic SG rest_api class
        self.rest_api = SGRestAPI(self.module)
        # Checking for the parameters passed and create new parameters list
        self.data = {}
        self.data["memberOf"] = []
        if self.parameters.get("full_name"):
            self.data["fullName"] = self.parameters["full_name"]
        if self.parameters.get("unique_name"):
            self.data["uniqueName"] = self.parameters["unique_name"]

        if self.parameters.get("disable") is not None:
            self.data["disable"] = self.parameters["disable"]

        re_local_user = re.compile("^user/")
        re_fed_user = re.compile("^federated-user/")

        if (re_local_user.match(self.parameters["unique_name"]) is None
                and re_fed_user.match(self.parameters["unique_name"]) is None):
            self.module.fail_json(
                msg="unique_name must begin with 'user/' or 'federated-user/'")

        self.pw_change = {}
        if self.parameters.get("password") is not None:
            if re_fed_user.match(self.parameters["unique_name"]):
                self.module.fail_json(
                    msg="password cannot be set for a federated user")
            self.pw_change["password"] = self.parameters["password"]

    def get_org_groups(self):
        # Get list of groups
        # Retrun mapping of uniqueName to ids if found, or None
        api = "api/v3/org/groups?limit=350"
        response, error = self.rest_api.get(api)

        if error:
            self.module.fail_json(msg=error)

        if response["data"]:
            name_to_id_map = dict(
                zip(
                    [i["uniqueName"] for i in response["data"]],
                    [j["id"] for j in response["data"]],
                ))
            return name_to_id_map

        return None

    def get_org_user(self, unique_name):
        # Use the unique name to check if the user exists
        api = "api/v3/org/users/%s" % unique_name
        response, error = self.rest_api.get(api)

        if error:
            if response["code"] != 404:
                self.module.fail_json(msg=error)
        else:
            return response["data"]
        return None

    def create_org_user(self):
        api = "api/v3/org/users"

        response, error = self.rest_api.post(api, self.data)

        if error:
            self.module.fail_json(msg=error)

        return response["data"]

    def delete_org_user(self, user_id):
        api = "api/v3/org/users/" + user_id

        self.data = None
        response, error = self.rest_api.delete(api, self.data)
        if error:
            self.module.fail_json(msg=error)

    def update_org_user(self, user_id):
        api = "api/v3/org/users/" + user_id

        response, error = self.rest_api.put(api, self.data)
        if error:
            self.module.fail_json(msg=error)

        return response["data"]

    def set_org_user_password(self, unique_name):
        api = "api/v3/org/users/%s/change-password" % unique_name
        response, error = self.rest_api.post(api, self.pw_change)

        if error:
            self.module.fail_json(msg=error["text"])

    def apply(self):
        """
        Perform pre-checks, call functions and exit
        """
        org_user = self.get_org_user(self.parameters["unique_name"])

        if self.parameters.get("member_of"):
            org_groups = self.get_org_groups()
            try:
                self.data["memberOf"] = [
                    org_groups[x] for x in self.parameters["member_of"]
                ]
            except KeyError as e:
                self.module.fail_json(
                    msg="Invalid unique_group supplied: '%s' not found" %
                    e.args[0])

        cd_action = self.na_helper.get_cd_action(org_user, self.parameters)

        if cd_action is None and self.parameters["state"] == "present":
            # let's see if we need to update parameters
            update = False

            if org_user["memberOf"] is None:
                member_of_diff = []
            else:
                member_of_diff = [
                    i for i in self.data["memberOf"] + org_user["memberOf"]
                    if i not in self.data["memberOf"]
                    or i not in org_user["memberOf"]
                ]
            if member_of_diff:
                update = True

            if self.parameters.get("disable") is not None and self.parameters[
                    "disable"] != org_user.get("disable"):
                update = True

            if update:
                self.na_helper.changed = True

        result_message = ""
        resp_data = org_user
        if self.na_helper.changed:
            if self.module.check_mode:
                pass
            else:
                if cd_action == "delete":
                    self.delete_org_user(org_user["id"])
                    result_message = "Org User deleted"

                elif cd_action == "create":
                    resp_data = self.create_org_user()
                    result_message = "Org User created"

                else:
                    resp_data = self.update_org_user(org_user["id"])
                    result_message = "Org User updated"

        # If a password has been set
        if self.pw_change:
            if self.module.check_mode:
                pass
            else:
                # Only update the password if update_password is always, or a create activity has occurred
                if cd_action == "create" or self.parameters[
                        "update_password"] == "always":
                    self.set_org_user_password(self.parameters["unique_name"])
                    self.na_helper.changed = True

                    results = [result_message, "Org User password updated"]
                    result_message = "; ".join(filter(None, results))

        self.module.exit_json(changed=self.na_helper.changed,
                              msg=result_message,
                              resp=resp_data)
    def __init__(self):
        """
        Parse arguments, setup state variables,
        check parameters and ensure request module is installed
        """
        self.argument_spec = netapp_utils.na_storagegrid_host_argument_spec()
        self.argument_spec.update(
            dict(
                state=dict(required=False,
                           type="str",
                           choices=["present", "absent"],
                           default="present"),
                display_name=dict(required=False, type="str"),
                unique_name=dict(required=True, type="str"),
                management_policy=dict(
                    required=False,
                    type="dict",
                    options=dict(
                        manage_all_containers=dict(required=False,
                                                   type="bool"),
                        manage_endpoints=dict(required=False, type="bool"),
                        manage_own_s3_credentials=dict(required=False,
                                                       type="bool"),
                        root_access=dict(required=False, type="bool"),
                    ),
                ),
                s3_policy=dict(required=False, type="json"),
            ))
        parameter_map = {
            "manage_all_containers": "manageAllContainers",
            "manage_endpoints": "manageEndpoints",
            "manage_own_s3_credentials": "manageOwnS3Credentials",
            "root_access": "rootAccess",
        }
        self.module = AnsibleModule(
            argument_spec=self.argument_spec,
            # required_if=[("state", "present", ["display_name"])],
            supports_check_mode=True,
        )

        self.na_helper = NetAppModule()

        # set up state variables
        self.parameters = self.na_helper.set_parameters(self.module.params)
        # Calling generic SG rest_api class
        self.rest_api = SGRestAPI(self.module)
        # Checking for the parameters passed and create new parameters list
        self.data = {}
        self.data["displayName"] = self.parameters.get("display_name")
        self.data["uniqueName"] = self.parameters["unique_name"]
        # Only add the parameter if value is True, as JSON response does not include non-true objects
        self.data["policies"] = {}
        if self.parameters.get("management_policy"):
            # self.data["policies"] = {
            #     "management": {
            #         parameter_map[k]: v
            #         for (k, v) in self.parameters["management_policy"].items()
            #         if v
            #     }
            # }
            self.data["policies"] = {
                "management":
                dict(
                    (parameter_map[k], v)
                    for (k, v) in self.parameters["management_policy"].items()
                    if v)
            }
        if not self.data["policies"].get("management"):
            self.data["policies"]["management"] = None

        if self.parameters.get("s3_policy"):
            try:
                self.data["policies"]["s3"] = json.loads(
                    self.parameters["s3_policy"])
            except ValueError:
                self.module.fail_json(
                    msg="Failed to decode s3_policy. Invalid JSON.")

        self.re_local_group = re.compile("^group/")
        self.re_fed_group = re.compile("^federated-group/")

        if (self.re_local_group.match(self.parameters["unique_name"]) is None
                and self.re_fed_group.match(
                    self.parameters["unique_name"]) is None):
            self.module.fail_json(
                msg="unique_name must begin with 'group/' or 'federated-group/'"
            )
class SgOrgGroup(object):
    """
    Create, modify and delete StorageGRID Tenant Account
    """
    def __init__(self):
        """
        Parse arguments, setup state variables,
        check parameters and ensure request module is installed
        """
        self.argument_spec = netapp_utils.na_storagegrid_host_argument_spec()
        self.argument_spec.update(
            dict(
                state=dict(required=False,
                           type="str",
                           choices=["present", "absent"],
                           default="present"),
                display_name=dict(required=False, type="str"),
                unique_name=dict(required=True, type="str"),
                management_policy=dict(
                    required=False,
                    type="dict",
                    options=dict(
                        manage_all_containers=dict(required=False,
                                                   type="bool"),
                        manage_endpoints=dict(required=False, type="bool"),
                        manage_own_s3_credentials=dict(required=False,
                                                       type="bool"),
                        root_access=dict(required=False, type="bool"),
                    ),
                ),
                s3_policy=dict(required=False, type="json"),
            ))
        parameter_map = {
            "manage_all_containers": "manageAllContainers",
            "manage_endpoints": "manageEndpoints",
            "manage_own_s3_credentials": "manageOwnS3Credentials",
            "root_access": "rootAccess",
        }
        self.module = AnsibleModule(
            argument_spec=self.argument_spec,
            # required_if=[("state", "present", ["display_name"])],
            supports_check_mode=True,
        )

        self.na_helper = NetAppModule()

        # set up state variables
        self.parameters = self.na_helper.set_parameters(self.module.params)
        # Calling generic SG rest_api class
        self.rest_api = SGRestAPI(self.module)
        # Checking for the parameters passed and create new parameters list
        self.data = {}
        self.data["displayName"] = self.parameters.get("display_name")
        self.data["uniqueName"] = self.parameters["unique_name"]
        # Only add the parameter if value is True, as JSON response does not include non-true objects
        self.data["policies"] = {}
        if self.parameters.get("management_policy"):
            # self.data["policies"] = {
            #     "management": {
            #         parameter_map[k]: v
            #         for (k, v) in self.parameters["management_policy"].items()
            #         if v
            #     }
            # }
            self.data["policies"] = {
                "management":
                dict(
                    (parameter_map[k], v)
                    for (k, v) in self.parameters["management_policy"].items()
                    if v)
            }
        if not self.data["policies"].get("management"):
            self.data["policies"]["management"] = None

        if self.parameters.get("s3_policy"):
            try:
                self.data["policies"]["s3"] = json.loads(
                    self.parameters["s3_policy"])
            except ValueError:
                self.module.fail_json(
                    msg="Failed to decode s3_policy. Invalid JSON.")

        self.re_local_group = re.compile("^group/")
        self.re_fed_group = re.compile("^federated-group/")

        if (self.re_local_group.match(self.parameters["unique_name"]) is None
                and self.re_fed_group.match(
                    self.parameters["unique_name"]) is None):
            self.module.fail_json(
                msg="unique_name must begin with 'group/' or 'federated-group/'"
            )

    def get_org_group(self, unique_name):
        # Use the unique name to check if the group exists
        api = "api/v3/org/groups/%s" % unique_name
        response, error = self.rest_api.get(api)

        if error:
            if response["code"] != 404:
                self.module.fail_json(msg=error)
        else:
            return response["data"]
        return None

    def create_org_group(self):
        api = "api/v3/org/groups"

        response, error = self.rest_api.post(api, self.data)

        if error:
            self.module.fail_json(msg=error)

        return response["data"]

    def delete_org_group(self, group_id):
        api = "api/v3/org/groups/" + group_id

        self.data = None
        response, error = self.rest_api.delete(api, self.data)
        if error:
            self.module.fail_json(msg=error)

    def update_org_group(self, group_id):
        api = "api/v3/org/groups/" + group_id

        response, error = self.rest_api.put(api, self.data)
        if error:
            self.module.fail_json(msg=error)

        return response["data"]

    def apply(self):
        """
        Perform pre-checks, call functions and exit
        """
        org_group = self.get_org_group(self.parameters["unique_name"])

        cd_action = self.na_helper.get_cd_action(org_group, self.parameters)

        if cd_action is None and self.parameters["state"] == "present":
            # let's see if we need to update parameters
            update = False

            if self.parameters.get("management_policy"):
                if org_group.get("policies") is None or org_group.get(
                        "policies", {}
                ).get("management") != self.data["policies"]["management"]:
                    # manageEndpointsself.module.fail_json(
                    #     msg="nochange",
                    #     c=org_group.get("policies", {}).get("management"),
                    #     d=self.data["policies"]["management"],
                    # )
                    update = True
            elif self.parameters.get("s3_policy"):
                if org_group.get("policies") is None or org_group.get(
                        "policies",
                    {}).get("s3") != self.data["policies"]["s3"]:
                    update = True

            if update:
                self.na_helper.changed = True
        result_message = ""
        resp_data = org_group
        if self.na_helper.changed:
            if self.module.check_mode:
                pass
            else:
                if cd_action == "delete":
                    self.delete_org_group(org_group["id"])
                    result_message = "Org Group deleted"

                elif cd_action == "create":
                    resp_data = self.create_org_group()
                    result_message = "Org Group created"

                else:
                    # for a federated group, the displayName parameter needs to be specified
                    # and must match the existing displayName
                    if self.re_fed_group.match(self.parameters["unique_name"]):
                        self.data["displayName"] = org_group["displayName"]

                    resp_data = self.update_org_group(org_group["id"])
                    result_message = "Org Group updated"

        self.module.exit_json(changed=self.na_helper.changed,
                              msg=result_message,
                              resp=resp_data)
示例#12
0
class NetAppSgGatherInfo(object):
    """ Class with gather info methods """
    def __init__(self):
        """
        Parse arguments, setup variables, check parameters and ensure
        request module is installed.
        """
        self.argument_spec = netapp_utils.na_storagegrid_host_argument_spec()
        self.argument_spec.update(
            dict(gather_subset=dict(default=['all'],
                                    type='list',
                                    elements='str',
                                    required=False),
                 parameters=dict(type='dict', required=False)))

        self.module = AnsibleModule(argument_spec=self.argument_spec,
                                    supports_check_mode=True)

        # set up variables
        self.na_helper = NetAppModule()
        self.parameters = self.na_helper.set_parameters(self.module.params)
        self.rest_api = SGRestAPI(self.module)

    def get_subset_info(self, gather_subset_info):
        """
        Gather StorageGRID information for the given subset using REST APIs
        Input for REST APIs call : (api, data)
        return gathered_sg_info
        """

        api = gather_subset_info['api_call']
        data = {}
        # allow for passing in any additional rest api parameters
        if self.parameters.get('parameters'):
            for each in self.parameters['parameters']:
                data[each] = self.parameters['parameters'][each]

        gathered_sg_info, error = self.rest_api.get(api, data)

        if error:
            self.module.fail_json(msg=error)
        else:
            return gathered_sg_info

        return None

    def convert_subsets(self):
        """ Convert an info to the REST API """
        info_to_rest_mapping = {
            'org_compliance_global_info': 'org/compliance-global',
            'org_config_info': 'org/config',
            'org_config_product_version_info': 'org/config/product-version',
            'org_containers_info': 'org/containers',
            'org_deactivated_features_info': 'org/deactivated-features',
            'org_endpoints_info': 'org/endpoints',
            'org_groups_info': 'org/groups',
            'org_identity_source_info': 'org/identity-source',
            'org_regions_info': 'org/regions',
            'org_users_current_user_s3_access_keys_info':
            'org/users/current-user/s3-access-keys',
            'org_usage_info': 'org/usage',
            'org_users_info': 'org/users',
            'org_users_root_info': 'org/users/root',
            'versions_info': 'versions'
        }
        # Add rest API names as there info version, also make sure we don't add a duplicate
        subsets = []
        for subset in self.parameters['gather_subset']:
            if subset in info_to_rest_mapping:
                if info_to_rest_mapping[subset] not in subsets:
                    subsets.append(info_to_rest_mapping[subset])
            else:
                if subset not in subsets:
                    subsets.append(subset)
        return subsets

    def apply(self):
        """ Perform pre-checks, call functions and exit """

        result_message = dict()

        # Defining gather_subset and appropriate api_call
        get_sg_subset_info = {
            'org/compliance-global': {
                'api_call': 'api/v3/org/compliance-global',
            },
            'org/config': {
                'api_call': 'api/v3/org/config',
            },
            'org/config/product-version': {
                'api_call': 'api/v3/org/config/product-version',
            },
            'org/containers': {
                'api_call': 'api/v3/org/containers',
            },
            'org/deactivated-features': {
                'api_call': 'api/v3/org/deactivated-features',
            },
            'org/endpoints': {
                'api_call': 'api/v3/org/endpoints',
            },
            'org/groups': {
                'api_call': 'api/v3/org/groups',
            },
            'org/identity-source': {
                'api_call': 'api/v3/org/identity-source',
            },
            'org/regions': {
                'api_call': 'api/v3/org/regions',
            },
            'org/users/current-user/s3-access-keys': {
                'api_call': 'api/v3/org/users/current-user/s3-access-keys',
            },
            'org/usage': {
                'api_call': 'api/v3/org/usage',
            },
            'org/users': {
                'api_call': 'api/v3/org/users',
            },
            'org/users/root': {
                'api_call': 'api/v3/org/users/root',
            },
            'versions': {
                'api_call': 'api/v3/versions',
            },
        }

        if 'all' in self.parameters['gather_subset']:
            # If all in subset list, get the information of all subsets
            self.parameters['gather_subset'] = sorted(
                get_sg_subset_info.keys())

        converted_subsets = self.convert_subsets()

        for subset in converted_subsets:
            try:
                # Verify whether the supported subset passed
                specified_subset = get_sg_subset_info[subset]
            except KeyError:
                self.module.fail_json(
                    msg=
                    "Specified subset %s not found, supported subsets are %s" %
                    (subset, list(get_sg_subset_info.keys())))

            result_message[subset] = self.get_subset_info(specified_subset)

        self.module.exit_json(changed='False', sg_info=result_message)
class SgOrgUserS3Key(object):
    """
    Create, modify and delete StorageGRID Tenant Account
    """

    def __init__(self):
        """
        Parse arguments, setup state variables,
        check parameters and ensure request module is installed
        """
        self.argument_spec = netapp_utils.na_storagegrid_host_argument_spec()
        self.argument_spec.update(
            dict(
                state=dict(required=False, type="str", choices=["present", "absent"], default="present"),
                unique_user_name=dict(required=True, type="str"),
                expires=dict(required=False, type="str"),
                access_key=dict(required=False, type="str"),
            )
        )

        self.module = AnsibleModule(
            argument_spec=self.argument_spec,
            required_if=[("state", "absent", ["access_key"])],
            supports_check_mode=False,
        )

        self.na_helper = NetAppModule()

        # set up state variables
        self.parameters = self.na_helper.set_parameters(self.module.params)
        # Calling generic SG rest_api class
        self.rest_api = SGRestAPI(self.module)
        # Checking for the parameters passed and create new parameters list
        self.data = {}
        self.data["expires"] = self.parameters.get("expires")

    def get_org_user_id(self, unique_name):
        # Use the unique name to check if the user exists
        api = "api/v3/org/users/%s" % unique_name
        response, error = self.rest_api.get(api)

        if error:
            if response["code"] != 404:
                self.module.fail_json(msg=error)
        else:
            return response["data"]["id"]
        return None

    def get_org_user_s3_key(self, user_id, access_key):
        # Use the unique name to check if the user exists
        api = "api/v3/org/users/current-user/s3-access-keys/%s" % access_key

        if user_id:
            api = "api/v3/org/users/%s/s3-access-keys/%s" % (
                user_id,
                access_key,
            )

        response, error = self.rest_api.get(api)

        if error:
            self.module.fail_json(msg=error)
        else:
            return response["data"]
        return None

    def create_org_user_s3_key(self, user_id):
        api = "api/v3/org/users/current-user/s3-access-keys"

        if user_id:
            api = "api/v3/org/users/%s/s3-access-keys" % user_id

        response, error = self.rest_api.post(api, self.data)

        if error:
            self.module.fail_json(msg=error)

        return response["data"]

    def delete_org_user_s3_key(self, user_id, access_key):
        api = "api/v3/org/users/current-user/s3-access-keys"

        if user_id:
            api = "api/v3/org/users/%s/s3-access-keys/%s" % (
                user_id,
                access_key,
            )

        self.data = None
        response, error = self.rest_api.delete(api, self.data)
        if error:
            self.module.fail_json(msg=error)

    def apply(self):
        """
        Perform pre-checks, call functions and exit
        """
        result_message = ""
        resp_data = {}
        user_id = None

        if self.parameters.get("unique_user_name"):
            user_id = self.get_org_user_id(self.parameters["unique_user_name"])

        if self.parameters["state"] == "present":
            org_user_s3_key = None
            if self.parameters.get("access_key"):
                org_user_s3_key = self.get_org_user_s3_key(
                    user_id, self.parameters["access_key"]
                )
                resp_data = org_user_s3_key

            if not org_user_s3_key:  # create
                resp_data = self.create_org_user_s3_key(user_id)
                self.na_helper.changed = True
        # ### DEBUG self.module.fail_json(msg=tenant_account, action=cd_action)

        if self.parameters["state"] == "absent":
            self.delete_org_user_s3_key(user_id, self.parameters["access_key"])
            self.na_helper.changed = True
            result_message = "Org User S3 key deleted"

        self.module.exit_json(
            changed=self.na_helper.changed, msg=result_message, resp=resp_data
        )
    def __init__(self):
        """
        Parse arguments, setup state variables,
        check parameters and ensure request module is installed
        """
        self.argument_spec = netapp_utils.na_storagegrid_host_argument_spec()
        self.argument_spec.update(
            dict(
                state=dict(required=False, type="str", choices=["present", "absent"], default="present"),
                display_name=dict(required=False, type="str"),
                unique_name=dict(required=True, type="str"),
                management_policy=dict(
                    required=False,
                    type="dict",
                    options=dict(
                        alarm_acknowledgement=dict(required=False, type="bool"),
                        other_grid_configuration=dict(required=False, type="bool"),
                        grid_topology_page_configuration=dict(
                            required=False, type="bool"
                        ),
                        tenant_accounts=dict(required=False, type="bool"),
                        change_tenant_root_password=dict(required=False, type="bool"),
                        maintenance=dict(required=False, type="bool"),
                        metrics_query=dict(required=False, type="bool"),
                        activate_features=dict(required=False, type="bool"),
                        ilm=dict(required=False, type="bool"),
                        object_metadata=dict(required=False, type="bool"),
                        root_access=dict(required=False, type="bool"),
                    ),
                ),
            )
        )
        parameter_map = {
            "alarm_acknowledgement": "alarmAcknowledgement",
            "other_grid_configuration": "otherGridConfiguration",
            "grid_topology_page_configuration": "gridTopologyPageConfiguration",
            "tenant_accounts": "tenantAccounts",
            "change_tenant_root_password": "******",
            "maintenance": "maintenance",
            "metrics_query": "metricsQuery",
            "activate_features": "activateFeatures",
            "ilm": "ilm",
            "object_metadata": "objectMetadata",
            "root_access": "rootAccess",
        }
        self.module = AnsibleModule(
            argument_spec=self.argument_spec, supports_check_mode=True,
        )

        self.na_helper = NetAppModule()

        # set up state variables
        self.parameters = self.na_helper.set_parameters(self.module.params)
        # Calling generic SG rest_api class
        self.rest_api = SGRestAPI(self.module)
        # Checking for the parameters passed and create new parameters list
        self.data = {}
        self.data["displayName"] = self.parameters.get("display_name")
        self.data["uniqueName"] = self.parameters["unique_name"]
        # Only add the parameter if value is True, as JSON response does not include non-true objects
        self.data["policies"] = {}
        if self.parameters.get("management_policy"):
            # self.data["policies"] = {
            #     "management": {
            #         parameter_map[k]: v
            #         for (k, v) in self.parameters["management_policy"].items()
            #         if v
            #     }
            self.data["policies"] = {
                "management": dict(
                    (parameter_map[k], v)
                    for (k, v) in self.parameters["management_policy"].items()
                    if v
                )
            }
        if not self.data["policies"].get("management"):
            self.data["policies"]["management"] = None

        self.re_local_group = re.compile("^group/")
        self.re_fed_group = re.compile("^federated-group/")

        if (
            self.re_local_group.match(self.parameters["unique_name"]) is None
            and self.re_fed_group.match(self.parameters["unique_name"]) is None
        ):
            self.module.fail_json(
                msg="unique_name must begin with 'group/' or 'federated-group/'"
            )
class SgGridGroup(object):
    """
    Create, modify and delete StorageGRID Grid-administration Group
    """

    def __init__(self):
        """
        Parse arguments, setup state variables,
        check parameters and ensure request module is installed
        """
        self.argument_spec = netapp_utils.na_storagegrid_host_argument_spec()
        self.argument_spec.update(
            dict(
                state=dict(required=False, type="str", choices=["present", "absent"], default="present"),
                display_name=dict(required=False, type="str"),
                unique_name=dict(required=True, type="str"),
                management_policy=dict(
                    required=False,
                    type="dict",
                    options=dict(
                        alarm_acknowledgement=dict(required=False, type="bool"),
                        other_grid_configuration=dict(required=False, type="bool"),
                        grid_topology_page_configuration=dict(
                            required=False, type="bool"
                        ),
                        tenant_accounts=dict(required=False, type="bool"),
                        change_tenant_root_password=dict(required=False, type="bool"),
                        maintenance=dict(required=False, type="bool"),
                        metrics_query=dict(required=False, type="bool"),
                        activate_features=dict(required=False, type="bool"),
                        ilm=dict(required=False, type="bool"),
                        object_metadata=dict(required=False, type="bool"),
                        root_access=dict(required=False, type="bool"),
                    ),
                ),
            )
        )
        parameter_map = {
            "alarm_acknowledgement": "alarmAcknowledgement",
            "other_grid_configuration": "otherGridConfiguration",
            "grid_topology_page_configuration": "gridTopologyPageConfiguration",
            "tenant_accounts": "tenantAccounts",
            "change_tenant_root_password": "******",
            "maintenance": "maintenance",
            "metrics_query": "metricsQuery",
            "activate_features": "activateFeatures",
            "ilm": "ilm",
            "object_metadata": "objectMetadata",
            "root_access": "rootAccess",
        }
        self.module = AnsibleModule(
            argument_spec=self.argument_spec, supports_check_mode=True,
        )

        self.na_helper = NetAppModule()

        # set up state variables
        self.parameters = self.na_helper.set_parameters(self.module.params)
        # Calling generic SG rest_api class
        self.rest_api = SGRestAPI(self.module)
        # Checking for the parameters passed and create new parameters list
        self.data = {}
        self.data["displayName"] = self.parameters.get("display_name")
        self.data["uniqueName"] = self.parameters["unique_name"]
        # Only add the parameter if value is True, as JSON response does not include non-true objects
        self.data["policies"] = {}
        if self.parameters.get("management_policy"):
            # self.data["policies"] = {
            #     "management": {
            #         parameter_map[k]: v
            #         for (k, v) in self.parameters["management_policy"].items()
            #         if v
            #     }
            self.data["policies"] = {
                "management": dict(
                    (parameter_map[k], v)
                    for (k, v) in self.parameters["management_policy"].items()
                    if v
                )
            }
        if not self.data["policies"].get("management"):
            self.data["policies"]["management"] = None

        self.re_local_group = re.compile("^group/")
        self.re_fed_group = re.compile("^federated-group/")

        if (
            self.re_local_group.match(self.parameters["unique_name"]) is None
            and self.re_fed_group.match(self.parameters["unique_name"]) is None
        ):
            self.module.fail_json(
                msg="unique_name must begin with 'group/' or 'federated-group/'"
            )

    def get_grid_group(self, unique_name):
        # Use the unique name to check if the group exists
        api = "api/v3/grid/groups/%s" % unique_name
        response, error = self.rest_api.get(api)

        if error:
            if response["code"] != 404:
                self.module.fail_json(msg=error)
        else:
            return response["data"]
        return None

    def create_grid_group(self):
        api = "api/v3/grid/groups"

        response, error = self.rest_api.post(api, self.data)

        if error:
            self.module.fail_json(msg=error)

        return response["data"]

    def delete_grid_group(self, group_id):
        api = "api/v3/grid/groups/" + group_id

        self.data = None
        response, error = self.rest_api.delete(api, self.data)
        if error:
            self.module.fail_json(msg=error)

    def update_grid_group(self, group_id):
        api = "api/v3/grid/groups/" + group_id

        response, error = self.rest_api.put(api, self.data)
        if error:
            self.module.fail_json(msg=error)

        return response["data"]

    def apply(self):
        """
        Perform pre-checks, call functions and exit
        """
        grid_group = self.get_grid_group(self.parameters["unique_name"])

        cd_action = self.na_helper.get_cd_action(grid_group, self.parameters)

        if cd_action is None and self.parameters["state"] == "present":
            # let's see if we need to update parameters
            update = False

            if self.parameters.get("management_policy"):
                if grid_group.get("policies") is None or grid_group.get("policies", {}).get("management") != self.data["policies"]["management"]:
                    update = True

            if update:
                self.na_helper.changed = True
        result_message = ""
        resp_data = grid_group
        if self.na_helper.changed:
            if self.module.check_mode:
                pass
            else:
                if cd_action == "delete":
                    self.delete_grid_group(grid_group["id"])
                    result_message = "Grid Group deleted"

                elif cd_action == "create":
                    resp_data = self.create_grid_group()
                    result_message = "Grid Group created"

                else:
                    # for a federated group, the displayName parameter needs to be specified
                    # and must match the existing displayName
                    if self.re_fed_group.match(self.parameters["unique_name"]):
                        self.data["displayName"] = grid_group["displayName"]

                    resp_data = self.update_grid_group(grid_group["id"])
                    result_message = "Grid Group updated"

        self.module.exit_json(
            changed=self.na_helper.changed, msg=result_message, resp=resp_data
        )
class SgOrgContainer(object):
    """
    Create, modify and delete StorageGRID Tenant Account
    """

    def __init__(self):
        """
        Parse arguments, setup state variables,
        check parameters and ensure request module is installed
        """
        self.argument_spec = netapp_utils.na_storagegrid_host_argument_spec()
        self.argument_spec.update(
            dict(
                state=dict(required=False, type="str", choices=["present"], default="present"),
                name=dict(required=True, type="str"),
                region=dict(required=False, type="str"),
                compliance=dict(
                    required=False,
                    type="dict",
                    options=dict(
                        auto_delete=dict(required=False, type="bool"),
                        legal_hold=dict(required=False, type="bool"),
                        retention_period_minutes=dict(required=False, type="int"),
                    ),
                ),
            )
        )
        parameter_map = {
            "auto_delete": "autoDelete",
            "legal_hold": "legalHold",
            "retention_period_minutes": "retentionPeriodMinutes",
        }
        self.module = AnsibleModule(
            argument_spec=self.argument_spec,
            # required_if=[("state", "present", ["state", "name", "protocol"])],
            supports_check_mode=True,
        )

        self.na_helper = NetAppModule()

        # set up state variables
        self.parameters = self.na_helper.set_parameters(self.module.params)
        # Calling generic SG rest_api class
        self.rest_api = SGRestAPI(self.module)
        # Checking for the parameters passed and create new parameters list
        self.data = {}
        self.data["name"] = self.parameters["name"]
        self.data["region"] = self.parameters.get("region")
        if self.parameters.get("compliance"):
            # self.data["compliance"] = {
            #     parameter_map[k]: v
            #     for (k, v) in self.parameters["compliance"].items()
            #     if v
            # }
            self.data["compliance"] = dict(
                (parameter_map[k], v)
                for (k, v) in self.parameters["compliance"].items()
                if v
            )

    def get_org_container(self):
        # Check if bucket/container exists
        # Return info if found, or None

        params = {"include": "compliance,region"}
        response, error = self.rest_api.get("api/v3/org/containers", params=params)

        if error:
            self.module.fail_json(msg=error)

        for container in response["data"]:
            if container["name"] == self.parameters["name"]:
                return container

        return None

    def create_org_container(self):
        api = "api/v3/org/containers"

        response, error = self.rest_api.post(api, self.data)

        if error:
            self.module.fail_json(msg=error)

        return response["data"]

    def update_org_container_compliance(self):
        api = "api/v3/org/containers/%s/compliance" % self.parameters["name"]

        response, error = self.rest_api.put(api, self.data["compliance"])
        if error:
            self.module.fail_json(msg=error)

        return response["data"]

    def apply(self):
        """
        Perform pre-checks, call functions and exit
        """
        org_container = self.get_org_container()

        cd_action = self.na_helper.get_cd_action(org_container, self.parameters)

        if cd_action is None and self.parameters["state"] == "present":
            # let's see if we need to update parameters
            update_compliance = False

            if (
                self.parameters.get("compliance")
                and org_container.get("compliance") != self.data["compliance"]
            ):
                update_compliance = True
                self.na_helper.changed = True

        # ### DEBUG self.module.fail_json(msg=tenant_account, action=cd_action)
        result_message = ""
        resp_data = org_container
        if self.na_helper.changed:
            if self.module.check_mode:
                pass
            else:
                if cd_action == "create":
                    resp_data = self.create_org_container()
                    result_message = "Org Container created"

                elif update_compliance:
                    resp_data = self.update_org_container_compliance()
                    result_message = "Org Container updated"

        self.module.exit_json(
            changed=self.na_helper.changed, msg=result_message, resp=resp_data
        )