diff --git a/hello.txt b/hello.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/playbooks/network_intent.yml b/playbooks/network_intent.yml index e144efc628..1f9ed2ac69 100644 --- a/playbooks/network_intent.yml +++ b/playbooks/network_intent.yml @@ -24,7 +24,7 @@ ippool: - ipPoolName: Global_Pool1 gateway: "" #use this for updating - IpAddressSpace: IPv4 #required when we are creating + IpAddressSpace: IPv4 #required when w2 are creating ipPoolCidr: 100.0.0.0/8 #required when we are creating type: Generic dhcpServerIps: [] #use this for updating @@ -32,13 +32,14 @@ # prev_name: Global_Pool ReservePoolDetails: ipv6AddressSpace: false - ipv4GlobalPool: 100.0.0.0/8 - ipv4Prefix: true - ipv4PrefixLength: 8 + ipv4GlobalPool: 100.0.0.0/8 + ipv4Prefix: True + ipv4PrefixLength: 9 ipv4DnsServers: [] + ipv4Subnet: 100.128.0.0 name: IP_Pool_3 siteName: Global/Chennai/Trill - slaacSupport: true + slaacSupport: True # prev_name: IP_Pool_4 type: LAN NetworkManagementDetails: @@ -49,34 +50,33 @@ domainName: cisco.co primaryIpAddress: 10.0.0.2 secondaryIpAddress: 10.0.0.3 - # clientAndEndpoint_aaa: #works only if we system settigns is set - # # ipAddress: string #Mandatory for ISE, sec ip for AAA - # network: 10.0.0.9 - # protocol: RADIUS - # servers: AAA - # # sharedSecret: string #ISE + clientAndEndpoint_aaa: #works only if we system settigns is set + # ipAddress: 10.197.156.42 #Mandatory for ISE, sec ip for AAA + network: 10.0.0.20 + protocol: RADIUS + servers: AAA + # sharedSecret: string #ISE messageOfTheday: bannerMessage: hello - retainExistingBanner: "true" + retainExistingBanner: True netflowcollector: ipAddress: 10.0.0.4 port: 443 - # network_aaa: #works only if we system settigns is set - # # ipAddress: string #Mandatory for ISE, sec ip for AAA - # network: 10.0.0.8 - # protocol: RADIUS - # servers: AAA - # # sharedSecret: string #ISE + network_aaa: #works only if we system settigns is set + # ipAddress: string #Mandatory for ISE, sec ip for AAA + network: 10.0.0.20 + protocol: TACACS + servers: AAA + # sharedSecret: string #ISE ntpServer: - 10.0.0.5 snmpServer: - configureDnacIP: true + configureDnacIP: True ipAddresses: - 10.0.0.6 syslogServer: - configureDnacIP: true + configureDnacIP: True ipAddresses: - 10.0.0.7 timezone: GMT siteName: Global/Chennai - diff --git a/plugins/modules/network_intent.py b/plugins/modules/network_intent.py index 32d1116a65..44c5f55d9d 100644 --- a/plugins/modules/network_intent.py +++ b/plugins/modules/network_intent.py @@ -1,128 +1,108 @@ -# This module will work for global_pool, Reserve_ip_pool and network (under network it will not work for network_aaa and clientEndpoint_aaa) +# This module will work for global_pool, Reserve_ip_pool and network -import copy +from __future__ import absolute_import, division, print_function -try: - from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( - AnsibleArgSpecValidator, - ) -except ImportError: - ANSIBLE_UTILS_IS_INSTALLED = False -else: - ANSIBLE_UTILS_IS_INSTALLED = True +import copy +from ansible.module_utils.basic import AnsibleModule from ansible_collections.cisco.dnac.plugins.module_utils.dnac import ( - DNACSDK, - dnac_argument_spec, + DnacBase, validate_list_of_dicts, - log, get_dict_result, dnac_compare_equality, ) -from ansible.module_utils.basic import AnsibleModule - -class DnacNetwork: +class DnacNetwork(DnacBase): + """Class containing member attributes for network intent module""" def __init__(self, module): - self.module = module - self.params = module.params - self.config = copy.deepcopy(module.params.get("config")) - self.have = {} - self.want = {} + super().__init__(module) + self.have_global = {} + self.want_global = {} self.have_reserve = {} self.want_reserve = {} - self.have_net = {} - self.want_net = {} + self.have_network = {} + self.want_network = {} self.site_id = None - self.validated = [] - dnac_params = self.get_dnac_params(self.params) - log(str(dnac_params)) - self.dnac = DNACSDK(params=dnac_params) - self.log = dnac_params.get("dnac_log") - - self.result = dict(changed=False, diff=[], response=[], warnings=[]) - def get_state(self): - return self.params.get("state") def validate_input(self): + """Validate the fields provided in the playbook""" + + if not self.config: + self.msg = "config not available in playbook for validattion" + self.status = "success" + return self + temp_spec = { - "IpAddressSpace": {"required": False, "type": 'string'}, - "dhcpServerIps": {"required": False, "type": 'list'}, - "dnsServerIps": {"required": False, "type": 'list'}, - "gateway": {"required": False, "type": 'string'}, - "ipPoolCidr": {"required": False, "type": 'string'}, - "ipPoolName": {"required": False, "type": 'string'}, - "name": {"required": False, "type": 'string'}, - "prev_name": {"required": False, "type": 'string'}, - "type": {"required": False, "type": "string", \ + "settings": {"type": 'dict'}, + "ippool":{"type": 'list'}, + "IpAddressSpace": {"type": 'string'}, + "dhcpServerIps": {"type": 'list'}, + "dnsServerIps": {"type": 'list'}, + "gateway": {"type": 'string'}, + "ipPoolCidr": {"type": 'string'}, + "ipPoolName": {"type": 'string'}, + "name": {"type": 'string'}, + "prev_name": {"type": 'string'}, + "type": {"type": "string", \ "choices": ["Generic", "tunnel", "LAN", "WAN", "management", "service"]}, - "ipv6AddressSpace": {"required": False, "type": 'string'}, - "ipv4GlobalPool": {"required": False, "type": 'string'}, - "ipv4Prefix": {"required": False, "type": 'string'}, - "ipv4PrefixLength": {"required": False, "type": 'string'}, - "ipv4GateWay": {"required": False, "type": 'string'}, - "ipv4DhcpServers": {"required": False, "type": 'list'}, - "ipv4DnsServers": {"required": False, "type": 'list'}, - "ipv6GlobalPool": {"required": False, "type": 'string'}, - "ipv6Prefix": {"required": False, "type": 'string'}, - "ipv6PrefixLength": {"required": False, "type": 'integer'}, - "ipv6GateWay": {"required": False, "type": 'string'}, - "ipv6DhcpServers": {"required": False, "type": 'list'}, - "ipv6DnsServers": {"required": False, "type": 'list'}, - "ipv4TotalHost": {"required": False, "type": 'integer'}, - "ipv6TotalHost": {"required": False, "type": 'integet'}, - "slaacSupport": {"required": False, "type": 'string'}, - "siteName": {"required": False, "type": 'string'}, - "dhcpServer": {"required": False, "type": 'list'}, - "domainName": {"required": False, "type": 'string'}, - "primaryIpAddress": {"required": False, "type": 'string'}, - "secondaryIpAddress": {"required": False, "type": 'string'} + "ipv6AddressSpace": {"type": 'bool'}, + "ipv4GlobalPool": {"type": 'string'}, + "ipv4Prefix": {"type": 'bool'}, + "ipv4PrefixLength": {"type": 'string'}, + "ipv4GateWay": {"type": 'string'}, + "ipv4DhcpServers": {"type": 'list'}, + "ipv4DnsServers": {"type": 'list'}, + "ipv6GlobalPool": {"type": 'string'}, + "ipv6Prefix": {"type": 'bool'}, + "ipv6PrefixLength": {"type": 'integer'}, + "ipv6GateWay": {"type": 'string'}, + "ipv6DhcpServers": {"type": 'list'}, + "ipv6DnsServers": {"type": 'list'}, + "ipv4TotalHost": {"type": 'integer'}, + "ipv6TotalHost": {"type": 'integer'}, + "slaacSupport": {"type": 'bool'}, + "siteName": {"type": 'string'}, + "dhcpServer": {"type": 'list'}, + "dnsServer": {"type": 'dict'}, + "syslogServer": {"type": 'dict'}, + "snmpServer": {"type": 'dict'}, + "netflowcollector": {"type": 'dict'}, + "messageOfTheday": {"type": 'dict'}, + "network_aaa": {"type": 'dict'}, + "clientAndEndpoint_aaa": {"type": 'dict'}, + "domainName": {"type": 'string'}, + "primaryIpAddress": {"type": 'string'}, + "secondaryIpAddress": {"type": 'string'}, + "servers" : {"type": 'string', "choices": ["ISE", "AAA"]}, + "ipAddress" : {"type": 'string'}, + "network": {"type": 'string'}, + "protocol": {"type": 'string', "choices": ["RADIUS", "TACACS"]}, + "bannerMessage": {"type": 'string'}, + "retainExistingBanner": {"type": 'bool'}, + "sharedSecret": {"type": 'string'}, + "configureDnacIP": {"type": 'bool'}, + "ipAddresses": {"type": 'list'}, + "timezone": {"type": 'string'}, + "ntpServer": {"type": 'list'} + } - if self.config: - msg = None - temp = [] - temp1 = [] - temp2 = [] - # Validate template params - if self.config[0].get("GlobalPoolDetails") is not None: - temp = self.config[0].get("GlobalPoolDetails").get("settings").get("ippool") - if self.config[0].get("ReservePoolDetails") is not None: - temp1 = [self.config[0].get("ReservePoolDetails")] - if self.config[0].get("NetworkManagementDetails") is not None: - temp2.append(self.config[0].get("NetworkManagementDetails") \ - .get("settings").get("dhcpServer")) - temp2.append(self.config[0].get("NetworkManagementDetails") \ - .get("settings").get("dnsServer").get("domainName")) - temp2.append(self.config[0].get("NetworkManagementDetails") \ - .get("settings").get("dnsServer").get("primaryIpAddress")) - temp2.append(self.config[0].get("NetworkManagementDetails") \ - .get("settings").get("dnsServer").get("secondaryIpAddress")) - - temp = temp + temp1 - valid_temp, invalid_params = validate_list_of_dicts( - temp, temp_spec - ) - if invalid_params: - msg = "Invalid parameters in playbook: {0}".format( - "\n".join(invalid_params) - ) - self.module.fail_json(msg=msg) - log(str(invalid_params)) - self.validated = valid_temp - - if self.log: - log(str(valid_temp)) - log(str(self.result)) - - log(str(self.validated)) - if self.params.get("config")[0].get("GlobalPoolDetails") is not None: - for temp in self.validated: - log(str(temp)) - if self.params.get("config")[0].get("GlobalPoolDetails") \ - .get("ipPoolName") is not None: - msg = "missing required arguments: ipPoolName" - self.module.fail_json(msg=msg) + + # Validate template params + valid_temp, invalid_params = validate_list_of_dicts( + self.config, temp_spec + ) + if invalid_params: + self.msg = "Invalid parameters in playbook: {0}".format( + "\n".join(invalid_params)) + self.status = "failed" + return self + + self.validated_config = valid_temp + self.log(str(valid_temp)) + self.msg = "Successfully validated input" + self.status = "success" + return self def get_dnac_params(self, params): dnac_params = dict( @@ -137,11 +117,11 @@ def get_dnac_params(self, params): return dnac_params - def requires_update(self, have, want, obj_params): - current_obj = have - requested_obj = want - log(str(current_obj)) - log(str(requested_obj)) + def requires_update(self, have_global, want_global, obj_params): + current_obj = have_global + requested_obj = want_global + self.log(str(current_obj)) + self.log(str(requested_obj)) return any(not dnac_compare_equality(current_obj.get(dnac_param), requested_obj.get(ansible_param)) @@ -161,9 +141,9 @@ def get_pool_id_from_name(self, pool_name): if isinstance(response, dict): if "response" in response: response = response.get("response") - log(str(response)) + self.log(str(response)) current_details = get_dict_result(response, "ipPoolName", pool_name) - log(str(current_details)) + self.log(str(current_details)) if current_details: pool_id = current_details.get("id") @@ -173,32 +153,60 @@ def get_pool_id_from_name(self, pool_name): return (pool_id, current_details) - def get_res_id_from_name(self, res_name): - _id = "" - current_details = None + def get_res_id_by_name(self, name): + _id = None try: response = self.dnac._exec( family="network_settings", function="get_reserve_ip_subpool", - params={"site_id": self.site_id} + params={"siteId":self.site_id}, ) + self.log(str(response)) + if isinstance(response, dict): if "response" in response: response = response.get("response") - log(str(response)) - current_details = get_dict_result(response, "groupName", res_name) - log(str(current_details)) - _id = current_details.get("id") + current_details = get_dict_result(response, "groupName", name) + if current_details: + _id = current_details.get("id") + + except: + result = None + + return _id + + + def get_site_id(self, site_name): + + response = {} + _id = None + try: + response = self.dnac._exec( + family="sites", + function='get_site', + params={"name":site_name}, + ) + except: - log("except") result = None + self.log(str(response)) + if not response: + self.log("Invalid site name or site not present") + self.msg = "Invalid site name or site not present" + self.status = "failed" + return self + else: + _id = response.get("response")[0].get("id") + self.log(str(_id)) + return _id + def get_current_pool(self, pool): - log(str(pool)) + self.log(str(pool)) pool_values = { "settings": { "ippool": [{ @@ -210,33 +218,36 @@ def get_current_pool(self, pool): }] } } - log(str(pool_values)) + self.log(str(pool_values)) + pool_ippool = pool_values.get("settings").get("ippool")[0] if pool.get("ipv6") is False: - pool_values.get("settings").get("ippool")[0].update({"IpAddressSpace": "IPv4"}) - log("ipv6 - false") + pool_ippool.update({"IpAddressSpace": "IPv4"}) + self.log("ipv6 - false") else: - pool_values.get("settings").get("ippool")[0].update({"IpAddressSpace": "IPv6"}) - log("ipv6 - true") + pool_ippool.update({"IpAddressSpace": "IPv6"}) + self.log("ipv6 - true") if not pool["gateways"]: - pool_values.get("settings").get("ippool")[0].update({"gateway": ""}) + pool_ippool.update({"gateway": ""}) else: - pool_values.get("settings").get("ippool")[0] \ - .update({"gateway": pool.get("gateways")[0]}) + pool_ippool.update({"gateway": pool.get("gateways")[0]}) return pool_values def get_current_res(self, res): - log(str(res)) - res_values = dict( - name = res.get("groupName"), - site_id = res.get("siteId"), - ) - + self.log(str(res)) + res_values = { + "name": res.get("groupName"), + "site_id": res.get("siteId"), + } if len(res.get("ipPools")) == 1: + res_values.update({"ipv4DhcpServers": res.get("ipPools")[0].get("dhcpServerIps")}) res_values.update({"ipv4DnsServers": res.get("ipPools")[0].get("dnsServerIps")}) - res_values.update({"ipv4GateWay": res.get("ipPools")[0].get("gateways")[0]}) + if res.get("ipPools")[0].get("gateways") != []: + res_values.update({"ipv4GateWay": res.get("ipPools")[0].get("gateways")[0]}) + else: + res_values.update({"ipv4GateWay": ""}) res_values.update({"ipv6AddressSpace": "False"}) elif len(res.get("ipPools")) == 2: @@ -247,7 +258,10 @@ def get_current_res(self, res): res_values.update({"ipv6AddressSpace": "True"}) res_values.update({"ipv4DhcpServers": res.get("ipPools")[1].get("dhcpServerIps")}) res_values.update({"ipv4DnsServers": res.get("ipPools")[1].get("dnsServerIps")}) - res_values.update({"ipv4GateWay": res.get("ipPools")[1].get("gateways")[0]}) + if res.get("ipPools")[1].get("gateways") != []: + res_values.update({"ipv4GateWay": res.get("ipPools")[1].get("gateways")[0]}) + else: + res_values.update({"ipv4GateWay": ""}) elif res.get("ipPools")[1].get("ipv6") is False: res_values.update({"ipv4DhcpServers": res.get("ipPools")[1].get("dhcpServerIps")}) @@ -256,13 +270,16 @@ def get_current_res(self, res): res_values.update({"ipv6AddressSpace": "True"}) res_values.update({"ipv4DhcpServers": res.get("ipPools")[0].get("dhcpServerIps")}) res_values.update({"ipv4DnsServers": res.get("ipPools")[0].get("dnsServerIps")}) - res_values.update({"ipv4GateWay": res.get("ipPools")[0].get("gateways")[0]}) - + if res.get("ipPools")[0].get("gateways") != []: + res_values.update({"ipv4GateWay": res.get("ipPools")[0].get("gateways")[0]}) + else: + res_values.update({"ipv4GateWay": ""}) + self.log(str(res_values)) return res_values def get_current_net(self, site_id): - log(str(site_id)) + self.log(str(site_id)) response = None try: @@ -274,7 +291,7 @@ def get_current_net(self, site_id): except: result = None - log(str(response)) + self.log(str(response)) if isinstance(response, dict): if "response" in response: @@ -287,73 +304,79 @@ def get_current_net(self, site_id): netflow_details = get_dict_result(response, "key", "netflow.collector") ntpserver_details = get_dict_result(response, "key", "ntp.server") timezone_details = get_dict_result(response, "key", "timezone.site") - messageoftheday_details = get_dict_result(response, "key", "device.banner") - - snmp_details - log(str(dhcp_details)) - log(str(dns_details)) + messageoftheday_details = get_dict_result(response, "key", "banner.setting") + network_aaa = get_dict_result(response, "key", "aaa.network.server.1") + network_aaa_pan = get_dict_result(response, "key", "aaa.server.pan.network") + clientAndEndpoint_aaa = get_dict_result(response, "key", "aaa.endpoint.server.1") + clientAndEndpoint_aaa_pan = get_dict_result(response, "key", "aaa.server.pan.endpoint") net_values = { "settings": { - "dhcpServer": dhcp_details.get("value"), - "dnsServer": { - "domainName": dns_details.get("value")[0].get("domainName"), - "primaryIpAddress": dns_details.get("value")[0].get("primaryIpAddress"), - "secondaryIpAddress": dns_details.get("value")[0].get("secondaryIpAddress") - }, + "snmpServer": { "configureDnacIP": snmp_details.get("value")[0].get("configureDnacIP"), "ipAddresses": snmp_details.get("value")[0].get("ipAddresses"), }, + "syslogServer": { "configureDnacIP": syslog_details.get("value")[0].get("configureDnacIP"), "ipAddresses": syslog_details.get("value")[0].get("ipAddresses"), }, + "netflowcollector": { "ipAddress": netflow_details.get("value")[0].get("ipAddress"), "port": netflow_details.get("value")[0].get("port"), "configureDnacIP": netflow_details.get("value")[0].get("configureDnacIP"), }, - "ntpServer": ntpserver_details.get("value"), - "timezone": timezone_details.get("value")[0], - "messageOfTheday": { - "bannerMessage": messageoftheday_details.get("value")[0].get("bannerMessage"), - "retainExistingBanner": messageoftheday_details.get("value")[0].get("retainExistingBanner"), - } + "timezone": timezone_details.get("value")[0], } } - + if dhcp_details != None: + net_values.get("settings").update({"dhcpServer": dhcp_details.get("value")}) + + if dns_details != None: + net_values.get("settings").update({"dnsServer": { + "domainName": dns_details.get("value")[0].get("domainName"), + "primaryIpAddress": dns_details.get("value")[0].get("primaryIpAddress"), + "secondaryIpAddress": dns_details.get("value")[0] \ + .get("secondaryIpAddress") + } + }) + + if ntpserver_details != None: + net_values.get("settings").update({"ntpServer": ntpserver_details.get("value")}) + + if messageoftheday_details != None: + net_values.get("settings").update({"messageOfTheday": { + "bannerMessage": messageoftheday_details \ + .get("value")[0].get("bannerMessage"), + "retainExistingBanner": messageoftheday_details \ + .get("value")[0].get("retainExistingBanner"), + } + }) + + if network_aaa and network_aaa_pan: + net_values.get("settings").update({"network_aaa": { + "network": network_aaa.get("value")[0].get("ipAddress"), + "protocol": network_aaa.get("value")[0].get("protocol"), + "ipAddress": network_aaa_pan.get("value")[0] + } + }) + + if clientAndEndpoint_aaa and clientAndEndpoint_aaa_pan: + net_values.get("settings").update({"clientAndEndpoint_aaa": { + "network": clientAndEndpoint_aaa.get("value")[0].get("ipAddress"), + "protocol": clientAndEndpoint_aaa.get("value")[0].get("protocol"), + "ipAddress": clientAndEndpoint_aaa_pan.get("value")[0], + } + }) + self.log(str(net_values)) return net_values - def get_site_id(self, site_name): - - response = {} - _id = None - try: - response = self.dnac._exec( - family="sites", - function='get_site', - params={"name":site_name}, - ) - - except: - result = None - log(str(response)) - if not response: - log("Invalid site name or site not present") - self.result["response"] = [] - self.result["msg"] = "Invalid site name or site not present" - self.module.fail_json(**self.result) - else: - _id = response.get("response")[0].get("id") - log(str(_id)) - - return _id - - def pool_exists(self): + def pool_exists(self, config): pool_exists = False pool_details = {} pool_id = None @@ -362,7 +385,7 @@ def pool_exists(self): #get it from validated - name = self.params.get("config")[0].get("GlobalPoolDetails") \ + name = config.get("GlobalPoolDetails") \ .get("settings").get("ippool")[0].get("ipPoolName") try: @@ -370,39 +393,41 @@ def pool_exists(self): family = "network_settings", function = "get_global_pool", ) - log(str(response)) + self.log(str(response)) if isinstance(response, dict): if "response" in response: response = response.get("response") current_details = get_dict_result(response, "ipPoolName", name) - log(str(current_details)) + self.log(str(name)) + self.log(str(current_details)) if current_details: pool_exists = True pool_id = current_details.get("id") - elif self.config[0].get("GlobalPoolDetails").get("settings") \ + elif config.get("GlobalPoolDetails").get("settings") \ .get("ippool")[0].get("prev_name") is not None: pool_id = None - (pool_id, current_details) = self.get_pool_id_from_name(self.config[0]. \ + (pool_id, current_details) = self.get_pool_id_from_name(config. \ get("GlobalPoolDetails").get("settings").get("ippool")[0].get("prev_name")) if pool_id is None: - msg = "Prev name doesn't exist\n" - self.module.fail_json(msg=msg) + self.msg = "Prev name doesn't exist\n" + self.status = "failed" + return self pool_exists = True current_details = get_dict_result(response, "id", pool_id) - log(str(current_details)) + self.log(str(current_details)) pool_details = self.get_current_pool(current_details) except Exception: result = None - log(str(pool_details)) - log(str(pool_id)) + self.log(str(pool_details)) + self.log(str(pool_id)) return (pool_exists, pool_details, pool_id) - def res_exists(self): + def res_exists(self, config): current_details = None res_exists = False res_details = None @@ -410,23 +435,24 @@ def res_exists(self): response = None site_name = None _id = "" - site_name = self.params.get("config")[0].get("ReservePoolDetails").get("siteName") - log(str(site_name)) + site_name = config.get("ReservePoolDetails").get("siteName") + self.log(str(site_name)) if site_name is not None: site_id = self.get_site_id(site_name) self.site_id = site_id - name = self.config[0].get("ReservePoolDetails").get("name") - prev_name = self.config[0].get("ReservePoolDetails").get("prev_name") + name = config.get("ReservePoolDetails").get("name") + prev_name = config.get("ReservePoolDetails").get("prev_name") if prev_name: - if not self.params.get("config")[0].get("ReservePoolDetails").get("siteName"): - msg = "Mandatory Parameter siteName required\n" - self.module.fail_json(msg=msg) - _id = self.get_res_id_from_name(prev_name) + if not config.get("ReservePoolDetails").get("siteName"): + self.msg = "Mandatory Parameter siteName required\n" + self.status = "failed" + return self + _id = self.get_res_id_by_name(prev_name) - log(str(_id)) + self.log(str(_id)) try: response = self.dnac._exec( family="network_settings", @@ -436,14 +462,14 @@ def res_exists(self): if isinstance(response, dict): if "response" in response: response = response.get("response") - log(str(response)) + self.log(str(response)) if _id: current_details = get_dict_result(response, "id", _id) elif name: current_details = get_dict_result(response, "groupName", name) - log(str(current_details)) + self.log(str(current_details)) if current_details: res_exists = True @@ -452,12 +478,12 @@ def res_exists(self): except Exception: result = None - log(str(res_details)) - log(str(res_id)) + self.log(str(res_details)) + self.log(str(res_id)) return (res_exists, res_details, res_id) - def get_have(self): + def get_have(self, config): pool_exists = False pool_details = None pool_id = None @@ -468,28 +494,24 @@ def get_have(self): #checking if the pool is already exists or not - if self.params.get("config")[0].get("GlobalPoolDetails") is not None: - have = {} - (pool_exists, pool_details, pool_id) = self.pool_exists() + if config.get("GlobalPoolDetails") is not None: + have_global = {} + (pool_exists, pool_details, pool_id) = self.pool_exists(config) - if self.log: - log("pool Exists: " + str(pool_exists) + "\n Current Site: " + str(pool_details)) + self.log("pool Exists: " + str(pool_exists) + "\n Current Site: " + str(pool_details)) if pool_exists: - have["pool_id"] = pool_id - have["pool_exists"] = pool_exists - have["pool_details"] = pool_details - log(str(pool_details)) + have_global["pool_id"] = pool_id + have_global["pool_exists"] = pool_exists + have_global["pool_details"] = pool_details - self.have = have + self.have_global = have_global - if self.params.get("config")[0].get("ReservePoolDetails") is not None: + if config.get("ReservePoolDetails") is not None: have_reserve = {} - (res_exists, res_details, res_id) = self.res_exists() - - if self.log: - log("Reservation Exists: " + str(res_exists) \ - + "\n Reserved Pool: " + str(res_details)) + (res_exists, res_details, res_id) = self.res_exists(config) + self.log("Reservation Exists: " + str(res_exists) \ + + "\n Reserved Pool: " + str(res_details)) if res_exists: have_reserve["res_exists"] = res_exists @@ -503,152 +525,127 @@ def get_have(self): self.have_reserve = have_reserve - if self.params.get("config")[0].get("NetworkManagementDetails") is not None: + if config.get("NetworkManagementDetails") is not None: - have_net = {} - site_name = self.params.get("config")[0].get("NetworkManagementDetails").get("siteName") + have_network = {} + site_name = config.get("NetworkManagementDetails").get("siteName") if site_name is None: - self.module.fail_json(msg="Mandatory Parameter siteName missings", response=[]) - - site_id_net = self.get_site_id(site_name) + self.msg = "Mandatory Parameter siteName missing" + self.status = "failed" + return self - if site_id_net is None: - self.module.fail_json(msg="Invalid siteName", response=[]) + site_id = self.get_site_id(site_name) - have_net["site_id"] = site_id_net - have_net["net_details"] = self.get_current_net(site_id_net) + if site_id is None: + self.msg = "Invalid siteName" + self.status = "failed" + return self - self.have_net = have_net + have_network["site_id"] = site_id + have_network["net_details"] = self.get_current_net(site_id) + self.log(str(have_network)) + self.have_network = have_network + self.status = "success" + return self - def get_want(self): - if self.params.get("config")[0].get("GlobalPoolDetails") is not None: - want = {} - IpAddressSpace = self.params.get("config")[0] \ - .get("GlobalPoolDetails").get("settings").get("ippool")[0] - dhcpServerIps = self.params.get("config")[0] \ - .get("GlobalPoolDetails").get("settings").get("ippool")[0] - dnsServerIps = self.params.get("config")[0] \ - .get("GlobalPoolDetails").get("settings").get("ippool")[0] - gateway = self.params.get("config")[0] \ - .get("GlobalPoolDetails").get("settings").get("ippool")[0] - ipPoolCidr = self.params.get("config")[0] \ - .get("GlobalPoolDetails").get("settings").get("ippool")[0] - ipPoolName = self.params.get("config")[0] \ - .get("GlobalPoolDetails").get("settings").get("ippool")[0] - _type = self.params.get("config")[0] \ + def get_want(self, config): + if config.get("GlobalPoolDetails") is not None: + want_global = {} + global_ippool = config \ .get("GlobalPoolDetails").get("settings").get("ippool")[0] - want = { + want_global = { "settings": { "ippool": [{ - "IpAddressSpace": IpAddressSpace.get("IpAddressSpace"), - "dhcpServerIps": dhcpServerIps.get("dhcpServerIps"), - "dnsServerIps": dnsServerIps.get("dnsServerIps"), - "gateway": gateway.get("gateway"), - "ipPoolCidr": ipPoolCidr.get("ipPoolCidr"), - "ipPoolName": ipPoolName.get("ipPoolName"), - "type": _type.get("type"), + "IpAddressSpace": global_ippool.get("IpAddressSpace"), + "dhcpServerIps": global_ippool.get("dhcpServerIps"), + "dnsServerIps": global_ippool.get("dnsServerIps"), + "gateway": global_ippool.get("gateway"), + "ipPoolCidr": global_ippool.get("ipPoolCidr"), + "ipPoolName": global_ippool.get("ipPoolName"), + "type": global_ippool.get("type"), }] } } - log(str(self.have)) - if not self.have.get("pool_exists"): - if want.get("settings").get("ippool")[0].get("dhcpServerIps") is None: - want.get("settings").get("ippool")[0].update({"dhcpServerIps": []}) - if want.get("settings").get("ippool")[0].get("dnsServerIps") is None: - want.get("settings").get("ippool")[0].update({"dnsServerIps": []}) - if want.get("settings").get("ippool")[0].get("IpAddressSpace") is None: - want.get("settings").get("ippool")[0].update({"IpAddressSpace": ""}) - if want.get("settings").get("ippool")[0].get("gateway") is None: - want.get("settings").get("ippool")[0].update({"gateway": ""}) - if want.get("settings").get("ippool")[0].get("type") is None: - want.get("settings").get("ippool")[0].update({"type": "Generic"}) + self.log(str(self.have_global)) + if not self.have_global.get("pool_exists"): + want_ippool = want_global.get("settings").get("ippool")[0] + + if want_ippool.get("dhcpServerIps") is None: + want_ippool.update({"dhcpServerIps": []}) + if want_ippool.get("dnsServerIps") is None: + want_ippool.update({"dnsServerIps": []}) + if want_ippool.get("IpAddressSpace") is None: + want_ippool.update({"IpAddressSpace": ""}) + if want_ippool.get("gateway") is None: + want_ippool.update({"gateway": ""}) + if want_ippool.get("type") is None: + want_ippool.update({"type": "Generic"}) else: - if self.have.get("pool_details").get("settings") \ - .get("ippool")[0].get("IpAddressSpace") == "IPv4": + have_ippool = self.have_global.get("pool_details") \ + .get("settings").get("ippool")[0] + want_ippool = want_global.get("settings").get("ippool")[0] + + if have_ippool.get("IpAddressSpace") == "IPv4": - want.get("settings").get("ippool")[0].update({"IpAddressSpace": "IPv4"}) - log("true") + want_ippool.update({"IpAddressSpace": "IPv4"}) + self.log("true") - elif self.have.get("pool_details").get("settings") \ - .get("ippool")[0].get("IpAddressSpace") == "Ipv6": + elif have_ippool.get("IpAddressSpace") == "Ipv6": - want.get("settings").get("ippool")[0].update({"IpAddressSpace": "IPv6"}) - log("false") + want_ippool.update({"IpAddressSpace": "IPv6"}) + self.log("false") - want.get("settings").get("ippool")[0].update({"type": self.have. \ - get("pool_details").get("settings").get("ippool")[0].get("ipPoolType")}) - want.get("settings").get("ippool")[0].update({"ipPoolCidr": \ - self.have.get("pool_details").get("settings") \ - .get("ippool")[0].get("ipPoolCidr")}) + want_ippool.update({"type": have_ippool.get("ipPoolType")}) + want_ippool.update({"ipPoolCidr": have_ippool.get("ipPoolCidr")}) - if want.get("settings").get("ippool")[0].get("dhcpServerIps") is None and \ - self.have.get("pool_details").get("settings") \ - .get("ippool")[0].get("dhcpServerIps") is not None: - want.get("settings").get("ippool")[0].update({"dhcpServerIps": \ - self.have.get("pool_details").get("settings") \ - .get("ippool")[0].get("dhcpServerIps")}) + if want_ippool.get("dhcpServerIps") is None and \ + have_ippool.get("dhcpServerIps") is not None: - if want.get("settings").get("ippool")[0].get("dnsServerIps") is None and \ - self.have.get("pool_details").get("settings") \ - .get("ippool")[0].get("dnsServerIps") is not None: + want_ippool.update({"dhcpServerIps": have_ippool.get("dhcpServerIps")}) - want.get("settings").get("ippool")[0].update({"dnsServerIps": \ - self.have.get("pool_details").get("settings") \ - .get("ippool")[0].get("dnsServerIps")}) + if want_ippool.get("dnsServerIps") is None and \ + have_ippool.get("dnsServerIps") is not None: - if want.get("settings").get("ippool")[0].get("gateway") is None and \ - self.have.get("pool_details").get("settings") \ - .get("ippool")[0].get("gateway") is not None: + want_ippool.update({"dnsServerIps": have_ippool.get("dnsServerIps")}) - want.get("settings").get("ippool")[0].update({"gateway": \ - self.have.get("pool_details").get("settings") \ - .get("ippool")[0].get("gateway")}) + if want_ippool.get("gateway") is None and \ + have_ippool.get("gateway") is not None: - log(str(want)) - self.want = want + want_ippool.update({"gateway": have_ippool.get("gateway")}) - if self.params.get("config")[0].get("ReservePoolDetails") is not None: + self.log(str(want_global)) + self.want_global = want_global + if config.get("ReservePoolDetails") is not None: + + res_pool = config.get("ReservePoolDetails") want_reserve = { - "name": self.params.get("config")[0].get("ReservePoolDetails").get("name"), - "type": self.params.get("config")[0].get("ReservePoolDetails").get("type"), - "ipv6AddressSpace": self.params.get("config")[0] \ - .get("ReservePoolDetails").get("ipv6AddressSpace"), - "ipv4GlobalPool": self.params.get("config")[0] \ - .get("ReservePoolDetails").get("ipv4GlobalPool"), - "ipv4Prefix": self.params.get("config")[0] \ - .get("ReservePoolDetails").get("ipv4Prefix"), - "ipv4PrefixLength": self.params.get("config")[0] \ - .get("ReservePoolDetails").get("ipv4PrefixLength"), - "ipv4GateWay": self.params.get("config")[0] \ - .get("ReservePoolDetails").get("ipv4GateWay"), - "ipv4DhcpServers": self.params.get("config")[0] \ - .get("ReservePoolDetails").get("ipv4DhcpServers"), - "ipv4DnsServers": self.params.get("config")[0] \ - .get("ReservePoolDetails").get("ipv4DnsServers"), - "ipv6GlobalPool": self.params.get("config")[0] \ - .get("ReservePoolDetails").get("ipv6GlobalPool"), - "ipv6Prefix": self.params.get("config")[0] \ - .get("ReservePoolDetails").get("ipv6Prefix"), - "ipv6PrefixLength": self.params.get("config")[0] \ - .get("ReservePoolDetails").get("ipv6PrefixLength"), - "ipv6GateWay": self.params.get("config")[0] \ - .get("ReservePoolDetails").get("ipv6GateWay"), - "ipv6DhcpServers": self.params.get("config")[0] \ - .get("ReservePoolDetails").get("ipv6DhcpServers"), - "ipv6DnsServers": self.params.get("config")[0] \ - .get("ReservePoolDetails").get("ipv6DnsServers"), - "ipv4TotalHost": self.params.get("config")[0] \ - .get("ReservePoolDetails").get("ipv4TotalHost"), - "ipv6TotalHost": self.params.get("config")[0] \ - .get("ReservePoolDetails").get("ipv6TotalHost") + "name": res_pool.get("name"), + "type": res_pool.get("type"), + "ipv6AddressSpace": res_pool.get("ipv6AddressSpace"), + "ipv4GlobalPool": res_pool.get("ipv4GlobalPool"), + "ipv4Prefix": res_pool.get("ipv4Prefix"), + "ipv4PrefixLength": res_pool.get("ipv4PrefixLength"), + "ipv4GateWay": res_pool.get("ipv4GateWay"), + "ipv4DhcpServers": res_pool.get("ipv4DhcpServers"), + "ipv4DnsServers": res_pool.get("ipv4DnsServers"), + "ipv4Subnet": res_pool.get("ipv4Subnet"), + "ipv6GlobalPool": res_pool.get("ipv6GlobalPool"), + "ipv6Prefix": res_pool.get("ipv6Prefix"), + "ipv6PrefixLength": res_pool.get("ipv6PrefixLength"), + "ipv6GateWay": res_pool.get("ipv6GateWay"), + "ipv6DhcpServers": res_pool.get("ipv6DhcpServers"), + "ipv6Subnet": res_pool.get("ipv6Subnet"), + "ipv6DnsServers": res_pool.get("ipv6DnsServers"), + "ipv4TotalHost": res_pool.get("ipv4TotalHost"), + "ipv6TotalHost": res_pool.get("ipv6TotalHost") } - log(str(self.have_reserve)) + self.log(str(self.have_reserve)) if not self.have_reserve: if want_reserve.get("type") is None: want_reserve.update({"type": "Generic"}) @@ -690,118 +687,305 @@ def get_want(self): del want_reserve['ipv4Prefix'] del want_reserve['ipv4PrefixLength'] del want_reserve['ipv4TotalHost'] + del want_reserve['ipv4Subnet'] self.want_reserve = want_reserve - if self.params.get("config")[0].get("NetworkManagementDetails") is not None: - log(str(self.params)) - want_net = { + if config.get("NetworkManagementDetails") is not None: + want_network = { "settings": { - "dhcpServer": self.params.get("config")[0].get("NetworkManagementDetails") \ - .get("settings").get("dhcpServer"), + "dhcpServer": { + + }, "dnsServer": { - "domainName": self.params.get("config")[0].get("NetworkManagementDetails") \ - .get("settings").get("dnsServer").get("domainName"), - "primaryIpAddress": self.params.get("config")[0] \ - .get("NetworkManagementDetails").get("settings") \ - .get("dnsServer").get("primaryIpAddress"), - "secondaryIpAddress": self.params.get("config")[0] \ - .get("NetworkManagementDetails").get("settings") \ - .get("dnsServer").get("secondaryIpAddress") + }, "snmpServer": { - "configureDnacIP": self.params.get("config")[0].get("NetworkManagementDetails") \ - .get("settings").get("snmpServer").get("configureDnacIP"), - "ipAddresses": self.params.get("config")[0].get("NetworkManagementDetails") \ - .get("settings").get("snmpServer").get("ipAddresses") + }, "syslogServer": { - "configureDnacIP": self.params.get("config")[0].get("NetworkManagementDetails") \ - .get("settings").get("syslogServer").get("configureDnacIP"), - "ipAddresses": self.params.get("config")[0].get("NetworkManagementDetails") \ - .get("settings").get("syslogServer").get("ipAddresses") + }, "netflowcollector": { - "ipAddress": self.params.get("config")[0].get("NetworkManagementDetails") \ - .get("settings").get("netflowcollector").get("ipAddress"), - "port": self.params.get("config")[0].get("NetworkManagementDetails") \ - .get("settings").get("netflowcollector").get("port"), - "configureDnacIP": self.params.get("config")[0].get("NetworkManagementDetails") \ - .get("settings").get("netflowcollector").get("configureDnacIP") + + }, + "ntpServer": { + }, - "ntpServer": self.params.get("config")[0].get("NetworkManagementDetails") \ - .get("settings").get("ntpServer"), - "timezone": self.params.get("config")[0].get("NetworkManagementDetails") \ - .get("settings").get("timezone"), + "timezone": "", "messageOfTheday": { - "bannerMessage": self.params.get("config")[0].get("NetworkManagementDetails") \ - .get("settings").get("messageOfTheday").get("bannerMessage"), - "retainExistingBanner": self.params.get("config")[0].get("NetworkManagementDetails") \ - .get("settings").get("messageOfTheday").get("retainExistingBanner") + + }, + "network_aaa": { + + }, + "clientAndEndpoint_aaa": { + } } } + network_management_details = config.get("NetworkManagementDetails") \ + .get("settings") + if network_management_details.get("dhcpServer"): + want_network.get("settings").update({"dhcpServer": + network_management_details.get("dhcpServer") + }) + else: + del want_network.get("settings")["dhcpServer"] + + if network_management_details.get("ntpServer"): + want_network.get("settings").update({"ntpServer": + network_management_details.get("ntpServer") + }) + else: + del want_network.get("settings")["ntpServer"] - self.want_net = want_net + if network_management_details.get("timezone"): + want_network.get("settings")["timezone"] = \ + network_management_details.get("timezone") + else: + del want_network.get("settings")["timezone"] + + if network_management_details.get("dnsServer"): + if network_management_details.get("dnsServer").get("domainName"): + want_network.get("settings").get("dnsServer").update({ + "domainName": network_management_details \ + .get("dnsServer").get("domainName") + }) + + if network_management_details.get("dnsServer").get("primaryIpAddress"): + want_network.get("settings").get("dnsServer").update({ + "primaryIpAddress": network_management_details \ + .get("dnsServer").get("primaryIpAddress") + }) + + if network_management_details.get("dnsServer").get("secondaryIpAddress"): + want_network.get("settings").get("dnsServer").update({ + "secondaryIpAddress": network_management_details \ + .get("dnsServer").get("secondaryIpAddress") + }) + else: + del want_network.get("settings")["dnsServer"] + + if network_management_details.get("snmpServer"): + if network_management_details.get("snmpServer").get("configureDnacIP"): + want_network.get("settings").get("snmpServer").update({ + "configureDnacIP": network_management_details \ + .get("snmpServer").get("configureDnacIP") + }) + if network_management_details.get("snmpServer").get("ipAddresses"): + want_network.get("settings").get("snmpServer").update({ + "ipAddresses": network_management_details \ + .get("snmpServer").get("ipAddresses") + }) + else: + del want_network.get("settings")["snmpServer"] + + if network_management_details.get("syslogServer"): + if network_management_details.get("syslogServer").get("configureDnacIP"): + want_network.get("settings").get("syslogServer").update({ + "configureDnacIP": network_management_details \ + .get("syslogServer").get("configureDnacIP") + }) + if network_management_details.get("syslogServer").get("ipAddresses"): + want_network.get("settings").get("syslogServer").update({ + "ipAddresses": network_management_details \ + .get("syslogServer").get("ipAddresses") + }) + else: + del want_network.get("settings")["syslogServer"] + + if network_management_details.get("netflowcollector"): + if network_management_details.get("netflowcollector").get("ipAddress"): + want_network.get("settings").get("netflowcollector").update({ + "ipAddress": network_management_details \ + .get("netflowcollector").get("ipAddress") + }) + if network_management_details.get("netflowcollector").get("port"): + want_network.get("settings").get("netflowcollector").update({ + "port": network_management_details \ + .get("netflowcollector").get("port") + }) + if network_management_details.get("netflowcollector").get("configureDnacIP"): + want_network.get("settings").get("netflowcollector").update({ + "configureDnacIP": network_management_details \ + .get("netflowcollector").get("configureDnacIP") + }) + else: + del want_network.get("settings")["netflowcollector"] + + if network_management_details.get("messageOfTheday"): + if network_management_details.get("messageOfTheday").get("bannerMessage"): + want_network.get("settings").get("messageOfTheday").update({ + "bannerMessage": network_management_details.get("messageOfTheday").get("bannerMessage") + }) + if network_management_details.get("messageOfTheday").get("retainExistingBanner"): + want_network.get("settings").get("messageOfTheday").update({ + "retainExistingBanner": network_management_details \ + .get("messageOfTheday").get("retainExistingBanner") + }) + else: + del want_network.get("settings")["messageOfTheday"] + + if network_management_details.get("network_aaa"): + if network_management_details.get("network_aaa").get("ipAddress"): + want_network.get("settings").get("network_aaa").update({ + "ipAddress": network_management_details \ + .get("network_aaa").get("ipAddress") + }) + else: + if network_management_details.get("network_aaa").get("servers") == "ISE": + self.msg = "missing parameter ipAddress" + self.status = "failed" + return self + if network_management_details.get("network_aaa").get("network"): + want_network.get("settings").get("network_aaa").update({ + "network": network_management_details.get("network_aaa").get("network") + }) + else: + self.msg="missing parameter network" + self.status = "failed" + return self + + if network_management_details.get("network_aaa").get("protocol"): + want_network.get("settings").get("network_aaa").update({ + "protocol": network_management_details \ + .get("network_aaa").get("protocol") + }) + else: + self.msg="missing parameter protocol" + self.status = "failed" + return self + + if network_management_details.get("network_aaa").get("servers"): + want_network.get("settings").get("network_aaa").update({ + "servers": network_management_details \ + .get("network_aaa").get("servers") + }) + else: + self.msg="missing parameter servers" + self.status = "failed" + return self + + if network_management_details.get("network_aaa").get("sharedSecret"): + want_network.get("settings").get("network_aaa").update({ + "sharedSecret": config \ + .get("NetworkManagementDetails") \ + .get("settings").get("network_aaa").get("sharedSecret") + }) + else: + del want_network.get("settings")["network_aaa"] + + if network_management_details.get("clientAndEndpoint_aaa"): + if network_management_details.get("clientAndEndpoint_aaa").get("ipAddress"): + want_network.get("settings").get("clientAndEndpoint_aaa").update({ + "ipAddress": network_management_details \ + .get("clientAndEndpoint_aaa").get("ipAddress") + }) + else: + if network_management_details.get("clientAndEndpoint_aaa").get("servers") == "ISE": + self. msg="missing parameter ipAddress" + self.status = "failed" + return self + if network_management_details.get("clientAndEndpoint_aaa").get("network"): + want_network.get("settings").get("clientAndEndpoint_aaa").update({ + "network": network_management_details \ + .get("clientAndEndpoint_aaa").get("network") + }) + else: + self.msg="missing parameter network" + self.status = "failed" + return self + + if network_management_details.get("clientAndEndpoint_aaa").get("protocol"): + want_network.get("settings").get("clientAndEndpoint_aaa").update({ + "protocol": network_management_details \ + .get("clientAndEndpoint_aaa").get("protocol") + }) + else: + self.msg="missing parameter protocol" + self.status = "failed" + return self + if network_management_details.get("clientAndEndpoint_aaa").get("servers"): + want_network.get("settings").get("clientAndEndpoint_aaa").update({ + "servers": network_management_details \ + .get("clientAndEndpoint_aaa").get("servers") + }) + else: + self.msg="missing parameter servers" + self.status = "failed" + return self + + if network_management_details.get("clientAndEndpoint_aaa").get("sharedSecret"): + want_network.get("settings").get("clientAndEndpoint_aaa").update({ + "sharedSecret": network_management_details \ + .get("clientAndEndpoint_aaa").get("sharedSecret") + }) + else: + del want_network.get("settings")["clientAndEndpoint_aaa"] + self.log(str(want_network)) + self.want_network = want_network + self.status = "success" + return self def get_execution_details(self, execid): response = None + self.log(str(execid)) response = self.dnac._exec( family="task", function='get_business_api_execution_details', params={"execution_id": execid} ) - if self.log: - log(str(response)) + self.log(str(response)) return response - def get_diff_merge(self): - if self.params.get("config")[0].get("GlobalPoolDetails") is not None: - if not self.params.get("config")[0].get("GlobalPoolDetails") \ + def get_diff_merged(self, config): + if config.get("GlobalPoolDetails") is not None: + + if not config.get("GlobalPoolDetails") \ .get("settings").get("ippool")[0].get("ipPoolName"): - msg = "Mandatory Parameter ipPoolName required\n" - self.module.fail_json(msg=msg) + self.msg = "Mandatory Parameter ipPoolName required\n" + self.status = "failed" + return self pool_updated = False pool_created = False - if self.have.get("pool_exists"): - log("entered") + if self.have_global.get("pool_exists"): obj_params = [ ("settings", "settings"), ] - if self.requires_update(self.have.get("pool_details"), self.want, obj_params): - log("Pool requires update") + if self.requires_update(self.have_global.get("pool_details"), self.want_global, obj_params): + self.log("Pool requires update") #Pool Exists - pool_params = copy.deepcopy(self.want) + pool_params = copy.deepcopy(self.want_global) pool_params.get("settings").get("ippool")[0] \ - .update({"id": self.have.get("pool_id")}) - log(str(self.want)) - log(str(pool_params)) + .update({"id": self.have_global.get("pool_id")}) + self.log(str(pool_params)) del pool_params["settings"]["ippool"][0]["IpAddressSpace"] del pool_params["settings"]["ippool"][0]["ipPoolCidr"] del pool_params["settings"]["ippool"][0]["type"] if pool_params.get("settings").get("ippool")[0].get("dhcpServerIps") is None: pool_params.get("settings").get("ippool")[0].update({"dhcpServerIps" : \ - self.have.get("pool_details").get("settings") \ + self.have_global.get("pool_details").get("settings") \ .get("ippool")[0].get("dhcpServerIps")}) if pool_params.get("settings").get("ippool")[0].get("dnsServerIps") is None: pool_params.get("settings").get("ippool")[0].update({"dnsServerIps" : \ - self.have.get("pool_details").get("settings") \ + self.have_global.get("pool_details").get("settings") \ .get("ippool")[0].get("dnsServerIps")}) if pool_params.get("settings").get("ippool")[0].get("gateway") is None: pool_params.get("settings").get("ippool")[0].update({"gateway" : \ - self.have.get("pool_details").get("settings") \ + self.have_global.get("pool_details").get("settings") \ .get("ippool")[0].get("gateway")}) - log(str(pool_params)) - log(str(self.have)) + self.log(str(pool_params)) + self.log(str(self.have_global)) response = self.dnac._exec( family = "network_settings", function = "update_global_pool", @@ -809,33 +993,32 @@ def get_diff_merge(self): ) pool_updated = True - log(str(pool_updated)) + self.log(str(pool_updated)) else: - log("Pool doesn't requires an update") - log(str(self.have)) - log(str(self.result)) - self.result['response'] = self.have.get("settings") + self.log("Pool doesn't requires an update") + self.log(str(self.have_global)) + self.log(str(self.result)) + self.result['response'] = self.have_global.get("settings") self.result['msg'] = "Pool doesn't requires an update" - # self.module.exit_json(**self.result) else: #creating New Pool - pool_params = self.want - log(str(pool_params)) + pool_params = self.want_global + self.log(str(pool_params)) response = self.dnac._exec( family="network_settings", function="create_global_pool", params = pool_params, ) - log("PoolCreated") - log(str(response)) + self.log("PoolCreated") + self.log(str(response)) pool_created = True if pool_created or pool_updated: if response and isinstance(response, dict): executionid = response.get("executionId") - + self.log(str(executionid)) while True: execution_details = self.get_execution_details(executionid) if execution_details.get("status") == "SUCCESS": @@ -844,38 +1027,37 @@ def get_diff_merge(self): break elif execution_details.get("bapiError"): - - self.module.fail_json(msg=execution_details.get("bapiError"), - response=execution_details) - break + + self.msg=execution_details.get("bapiError") + self.status = "failed" + return self if pool_updated: - log("Pool Updated Successfully") + self.log("Pool Updated Successfully") self.result['msg'] = "Pool Updated Successfully" self.result['response'].update({"Id": \ - self.have.get("pool_details").get("id")}) + self.have_global.get("pool_details").get("id")}) elif pool_created: - log("Pool Created Successfully") - (pool_exists, pool_details, pool_id) = self.pool_exists() + self.log("Pool Created Successfully") + (pool_exists, pool_details, pool_id) = self.pool_exists(config) self.result['response'].update({"Id": pool_id}) self.result['response'].update({"Pool Exists": pool_exists}) self.result['response'].update({"Pool Details": pool_details}) self.result['msg'] = "Pool Created Successfully" else: - log("Pool doesn't need a update") + self.log("Pool doesn't need a update") self.result['msg'] = "Pool doesn't requires an update" self.result['response'].update({"Id": \ - self.have.get("pool_details").get("id")}) + self.have_global.get("pool_details").get("id")}) - if self.params.get("config")[0].get("ReservePoolDetails") is not None: + if config.get("ReservePoolDetails") is not None: res_updated = False res_created = False - log(str(self.have_reserve.get("res_details"))) - log(str(self.want_reserve)) + self.log(str(self.have_reserve.get("res_details"))) + self.log(str(self.want_reserve)) if self.have_reserve: - log("entered") obj_params = [ ("name", "name"), ("type", "type"), @@ -896,10 +1078,10 @@ def get_diff_merge(self): if self.requires_update(self.have_reserve.get("res_details"), \ self.want_reserve, obj_params): - log("Network requires update") + self.log("Network requires update") #Pool Exists - log(str(self.have_reserve)) - log(str(self.want_reserve)) + self.log(str(self.have_reserve)) + self.log(str(self.want_reserve)) res_params = copy.deepcopy(self.want_reserve) res_params.update({"site_id": self.site_id}) @@ -910,36 +1092,37 @@ def get_diff_merge(self): params=res_params, ) - log("Reservation Updated") - log(str(response)) + self.log("Reservation Updated") + self.log(str(response)) res_updated = True else: - log("Reserved ip subpool doesn't requires an update") + self.log("Reserved ip subpool doesn't requires an update") self.result["response"] = self.have_reserve self.result["msg"] = "Reserved ip subpool doesn't requires an update" - # self.module.exit_json(**self.result) else: - #creating New Pool + #creating New Reservation res_params = self.want_reserve - log(str(res_params)) + self.log(str(res_params)) if not self.want_reserve.get("name") or \ not self.want_reserve.get("ipv4GlobalPool") or \ not self.want_reserve.get("ipv4PrefixLength") or not self.site_id: - self.module.fail_json(msg="missing parameter name or \ - ipv4GlobalPool or ipv4PrefixLength or siteName", response=[]) + self.msg="missing parameter name or \ + ipv4GlobalPool or ipv4PrefixLength or siteName" + self.status = "failed" + return self res_params.update({"site_id": self.site_id}) - log(str(res_params)) + self.log(str(res_params)) response = self.dnac._exec( family="network_settings", function="reserve_ip_subpool", params=res_params, ) - log("Reservation Created") - log(str(response)) + self.log("Reservation Created") + self.log(str(response)) res_created = True if res_created or res_updated: @@ -955,130 +1138,115 @@ def get_diff_merge(self): elif execution_details.get("bapiError"): - self.module.fail_json(msg=execution_details.get("bapiError"), - response=execution_details) - break + self.msg = execution_details.get("bapiError") + self.status = "failed" + return self if res_updated: - log("Reserved Ip Subpool Updated Successfully") + self.log("Reserved Ip Subpool Updated Successfully") self.result['msg'] = "Reserved Ip Subpool Updated Successfully" self.result['response'].update({"Reservation details": \ - self.have.get("res_details")}) + self.have_global.get("res_details")}) elif res_created: - log("Ip Subpool Reservation Created Successfully") - (res_exists, res_details, res_id) = self.res_exists() + self.log("Ip Subpool Reservation Created Successfully") + (res_exists, res_details, res_id) = self.res_exists(config) self.result['response'].update({"Reservation Id": res_id}) self.result['response'].update({"Reservation Exists": res_exists}) self.result['response'].update({"Reservation details": res_details}) self.result['msg'] = "Ip Subpool Reservation Created Successfully" else: - log("Ip Subpool Reservation doesn't need a update") + self.log("Ip Subpool Reservation doesn't need a update") self.result['msg'] = "Ip Subpool Reservation doesn't requires an update" self.result['response'].update({"Reservation details": \ - self.have.get("res_details")}) + self.have_global.get("res_details")}) - if self.params.get("config")[0].get("NetworkManagementDetails") is not None: + if config.get("NetworkManagementDetails") is not None: net_updated = False - if self.have_net: - log("entered") + net_created = False + if self.have_network: obj_params = [ ("settings", "settings"), ("siteName", "siteName") ] - if self.requires_update(self.have_net.get("net_details"), self.want_net, obj_params): - log("Network update requires") - #Pool Exists - log(str(self.have_net)) - log(str(self.want_net)) - - res_params = copy.deepcopy(self.want_net) - res_params.update({"site_id": self.have_net.get("site_id")}) + if self.want_network.get("settings").get("timezone") is None: + self.msg = "Missing required parameter timezone" + self.status = "failed" + return self + + if self.requires_update(self.have_network.get("net_details"), self.want_network, obj_params): + self.log("Network update requires") + self.log(str(self.have_network)) + self.log(str(self.want_network)) + + net_params = copy.deepcopy(self.want_network) + net_params.update({"site_id": self.have_network.get("site_id")}) response = self.dnac._exec( family="network_settings", function='update_network', - params=res_params, + params=net_params, ) - log("Network Updated") - log(str(response)) + self.log("Network Updated") + self.log(str(response)) net_updated = True else: - log("Network doesn't need an update") - self.result["response"] = self.have_net + self.log("Network doesn't need an update") + self.result["response"] = self.have_network self.result["msg"] = "Network doesn't need an update" self.module.exit_json(**self.result) if net_updated: if response and isinstance(response, dict): - executionid = response.get("executionId") + task_id = response.get("response").get("taskId") + self.log(str(response)) + self.log(str(task_id)) while True: - execution_details = self.get_execution_details(executionid) - if execution_details.get("status") == "SUCCESS": + task_details = self.get_task_details(task_id) + if task_details.get("status") == "SUCCESS": self.result['changed'] = True - self.result['response'] = execution_details + self.result['response'] = task_details break - elif execution_details.get("bapiError"): + elif task_details.get("bapiError"): - self.module.fail_json(msg=execution_details.get("bapiError"), - response=execution_details) - break + self.msg = task_details.get("bapiError") + self.status = "failed" + return self if net_updated: - log("Network Updated Successfully") - self.result['msg'] = "Network Updated Successfully" - self.result['response'] = self.want_net + self.log("Network has been changed Successfully") + self.result['msg'] = "Network Updated successfully" + self.result['response'] = self.want_network else: - log("Pool doesn't need a update") - self.result['msg'] = "Pool doesn't requires an update" - self.result['response'] = self.have_net + self.log("Pool doesn't need a update") + self.result['msg'] = "Network doesn't requires an update" + self.result['response'] = self.have_network - def get_res_id_by_name(self, name): - _id = None - try: - response = self.dnac._exec( - family="network_settings", - function="get_reserve_ip_subpool", - params={"siteId":self.site_id}, - ) + return self - log(str(response)) - if isinstance(response, dict): - if "response" in response: - response = response.get("response") - log(str(response)) + def get_diff_deleted(self,config): - current_details = get_dict_result(response, "groupName", name) - if current_details: - _id = current_details.get("id") - - except: - result = None - - return _id - - - def get_diff_delete(self): - - if self.params.get("config")[0].get("ReservePoolDetails") is not None: + if config.get("ReservePoolDetails") is not None: res_exists = self.have_reserve.get("res_exists") - log(str(res_exists)) + self.log(str(res_exists)) _id = None if self.want_reserve.get("name"): - log(str(self.want_reserve.get("name"))) + self.log(str(self.want_reserve.get("name"))) _id = self.get_res_id_by_name(self.want_reserve.get("name")) - log(str(_id)) + self.log(str(_id)) if res_exists: if not _id: - self.module.fail_json(msg="missing or \ - incorrect parameter reserved pool name", response=[]) - log(str(self.have_reserve.get("res_id"))) + self.msg = "missing or \ + incorrect parameter reserved pool name" + self.status = "failed" + return self + self.log(str(self.have_reserve.get("res_id"))) response = self.dnac._exec( family="network_settings", function="release_reserve_ip_subpool", @@ -1088,50 +1256,67 @@ def get_diff_delete(self): if response and isinstance(response, dict): executionid = response.get("executionId") while True: - execution_details = self.get_execution_details(executionid) - if execution_details.get("status") == "SUCCESS": + task_details = self.get_execution_details(executionid) + if task_details.get("status") == "SUCCESS": self.result['changed'] = True - self.result['response'] = execution_details - log(str(response)) + self.result['response'] = task_details + self.log(str(response)) self.result['msg'] = "Ip subpool reservation released successfully" + break - elif execution_details.get("bapiError"): - self.module.fail_json(msg=execution_details.get("bapiError"), - response=execution_details) + elif task_details.get("bapiError"): + self.msg = task_details.get("bapiError") + self.status = "failed" + return self else: - self.module.fail_json(msg="Reserved Ip Subpool Not Found", response=[]) + self.msg = "Reserved Ip Subpool Not Found" + self.status = "failed" + return self - if self.params.get("config")[0].get("GlobalPoolDetails") is not None: - pool_exists = self.have.get("pool_exists") + if config.get("GlobalPoolDetails") is not None: + pool_exists = self.have_global.get("pool_exists") if pool_exists: response = self.dnac._exec( family="network_settings", function="delete_global_ip_pool", - params={"id": self.have.get("pool_id")}, + params={"id": self.have_global.get("pool_id")}, ) if response and isinstance(response, dict): executionid = response.get("executionId") while True: - execution_details = self.get_execution_details(executionid) - if execution_details.get("status") == "SUCCESS": + task_details = self.get_execution_details(executionid) + if task_details.get("status") == "SUCCESS": self.result['changed'] = True - self.result['response'] = execution_details - log(str(response)) + self.result['response'] = task_details + self.log(str(response)) self.result['msg'] = "Pool deleted successfully" + break - elif execution_details.get("bapiError"): - self.module.fail_json(msg=execution_details.get("bapiError"), - response=execution_details) + elif task_details.get("bapiError"): + self.msg = task_details.get("bapiError") + self.status = "failed" + return self else: - self.module.fail_json(msg="Pool Not Found", response=[]) + self.msg = "Pool Not Found" + self.status = "failed" + return self + return self - if self.params.get("config")[0].get("NetworkManagementDetails") is not None: - self.module.fail_json(msg="No operation available for Delete Network", response=[]) + def reset_values(self): + """Reset all neccessary attributes to default values""" + + self.have_global.clear() + self.want_global.clear() + self.have_reserve.clear() + self.want_reserve.clear() + self.have_network.clear() + self.want_network.clear() + self.site_id = None def main(): @@ -1155,18 +1340,19 @@ def main(): dnac_network = DnacNetwork(module) - state = dnac_network.get_state() - dnac_network.validate_input() - - dnac_network.get_have() - dnac_network.get_want() + dnac_network.validate_input().check_return_status() + state = dnac_network.params.get("state") + if state not in dnac_network.supported_states: + dnac_network.status = "invalid" + dnac_network.msg = "State {0} is invalid".format(state) + dnac_network.check_return_status() - if state == "merged": - dnac_network.get_diff_merge() + for config in dnac_network.config: + dnac_network.reset_values() + dnac_network.get_have(config).check_return_status() + dnac_network.get_want(config).check_return_status() - elif state == "deleted": - dnac_network.get_diff_delete() - log(str(dnac_network.result)) + dnac_network.get_diff_state_apply[state](config).check_return_status() module.exit_json(**dnac_network.result)