Repository URL to install this package:
|
Version:
6.0.0 ▾
|
#!/usr/bin/python
# (c) 2020, NetApp Inc
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
"""NetApp StorageGRID - Manage tenant Groups"""
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {
"metadata_version": "1.1",
"status": ["preview"],
"supported_by": "community",
}
DOCUMENTATION = """
module: na_sg_org_group
short_description: NetApp StorageGRID manage groups within a tenancy.
extends_documentation_fragment:
- netapp.storagegrid.netapp.sg
version_added: '20.6.0'
author: NetApp Ansible Team (@joshedmonds) <ng-ansibleteam@netapp.com>
description:
- Create, Update, Delete Groups within NetApp StorageGRID tenant.
options:
state:
description:
- Whether the specified group should exist or not.
type: str
choices: ['present', 'absent']
default: present
unique_name:
description:
- Unique Name for the group. Must begin with C(group/) or C(federated-group/).
- Required for create, modify or delete operation.
type: str
required: true
display_name:
description:
- Name of the group.
- Required for create operation.
type: str
management_policy:
description:
- Management access controls granted to the group within the tenancy.
type: dict
suboptions:
manage_all_containers:
description:
- Allows users to manage the settings for all S3 buckets in the tenant account, regardless of S3 bucket or group policies.
type: bool
manage_endpoints:
description:
- Allows users to use the Tenant Manager or the Tenant Management API to create or edit endpoints.
- Endpoints are used as the destination for StorageGRID platform services.
type: bool
manage_own_s3_credentials:
description:
- Allows users to create and remove their own S3 access keys.
- Users who do not have this permission do not see the S3 > My Credentials menu option.
type: bool
root_access:
description:
- Provides full access to the Tenant Manager and the Tenant Management API.
type: bool
s3_policy:
description:
- StorageGRID S3 Group Policy.
default: ""
type: json
"""
EXAMPLES = """
- name: create a group
netapp.storagegrid.na_sg_org_group:
api_url: "https://<storagegrid-endpoint-url>"
auth_token: "storagegrid-auth-token"
validate_certs: false
state: present
display_name: ansiblegroup1
unique_name: group/ansiblegroup1
management_policy:
manage_all_containers: true
manage_endpoints: true
manage_own_s3_credentials: false
root_access: false
s3_policy: {"Statement":[{"Effect":"Deny","Action":"s3:*","Resource":"arn:aws:s3:::*"}]}
"""
RETURN = """
resp:
description: Returns information about the StorageGRID tenant group attributes.
returned: success
type: dict
sample: {
"displayName": "Example Group",
"policies": {
"management": {
"manageAllContainers": true,
"manageEndpoints": true,
"manageOwnS3Credentials": true,
"rootAccess": true
},
"s3": {...},
"swift": {...}
},
"uniqueName": "group/examplegroup",
"accountId": "12345678901234567890",
"id": "00000000-0000-0000-0000-000000000000",
"federated": false,
"groupURN": "urn:sgws:identity::12345678901234567890:group/examplegroup"
}
"""
import json
import re
import ansible_collections.netapp.storagegrid.plugins.module_utils.netapp as netapp_utils
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.netapp.storagegrid.plugins.module_utils.netapp_module import NetAppModule
from ansible_collections.netapp.storagegrid.plugins.module_utils.netapp import SGRestAPI
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": 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"]:
update = True
if 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)
def main():
"""
Main function
"""
na_sg_org_group = SgOrgGroup()
na_sg_org_group.apply()
if __name__ == "__main__":
main()