#!/usr/bin/python # # This file is part of Ansible # # Ansible is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Ansible is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Ansible. If not, see . # from __future__ import (absolute_import, division, print_function) __metaclass__ = type ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported_by': 'community'} DOCUMENTATION = ''' --- module: ce_aaa_server_host short_description: Manages AAA server host configuration on HUAWEI CloudEngine switches. description: - Manages AAA server host configuration on HUAWEI CloudEngine switches. author: - wangdezhuang (@QijunPan) notes: - This module requires the netconf system service be enabled on the remote device being managed. - Recommended connection is C(netconf). - This module also works with C(local) connections for legacy playbooks. options: state: description: - Specify desired state of the resource. default: present choices: ['present', 'absent'] local_user_name: description: - Name of a local user. The value is a string of 1 to 253 characters. local_password: description: - Login password of a user. The password can contain letters, numbers, and special characters. The value is a string of 1 to 255 characters. local_service_type: description: - The type of local user login through, such as ftp ssh snmp telnet. local_ftp_dir: description: - FTP user directory. The value is a string of 1 to 255 characters. local_user_level: description: - Login level of a local user. The value is an integer ranging from 0 to 15. local_user_group: description: - Name of the user group where the user belongs. The user inherits all the rights of the user group. The value is a string of 1 to 32 characters. radius_group_name: description: - RADIUS server group's name. The value is a string of 1 to 32 case-insensitive characters. radius_server_type: description: - Type of Radius Server. choices: ['Authentication', 'Accounting'] radius_server_ip: description: - IPv4 address of configured server. The value is a string of 0 to 255 characters, in dotted decimal notation. radius_server_ipv6: description: - IPv6 address of configured server. The total length is 128 bits. radius_server_port: description: - Configured server port for a particular server. The value is an integer ranging from 1 to 65535. radius_server_mode: description: - Configured primary or secondary server for a particular server. choices: ['Secondary-server', 'Primary-server'] radius_vpn_name: description: - Set VPN instance. The value is a string of 1 to 31 case-sensitive characters. radius_server_name: description: - Hostname of configured server. The value is a string of 0 to 255 case-sensitive characters. hwtacacs_template: description: - Name of a HWTACACS template. The value is a string of 1 to 32 case-insensitive characters. hwtacacs_server_ip: description: - Server IPv4 address. Must be a valid unicast IP address. The value is a string of 0 to 255 characters, in dotted decimal notation. hwtacacs_server_ipv6: description: - Server IPv6 address. Must be a valid unicast IP address. The total length is 128 bits. hwtacacs_server_type: description: - Hwtacacs server type. choices: ['Authentication', 'Authorization', 'Accounting', 'Common'] hwtacacs_is_secondary_server: description: - Whether the server is secondary. type: bool default: 'no' hwtacacs_vpn_name: description: - VPN instance name. hwtacacs_is_public_net: description: - Set the public-net. type: bool default: 'no' hwtacacs_server_host_name: description: - Hwtacacs server host name. ''' EXAMPLES = ''' - name: AAA server host test hosts: cloudengine connection: local gather_facts: no vars: cli: host: "{{ inventory_hostname }}" port: "{{ ansible_ssh_port }}" username: "{{ username }}" password: "{{ password }}" transport: cli tasks: - name: "Config local user when use local scheme" ce_aaa_server_host: state: present local_user_name: user1 local_password: 123456 provider: "{{ cli }}" - name: "Undo local user when use local scheme" ce_aaa_server_host: state: absent local_user_name: user1 local_password: 123456 provider: "{{ cli }}" - name: "Config radius server ip" ce_aaa_server_host: state: present radius_group_name: group1 radius_server_type: Authentication radius_server_ip: 10.1.10.1 radius_server_port: 2000 radius_server_mode: Primary-server radius_vpn_name: _public_ provider: "{{ cli }}" - name: "Undo radius server ip" ce_aaa_server_host: state: absent radius_group_name: group1 radius_server_type: Authentication radius_server_ip: 10.1.10.1 radius_server_port: 2000 radius_server_mode: Primary-server radius_vpn_name: _public_ provider: "{{ cli }}" - name: "Config hwtacacs server ip" ce_aaa_server_host: state: present hwtacacs_template: template hwtacacs_server_ip: 10.10.10.10 hwtacacs_server_type: Authorization hwtacacs_vpn_name: _public_ provider: "{{ cli }}" - name: "Undo hwtacacs server ip" ce_aaa_server_host: state: absent hwtacacs_template: template hwtacacs_server_ip: 10.10.10.10 hwtacacs_server_type: Authorization hwtacacs_vpn_name: _public_ provider: "{{ cli }}" ''' RETURN = ''' changed: description: check to see if a change was made on the device returned: always type: bool sample: true proposed: description: k/v pairs of parameters passed into module returned: always type: dict sample: {"hwtacacs_is_public_net": "false", "hwtacacs_is_secondary_server": "false", "hwtacacs_server_ip": "10.135.182.157", "hwtacacs_server_type": "Authorization", "hwtacacs_template": "wdz", "hwtacacs_vpn_name": "_public_", "local_password": "******", "state": "present"} existing: description: k/v pairs of existing aaa server host returned: always type: dict sample: {"radius server ipv4": []} end_state: description: k/v pairs of aaa params after module execution returned: always type: dict sample: {"radius server ipv4": [ [ "10.1.10.1", "Authentication", "2000", "Primary-server", "_public_" ] ]} updates: description: command sent to the device returned: always type: list sample: ["hwtacacs server template test", "hwtacacs server authorization 10.135.182.157 vpn-instance test_vpn public-net"] ''' from xml.etree import ElementTree from ansible.module_utils.basic import AnsibleModule from ansible_collections.community.general.plugins.module_utils.network.cloudengine.ce import get_nc_config, set_nc_config, ce_argument_spec, check_ip_addr SUCCESS = """success""" FAILED = """failed""" INVALID_USER_NAME_CHAR = [' ', '/', '\\', ':', '*', '?', '"', '\'', '<', '>', '%'] # get local user name CE_GET_LOCAL_USER_INFO_HEADER = """ """ CE_GET_LOCAL_USER_INFO_TAIL = """ """ # merge local user name CE_MERGE_LOCAL_USER_INFO_HEADER = """ %s """ CE_MERGE_LOCAL_USER_INFO_TAIL = """ """ # delete local user name CE_DELETE_LOCAL_USER_INFO_HEADER = """ %s """ CE_DELETE_LOCAL_USER_INFO_TAIL = """ """ # get radius server config ipv4 CE_GET_RADIUS_SERVER_CFG_IPV4 = """ %s """ # merge radius server config ipv4 CE_MERGE_RADIUS_SERVER_CFG_IPV4 = """ %s %s %s %s %s %s """ # delete radius server config ipv4 CE_DELETE_RADIUS_SERVER_CFG_IPV4 = """ %s %s %s %s %s %s """ # get radius server config ipv6 CE_GET_RADIUS_SERVER_CFG_IPV6 = """ %s """ # merge radius server config ipv6 CE_MERGE_RADIUS_SERVER_CFG_IPV6 = """ %s %s %s %s %s """ # delete radius server config ipv6 CE_DELETE_RADIUS_SERVER_CFG_IPV6 = """ %s %s %s %s %s """ # get radius server name CE_GET_RADIUS_SERVER_NAME = """ %s """ # merge radius server name CE_MERGE_RADIUS_SERVER_NAME = """ %s %s %s %s %s %s """ # delete radius server name CE_DELETE_RADIUS_SERVER_NAME = """ %s %s %s %s %s %s """ # get hwtacacs server config ipv4 CE_GET_HWTACACS_SERVER_CFG_IPV4 = """ %s """ # merge hwtacacs server config ipv4 CE_MERGE_HWTACACS_SERVER_CFG_IPV4 = """ %s %s %s %s %s %s """ # delete hwtacacs server config ipv4 CE_DELETE_HWTACACS_SERVER_CFG_IPV4 = """ %s %s %s %s %s %s """ # get hwtacacs server config ipv6 CE_GET_HWTACACS_SERVER_CFG_IPV6 = """ %s """ # merge hwtacacs server config ipv6 CE_MERGE_HWTACACS_SERVER_CFG_IPV6 = """ %s %s %s %s %s """ # delete hwtacacs server config ipv6 CE_DELETE_HWTACACS_SERVER_CFG_IPV6 = """ %s %s %s %s %s """ # get hwtacacs host server config CE_GET_HWTACACS_HOST_SERVER_CFG = """ %s """ # merge hwtacacs host server config CE_MERGE_HWTACACS_HOST_SERVER_CFG = """ %s %s %s %s %s %s """ # delete hwtacacs host server config CE_DELETE_HWTACACS_HOST_SERVER_CFG = """ %s %s %s %s %s %s """ class AaaServerHost(object): """ Manages aaa server host configuration """ def netconf_get_config(self, **kwargs): """ Get configure by netconf """ module = kwargs["module"] conf_str = kwargs["conf_str"] xml_str = get_nc_config(module, conf_str) return xml_str def netconf_set_config(self, **kwargs): """ Set configure by netconf """ module = kwargs["module"] conf_str = kwargs["conf_str"] recv_xml = set_nc_config(module, conf_str) return recv_xml def get_local_user_info(self, **kwargs): """ Get local user information """ module = kwargs["module"] local_user_name = module.params['local_user_name'] local_service_type = module.params['local_service_type'] local_ftp_dir = module.params['local_ftp_dir'] local_user_level = module.params['local_user_level'] local_user_group = module.params['local_user_group'] state = module.params['state'] result = dict() result["local_user_info"] = [] need_cfg = False conf_str = CE_GET_LOCAL_USER_INFO_HEADER if local_service_type: if local_service_type == "none": conf_str += "" conf_str += "" conf_str += "" conf_str += "" conf_str += "" conf_str += "" elif local_service_type == "dot1x": conf_str += "" else: option = local_service_type.split(" ") for tmp in option: if tmp == "dot1x": module.fail_json( msg='Error: Do not input dot1x with other service type.') elif tmp == "none": module.fail_json( msg='Error: Do not input none with other service type.') elif tmp == "ftp": conf_str += "" elif tmp == "snmp": conf_str += "" elif tmp == "ssh": conf_str += "" elif tmp == "telnet": conf_str += "" elif tmp == "terminal": conf_str += "" else: module.fail_json( msg='Error: Do not support the type [%s].' % tmp) if local_ftp_dir: conf_str += "" if local_user_level: conf_str += "" if local_user_group: conf_str += "" conf_str += CE_GET_LOCAL_USER_INFO_TAIL recv_xml = self.netconf_get_config(module=module, conf_str=conf_str) if "" in recv_xml: if state == "present": need_cfg = True else: xml_str = recv_xml.replace('\r', '').replace('\n', '').\ replace('xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"', "").\ replace('xmlns="http://www.huawei.com/netconf/vrp"', "") root = ElementTree.fromstring(xml_str) local_user_info = root.findall("aaa/lam/users/user") if local_user_info: for tmp in local_user_info: tmp_dict = dict() for site in tmp: if site.tag in ["userName", "password", "userLevel", "ftpDir", "userGroupName", "serviceTerminal", "serviceTelnet", "serviceFtp", "serviceSsh", "serviceSnmp", "serviceDot1x"]: tmp_dict[site.tag] = site.text result["local_user_info"].append(tmp_dict) if state == "present": need_cfg = True else: if result["local_user_info"]: for tmp in result["local_user_info"]: if "userName" in tmp.keys(): if tmp["userName"] == local_user_name: if not local_service_type and not local_user_level \ and not local_ftp_dir and not local_user_group: need_cfg = True if local_service_type: if local_service_type == "none": if tmp.get("serviceTerminal") == "true" or \ tmp.get("serviceTelnet") == "true" or \ tmp.get("serviceFtp") == "true" or \ tmp.get("serviceSsh") == "true" or \ tmp.get("serviceSnmp") == "true" or \ tmp.get("serviceDot1x") == "true": need_cfg = True elif local_service_type == "dot1x": if tmp.get("serviceDot1x") == "true": need_cfg = True elif tmp == "ftp": if tmp.get("serviceFtp") == "true": need_cfg = True elif tmp == "snmp": if tmp.get("serviceSnmp") == "true": need_cfg = True elif tmp == "ssh": if tmp.get("serviceSsh") == "true": need_cfg = True elif tmp == "telnet": if tmp.get("serviceTelnet") == "true": need_cfg = True elif tmp == "terminal": if tmp.get("serviceTerminal") == "true": need_cfg = True if local_user_level: if tmp.get("userLevel") == local_user_level: need_cfg = True if local_ftp_dir: if tmp.get("ftpDir") == local_ftp_dir: need_cfg = True if local_user_group: if tmp.get("userGroupName") == local_user_group: need_cfg = True break result["need_cfg"] = need_cfg return result def merge_local_user_info(self, **kwargs): """ Merge local user information by netconf """ module = kwargs["module"] local_user_name = module.params['local_user_name'] local_password = module.params['local_password'] local_service_type = module.params['local_service_type'] local_ftp_dir = module.params['local_ftp_dir'] local_user_level = module.params['local_user_level'] local_user_group = module.params['local_user_group'] state = module.params['state'] cmds = [] conf_str = CE_MERGE_LOCAL_USER_INFO_HEADER % local_user_name if local_password: conf_str += "%s" % local_password if state == "present": cmd = "local-user %s password cipher %s" % ( local_user_name, local_password) cmds.append(cmd) if local_service_type: if local_service_type == "none": conf_str += "false" conf_str += "false" conf_str += "false" conf_str += "false" conf_str += "false" conf_str += "false" cmd = "local-user %s service-type none" % local_user_name cmds.append(cmd) elif local_service_type == "dot1x": if state == "present": conf_str += "true" cmd = "local-user %s service-type dot1x" % local_user_name else: conf_str += "false" cmd = "undo local-user %s service-type" % local_user_name cmds.append(cmd) else: option = local_service_type.split(" ") for tmp in option: if tmp == "dot1x": module.fail_json( msg='Error: Do not input dot1x with other service type.') if tmp == "none": module.fail_json( msg='Error: Do not input none with other service type.') if state == "present": if tmp == "ftp": conf_str += "true" cmd = "local-user %s service-type ftp" % local_user_name elif tmp == "snmp": conf_str += "true" cmd = "local-user %s service-type snmp" % local_user_name elif tmp == "ssh": conf_str += "true" cmd = "local-user %s service-type ssh" % local_user_name elif tmp == "telnet": conf_str += "true" cmd = "local-user %s service-type telnet" % local_user_name elif tmp == "terminal": conf_str += "true" cmd = "local-user %s service-type terminal" % local_user_name cmds.append(cmd) else: if tmp == "ftp": conf_str += "false" elif tmp == "snmp": conf_str += "false" elif tmp == "ssh": conf_str += "false" elif tmp == "telnet": conf_str += "false" elif tmp == "terminal": conf_str += "false" if state == "absent": cmd = "undo local-user %s service-type" % local_user_name cmds.append(cmd) if local_ftp_dir: if state == "present": conf_str += "%s" % local_ftp_dir cmd = "local-user %s ftp-directory %s" % ( local_user_name, local_ftp_dir) cmds.append(cmd) else: conf_str += "" cmd = "undo local-user %s ftp-directory" % local_user_name cmds.append(cmd) if local_user_level: if state == "present": conf_str += "%s" % local_user_level cmd = "local-user %s level %s" % ( local_user_name, local_user_level) cmds.append(cmd) else: conf_str += "" cmd = "undo local-user %s level" % local_user_name cmds.append(cmd) if local_user_group: if state == "present": conf_str += "%s" % local_user_group cmd = "local-user %s user-group %s" % ( local_user_name, local_user_group) cmds.append(cmd) else: conf_str += "" cmd = "undo local-user %s user-group" % local_user_name cmds.append(cmd) conf_str += CE_MERGE_LOCAL_USER_INFO_TAIL recv_xml = self.netconf_set_config(module=module, conf_str=conf_str) if "" not in recv_xml: module.fail_json(msg='Error: Merge local user info failed.') return cmds def delete_local_user_info(self, **kwargs): """ Delete local user information by netconf """ module = kwargs["module"] local_user_name = module.params['local_user_name'] conf_str = CE_DELETE_LOCAL_USER_INFO_HEADER % local_user_name conf_str += CE_DELETE_LOCAL_USER_INFO_TAIL cmds = [] recv_xml = self.netconf_set_config(module=module, conf_str=conf_str) if "" not in recv_xml: module.fail_json(msg='Error: Delete local user info failed.') cmd = "undo local-user %s" % local_user_name cmds.append(cmd) return cmds def get_radius_server_cfg_ipv4(self, **kwargs): """ Get radius server configure ipv4 """ module = kwargs["module"] radius_group_name = module.params['radius_group_name'] radius_server_type = module.params['radius_server_type'] radius_server_ip = module.params['radius_server_ip'] radius_server_port = module.params['radius_server_port'] radius_server_mode = module.params['radius_server_mode'] radius_vpn_name = module.params['radius_vpn_name'] state = module.params['state'] result = dict() result["radius_server_ip_v4"] = [] need_cfg = False conf_str = CE_GET_RADIUS_SERVER_CFG_IPV4 % radius_group_name recv_xml = self.netconf_get_config(module=module, conf_str=conf_str) if "" in recv_xml: if state == "present": need_cfg = True else: xml_str = recv_xml.replace('\r', '').replace('\n', '').\ replace('xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"', "").\ replace('xmlns="http://www.huawei.com/netconf/vrp"', "") root = ElementTree.fromstring(xml_str) radius_server_ip_v4 = root.findall( "radius/rdsTemplates/rdsTemplate/rdsServerIPV4s/rdsServerIPV4") if radius_server_ip_v4: for tmp in radius_server_ip_v4: tmp_dict = dict() for site in tmp: if site.tag in ["serverType", "serverIPAddress", "serverPort", "serverMode", "vpnName"]: tmp_dict[site.tag] = site.text result["radius_server_ip_v4"].append(tmp_dict) if result["radius_server_ip_v4"]: cfg = dict() config_list = list() if radius_server_type: cfg["serverType"] = radius_server_type.lower() if radius_server_ip: cfg["serverIPAddress"] = radius_server_ip.lower() if radius_server_port: cfg["serverPort"] = radius_server_port.lower() if radius_server_mode: cfg["serverMode"] = radius_server_mode.lower() if radius_vpn_name: cfg["vpnName"] = radius_vpn_name.lower() for tmp in result["radius_server_ip_v4"]: exist_cfg = dict() if radius_server_type: exist_cfg["serverType"] = tmp.get("serverType").lower() if radius_server_ip: exist_cfg["serverIPAddress"] = tmp.get("serverIPAddress").lower() if radius_server_port: exist_cfg["serverPort"] = tmp.get("serverPort").lower() if radius_server_mode: exist_cfg["serverMode"] = tmp.get("serverMode").lower() if radius_vpn_name: exist_cfg["vpnName"] = tmp.get("vpnName").lower() config_list.append(exist_cfg) if cfg in config_list: if state == "present": need_cfg = False else: need_cfg = True else: if state == "present": need_cfg = True else: need_cfg = False result["need_cfg"] = need_cfg return result def merge_radius_server_cfg_ipv4(self, **kwargs): """ Merge radius server configure ipv4 """ module = kwargs["module"] radius_group_name = module.params['radius_group_name'] radius_server_type = module.params['radius_server_type'] radius_server_ip = module.params['radius_server_ip'] radius_server_port = module.params['radius_server_port'] radius_server_mode = module.params['radius_server_mode'] radius_vpn_name = module.params['radius_vpn_name'] conf_str = CE_MERGE_RADIUS_SERVER_CFG_IPV4 % ( radius_group_name, radius_server_type, radius_server_ip, radius_server_port, radius_server_mode, radius_vpn_name) recv_xml = self.netconf_set_config(module=module, conf_str=conf_str) if "" not in recv_xml: module.fail_json( msg='Error: Merge radius server config ipv4 failed.') cmds = [] cmd = "radius server group %s" % radius_group_name cmds.append(cmd) if radius_server_type == "Authentication": cmd = "radius server authentication %s %s" % ( radius_server_ip, radius_server_port) if radius_vpn_name and radius_vpn_name != "_public_": cmd += " vpn-instance %s" % radius_vpn_name if radius_server_mode == "Secondary-server": cmd += " secondary" else: cmd = "radius server accounting %s %s" % ( radius_server_ip, radius_server_port) if radius_vpn_name and radius_vpn_name != "_public_": cmd += " vpn-instance %s" % radius_vpn_name if radius_server_mode == "Secondary-server": cmd += " secondary" cmds.append(cmd) return cmds def delete_radius_server_cfg_ipv4(self, **kwargs): """ Delete radius server configure ipv4 """ module = kwargs["module"] radius_group_name = module.params['radius_group_name'] radius_server_type = module.params['radius_server_type'] radius_server_ip = module.params['radius_server_ip'] radius_server_port = module.params['radius_server_port'] radius_server_mode = module.params['radius_server_mode'] radius_vpn_name = module.params['radius_vpn_name'] conf_str = CE_DELETE_RADIUS_SERVER_CFG_IPV4 % ( radius_group_name, radius_server_type, radius_server_ip, radius_server_port, radius_server_mode, radius_vpn_name) recv_xml = self.netconf_set_config(module=module, conf_str=conf_str) if "" not in recv_xml: module.fail_json( msg='Error: Create radius server config ipv4 failed.') cmds = [] cmd = "radius server group %s" % radius_group_name cmds.append(cmd) if radius_server_type == "Authentication": cmd = "undo radius server authentication %s %s" % ( radius_server_ip, radius_server_port) if radius_vpn_name and radius_vpn_name != "_public_": cmd += " vpn-instance %s" % radius_vpn_name if radius_server_mode == "Secondary-server": cmd += " secondary" else: cmd = "undo radius server accounting %s %s" % ( radius_server_ip, radius_server_port) if radius_vpn_name and radius_vpn_name != "_public_": cmd += " vpn-instance %s" % radius_vpn_name if radius_server_mode == "Secondary-server": cmd += " secondary" cmds.append(cmd) return cmds def get_radius_server_cfg_ipv6(self, **kwargs): """ Get radius server configure ipv6 """ module = kwargs["module"] radius_group_name = module.params['radius_group_name'] radius_server_type = module.params['radius_server_type'] radius_server_ipv6 = module.params['radius_server_ipv6'] radius_server_port = module.params['radius_server_port'] radius_server_mode = module.params['radius_server_mode'] state = module.params['state'] result = dict() result["radius_server_ip_v6"] = [] need_cfg = False conf_str = CE_GET_RADIUS_SERVER_CFG_IPV6 % radius_group_name recv_xml = self.netconf_get_config(module=module, conf_str=conf_str) if "" in recv_xml: if state == "present": need_cfg = True else: xml_str = recv_xml.replace('\r', '').replace('\n', '').\ replace('xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"', "").\ replace('xmlns="http://www.huawei.com/netconf/vrp"', "") root = ElementTree.fromstring(xml_str) radius_server_ip_v6 = root.findall( "radius/rdsTemplates/rdsTemplate/rdsServerIPV6s/rdsServerIPV6") if radius_server_ip_v6: for tmp in radius_server_ip_v6: tmp_dict = dict() for site in tmp: if site.tag in ["serverType", "serverIPAddress", "serverPort", "serverMode"]: tmp_dict[site.tag] = site.text result["radius_server_ip_v6"].append(tmp_dict) if result["radius_server_ip_v6"]: cfg = dict() config_list = list() if radius_server_type: cfg["serverType"] = radius_server_type.lower() if radius_server_ipv6: cfg["serverIPAddress"] = radius_server_ipv6.lower() if radius_server_port: cfg["serverPort"] = radius_server_port.lower() if radius_server_mode: cfg["serverMode"] = radius_server_mode.lower() for tmp in result["radius_server_ip_v6"]: exist_cfg = dict() if radius_server_type: exist_cfg["serverType"] = tmp.get("serverType").lower() if radius_server_ipv6: exist_cfg["serverIPAddress"] = tmp.get("serverIPAddress").lower() if radius_server_port: exist_cfg["serverPort"] = tmp.get("serverPort").lower() if radius_server_mode: exist_cfg["serverMode"] = tmp.get("serverMode").lower() config_list.append(exist_cfg) if cfg in config_list: if state == "present": need_cfg = False else: need_cfg = True else: if state == "present": need_cfg = True else: need_cfg = False result["need_cfg"] = need_cfg return result def merge_radius_server_cfg_ipv6(self, **kwargs): """ Merge radius server configure ipv6 """ module = kwargs["module"] radius_group_name = module.params['radius_group_name'] radius_server_type = module.params['radius_server_type'] radius_server_ipv6 = module.params['radius_server_ipv6'] radius_server_port = module.params['radius_server_port'] radius_server_mode = module.params['radius_server_mode'] conf_str = CE_MERGE_RADIUS_SERVER_CFG_IPV6 % ( radius_group_name, radius_server_type, radius_server_ipv6, radius_server_port, radius_server_mode) recv_xml = self.netconf_set_config(module=module, conf_str=conf_str) if "" not in recv_xml: module.fail_json( msg='Error: Merge radius server config ipv6 failed.') cmds = [] cmd = "radius server group %s" % radius_group_name cmds.append(cmd) if radius_server_type == "Authentication": cmd = "radius server authentication %s %s" % ( radius_server_ipv6, radius_server_port) if radius_server_mode == "Secondary-server": cmd += " secondary" else: cmd = "radius server accounting %s %s" % ( radius_server_ipv6, radius_server_port) if radius_server_mode == "Secondary-server": cmd += " secondary" cmds.append(cmd) return cmds def delete_radius_server_cfg_ipv6(self, **kwargs): """ Delete radius server configure ipv6 """ module = kwargs["module"] radius_group_name = module.params['radius_group_name'] radius_server_type = module.params['radius_server_type'] radius_server_ipv6 = module.params['radius_server_ipv6'] radius_server_port = module.params['radius_server_port'] radius_server_mode = module.params['radius_server_mode'] conf_str = CE_DELETE_RADIUS_SERVER_CFG_IPV6 % ( radius_group_name, radius_server_type, radius_server_ipv6, radius_server_port, radius_server_mode) recv_xml = self.netconf_set_config(module=module, conf_str=conf_str) if "" not in recv_xml: module.fail_json( msg='Error: Create radius server config ipv6 failed.') cmds = [] cmd = "radius server group %s" % radius_group_name cmds.append(cmd) if radius_server_type == "Authentication": cmd = "undo radius server authentication %s %s" % ( radius_server_ipv6, radius_server_port) if radius_server_mode == "Secondary-server": cmd += " secondary" else: cmd = "undo radius server accounting %s %s" % ( radius_server_ipv6, radius_server_port) if radius_server_mode == "Secondary-server": cmd += " secondary" cmds.append(cmd) return cmds def get_radius_server_name(self, **kwargs): """ Get radius server name """ module = kwargs["module"] radius_group_name = module.params['radius_group_name'] radius_server_type = module.params['radius_server_type'] radius_server_name = module.params['radius_server_name'] radius_server_port = module.params['radius_server_port'] radius_server_mode = module.params['radius_server_mode'] radius_vpn_name = module.params['radius_vpn_name'] state = module.params['state'] result = dict() result["radius_server_name_cfg"] = [] need_cfg = False conf_str = CE_GET_RADIUS_SERVER_NAME % radius_group_name recv_xml = self.netconf_get_config(module=module, conf_str=conf_str) if "" in recv_xml: if state == "present": need_cfg = True else: xml_str = recv_xml.replace('\r', '').replace('\n', '').\ replace('xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"', "").\ replace('xmlns="http://www.huawei.com/netconf/vrp"', "") root = ElementTree.fromstring(xml_str) radius_server_name_cfg = root.findall( "radius/rdsTemplates/rdsTemplate/rdsServerNames/rdsServerName") if radius_server_name_cfg: for tmp in radius_server_name_cfg: tmp_dict = dict() for site in tmp: if site.tag in ["serverType", "serverName", "serverPort", "serverMode", "vpnName"]: tmp_dict[site.tag] = site.text result["radius_server_name_cfg"].append(tmp_dict) if result["radius_server_name_cfg"]: cfg = dict() config_list = list() if radius_server_type: cfg["serverType"] = radius_server_type.lower() if radius_server_name: cfg["serverName"] = radius_server_name.lower() if radius_server_port: cfg["serverPort"] = radius_server_port.lower() if radius_server_mode: cfg["serverMode"] = radius_server_mode.lower() if radius_vpn_name: cfg["vpnName"] = radius_vpn_name.lower() for tmp in result["radius_server_name_cfg"]: exist_cfg = dict() if radius_server_type: exist_cfg["serverType"] = tmp.get("serverType").lower() if radius_server_name: exist_cfg["serverName"] = tmp.get("serverName").lower() if radius_server_port: exist_cfg["serverPort"] = tmp.get("serverPort").lower() if radius_server_mode: exist_cfg["serverMode"] = tmp.get("serverMode").lower() if radius_vpn_name: exist_cfg["vpnName"] = tmp.get("vpnName").lower() config_list.append(exist_cfg) if cfg in config_list: if state == "present": need_cfg = False else: need_cfg = True else: if state == "present": need_cfg = True else: need_cfg = False result["need_cfg"] = need_cfg return result def merge_radius_server_name(self, **kwargs): """ Merge radius server name """ module = kwargs["module"] radius_group_name = module.params['radius_group_name'] radius_server_type = module.params['radius_server_type'] radius_server_name = module.params['radius_server_name'] radius_server_port = module.params['radius_server_port'] radius_server_mode = module.params['radius_server_mode'] radius_vpn_name = module.params['radius_vpn_name'] conf_str = CE_MERGE_RADIUS_SERVER_NAME % ( radius_group_name, radius_server_type, radius_server_name, radius_server_port, radius_server_mode, radius_vpn_name) recv_xml = self.netconf_set_config(module=module, conf_str=conf_str) if "" not in recv_xml: module.fail_json(msg='Error: Merge radius server name failed.') cmds = [] cmd = "radius server group %s" % radius_group_name cmds.append(cmd) if radius_server_type == "Authentication": cmd = "radius server authentication hostname %s %s" % ( radius_server_name, radius_server_port) if radius_vpn_name and radius_vpn_name != "_public_": cmd += " vpn-instance %s" % radius_vpn_name if radius_server_mode == "Secondary-server": cmd += " secondary" else: cmd = "radius server accounting hostname %s %s" % ( radius_server_name, radius_server_port) if radius_vpn_name and radius_vpn_name != "_public_": cmd += " vpn-instance %s" % radius_vpn_name if radius_server_mode == "Secondary-server": cmd += " secondary" cmds.append(cmd) return cmds def delete_radius_server_name(self, **kwargs): """ Delete radius server name """ module = kwargs["module"] radius_group_name = module.params['radius_group_name'] radius_server_type = module.params['radius_server_type'] radius_server_name = module.params['radius_server_name'] radius_server_port = module.params['radius_server_port'] radius_server_mode = module.params['radius_server_mode'] radius_vpn_name = module.params['radius_vpn_name'] conf_str = CE_DELETE_RADIUS_SERVER_NAME % ( radius_group_name, radius_server_type, radius_server_name, radius_server_port, radius_server_mode, radius_vpn_name) recv_xml = self.netconf_set_config(module=module, conf_str=conf_str) if "" not in recv_xml: module.fail_json(msg='Error: delete radius server name failed.') cmds = [] cmd = "radius server group %s" % radius_group_name cmds.append(cmd) if radius_server_type == "Authentication": cmd = "undo radius server authentication hostname %s %s" % ( radius_server_name, radius_server_port) if radius_vpn_name and radius_vpn_name != "_public_": cmd += " vpn-instance %s" % radius_vpn_name if radius_server_mode == "Secondary-server": cmd += " secondary" else: cmd = "undo radius server accounting hostname %s %s" % ( radius_server_name, radius_server_port) if radius_vpn_name and radius_vpn_name != "_public_": cmd += " vpn-instance %s" % radius_vpn_name if radius_server_mode == "Secondary-server": cmd += " secondary" cmds.append(cmd) return cmds def get_hwtacacs_server_cfg_ipv4(self, **kwargs): """ Get hwtacacs server configure ipv4 """ module = kwargs["module"] hwtacacs_template = module.params["hwtacacs_template"] hwtacacs_server_ip = module.params["hwtacacs_server_ip"] hwtacacs_server_type = module.params["hwtacacs_server_type"] hwtacacs_is_secondary_server = module.params[ "hwtacacs_is_secondary_server"] hwtacacs_vpn_name = module.params["hwtacacs_vpn_name"] hwtacacs_is_public_net = module.params["hwtacacs_is_public_net"] state = module.params["state"] result = dict() result["hwtacacs_server_cfg_ipv4"] = [] need_cfg = False conf_str = CE_GET_HWTACACS_SERVER_CFG_IPV4 % hwtacacs_template recv_xml = self.netconf_get_config(module=module, conf_str=conf_str) if "" in recv_xml: if state == "present": need_cfg = True else: xml_str = recv_xml.replace('\r', '').replace('\n', '').\ replace('xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"', "").\ replace('xmlns="http://www.huawei.com/netconf/vrp"', "") root = ElementTree.fromstring(xml_str) hwtacacs_server_cfg_ipv4 = root.findall( "hwtacacs/hwTacTempCfgs/hwTacTempCfg/hwTacSrvCfgs/hwTacSrvCfg") if hwtacacs_server_cfg_ipv4: for tmp in hwtacacs_server_cfg_ipv4: tmp_dict = dict() for site in tmp: if site.tag in ["serverIpAddress", "serverType", "isSecondaryServer", "isPublicNet", "vpnName"]: tmp_dict[site.tag] = site.text result["hwtacacs_server_cfg_ipv4"].append(tmp_dict) if result["hwtacacs_server_cfg_ipv4"]: cfg = dict() config_list = list() if hwtacacs_server_ip: cfg["serverIpAddress"] = hwtacacs_server_ip.lower() if hwtacacs_server_type: cfg["serverType"] = hwtacacs_server_type.lower() if hwtacacs_is_secondary_server: cfg["isSecondaryServer"] = str(hwtacacs_is_secondary_server).lower() if hwtacacs_is_public_net: cfg["isPublicNet"] = str(hwtacacs_is_public_net).lower() if hwtacacs_vpn_name: cfg["vpnName"] = hwtacacs_vpn_name.lower() for tmp in result["hwtacacs_server_cfg_ipv4"]: exist_cfg = dict() if hwtacacs_server_ip: exist_cfg["serverIpAddress"] = tmp.get("serverIpAddress").lower() if hwtacacs_server_type: exist_cfg["serverType"] = tmp.get("serverType").lower() if hwtacacs_is_secondary_server: exist_cfg["isSecondaryServer"] = tmp.get("isSecondaryServer").lower() if hwtacacs_is_public_net: exist_cfg["isPublicNet"] = tmp.get("isPublicNet").lower() if hwtacacs_vpn_name: exist_cfg["vpnName"] = tmp.get("vpnName").lower() config_list.append(exist_cfg) if cfg in config_list: if state == "present": need_cfg = False else: need_cfg = True else: if state == "present": need_cfg = True else: need_cfg = False result["need_cfg"] = need_cfg return result def merge_hwtacacs_server_cfg_ipv4(self, **kwargs): """ Merge hwtacacs server configure ipv4 """ module = kwargs["module"] hwtacacs_template = module.params["hwtacacs_template"] hwtacacs_server_ip = module.params["hwtacacs_server_ip"] hwtacacs_server_type = module.params["hwtacacs_server_type"] hwtacacs_is_secondary_server = module.params[ "hwtacacs_is_secondary_server"] hwtacacs_vpn_name = module.params["hwtacacs_vpn_name"] hwtacacs_is_public_net = module.params["hwtacacs_is_public_net"] conf_str = CE_MERGE_HWTACACS_SERVER_CFG_IPV4 % ( hwtacacs_template, hwtacacs_server_ip, hwtacacs_server_type, str(hwtacacs_is_secondary_server).lower(), hwtacacs_vpn_name, str(hwtacacs_is_public_net).lower()) recv_xml = self.netconf_set_config(module=module, conf_str=conf_str) if "" not in recv_xml: module.fail_json( msg='Error: Merge hwtacacs server config ipv4 failed.') cmds = [] cmd = "hwtacacs server template %s" % hwtacacs_template cmds.append(cmd) if hwtacacs_server_type == "Authentication": cmd = "hwtacacs server authentication %s" % hwtacacs_server_ip if hwtacacs_vpn_name and hwtacacs_vpn_name != "_public_": cmd += " vpn-instance %s" % hwtacacs_vpn_name if hwtacacs_is_public_net: cmd += " public-net" if hwtacacs_is_secondary_server: cmd += " secondary" elif hwtacacs_server_type == "Authorization": cmd = "hwtacacs server authorization %s" % hwtacacs_server_ip if hwtacacs_vpn_name and hwtacacs_vpn_name != "_public_": cmd += " vpn-instance %s" % hwtacacs_vpn_name if hwtacacs_is_public_net: cmd += " public-net" if hwtacacs_is_secondary_server: cmd += " secondary" elif hwtacacs_server_type == "Accounting": cmd = "hwtacacs server accounting %s" % hwtacacs_server_ip if hwtacacs_vpn_name and hwtacacs_vpn_name != "_public_": cmd += " vpn-instance %s" % hwtacacs_vpn_name if hwtacacs_is_public_net: cmd += " public-net" if hwtacacs_is_secondary_server: cmd += " secondary" elif hwtacacs_server_type == "Common": cmd = "hwtacacs server %s" % hwtacacs_server_ip if hwtacacs_vpn_name and hwtacacs_vpn_name != "_public_": cmd += " vpn-instance %s" % hwtacacs_vpn_name if hwtacacs_is_public_net: cmd += " public-net" if hwtacacs_is_secondary_server: cmd += " secondary" cmds.append(cmd) return cmds def delete_hwtacacs_server_cfg_ipv4(self, **kwargs): """ Delete hwtacacs server configure ipv4 """ module = kwargs["module"] hwtacacs_template = module.params["hwtacacs_template"] hwtacacs_server_ip = module.params["hwtacacs_server_ip"] hwtacacs_server_type = module.params["hwtacacs_server_type"] hwtacacs_is_secondary_server = module.params[ "hwtacacs_is_secondary_server"] hwtacacs_vpn_name = module.params["hwtacacs_vpn_name"] hwtacacs_is_public_net = module.params["hwtacacs_is_public_net"] conf_str = CE_DELETE_HWTACACS_SERVER_CFG_IPV4 % ( hwtacacs_template, hwtacacs_server_ip, hwtacacs_server_type, str(hwtacacs_is_secondary_server).lower(), hwtacacs_vpn_name, str(hwtacacs_is_public_net).lower()) recv_xml = self.netconf_set_config(module=module, conf_str=conf_str) if "" not in recv_xml: module.fail_json( msg='Error: Delete hwtacacs server config ipv4 failed.') cmds = [] cmd = "hwtacacs server template %s" % hwtacacs_template cmds.append(cmd) if hwtacacs_server_type == "Authentication": cmd = "undo hwtacacs server authentication %s" % hwtacacs_server_ip if hwtacacs_vpn_name and hwtacacs_vpn_name != "_public_": cmd += " vpn-instance %s" % hwtacacs_vpn_name if hwtacacs_is_public_net: cmd += " public-net" if hwtacacs_is_secondary_server: cmd += " secondary" elif hwtacacs_server_type == "Authorization": cmd = "undo hwtacacs server authorization %s" % hwtacacs_server_ip if hwtacacs_vpn_name and hwtacacs_vpn_name != "_public_": cmd += " vpn-instance %s" % hwtacacs_vpn_name if hwtacacs_is_public_net: cmd += " public-net" if hwtacacs_is_secondary_server: cmd += " secondary" elif hwtacacs_server_type == "Accounting": cmd = "undo hwtacacs server accounting %s" % hwtacacs_server_ip if hwtacacs_vpn_name and hwtacacs_vpn_name != "_public_": cmd += " vpn-instance %s" % hwtacacs_vpn_name if hwtacacs_is_public_net: cmd += " public-net" if hwtacacs_is_secondary_server: cmd += " secondary" elif hwtacacs_server_type == "Common": cmd = "undo hwtacacs server %s" % hwtacacs_server_ip if hwtacacs_vpn_name and hwtacacs_vpn_name != "_public_": cmd += " vpn-instance %s" % hwtacacs_vpn_name if hwtacacs_is_public_net: cmd += " public-net" if hwtacacs_is_secondary_server: cmd += " secondary" cmds.append(cmd) return cmds def get_hwtacacs_server_cfg_ipv6(self, **kwargs): """ Get hwtacacs server configure ipv6 """ module = kwargs["module"] hwtacacs_template = module.params["hwtacacs_template"] hwtacacs_server_ipv6 = module.params["hwtacacs_server_ipv6"] hwtacacs_server_type = module.params["hwtacacs_server_type"] hwtacacs_is_secondary_server = module.params[ "hwtacacs_is_secondary_server"] hwtacacs_vpn_name = module.params["hwtacacs_vpn_name"] state = module.params["state"] result = dict() result["hwtacacs_server_cfg_ipv6"] = [] need_cfg = False conf_str = CE_GET_HWTACACS_SERVER_CFG_IPV6 % hwtacacs_template recv_xml = self.netconf_get_config(module=module, conf_str=conf_str) if "" in recv_xml: if state == "present": need_cfg = True else: xml_str = recv_xml.replace('\r', '').replace('\n', '').\ replace('xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"', "").\ replace('xmlns="http://www.huawei.com/netconf/vrp"', "") root = ElementTree.fromstring(xml_str) hwtacacs_server_cfg_ipv6 = root.findall( "hwtacacs/hwTacTempCfgs/hwTacTempCfg/hwTacIpv6SrvCfgs/hwTacIpv6SrvCfg") if hwtacacs_server_cfg_ipv6: for tmp in hwtacacs_server_cfg_ipv6: tmp_dict = dict() for site in tmp: if site.tag in ["serverIpAddress", "serverType", "isSecondaryServer", "vpnName"]: tmp_dict[site.tag] = site.text result["hwtacacs_server_cfg_ipv6"].append(tmp_dict) if result["hwtacacs_server_cfg_ipv6"]: cfg = dict() config_list = list() if hwtacacs_server_ipv6: cfg["serverIpAddress"] = hwtacacs_server_ipv6.lower() if hwtacacs_server_type: cfg["serverType"] = hwtacacs_server_type.lower() if hwtacacs_is_secondary_server: cfg["isSecondaryServer"] = str(hwtacacs_is_secondary_server).lower() if hwtacacs_vpn_name: cfg["vpnName"] = hwtacacs_vpn_name.lower() for tmp in result["hwtacacs_server_cfg_ipv6"]: exist_cfg = dict() if hwtacacs_server_ipv6: exist_cfg["serverIpAddress"] = tmp.get("serverIpAddress").lower() if hwtacacs_server_type: exist_cfg["serverType"] = tmp.get("serverType").lower() if hwtacacs_is_secondary_server: exist_cfg["isSecondaryServer"] = tmp.get("isSecondaryServer").lower() if hwtacacs_vpn_name: exist_cfg["vpnName"] = tmp.get("vpnName").lower() config_list.append(exist_cfg) if cfg in config_list: if state == "present": need_cfg = False else: need_cfg = True else: if state == "present": need_cfg = True else: need_cfg = False result["need_cfg"] = need_cfg return result def merge_hwtacacs_server_cfg_ipv6(self, **kwargs): """ Merge hwtacacs server configure ipv6 """ module = kwargs["module"] hwtacacs_template = module.params["hwtacacs_template"] hwtacacs_server_ipv6 = module.params["hwtacacs_server_ipv6"] hwtacacs_server_type = module.params["hwtacacs_server_type"] hwtacacs_is_secondary_server = module.params[ "hwtacacs_is_secondary_server"] hwtacacs_vpn_name = module.params["hwtacacs_vpn_name"] conf_str = CE_MERGE_HWTACACS_SERVER_CFG_IPV6 % ( hwtacacs_template, hwtacacs_server_ipv6, hwtacacs_server_type, str(hwtacacs_is_secondary_server).lower(), hwtacacs_vpn_name) recv_xml = self.netconf_set_config(module=module, conf_str=conf_str) if "" not in recv_xml: module.fail_json( msg='Error: Merge hwtacacs server config ipv6 failed.') cmds = [] cmd = "hwtacacs server template %s" % hwtacacs_template cmds.append(cmd) if hwtacacs_server_type == "Authentication": cmd = "hwtacacs server authentication %s" % hwtacacs_server_ipv6 if hwtacacs_vpn_name and hwtacacs_vpn_name != "_public_": cmd += " vpn-instance %s" % hwtacacs_vpn_name if hwtacacs_is_secondary_server: cmd += " secondary" elif hwtacacs_server_type == "Authorization": cmd = "hwtacacs server authorization %s" % hwtacacs_server_ipv6 if hwtacacs_vpn_name and hwtacacs_vpn_name != "_public_": cmd += " vpn-instance %s" % hwtacacs_vpn_name if hwtacacs_is_secondary_server: cmd += " secondary" elif hwtacacs_server_type == "Accounting": cmd = "hwtacacs server accounting %s" % hwtacacs_server_ipv6 if hwtacacs_vpn_name and hwtacacs_vpn_name != "_public_": cmd += " vpn-instance %s" % hwtacacs_vpn_name if hwtacacs_is_secondary_server: cmd += " secondary" elif hwtacacs_server_type == "Common": cmd = "hwtacacs server %s" % hwtacacs_server_ipv6 if hwtacacs_vpn_name and hwtacacs_vpn_name != "_public_": cmd += " vpn-instance %s" % hwtacacs_vpn_name if hwtacacs_is_secondary_server: cmd += " secondary" cmds.append(cmd) return cmds def delete_hwtacacs_server_cfg_ipv6(self, **kwargs): """ Delete hwtacacs server configure ipv6 """ module = kwargs["module"] hwtacacs_template = module.params["hwtacacs_template"] hwtacacs_server_ipv6 = module.params["hwtacacs_server_ipv6"] hwtacacs_server_type = module.params["hwtacacs_server_type"] hwtacacs_is_secondary_server = module.params[ "hwtacacs_is_secondary_server"] hwtacacs_vpn_name = module.params["hwtacacs_vpn_name"] conf_str = CE_DELETE_HWTACACS_SERVER_CFG_IPV6 % ( hwtacacs_template, hwtacacs_server_ipv6, hwtacacs_server_type, str(hwtacacs_is_secondary_server).lower(), hwtacacs_vpn_name) recv_xml = self.netconf_set_config(module=module, conf_str=conf_str) if "" not in recv_xml: module.fail_json( msg='Error: Delete hwtacacs server config ipv6 failed.') cmds = [] cmd = "hwtacacs server template %s" % hwtacacs_template cmds.append(cmd) if hwtacacs_server_type == "Authentication": cmd = "undo hwtacacs server authentication %s" % hwtacacs_server_ipv6 if hwtacacs_vpn_name and hwtacacs_vpn_name != "_public_": cmd += " vpn-instance %s" % hwtacacs_vpn_name if hwtacacs_is_secondary_server: cmd += " secondary" elif hwtacacs_server_type == "Authorization": cmd = "undo hwtacacs server authorization %s" % hwtacacs_server_ipv6 if hwtacacs_vpn_name and hwtacacs_vpn_name != "_public_": cmd += " vpn-instance %s" % hwtacacs_vpn_name if hwtacacs_is_secondary_server: cmd += " secondary" elif hwtacacs_server_type == "Accounting": cmd = "undo hwtacacs server accounting %s" % hwtacacs_server_ipv6 if hwtacacs_vpn_name and hwtacacs_vpn_name != "_public_": cmd += " vpn-instance %s" % hwtacacs_vpn_name if hwtacacs_is_secondary_server: cmd += " secondary" elif hwtacacs_server_type == "Common": cmd = "undo hwtacacs server %s" % hwtacacs_server_ipv6 if hwtacacs_vpn_name and hwtacacs_vpn_name != "_public_": cmd += " vpn-instance %s" % hwtacacs_vpn_name if hwtacacs_is_secondary_server: cmd += " secondary" cmds.append(cmd) return cmds def get_hwtacacs_host_server_cfg(self, **kwargs): """ Get hwtacacs host server configure """ module = kwargs["module"] hwtacacs_template = module.params["hwtacacs_template"] hwtacacs_server_host_name = module.params["hwtacacs_server_host_name"] hwtacacs_server_type = module.params["hwtacacs_server_type"] hwtacacs_is_secondary_server = "true" if module.params[ "hwtacacs_is_secondary_server"] is True else "false" hwtacacs_vpn_name = module.params["hwtacacs_vpn_name"] hwtacacs_is_public_net = "true" if module.params[ "hwtacacs_is_public_net"] is True else "false" state = module.params["state"] result = dict() result["hwtacacs_server_name_cfg"] = [] need_cfg = False conf_str = CE_GET_HWTACACS_HOST_SERVER_CFG % hwtacacs_template recv_xml = self.netconf_get_config(module=module, conf_str=conf_str) if "" in recv_xml: if state == "present": need_cfg = True else: xml_str = recv_xml.replace('\r', '').replace('\n', '').\ replace('xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"', "").\ replace('xmlns="http://www.huawei.com/netconf/vrp"', "") root = ElementTree.fromstring(xml_str) hwtacacs_server_name_cfg = root.findall( "hwtacacs/hwTacTempCfgs/hwTacTempCfg/hwTacHostSrvCfgs/hwTacHostSrvCfg") if hwtacacs_server_name_cfg: for tmp in hwtacacs_server_name_cfg: tmp_dict = dict() for site in tmp: if site.tag in ["serverHostName", "serverType", "isSecondaryServer", "isPublicNet", "vpnName"]: tmp_dict[site.tag] = site.text result["hwtacacs_server_name_cfg"].append(tmp_dict) if result["hwtacacs_server_name_cfg"]: cfg = dict() config_list = list() if hwtacacs_server_host_name: cfg["serverHostName"] = hwtacacs_server_host_name.lower() if hwtacacs_server_type: cfg["serverType"] = hwtacacs_server_type.lower() if hwtacacs_is_secondary_server: cfg["isSecondaryServer"] = str(hwtacacs_is_secondary_server).lower() if hwtacacs_is_public_net: cfg["isPublicNet"] = str(hwtacacs_is_public_net).lower() if hwtacacs_vpn_name: cfg["vpnName"] = hwtacacs_vpn_name.lower() for tmp in result["hwtacacs_server_name_cfg"]: exist_cfg = dict() if hwtacacs_server_host_name: exist_cfg["serverHostName"] = tmp.get("serverHostName").lower() if hwtacacs_server_type: exist_cfg["serverType"] = tmp.get("serverType").lower() if hwtacacs_is_secondary_server: exist_cfg["isSecondaryServer"] = tmp.get("isSecondaryServer").lower() if hwtacacs_is_public_net: exist_cfg["isPublicNet"] = tmp.get("isPublicNet").lower() if hwtacacs_vpn_name: exist_cfg["vpnName"] = tmp.get("vpnName").lower() config_list.append(exist_cfg) if cfg in config_list: if state == "present": need_cfg = False else: need_cfg = True else: if state == "present": need_cfg = True else: need_cfg = False result["need_cfg"] = need_cfg return result def merge_hwtacacs_host_server_cfg(self, **kwargs): """ Merge hwtacacs host server configure """ module = kwargs["module"] hwtacacs_template = module.params["hwtacacs_template"] hwtacacs_server_host_name = module.params["hwtacacs_server_host_name"] hwtacacs_server_type = module.params["hwtacacs_server_type"] hwtacacs_is_secondary_server = module.params[ "hwtacacs_is_secondary_server"] hwtacacs_vpn_name = module.params["hwtacacs_vpn_name"] hwtacacs_is_public_net = module.params["hwtacacs_is_public_net"] conf_str = CE_MERGE_HWTACACS_HOST_SERVER_CFG % ( hwtacacs_template, hwtacacs_server_host_name, hwtacacs_server_type, str(hwtacacs_is_secondary_server).lower(), hwtacacs_vpn_name, str(hwtacacs_is_public_net).lower()) recv_xml = self.netconf_set_config(module=module, conf_str=conf_str) if "" not in recv_xml: module.fail_json( msg='Error: Merge hwtacacs host server config failed.') cmds = [] if hwtacacs_server_type == "Authentication": cmd = "hwtacacs server authentication host %s" % hwtacacs_server_host_name if hwtacacs_vpn_name and hwtacacs_vpn_name != "_public_": cmd += " vpn-instance %s" % hwtacacs_vpn_name if hwtacacs_is_public_net: cmd += " public-net" if hwtacacs_is_secondary_server: cmd += " secondary" elif hwtacacs_server_type == "Authorization": cmd = "hwtacacs server authorization host %s" % hwtacacs_server_host_name if hwtacacs_vpn_name and hwtacacs_vpn_name != "_public_": cmd += " vpn-instance %s" % hwtacacs_vpn_name if hwtacacs_is_public_net: cmd += " public-net" if hwtacacs_is_secondary_server: cmd += " secondary" elif hwtacacs_server_type == "Accounting": cmd = "hwtacacs server accounting host %s" % hwtacacs_server_host_name if hwtacacs_vpn_name and hwtacacs_vpn_name != "_public_": cmd += " vpn-instance %s" % hwtacacs_vpn_name if hwtacacs_is_public_net: cmd += " public-net" if hwtacacs_is_secondary_server: cmd += " secondary" elif hwtacacs_server_type == "Common": cmd = "hwtacacs server host host-name %s" % hwtacacs_server_host_name if hwtacacs_vpn_name and hwtacacs_vpn_name != "_public_": cmd += " vpn-instance %s" % hwtacacs_vpn_name if hwtacacs_is_public_net: cmd += " public-net" if hwtacacs_is_secondary_server: cmd += " secondary" cmds.append(cmd) return cmds def delete_hwtacacs_host_server_cfg(self, **kwargs): """ Delete hwtacacs host server configure """ module = kwargs["module"] hwtacacs_template = module.params["hwtacacs_template"] hwtacacs_server_host_name = module.params["hwtacacs_server_host_name"] hwtacacs_server_type = module.params["hwtacacs_server_type"] hwtacacs_is_secondary_server = module.params[ "hwtacacs_is_secondary_server"] hwtacacs_vpn_name = module.params["hwtacacs_vpn_name"] hwtacacs_is_public_net = module.params["hwtacacs_is_public_net"] conf_str = CE_DELETE_HWTACACS_HOST_SERVER_CFG % ( hwtacacs_template, hwtacacs_server_host_name, hwtacacs_server_type, str(hwtacacs_is_secondary_server).lower(), hwtacacs_vpn_name, str(hwtacacs_is_public_net).lower()) recv_xml = self.netconf_set_config(module=module, conf_str=conf_str) if "" not in recv_xml: module.fail_json( msg='Error: Delete hwtacacs host server config failed.') cmds = [] if hwtacacs_server_type == "Authentication": cmd = "undo hwtacacs server authentication host %s" % hwtacacs_server_host_name if hwtacacs_vpn_name and hwtacacs_vpn_name != "_public_": cmd += " vpn-instance %s" % hwtacacs_vpn_name if hwtacacs_is_public_net: cmd += " public-net" if hwtacacs_is_secondary_server: cmd += " secondary" elif hwtacacs_server_type == "Authorization": cmd = "undo hwtacacs server authorization host %s" % hwtacacs_server_host_name if hwtacacs_vpn_name and hwtacacs_vpn_name != "_public_": cmd += " vpn-instance %s" % hwtacacs_vpn_name if hwtacacs_is_public_net: cmd += " public-net" if hwtacacs_is_secondary_server: cmd += " secondary" elif hwtacacs_server_type == "Accounting": cmd = "undo hwtacacs server accounting host %s" % hwtacacs_server_host_name if hwtacacs_vpn_name and hwtacacs_vpn_name != "_public_": cmd += " vpn-instance %s" % hwtacacs_vpn_name if hwtacacs_is_public_net: cmd += " public-net" if hwtacacs_is_secondary_server: cmd += " secondary" elif hwtacacs_server_type == "Common": cmd = "undo hwtacacs server host %s" % hwtacacs_server_host_name if hwtacacs_vpn_name and hwtacacs_vpn_name != "_public_": cmd += " vpn-instance %s" % hwtacacs_vpn_name if hwtacacs_is_public_net: cmd += " public-net" if hwtacacs_is_secondary_server: cmd += " secondary" cmds.append(cmd) return cmds def check_name(**kwargs): """ Check invalid name """ module = kwargs["module"] name = kwargs["name"] invalid_char = kwargs["invalid_char"] for item in invalid_char: if item in name: module.fail_json( msg='Error: Invalid char %s is in the name %s ' % (item, name)) def check_module_argument(**kwargs): """ Check module argument """ module = kwargs["module"] # local para local_user_name = module.params['local_user_name'] local_password = module.params['local_password'] local_ftp_dir = module.params['local_ftp_dir'] local_user_level = module.params['local_user_level'] local_user_group = module.params['local_user_group'] # radius para radius_group_name = module.params['radius_group_name'] radius_server_ip = module.params['radius_server_ip'] radius_server_port = module.params['radius_server_port'] radius_vpn_name = module.params['radius_vpn_name'] radius_server_name = module.params['radius_server_name'] # hwtacacs para hwtacacs_template = module.params['hwtacacs_template'] hwtacacs_server_ip = module.params['hwtacacs_server_ip'] hwtacacs_vpn_name = module.params['hwtacacs_vpn_name'] hwtacacs_server_host_name = module.params['hwtacacs_server_host_name'] if local_user_name: if len(local_user_name) > 253: module.fail_json( msg='Error: The local_user_name %s is large than 253.' % local_user_name) check_name(module=module, name=local_user_name, invalid_char=INVALID_USER_NAME_CHAR) if local_password and len(local_password) > 255: module.fail_json( msg='Error: The local_password %s is large than 255.' % local_password) if local_user_level: if int(local_user_level) > 15 or int(local_user_level) < 0: module.fail_json( msg='Error: The local_user_level %s is out of [0 - 15].' % local_user_level) if local_ftp_dir: if len(local_ftp_dir) > 255: module.fail_json( msg='Error: The local_ftp_dir %s is large than 255.' % local_ftp_dir) if local_user_group: if len(local_user_group) > 32 or len(local_user_group) < 1: module.fail_json( msg='Error: The local_user_group %s is out of [1 - 32].' % local_user_group) if radius_group_name and len(radius_group_name) > 32: module.fail_json( msg='Error: The radius_group_name %s is large than 32.' % radius_group_name) if radius_server_ip and not check_ip_addr(radius_server_ip): module.fail_json( msg='Error: The radius_server_ip %s is invalid.' % radius_server_ip) if radius_server_port and not radius_server_port.isdigit(): module.fail_json( msg='Error: The radius_server_port %s is invalid.' % radius_server_port) if radius_vpn_name: if len(radius_vpn_name) > 31: module.fail_json( msg='Error: The radius_vpn_name %s is large than 31.' % radius_vpn_name) if ' ' in radius_vpn_name: module.fail_json( msg='Error: The radius_vpn_name %s include space.' % radius_vpn_name) if radius_server_name: if len(radius_server_name) > 255: module.fail_json( msg='Error: The radius_server_name %s is large than 255.' % radius_server_name) if ' ' in radius_server_name: module.fail_json( msg='Error: The radius_server_name %s include space.' % radius_server_name) if hwtacacs_template and len(hwtacacs_template) > 32: module.fail_json( msg='Error: The hwtacacs_template %s is large than 32.' % hwtacacs_template) if hwtacacs_server_ip and not check_ip_addr(hwtacacs_server_ip): module.fail_json( msg='Error: The hwtacacs_server_ip %s is invalid.' % hwtacacs_server_ip) if hwtacacs_vpn_name: if len(hwtacacs_vpn_name) > 31: module.fail_json( msg='Error: The hwtacacs_vpn_name %s is large than 31.' % hwtacacs_vpn_name) if ' ' in hwtacacs_vpn_name: module.fail_json( msg='Error: The hwtacacs_vpn_name %s include space.' % hwtacacs_vpn_name) if hwtacacs_server_host_name: if len(hwtacacs_server_host_name) > 255: module.fail_json( msg='Error: The hwtacacs_server_host_name %s is large than 255.' % hwtacacs_server_host_name) if ' ' in hwtacacs_server_host_name: module.fail_json( msg='Error: The hwtacacs_server_host_name %s include space.' % hwtacacs_server_host_name) def main(): """ Module main """ argument_spec = dict( state=dict(choices=['present', 'absent'], default='present'), local_user_name=dict(type='str'), local_password=dict(type='str', no_log=True), local_service_type=dict(type='str'), local_ftp_dir=dict(type='str'), local_user_level=dict(type='str'), local_user_group=dict(type='str'), radius_group_name=dict(type='str'), radius_server_type=dict(choices=['Authentication', 'Accounting']), radius_server_ip=dict(type='str'), radius_server_ipv6=dict(type='str'), radius_server_port=dict(type='str'), radius_server_mode=dict( choices=['Secondary-server', 'Primary-server']), radius_vpn_name=dict(type='str'), radius_server_name=dict(type='str'), hwtacacs_template=dict(type='str'), hwtacacs_server_ip=dict(type='str'), hwtacacs_server_ipv6=dict(type='str'), hwtacacs_server_type=dict( choices=['Authentication', 'Authorization', 'Accounting', 'Common']), hwtacacs_is_secondary_server=dict( required=False, default=False, type='bool'), hwtacacs_vpn_name=dict(type='str'), hwtacacs_is_public_net=dict( required=False, default=False, type='bool'), hwtacacs_server_host_name=dict(type='str') ) argument_spec.update(ce_argument_spec) module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) check_module_argument(module=module) changed = False proposed = dict() existing = dict() end_state = dict() updates = [] # common para state = module.params['state'] # local para local_user_name = module.params['local_user_name'] local_password = module.params['local_password'] local_service_type = module.params['local_service_type'] local_ftp_dir = module.params['local_ftp_dir'] local_user_level = module.params['local_user_level'] local_user_group = module.params['local_user_group'] # radius para radius_group_name = module.params['radius_group_name'] radius_server_type = module.params['radius_server_type'] radius_server_ip = module.params['radius_server_ip'] radius_server_ipv6 = module.params['radius_server_ipv6'] radius_server_port = module.params['radius_server_port'] radius_server_mode = module.params['radius_server_mode'] radius_vpn_name = module.params['radius_vpn_name'] radius_server_name = module.params['radius_server_name'] # hwtacacs para hwtacacs_template = module.params['hwtacacs_template'] hwtacacs_server_ip = module.params['hwtacacs_server_ip'] hwtacacs_server_ipv6 = module.params['hwtacacs_server_ipv6'] hwtacacs_server_type = module.params['hwtacacs_server_type'] hwtacacs_is_secondary_server = module.params[ 'hwtacacs_is_secondary_server'] hwtacacs_vpn_name = module.params['hwtacacs_vpn_name'] hwtacacs_is_public_net = module.params['hwtacacs_is_public_net'] hwtacacs_server_host_name = module.params['hwtacacs_server_host_name'] ce_aaa_server_host = AaaServerHost() if not ce_aaa_server_host: module.fail_json(msg='Error: Construct ce_aaa_server failed.') # get proposed proposed["state"] = state if local_user_name: proposed["local_user_name"] = local_user_name if local_password: proposed["local_password"] = "******" if local_service_type: proposed["local_service_type"] = local_service_type if local_ftp_dir: proposed["local_ftp_dir"] = local_ftp_dir if local_user_level: proposed["local_user_level"] = local_user_level if local_user_group: proposed["local_user_group"] = local_user_group if radius_group_name: proposed["radius_group_name"] = radius_group_name if radius_server_type: proposed["radius_server_type"] = radius_server_type if radius_server_ip: proposed["radius_server_ip"] = radius_server_ip if radius_server_ipv6: proposed["radius_server_ipv6"] = radius_server_ipv6 if radius_server_port: proposed["radius_server_port"] = radius_server_port if radius_server_mode: proposed["radius_server_mode"] = radius_server_mode if radius_vpn_name: proposed["radius_vpn_name"] = radius_vpn_name if radius_server_name: proposed["radius_server_name"] = radius_server_name if hwtacacs_template: proposed["hwtacacs_template"] = hwtacacs_template if hwtacacs_server_ip: proposed["hwtacacs_server_ip"] = hwtacacs_server_ip if hwtacacs_server_ipv6: proposed["hwtacacs_server_ipv6"] = hwtacacs_server_ipv6 if hwtacacs_server_type: proposed["hwtacacs_server_type"] = hwtacacs_server_type proposed["hwtacacs_is_secondary_server"] = hwtacacs_is_secondary_server if hwtacacs_vpn_name: proposed["hwtacacs_vpn_name"] = hwtacacs_vpn_name proposed["hwtacacs_is_public_net"] = hwtacacs_is_public_net if hwtacacs_server_host_name: proposed["hwtacacs_server_host_name"] = hwtacacs_server_host_name if local_user_name: if state == "present" and not local_password: module.fail_json( msg='Error: Please input local_password when config local user.') local_user_result = ce_aaa_server_host.get_local_user_info( module=module) existing["local user name"] = local_user_result["local_user_info"] if state == "present": # present local user if local_user_result["need_cfg"]: cmd = ce_aaa_server_host.merge_local_user_info(module=module) changed = True updates.append(cmd) else: # absent local user if local_user_result["need_cfg"]: if not local_service_type and not local_ftp_dir and not local_user_level and not local_user_group: cmd = ce_aaa_server_host.delete_local_user_info( module=module) else: cmd = ce_aaa_server_host.merge_local_user_info( module=module) changed = True updates.append(cmd) local_user_result = ce_aaa_server_host.get_local_user_info( module=module) end_state["local user name"] = local_user_result["local_user_info"] if radius_group_name: if not radius_server_ip and not radius_server_ipv6 and not radius_server_name: module.fail_json( msg='Error: Please input radius_server_ip or radius_server_ipv6 or radius_server_name.') if radius_server_ip and radius_server_ipv6: module.fail_json( msg='Error: Please do not input radius_server_ip and radius_server_ipv6 at the same time.') if not radius_server_type or not radius_server_port or not radius_server_mode or not radius_vpn_name: module.fail_json( msg='Error: Please input radius_server_type radius_server_port radius_server_mode radius_vpn_name.') if radius_server_ip: rds_server_ipv4_result = ce_aaa_server_host.get_radius_server_cfg_ipv4( module=module) if radius_server_ipv6: rds_server_ipv6_result = ce_aaa_server_host.get_radius_server_cfg_ipv6( module=module) if radius_server_name: rds_server_name_result = ce_aaa_server_host.get_radius_server_name( module=module) if radius_server_ip and rds_server_ipv4_result["radius_server_ip_v4"]: existing["radius server ipv4"] = rds_server_ipv4_result[ "radius_server_ip_v4"] if radius_server_ipv6 and rds_server_ipv6_result["radius_server_ip_v6"]: existing["radius server ipv6"] = rds_server_ipv6_result[ "radius_server_ip_v6"] if radius_server_name and rds_server_name_result["radius_server_name_cfg"]: existing["radius server name cfg"] = rds_server_name_result[ "radius_server_name_cfg"] if state == "present": if radius_server_ip and rds_server_ipv4_result["need_cfg"]: cmd = ce_aaa_server_host.merge_radius_server_cfg_ipv4( module=module) changed = True updates.append(cmd) if radius_server_ipv6 and rds_server_ipv6_result["need_cfg"]: cmd = ce_aaa_server_host.merge_radius_server_cfg_ipv6( module=module) changed = True updates.append(cmd) if radius_server_name and rds_server_name_result["need_cfg"]: cmd = ce_aaa_server_host.merge_radius_server_name( module=module) changed = True updates.append(cmd) else: if radius_server_ip and rds_server_ipv4_result["need_cfg"]: cmd = ce_aaa_server_host.delete_radius_server_cfg_ipv4( module=module) changed = True updates.append(cmd) if radius_server_ipv6 and rds_server_ipv6_result["need_cfg"]: cmd = ce_aaa_server_host.delete_radius_server_cfg_ipv6( module=module) changed = True updates.append(cmd) if radius_server_name and rds_server_name_result["need_cfg"]: cmd = ce_aaa_server_host.delete_radius_server_name( module=module) changed = True updates.append(cmd) if radius_server_ip: rds_server_ipv4_result = ce_aaa_server_host.get_radius_server_cfg_ipv4( module=module) if radius_server_ipv6: rds_server_ipv6_result = ce_aaa_server_host.get_radius_server_cfg_ipv6( module=module) if radius_server_name: rds_server_name_result = ce_aaa_server_host.get_radius_server_name( module=module) if radius_server_ip and rds_server_ipv4_result["radius_server_ip_v4"]: end_state["radius server ipv4"] = rds_server_ipv4_result[ "radius_server_ip_v4"] if radius_server_ipv6 and rds_server_ipv6_result["radius_server_ip_v6"]: end_state["radius server ipv6"] = rds_server_ipv6_result[ "radius_server_ip_v6"] if radius_server_name and rds_server_name_result["radius_server_name_cfg"]: end_state["radius server name cfg"] = rds_server_name_result[ "radius_server_name_cfg"] if hwtacacs_template: if not hwtacacs_server_ip and not hwtacacs_server_ipv6 and not hwtacacs_server_host_name: module.fail_json( msg='Error: Please input hwtacacs_server_ip or hwtacacs_server_ipv6 or hwtacacs_server_host_name.') if not hwtacacs_server_type or not hwtacacs_vpn_name: module.fail_json( msg='Error: Please input hwtacacs_server_type hwtacacs_vpn_name.') if hwtacacs_server_ip and hwtacacs_server_ipv6: module.fail_json( msg='Error: Please do not set hwtacacs_server_ip and hwtacacs_server_ipv6 at the same time.') if hwtacacs_vpn_name and hwtacacs_vpn_name != "_public_": if hwtacacs_is_public_net: module.fail_json( msg='Error: Please do not set vpn and public net at the same time.') if hwtacacs_server_ip: hwtacacs_server_ipv4_result = ce_aaa_server_host.get_hwtacacs_server_cfg_ipv4( module=module) if hwtacacs_server_ipv6: hwtacacs_server_ipv6_result = ce_aaa_server_host.get_hwtacacs_server_cfg_ipv6( module=module) if hwtacacs_server_host_name: hwtacacs_host_name_result = ce_aaa_server_host.get_hwtacacs_host_server_cfg( module=module) if hwtacacs_server_ip and hwtacacs_server_ipv4_result["hwtacacs_server_cfg_ipv4"]: existing["hwtacacs server cfg ipv4"] = hwtacacs_server_ipv4_result[ "hwtacacs_server_cfg_ipv4"] if hwtacacs_server_ipv6 and hwtacacs_server_ipv6_result["hwtacacs_server_cfg_ipv6"]: existing["hwtacacs server cfg ipv6"] = hwtacacs_server_ipv6_result[ "hwtacacs_server_cfg_ipv6"] if hwtacacs_server_host_name and hwtacacs_host_name_result["hwtacacs_server_name_cfg"]: existing["hwtacacs server name cfg"] = hwtacacs_host_name_result[ "hwtacacs_server_name_cfg"] if state == "present": if hwtacacs_server_ip and hwtacacs_server_ipv4_result["need_cfg"]: cmd = ce_aaa_server_host.merge_hwtacacs_server_cfg_ipv4( module=module) changed = True updates.append(cmd) if hwtacacs_server_ipv6 and hwtacacs_server_ipv6_result["need_cfg"]: cmd = ce_aaa_server_host.merge_hwtacacs_server_cfg_ipv6( module=module) changed = True updates.append(cmd) if hwtacacs_server_host_name and hwtacacs_host_name_result["need_cfg"]: cmd = ce_aaa_server_host.merge_hwtacacs_host_server_cfg( module=module) changed = True updates.append(cmd) else: if hwtacacs_server_ip and hwtacacs_server_ipv4_result["need_cfg"]: cmd = ce_aaa_server_host.delete_hwtacacs_server_cfg_ipv4( module=module) changed = True updates.append(cmd) if hwtacacs_server_ipv6 and hwtacacs_server_ipv6_result["need_cfg"]: cmd = ce_aaa_server_host.delete_hwtacacs_server_cfg_ipv6( module=module) changed = True updates.append(cmd) if hwtacacs_server_host_name and hwtacacs_host_name_result["need_cfg"]: cmd = ce_aaa_server_host.delete_hwtacacs_host_server_cfg( module=module) changed = True updates.append(cmd) if hwtacacs_server_ip: hwtacacs_server_ipv4_result = ce_aaa_server_host.get_hwtacacs_server_cfg_ipv4( module=module) if hwtacacs_server_ipv6: hwtacacs_server_ipv6_result = ce_aaa_server_host.get_hwtacacs_server_cfg_ipv6( module=module) if hwtacacs_server_host_name: hwtacacs_host_name_result = ce_aaa_server_host.get_hwtacacs_host_server_cfg( module=module) if hwtacacs_server_ip and hwtacacs_server_ipv4_result["hwtacacs_server_cfg_ipv4"]: end_state["hwtacacs server cfg ipv4"] = hwtacacs_server_ipv4_result[ "hwtacacs_server_cfg_ipv4"] if hwtacacs_server_ipv6 and hwtacacs_server_ipv6_result["hwtacacs_server_cfg_ipv6"]: end_state["hwtacacs server cfg ipv6"] = hwtacacs_server_ipv6_result[ "hwtacacs_server_cfg_ipv6"] if hwtacacs_server_host_name and hwtacacs_host_name_result["hwtacacs_server_name_cfg"]: end_state["hwtacacs server name cfg"] = hwtacacs_host_name_result[ "hwtacacs_server_name_cfg"] results = dict() results['proposed'] = proposed results['existing'] = existing results['changed'] = changed results['end_state'] = end_state results['updates'] = updates module.exit_json(**results) if __name__ == '__main__': main()