Repository URL to install this package:
|
Version:
6.0.0 ▾
|
#!/usr/bin/python
# (c) 2021, NetApp Inc
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
"""NetApp StorageGRID - Manage Grid Identity Federation"""
from __future__ import absolute_import, division, print_function
__metaclass__ = type
DOCUMENTATION = """
module: na_sg_grid_identity_federation
short_description: NetApp StorageGRID manage Grid identity federation.
extends_documentation_fragment:
- netapp.storagegrid.netapp.sg
version_added: '21.6.0'
author: NetApp Ansible Team (@joshedmonds) <ng-ansibleteam@netapp.com>
description:
- Configure Grid Identity Federation within NetApp StorageGRID.
- If module is run with I(check_mode), a connectivity test will be performed using the supplied values without changing the configuration.
- This module is idempotent if I(password) is not specified.
options:
state:
description:
- Whether identity federation should be enabled or not.
type: str
choices: ['present', 'absent']
default: present
username:
description:
- The username to bind to the LDAP server.
type: str
password:
description:
- The password associated with the username.
type: str
hostname:
description:
- The hostname or IP address of the LDAP server.
type: str
port:
description:
- The port used to connect to the LDAP server. Typically 389 for LDAP, or 636 for LDAPS.
type: int
base_group_dn:
description:
- The Distinguished Name of the LDAP subtree to search for groups.
type: str
base_user_dn:
description:
- The Distinguished Name of the LDAP subtree to search for users.
type: str
ldap_service_type:
description:
- The type of LDAP server.
choices: ['Active Directory', 'OpenLDAP', 'Other']
type: str
type:
description:
- The type of identity source.
- Default is C(ldap).
type: str
default: ldap
ldap_user_id_attribute:
description:
- The LDAP attribute which contains the unique user name of a user.
- Should be configured if I(ldap_service_type=Other).
type: str
ldap_user_uuid_attribute:
description:
- The LDAP attribute which contains the permanent unique identity of a user.
- Should be configured if I(ldap_service_type=Other).
type: str
ldap_group_id_attribute:
description:
- The LDAP attribute which contains the group for a user.
- Should be configured if I(ldap_service_type=Other).
type: str
ldap_group_uuid_attribute:
description:
- The LDAP attribute which contains the group's permanent unique identity.
- Should be configured if I(ldap_service_type=Other).
type: str
tls:
description:
- Whether Transport Layer Security is used to connect to the LDAP server.
choices: ['STARTTLS', 'LDAPS', 'Disabled']
type: str
default: STARTTLS
ca_cert:
description:
- Custom certificate used to connect to the LDAP server.
- If a custom certificate is not supplied, the operating system CA certificate will be used.
type: str
"""
EXAMPLES = """
- name: test identity federation configuration
netapp.storagegrid.na_sg_grid_identity_federation:
api_url: "https://<storagegrid-endpoint-url>"
auth_token: "storagegrid-auth-token"
validate_certs: false
state: present
ldap_service_type: "Active Directory"
hostname: "ad.example.com"
port: 389
username: "binduser"
password: "bindpass"
base_group_dn: "DC=example,DC=com"
base_user_dn: "DC=example,DC=com"
tls: "Disabled"
check_mode: yes
- name: configure identity federation with AD and TLS
netapp.storagegrid.na_sg_grid_identity_federation:
api_url: "https://<storagegrid-endpoint-url>"
auth_token: "storagegrid-auth-token"
validate_certs: false
state: present
ldap_service_type: "Active Directory"
hostname: "ad.example.com"
port: 636
username: "binduser"
password: "bindpass"
base_group_dn: "DC=example,DC=com"
base_user_dn: "DC=example,DC=com"
tls: "LDAPS"
ca_cert: |
-----BEGIN CERTIFICATE-----
MIIC+jCCAeICCQDmn9Gow08LTzANBgkqhkiG9w0BAQsFADA/..swCQYDVQQGEwJV
bXBsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB..JFzNIXQEGnsgjV
JGU4giuvOLOZ8Q3gyuUbkSUQDjmjpMR8PliwJ6iW2Ity89Dv..dl1TaIYI/ansyZ
Uxk4YXeN6kUkrDtNxCg1McALzXVAfxMTtj2SFlLxne4Z6rX2..UyftQrfM13F1vY
gK8dBPz+l+X/Uozo/xNm7gxe68p9le9/pcULst1CQn5/sPqq..kgWcSvlKUItu82
lq3B2169rovdIaNdcvaQjMPhrDGo5rvLfMN35U3Hgbz41PL5..x2BcUE6/0ab5T4
qKBxKa3t9twj+zpUqOzyL0PFfCE+SK5fEXAS1ow4eAcLN+eB..gR/PuvGAyIPCtE
1+X4GrECAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAFpO+04Ra..FMJPH6dBmzfb7l
k04BWTvSlur6HiQdXY+oFQMJZzyI7MQ8v9HBIzS0ZAzYWLp4..VZhHmRxnrWyxVs
u783V5YfQH2L4QnBDoiDefgxyfDs2PcoF5C+X9CGXmPqzst2..y/6tdOVJzdiA==
-----END CERTIFICATE-----
"""
RETURN = """
resp:
description: Returns information about the StorageGRID management identity source configuration.
returned: success
type: dict
sample: {
"id": "00000000-0000-0000-0000-000000000000",
"disable": false,
"hostname": "10.1.2.3",
"port": 389,
"username": "MYDOMAIN\\\\Administrator",
"password": "********",
"baseGroupDn": "DC=example,DC=com",
"baseUserDn": "DC=example,DC=com",
"ldapServiceType": "Active Directory",
"type": "ldap",
"disableTLS": false,
"enableLDAPS": false,
"caCert": "-----BEGIN CERTIFICATE----- abcdefghijkl123456780ABCDEFGHIJKL 123456/7890ABCDEFabcdefghijklABCD -----END CERTIFICATE-----\n"
}
"""
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 SgGridIdentityFederation:
"""
Configure and modify StorageGRID Grid Identity Federation
"""
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"),
username=dict(required=False, type="str"),
password=dict(required=False, type="str", no_log=True),
hostname=dict(required=False, type="str"),
port=dict(required=False, type="int"),
base_group_dn=dict(required=False, type="str"),
base_user_dn=dict(required=False, type="str"),
ldap_service_type=dict(required=False, type="str", choices=["OpenLDAP", "Active Directory", "Other"]),
type=dict(required=False, type="str", default="ldap"),
ldap_user_id_attribute=dict(required=False, type="str"),
ldap_user_uuid_attribute=dict(required=False, type="str"),
ldap_group_id_attribute=dict(required=False, type="str"),
ldap_group_uuid_attribute=dict(required=False, type="str"),
tls=dict(required=False, type="str", choices=["STARTTLS", "LDAPS", "Disabled"], default="STARTTLS"),
ca_cert=dict(required=False, type="str"),
),
)
parameter_map = {
"username": "username",
"password": "password",
"hostname": "hostname",
"port": "port",
"base_group_dn": "baseGroupDn",
"base_user_dn": "baseUserDn",
"ldap_service_type": "ldapServiceType",
"ldap_user_id_attribute": "ldapUserIdAttribute",
"ldap_user_uuid_attribute": "ldapUserUUIDAttribute",
"ldap_group_id_attribute": "ldapGroupIdAttribute",
"ldap_group_uuid_attribute": "ldapGroupUUIDAttribute",
"ca_cert": "caCert",
}
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 = {}
if self.parameters["state"] == "present":
self.data["disable"] = False
for k in parameter_map.keys():
if self.parameters.get(k) is not None:
self.data[parameter_map[k]] = self.parameters[k]
if self.parameters.get("tls") == "STARTTLS":
self.data["disableTLS"] = False
self.data["enableLDAPS"] = False
elif self.parameters.get("tls") == "LDAPS":
self.data["disableTLS"] = False
self.data["enableLDAPS"] = True
else:
self.data["disableTLS"] = True
self.data["enableLDAPS"] = False
def get_grid_identity_source(self):
api = "api/v3/grid/identity-source"
response, error = self.rest_api.get(api)
if error:
self.module.fail_json(msg=error)
else:
return response["data"]
return None
def update_identity_federation(self, test=False):
api = "api/v3/grid/identity-source"
params = {}
if test:
params["test"] = True
response, error = self.rest_api.put(api, self.data, params=params)
if error:
self.module.fail_json(msg=error, payload=self.data)
if response is not None:
return response["data"]
else:
return None
def apply(self):
"""
Perform pre-checks, call functions and exit
"""
grid_identity_source = self.get_grid_identity_source()
cd_action = self.na_helper.get_cd_action(grid_identity_source, self.parameters)
if cd_action is None and self.parameters["state"] == "present":
# let's see if we need to update parameters
update = False
for k in (i for i in self.data.keys() if i != "password"):
if self.data[k] != grid_identity_source.get(k):
update = True
break
# if a password has been specified we need to update it
if self.data.get("password") and self.parameters["state"] == "present":
update = True
self.module.warn("Password attribute has been specified. Task is not idempotent.")
if update:
self.na_helper.changed = True
if cd_action == "delete":
# if identity federation is already in a disable state
if grid_identity_source.get("disable"):
self.na_helper.changed = False
result_message = ""
resp_data = grid_identity_source
if self.na_helper.changed and not self.module.check_mode:
if cd_action == "delete":
self.data = dict(disable=True)
resp_data = self.update_identity_federation()
result_message = "Grid identity federation disabled"
else:
resp_data = self.update_identity_federation()
result_message = "Grid identity federation updated"
if self.module.check_mode:
self.update_identity_federation(test=True)
# if no error, connection test successful
self.module.exit_json(changed=self.na_helper.changed, msg="Connection test successful")
self.module.exit_json(changed=self.na_helper.changed, msg=result_message, resp=resp_data)
def main():
"""
Main function
"""
na_sg_grid_identity_federation = SgGridIdentityFederation()
na_sg_grid_identity_federation.apply()
if __name__ == "__main__":
main()