Repository URL to install this package:
|
Version:
6.0.0 ▾
|
#!/usr/bin/python
# (c) 2022, NetApp Inc
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
"""NetApp StorageGRID - Manage HA Groups"""
from __future__ import absolute_import, division, print_function
__metaclass__ = type
DOCUMENTATION = """
module: na_sg_grid_ha_group
short_description: Manage high availability (HA) group configuration on StorageGRID.
extends_documentation_fragment:
- netapp.storagegrid.netapp.sg
version_added: '21.10.0'
author: NetApp Ansible Team (@joshedmonds) <ng-ansibleteam@netapp.com>
description:
- Create, Update, Delete HA Groups on NetApp StorageGRID.
options:
state:
description:
- Whether the specified HA Group should exist.
type: str
choices: ['present', 'absent']
default: present
name:
description:
- Name of the HA Group.
type: str
ha_group_id:
description:
- HA Group ID.
- May be used for modify or delete operation.
type: str
description:
description:
- Description of the HA Group.
type: str
gateway_cidr:
description:
- CIDR for the gateway IP and VIP subnet.
type: str
virtual_ips:
description:
- A list of virtual IP addresses.
type: list
elements: str
interfaces:
description:
- A set of StorageGRID node interface pairs.
- The primary interface is specified first, followed by the other interface pairs in failover order.
type: list
elements: dict
suboptions:
node:
description:
- Name of the StorageGRID node.
type: str
interface:
description:
- The interface to bind to. eth0 corresponds to the Grid Network, eth1 to the Admin Network, and eth2 to the Client Network.
type: str
"""
EXAMPLES = """
- name: create HA Group
netapp.storagegrid.na_sg_grid_ha_group:
api_url: "https://<storagegrid-endpoint-url>"
auth_token: "storagegrid-auth-token"
validate_certs: false
state: present
name: Site1-HA-Group
description: "Site 1 HA Group"
gateway_cidr: 192.168.50.1/24
virtual_ips: 192.168.50.5
interfaces:
- node: SITE1-ADM1
interface: eth2
- node: SITE1-G1
interface: eth2
- name: add VIP to HA Group
netapp.storagegrid.na_sg_grid_ha_group:
api_url: "https://<storagegrid-endpoint-url>"
auth_token: "storagegrid-auth-token"
validate_certs: false
state: present
name: Site1-HA-Group
description: "Site 1 HA Group"
gateway_cidr: 192.168.50.1/24
virtual_ips: 192.168.50.5,192.168.50.6
interfaces:
- node: SITE1-ADM1
interface: eth2
- node: SITE1-G1
interface: eth2
- name: rename HA Group
netapp.storagegrid.na_sg_grid_ha_group:
api_url: "https://<storagegrid-endpoint-url>"
auth_token: "storagegrid-auth-token"
validate_certs: false
state: present
ha_group_id: 00000000-0000-0000-0000-000000000000
name: Site1-HA-Group-New-Name
description: "Site 1 HA Group"
gateway_cidr: 192.168.50.1/24
virtual_ips: 192.168.50.5
interfaces:
- node: SITE1-ADM1
interface: eth2
- node: SITE1-G1
interface: eth2
- name: delete HA Group
netapp.storagegrid.na_sg_grid_ha_group:
api_url: "https://<storagegrid-endpoint-url>"
auth_token: "storagegrid-auth-token"
validate_certs: false
state: absent
name: Site1-HA-Group
"""
RETURN = """
resp:
description: Returns information about the StorageGRID HA Group.
returned: success
type: dict
sample: {
"description": "Site 1 HA Group",
"gatewayCidr": "192.168.50.1/24",
"id": "bb386f30-805d-4fec-a2c5-85790b460db0",
"interfaces": [
{
"interface": "eth2",
"nodeId": "0b1866ed-d6e7-41b4-815f-bf867348b76b"
},
{
"interface": "eth2",
"nodeId": "7bb5bf05-a04c-4344-8abd-08c5c4048666"
}
],
"name": "Site1-HA-Group",
"virtualIps": [
"192.168.50.5",
"192.168.50.6"
]
}
"""
import json
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 SgGridHaGroup:
"""
Create, modify and delete HA Group configurations 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", "absent"], default="present"),
name=dict(required=False, type="str"),
ha_group_id=dict(required=False, type="str"),
description=dict(required=False, type="str"),
gateway_cidr=dict(required=False, type="str"),
virtual_ips=dict(required=False, type="list", elements="str"),
interfaces=dict(
required=False,
type="list",
elements="dict",
options=dict(
node=dict(required=False, type="str"),
interface=dict(required=False, type="str"),
),
),
)
)
parameter_map = {
"name": "name",
"description": "description",
"gateway_cidr": "gatewayCidr",
"virtual_ips": "virtualIps",
}
self.module = AnsibleModule(
argument_spec=self.argument_spec,
required_if=[("state", "present", ["name", "gateway_cidr", "virtual_ips", "interfaces"])],
required_one_of=[("name", "ha_group_id")],
)
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":
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("interfaces") is not None:
self.data["interfaces"] = self.build_node_interface_list()
def build_node_interface_list(self):
node_interfaces = []
api = "api/v3/grid/node-health"
nodes, error = self.rest_api.get(api)
if error:
self.module.fail_json(msg=error)
for node_interface in self.parameters["interfaces"]:
node_dict = {}
node = next((item for item in nodes["data"] if item["name"] == node_interface["node"]), None)
if node is not None:
node_dict["nodeId"] = node["id"]
node_dict["interface"] = node_interface["interface"]
node_interfaces.append(node_dict)
else:
self.module.fail_json(msg="Node '%s' is invalid" % node_interface["node"])
return node_interfaces
def get_ha_group_id(self):
# Check if HA Group exists
# Return HA Group info if found, or None
api = "api/v3/private/ha-groups"
response, error = self.rest_api.get(api)
if error:
self.module.fail_json(msg=error)
return next((item["id"] for item in response.get("data") if item["name"] == self.parameters["name"]), None)
def get_ha_group(self, ha_group_id):
api = "api/v3/private/ha-groups/%s" % ha_group_id
response, error = self.rest_api.get(api)
if error:
self.module.fail_json(msg=error)
return response["data"]
def create_ha_group(self):
api = "api/v3/private/ha-groups"
response, error = self.rest_api.post(api, self.data)
if error:
self.module.fail_json(msg=error)
return response["data"]
def delete_ha_group(self, ha_group_id):
api = "api/v3/private/ha-groups/%s" % ha_group_id
dummy, error = self.rest_api.delete(api, self.data)
if error:
self.module.fail_json(msg=error)
def update_ha_group(self, ha_group_id):
api = "api/v3/private/ha-groups/%s" % ha_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
"""
ha_group = None
if self.parameters.get("ha_group_id"):
ha_group = self.get_ha_group(self.parameters["ha_group_id"])
else:
ha_group_id = self.get_ha_group_id()
if ha_group_id:
ha_group = self.get_ha_group(ha_group_id)
cd_action = self.na_helper.get_cd_action(ha_group, self.parameters)
if cd_action is None and self.parameters["state"] == "present":
# let's see if we need to update parameters
modify = self.na_helper.get_modified_attributes(ha_group, self.data)
result_message = ""
resp_data = {}
if self.na_helper.changed and not self.module.check_mode:
if cd_action == "delete":
self.delete_ha_group(ha_group["id"])
result_message = "HA Group deleted"
elif cd_action == "create":
resp_data = self.create_ha_group()
result_message = "HA Group created"
elif modify:
resp_data = self.update_ha_group(ha_group["id"])
result_message = "HA Group updated"
self.module.exit_json(changed=self.na_helper.changed, msg=result_message, resp=resp_data)
def main():
"""
Main function
"""
na_sg_grid_ha_group = SgGridHaGroup()
na_sg_grid_ha_group.apply()
if __name__ == "__main__":
main()