def main(): module_args = dict(interface=dict(type='str', required=True), admin_state=dict(default='up', choices=['up', 'down']), description=dict(type='str', default=None), vlan_mode=dict(default='access', choices=['access', 'trunk']), vlan_id=dict(type='list', default=None), vlan_trunk_native_id=dict(type='str', default=None), vlan_trunk_native_tag=dict(type='bool', default=False), qos_rate=dict(type='dict', default=None), qos_schedule_profile=dict(type='str', default=None), aclv4_in=dict(type='str', default=None), aclv6_in=dict(type='str', default=None), aclmac_in=dict(type='str', default=None), state=dict(default='present', choices=['present', 'absent'])) warnings = list() result = dict(changed=False, warnings=warnings) module = AnsibleModule(argument_spec=module_args, supports_check_mode=True) if module.check_mode: module.exit_json(changed=False) connection = Connection(module._socket_path) get_response = connection.get_running_config() module.log(msg=get_response) interface = module.params['interface'].lower() admin_state = module.params['admin_state'] description = module.params['description'] vlan_mode = module.params['vlan_mode'] vlan_id = module.params['vlan_id'] vlan_trunk_native_id = module.params['vlan_trunk_native_id'] vlan_trunk_native_tag = module.params['vlan_trunk_native_tag'] qos_rate = module.params['qos_rate'] qos_schedule_profile = module.params['qos_schedule_profile'] aclv4_in = module.params['aclv4_in'] aclv6_in = module.params['aclv6_in'] aclmac_in = module.params['aclmac_in'] state = module.params['state'] try: json_data = json.loads(get_response) except ValueError: module.fail_json(msg=get_response) ''' Verify if input interface string is valid ''' if (len(interface.encode('utf-8')) > 8) or (not bool( re.match('^[a-zA-Z0-9/]+$', interface))): module.fail_json(msg='Interface is not valid.') ''' Deleting interface ''' if state == 'absent': get_json = json.loads(get_response) encode_interface = interface.replace('/', '%2F') if encode_interface in json_data["Port"].keys(): json_data["Port"].pop(encode_interface) json_data["System"]["bridge"]["Bridge1"]["ports"].remove( encode_interface) if "Interface" in json_data.keys(): if encode_interface in json_data["Interface"].keys(): json_data["Interface"].pop(encode_interface) else: warnings.append("Interface " + interface + " has already been removed.") ''' Adding interface ''' if state == 'present': get_json = json.loads(get_response) if interface is not None: encode_interface = interface.replace('/', '%2F') if "Port" not in json_data: json_data["Port"] = {} json_data["Port"].setdefault(encode_interface, {})["name"] = interface if encode_interface not in json_data["Port"][ encode_interface].setdefault("interfaces", []): json_data["Port"][encode_interface]["interfaces"].append( encode_interface) if "default" in json_data["System"]["vrfs"].keys(): if encode_interface not in json_data["System"]["vrfs"][ "default"]["ports"]: json_data["System"]["vrfs"]["default"].setdefault( "ports", []).append(encode_interface) else: json_data["System"]["vrfs"]["default"] = { "name": "default", "ports": [encode_interface] } module.log(msg='Added Interface: ' + interface) if admin_state == "up": json_data["Port"][encode_interface]["admin"] = "up" json_data.setdefault("Interface", {})[encode_interface] = { "name": interface, "user_config": { "admin": "up" } } elif admin_state == "down": json_data["Port"][encode_interface]["admin"] = "down" json_data.setdefault("Interface", {})[encode_interface] = { "name": interface, "user_config": { "admin": "down" } } if description is not None: encode_interface = interface.replace('/', '%2F') json_data["Interface"][encode_interface][ "description"] = description module.log(msg="Added interface with name='" + interface + "' description='" + description + "'") ''' Attaching access VLAN to interface ''' if (vlan_mode == 'access') and (vlan_id is not None): vlan_id = vlan_id[0] if "vlans" not in json_data["System"]["bridge"]["Bridge1"].keys(): warnings.append('VLAN ' + str(vlan_id) + ' does not exist on switch.') elif str(vlan_id) not in json_data["System"]["bridge"]["Bridge1"][ "vlans"].keys(): warnings.append('VLAN ' + str(vlan_id) + ' does not exist on switch.') else: json_data["Port"][encode_interface]["vlan_mode"] = "access" json_data["Port"][encode_interface]["vlan_tag"] = str(vlan_id) if encode_interface not in json_data["System"]["bridge"][ "Bridge1"].setdefault("ports", []): json_data["System"]["bridge"]["Bridge1"]["ports"].append( encode_interface) if encode_interface in json_data["System"]["vrfs"].get( "default", {}).setdefault("ports", []): json_data["System"]["vrfs"]["default"]["ports"].remove( encode_interface) if not json_data["System"]["vrfs"]["default"]["ports"]: json_data["System"]["vrfs"].pop("default") module.log(msg='Attached interface ' + interface + ' to access VLAN ' + str(vlan_id)) ''' Attaching trunk VLAN to interface ''' if (vlan_mode == 'trunk') and (vlan_id is not None): if "vlan_trunks" in json_data["Port"][encode_interface].keys(): json_data["Port"][encode_interface]["vlan_trunks"] = [] if encode_interface not in json_data["System"]["bridge"][ "Bridge1"].setdefault("ports", []): json_data["System"]["bridge"]["Bridge1"]["ports"].append( encode_interface) if encode_interface in json_data["System"]["vrfs"].get( "default", {}).setdefault("ports", []): json_data["System"]["vrfs"]["default"]["ports"].remove( encode_interface) if not json_data["System"]["vrfs"]["default"]["ports"]: json_data["System"]["vrfs"].pop("default") for vid in vlan_id: if ("vlans" not in json_data["System"]["bridge"] ["Bridge1"].keys()) and (vid != 1): warnings.append('VLAN ' + str(vid) + ' does not exist on switch.') elif (str(vid) not in json_data["System"]["bridge"]["Bridge1"].get( "vlans", {}).keys()) and (vid != 1): warnings.append('VLAN ' + str(vid) + ' does not exist on switch.') else: json_data["Port"][encode_interface][ "vlan_mode"] = "native-untagged" json_data["Port"][encode_interface]["vlan_tag"] = "1" json_data["Port"][encode_interface].setdefault( "vlan_trunks", []).append(str(vid)) module.log(msg='Attached interface ' + interface + ' to trunk VLAN ' + str(vid)) if vlan_trunk_native_tag: json_data["Port"][encode_interface][ "vlan_mode"] = "native-tagged" if (vlan_trunk_native_id is not None) and\ (vlan_trunk_native_id in json_data["System"]["bridge"]["Bridge1"].get("vlans", {}).keys()): json_data["Port"][encode_interface][ "vlan_tag"] = vlan_trunk_native_id if (vlan_mode is not None) and (vlan_id is None): module.fail_json(msg='Missing vlan_id') elif (vlan_mode is None) and (vlan_id is not None): module.fail_json(msg='Missing vlan_mode') ''' Attaching QoS rate to interface ''' if qos_rate is not None: for k, v in qos_rate.items(): number, unit = number_unit(v) json_data["Port"][encode_interface].setdefault( "rate_limits", {})[k] = number json_data["Port"][encode_interface].setdefault( "rate_limits", {})[k + '_units'] = unit module.log(msg='Applied QoS_rate ' + json.dumps(qos_rate) + ' to inteface ' + interface) ''' Attaching QoS schedule profile to interface ''' if qos_schedule_profile is not None: if "QoS" not in json_data.keys(): warnings.append('QoS_schedule_profile ' + qos_schedule_profile + ' does not exist on switch.') elif qos_schedule_profile not in json_data["QoS"].keys(): warnings.append('QoS_schedule_profile ' + qos_schedule_profile + ' does not exist on switch.') else: json_data["Port"][encode_interface][ "qos"] = qos_schedule_profile module.log(msg='Attached QoS_schedule_profile ' + qos_schedule_profile + ' to interface ' + interface) ''' Attaching ACL to interface ''' if (aclv6_in is not None) or (aclv4_in is not None) or (aclmac_in is not None): if "aclv4_in_cfg" in json_data["Port"][encode_interface].keys(): json_data["Port"][encode_interface].pop("aclv4_in_cfg") json_data["Port"][encode_interface][ "aclv4_in_cfg_version"] = randint(-900719925474099, 900719925474099) if "aclv6_in_cfg" in json_data["Port"][encode_interface].keys(): json_data["Port"][encode_interface].pop("aclv6_in_cfg") json_data["Port"][encode_interface][ "aclv6_in_cfg_version"] = randint(-900719925474099, 900719925474099) if "aclmac_in_cfg" in json_data["Port"][encode_interface].keys(): json_data["Port"][encode_interface].pop("aclmac_in_cfg") json_data["Port"][encode_interface][ "aclmac_in_cfg_version"] = randint(-900719925474099, 900719925474099) if aclv6_in is not None: add_acl(aclv6_in, 'ipv6', json_data, encode_interface, get_json, warnings) if aclv4_in is not None: add_acl(aclv4_in, 'ipv4', json_data, encode_interface, get_json, warnings) if aclmac_in is not None: add_acl(aclmac_in, 'mac', json_data, encode_interface, get_json, warnings) ''' Updating running config on remote switch ''' connection.put_running_config(json.dumps(json_data)) ''' Writing Debugging File ''' with open('/tmp/debugging_running_config.json', 'w') as to_file: json.dump(json_data, to_file, indent=4) to_file.write("\n") ''' Checking if change is idempotent ''' if get_json != json_data: result["changed"] = True else: module.log(msg="========Nothing Changed=========") module.exit_json(**result)
def main(): module_args = dict(interface=dict(type='str', required=True), admin_state=dict(default='up', choices=['up', 'down']), description=dict(type='str', default=None), ipv4=dict(type='list', default=None), ipv6=dict(type='list', default=None), vrf=dict(type='str', default=None), ip_helper_address=dict(type='list', default=None), active_gateway_ip=dict(type='str', default=None), active_gateway_mac_v4=dict(type='str', default=None), state=dict(default='present', choices=['present', 'absent'])) warnings = list() result = dict(changed=False, warnings=warnings) module = AnsibleModule(argument_spec=module_args, supports_check_mode=True) if module.check_mode: module.exit_json(changed=False) connection = Connection(module._socket_path) get_response = connection.get_running_config() module.log(msg=get_response) interface = module.params['interface'].lower() admin_state = module.params['admin_state'] description = module.params['description'] ipv4 = module.params['ipv4'] ipv6 = module.params['ipv6'] vrf = module.params['vrf'] ip_helper_address = module.params['ip_helper_address'] active_gateway_ip = module.params['active_gateway_ip'] active_gateway_mac_v4 = module.params['active_gateway_mac_v4'] state = module.params['state'] try: json_data = json.loads(get_response) except ValueError: module.fail_json(msg=get_response) ''' Verify if input interface string is valid ''' if (len(interface.encode('utf-8')) > 8) or (not bool( re.match('^[a-zA-Z0-9/]+$', interface))): module.fail_json(msg='Interface is not valid.') ''' Deleting interface ''' if state == 'absent': get_json = json.loads(get_response) encode_interface = interface.replace('/', '%2F') if encode_interface in json_data["Port"].keys(): json_data["Port"].pop(encode_interface) else: warnings.append("Interface " + interface + " has already been removed.") if encode_interface in json_data["System"]["bridge"][ "Bridge1"].setdefault("ports", []): json_data["System"]["bridge"]["Bridge1"]["ports"].remove( encode_interface) if "Interface" in json_data.keys(): if encode_interface in json_data["Interface"].keys(): json_data["Interface"].pop(encode_interface) for item in json_data["System"]["vrfs"].keys(): if encode_interface in json_data["System"]["vrfs"][ item].setdefault("ports", []): json_data["System"]["vrfs"][item].get("ports").remove( encode_interface) ''' Adding interface ''' if state == 'present': get_json = json.loads(get_response) if interface is not None: vid = interface.replace('vlan', '') if "vlans" not in json_data["System"]["bridge"]["Bridge1"].keys(): module.fail_json( msg='VLAN ' + str(vid) + ' should be created before creating interface ' + interface) if vid not in json_data["System"]["bridge"]["Bridge1"][ "vlans"].keys(): module.fail_json( msg='VLAN ' + str(vid) + ' should be created before creating interface ' + interface) if "Port" not in json_data: json_data["Port"] = {} json_data["Port"].setdefault(interface, {})["name"] = interface json_data["Port"][interface]["vlan_tag"] = interface.replace( 'vlan', '') if interface not in json_data["Port"][interface].setdefault( "interfaces", []): json_data["Port"][interface]["interfaces"].append(interface) if "default" in json_data["System"]["vrfs"].keys(): if interface not in json_data["System"]["vrfs"]["default"][ "ports"]: json_data["System"]["vrfs"]["default"].setdefault( "ports", []).append(interface) else: json_data["System"]["vrfs"]["default"] = { "name": "default", "ports": [interface] } if interface not in json_data["System"]["bridge"][ "Bridge1"].setdefault("ports", []): json_data["System"]["bridge"]["Bridge1"]["ports"].append( interface) module.log(msg='Added Interface: ' + interface) if admin_state == "up": json_data["Port"][interface]["admin"] = "up" json_data.setdefault("Interface", {})[interface] = { "name": interface, "type": "internal", "user_config": { "admin": "up" } } elif admin_state == "down": json_data["Port"][interface]["admin"] = "down" json_data.setdefault("Interface", {})[interface] = { "name": interface, "type": "internal", "user_config": { "admin": "down" } } if description is not None: json_data["Port"][interface]["description"] = description module.log(msg="Added interface with name='" + interface + "' description='" + description + "'") ''' Attaching IPv4 address to interface ''' if ipv4 is not None: json_data["Port"][interface]["ip4_address"] = ipv4[0] if len(ipv4) > 2: json_data["Port"][interface]["ip4_address_secondary"] = [] for item in ipv4[1:]: json_data["Port"][interface][ "ip4_address_secondary"].append(item) elif len(ipv4) == 2: json_data["Port"][interface]["ip4_address_secondary"] = ipv4[1] module.log(msg='Attached IPv4 address ' + ''.join(ipv4) + ' to interface ' + interface) ''' Attaching IPv6 address to interface ''' if ipv6 is not None: if "ip6_addresses" in json_data["Port"][interface].keys(): json_data["Port"][interface]["ip6_addresses"] = {} for item in ipv6: json_data["Port"][interface].setdefault("ip6_addresses", {})[item] =\ {"node_address": True, "preferred_lifetime": 604800, "ra_prefix": True, "type": "global-unicast", "valid_lifetime": 2592000} module.log(msg='Attached IPv6 address ' + ' '.join(ipv6) + ' to interface ' + interface) ''' Attaching interface to non-default VRF ''' if vrf is not None: if vrf not in json_data["System"]["vrfs"].keys(): warnings.append('VRF ' + vrf + ' does not exist on switch.') elif interface not in json_data["System"]["vrfs"][vrf].setdefault( "ports", []): json_data["System"]["vrfs"][vrf]["ports"].append(interface) if vrf != 'default' and (interface in json_data["System"]["vrfs"].get( "default", {}).get("ports", [])): json_data["System"]["vrfs"]["default"]["ports"].remove( interface) if not json_data["System"]["vrfs"]["default"]["ports"]: json_data["System"]["vrfs"].pop("default") module.log(msg='Attached interface ' + interface + ' to VRF ' + vrf) elif interface in json_data["System"]["vrfs"][vrf].get( "ports", []): if vrf != 'default' and (interface in json_data["System"]["vrfs"].get( "default", {}).get("ports", [])): json_data["System"]["vrfs"]["default"]["ports"].remove( interface) if not json_data["System"]["vrfs"]["default"]["ports"]: json_data["System"]["vrfs"].pop("default") ''' Attaching helper-address to interface ''' if ip_helper_address is not None: if (vrf is not None) and (vrf in json_data["System"]["vrfs"].keys()): vrf_dhcp = vrf else: vrf_dhcp = "default" dhcp_name = vrf_dhcp + "/" + interface if len(ip_helper_address) <= 1: json_data.setdefault("DHCP_Relay", {})[dhcp_name] = { "ipv4_ucast_server": ip_helper_address[0], "port": interface, "vrf": vrf_dhcp } else: json_data.setdefault("DHCP_Relay", {})[dhcp_name] = { "ipv4_ucast_server": [], "port": interface, "vrf": vrf_dhcp } for item in ip_helper_address: json_data["DHCP_Relay"][dhcp_name][ "ipv4_ucast_server"].append(item) json_data["DHCP_Relay"][dhcp_name][ "ipv4_ucast_server"].sort() ''' Attaching active gateway to interface ''' if (active_gateway_ip is None) and (active_gateway_mac_v4 is not None): warnings.append( "Both active_gateway_ip and active_gateway_mac_v4 are required for configure active gateway." ) if (active_gateway_ip is not None) and (active_gateway_mac_v4 is not None): json_data["Port"][interface]["vsx_virtual_ip4"] = active_gateway_ip json_data["Port"][interface][ "vsx_virtual_gw_mac_v4"] = active_gateway_mac_v4 ''' Updating running config on remote switch ''' connection.put_running_config(json.dumps(json_data)) ''' Writing Debugging File ''' with open('/tmp/debugging_running_config.json', 'w') as to_file: json.dump(json_data, to_file, indent=4) to_file.write("\n") ''' Checking if change is idempotent ''' if get_json != json_data: result["changed"] = True else: module.log(msg="========Nothing Changed=========") module.exit_json(**result)
def main(): module_args = dict(interface=dict(type='str', required=True), admin_state=dict(default='up', choices=['up', 'down']), description=dict(type='str', default=None), ipv4=dict(type='list', default=None), ipv6=dict(type='list', default=None), qos_rate=dict(type='dict', default=None), qos_schedule_profile=dict(type='str', default=None), aclv4_in=dict(type='str', default=None), aclv6_in=dict(type='str', default=None), aclmac_in=dict(type='str', default=None), aclv4_out=dict(type='str', default=None), vrf=dict(type='str', default=None), ip_helper_address=dict(type='list', default=None), state=dict(default='present', choices=['present', 'absent'])) warnings = list() result = dict(changed=False, warnings=warnings) module = AnsibleModule(argument_spec=module_args, supports_check_mode=True) if module.check_mode: module.exit_json(changed=False) connection = Connection(module._socket_path) get_response = connection.get_running_config() module.log(msg=get_response) interface = module.params['interface'] admin_state = module.params['admin_state'] description = module.params['description'] ipv4 = module.params['ipv4'] ipv6 = module.params['ipv6'] qos_rate = module.params['qos_rate'] qos_schedule_profile = module.params['qos_schedule_profile'] aclv4_in = module.params['aclv4_in'] aclv6_in = module.params['aclv6_in'] aclmac_in = module.params['aclmac_in'] aclv4_out = module.params['aclv4_out'] vrf = module.params['vrf'] ip_helper_address = module.params['ip_helper_address'] state = module.params['state'] try: json_data = json.loads(get_response) except ValueError: module.fail_json(msg=get_response) ''' Verify if input interface string is valid ''' if (len(interface.encode('utf-8')) > 8) or (not bool( re.match('^[a-zA-Z0-9/]+$', interface))): module.fail_json(msg='Interface is not valid.') ''' Deleting interface ''' if state == 'absent': get_json = json.loads(get_response) encode_interface = interface.replace('/', '%2F') if encode_interface in json_data["Port"].keys(): json_data["Port"].pop(encode_interface) else: warnings.append("Interface " + interface + " has already been removed.") if encode_interface in json_data["System"]["bridge"][ "Bridge1"].setdefault("ports", []): json_data["System"]["bridge"]["Bridge1"]["ports"].remove( encode_interface) if "Interface" in json_data.keys(): if encode_interface in json_data["Interface"].keys(): json_data["Interface"].pop(encode_interface) for item in json_data["System"]["vrfs"].keys(): if encode_interface in json_data["System"]["vrfs"][ item].setdefault("ports", []): json_data["System"]["vrfs"][item].get("ports").remove( encode_interface) ''' Adding interface ''' if state == 'present': get_json = json.loads(get_response) if interface is not None: encode_interface = interface.replace('/', '%2F') if "Port" not in json_data: json_data["Port"] = {} json_data["Port"].setdefault(encode_interface, {})["name"] = interface if encode_interface not in json_data["Port"][ encode_interface].setdefault("interfaces", []): json_data["Port"][encode_interface]["interfaces"].append( encode_interface) if "default" in json_data["System"]["vrfs"].keys(): if encode_interface not in json_data["System"]["vrfs"][ "default"].setdefault("ports", []): json_data["System"]["vrfs"]["default"].get("ports").append( encode_interface) else: json_data["System"]["vrfs"]["default"] = { "name": "default", "ports": [encode_interface] } module.log(msg='Added Interface: ' + interface) if admin_state == "up": json_data["Port"][encode_interface]["admin"] = "up" json_data.setdefault("Interface", {})[encode_interface] = { "name": interface, "user_config": { "admin": "up" } } elif admin_state == "down": json_data["Port"][encode_interface]["admin"] = "down" json_data.setdefault("Interface", {})[encode_interface] = { "name": interface, "user_config": { "admin": "down" } } if description is not None: encode_interface = interface.replace('/', '%2F') json_data["Interface"][encode_interface][ "description"] = description module.log(msg="Added interface with name='" + interface + "' description='" + description + "'") ''' Attaching IPv4 address to interface ''' if ipv4 is not None: json_data["Port"][encode_interface]["ip4_address"] = ipv4[0] if len(ipv4) > 2: json_data["Port"][encode_interface][ "ip4_address_secondary"] = [] for item in ipv4[1:]: json_data["Port"][encode_interface][ "ip4_address_secondary"].append(item) elif len(ipv4) == 2: json_data["Port"][encode_interface][ "ip4_address_secondary"] = ipv4[1] if encode_interface in json_data["System"]["bridge"][ "Bridge1"].setdefault("ports", []): json_data["System"]["bridge"]["Bridge1"]["ports"].remove( encode_interface) if "default" not in json_data["System"]["vrfs"].keys(): json_data["System"]["vrfs"]["default"] = { "name": "default", "ports": [encode_interface] } elif encode_interface not in json_data["System"]["vrfs"].get( "default", {}).get("ports", []): json_data["System"]["vrfs"]["default"]["ports"].append( encode_interface) module.log(msg='Attached IPv4 address ' + ''.join(ipv4) + ' to interface ' + interface) ''' Attaching IPv6 address to interface ''' if ipv6 is not None: if "ip6_addresses" in json_data["Port"][encode_interface].keys(): json_data["Port"][encode_interface]["ip6_addresses"] = {} for item in ipv6: json_data["Port"][encode_interface].setdefault("ip6_addresses", {})[item] =\ {"node_address": True, "preferred_lifetime": 604800, "ra_prefix": True, "type": "global-unicast", "valid_lifetime": 2592000} if encode_interface in json_data["System"]["bridge"]["Bridge1"][ "ports"]: json_data["System"]["bridge"]["Bridge1"]["ports"].remove( encode_interface) if "default" not in json_data["System"]["vrfs"].keys(): json_data["System"]["vrfs"]["default"] = { "name": "default", "ports": [encode_interface] } elif encode_interface not in json_data["System"]["vrfs"].get( "default", {}).get("ports", []): json_data["System"]["vrfs"]["default"]["ports"].append( encode_interface) module.log(msg='Attached IPv6 address ' + ' '.join(ipv6) + ' to interface ' + interface) ''' Adding QoS_rate to interface ''' if qos_rate is not None: for k, v in qos_rate.items(): number, unit = number_unit(v) json_data["Port"][encode_interface].setdefault( "rate_limits", {})[k] = number json_data["Port"][encode_interface].setdefault( "rate_limits", {})[k + '_units'] = unit module.log(msg='Applied QoS_rate ' + json.dumps(qos_rate) + ' to inteface ' + interface) ''' Attaching QoS_schedule_profile to interface ''' if qos_schedule_profile is not None: if "QoS" not in json_data.keys(): warnings.append('QoS_schedule_profile ' + qos_schedule_profile + ' does not exist on switch.') elif qos_schedule_profile not in json_data["QoS"].keys(): warnings.append('QoS_schedule_profile ' + qos_schedule_profile + ' does not exist on switch.') else: json_data["Port"][encode_interface][ "qos"] = qos_schedule_profile module.log(msg='Applied QoS_schedule_profile ' + qos_schedule_profile + ' to interface ' + interface) ''' Attaching ACL to interface ''' if (aclv6_in is not None) or (aclv4_in is not None) or ( aclmac_in is not None) or (aclv4_out is not None): if "aclv4_in_cfg" in json_data["Port"][encode_interface].keys(): json_data["Port"][encode_interface].pop("aclv4_in_cfg") json_data["Port"][encode_interface][ "aclv4_in_cfg_version"] = randint(-900719925474099, 900719925474099) if "aclv6_in_cfg" in json_data["Port"][encode_interface].keys(): json_data["Port"][encode_interface].pop("aclv6_in_cfg") json_data["Port"][encode_interface][ "aclv6_in_cfg_version"] = randint(-900719925474099, 900719925474099) if "aclmac_in_cfg" in json_data["Port"][encode_interface].keys(): json_data["Port"][encode_interface].pop("aclmac_in_cfg") json_data["Port"][encode_interface][ "aclmac_in_cfg_version"] = randint(-900719925474099, 900719925474099) if "aclv4_out_cfg" in json_data["Port"][encode_interface].keys(): json_data["Port"][encode_interface].pop("aclv4_out_cfg") json_data["Port"][encode_interface][ "aclv4_out_cfg_version"] = randint(-900719925474099, 900719925474099) if aclv4_in is not None: add_acl(aclv4_in, 'ipv4in', json_data, encode_interface, get_json, warnings) if aclv6_in is not None: add_acl(aclv6_in, 'ipv6in', json_data, encode_interface, get_json, warnings) if aclmac_in is not None: add_acl(aclmac_in, 'macin', json_data, encode_interface, get_json, warnings) if aclv4_out is not None: add_acl(aclv4_out, 'ipv4out', json_data, encode_interface, get_json, warnings) ''' Attaching interface to non-default VRF ''' if vrf is not None: if vrf not in json_data["System"]["vrfs"].keys(): warnings.append('VRF ' + vrf + ' does not exist on switch.') elif encode_interface not in json_data["System"]["vrfs"][vrf].get( "ports", []): json_data["System"]["vrfs"][vrf].setdefault( "ports", []).append(encode_interface) if vrf != 'default' and (encode_interface in json_data["System"]["vrfs"].get( "default", {}).get("ports", [])): json_data["System"]["vrfs"]["default"]["ports"].remove( encode_interface) if not json_data["System"]["vrfs"]["default"]["ports"]: json_data["System"]["vrfs"].pop("default") module.log(msg='Attached interface ' + interface + ' to VRF ' + vrf) elif encode_interface in json_data["System"]["vrfs"][vrf].get( "ports", []): if vrf != 'default' and (encode_interface in json_data["System"]["vrfs"].get( "default", {}).get("ports", [])): json_data["System"]["vrfs"]["default"]["ports"].remove( encode_interface) if not json_data["System"]["vrfs"]["default"]["ports"]: json_data["System"]["vrfs"].pop("default") ''' Attaching helper-address to interface ''' if ip_helper_address is not None: if (vrf is not None) and (vrf in json_data["System"]["vrfs"].keys()): vrf_dhcp = vrf else: vrf_dhcp = "default" dhcp_name = vrf_dhcp + "/" + encode_interface.replace( '%2F', '%252F') if len(ip_helper_address) <= 1: json_data.setdefault("DHCP_Relay", {})[dhcp_name] = { "ipv4_ucast_server": ip_helper_address[0], "port": encode_interface, "vrf": vrf_dhcp } else: json_data.setdefault("DHCP_Relay", {})[dhcp_name] = { "ipv4_ucast_server": [], "port": encode_interface, "vrf": vrf_dhcp } for item in ip_helper_address: json_data["DHCP_Relay"][dhcp_name][ "ipv4_ucast_server"].append(item) json_data["DHCP_Relay"][dhcp_name][ "ipv4_ucast_server"].sort() ''' Updating running config on remote switch ''' connection.put_running_config(json.dumps(json_data)) ''' Writing Debugging File ''' with open('/tmp/debugging_running_config.json', 'w') as to_file: json.dump(json_data, to_file, indent=4) to_file.write("\n") ''' Checking if change is idempotent ''' if get_json != json_data: result["changed"] = True else: module.log(msg="========Nothing Changed=========") module.exit_json(**result)
def main(): module_args = dict(vlan_id=dict(type='int', required=True), name=dict(type='str', default=None), description=dict(type='str', default=None), interfaces=dict(type='list', default=None), state=dict(default='present', choices=['present', 'absent'])) warnings = list() result = dict(changed=False, warnings=warnings) module = AnsibleModule(argument_spec=module_args, supports_check_mode=True) if module.check_mode: module.exit_json(changed=False) connection = Connection(module._socket_path) get_response = connection.get_running_config() module.log(msg=get_response) vid = module.params['vlan_id'] name = module.params['name'] description = module.params['description'] interfaces = module.params['interfaces'] state = module.params['state'] try: json_data = json.loads(get_response) except ValueError: module.fail_json(msg=get_response) get_json = json.loads(get_response) ''' Deleting VLAN ''' if state == 'absent': if "vlans" in json_data["System"]["bridge"]["Bridge1"].keys(): if str(vid) in json_data["System"]["bridge"]["Bridge1"]["vlans"]\ .keys(): json_data["System"]["bridge"]["Bridge1"]["vlans"].pop(str(vid)) for item in json_data["Port"].values(): for v in item.values(): if v == str(vid): item.pop("vlan_tag") else: warnings.append("VLAN " + str(vid) + " has already been removed") warnings.append("All VLANs have already been removed") ''' Adding new VLAN ''' if state == "present": if "vlans" not in json_data["System"]["bridge"]["Bridge1"].keys(): json_data["System"]["bridge"]["Bridge1"]["vlans"] = {} if str(vid) in json_data["System"]["bridge"]["Bridge1"]["vlans"].keys( ): module.log("VLAN " + str(vid) + " already exist.") if name is not None: json_data["System"]["bridge"]["Bridge1"]["vlans"][str(vid)] = \ {"admin": "up", "id": vid, "type": "static", "name": name} module.log(msg="Added VLAN " + str(vid) + " with name: " + name) else: json_data["System"]["bridge"]["Bridge1"]["vlans"][str(vid)] = \ {"admin": "up", "id": vid, "type": "static", "name": "VLAN" + str(vid)} module.log(msg="Added VLAN " + str(vid) + " with name: " + "VLAN" + str(vid)) if description is not None: json_data["System"]["bridge"]["Bridge1"]["vlans"][str(vid)]["description"] = \ description module.log(msg="Added description " + description + " to VLAN " + str(vid)) ''' Attaching interface to VLAN ''' if interfaces is not None: ''' Removing interfaces that already attached to VLAN ''' for k, v in json_data.setdefault("Port", {}).items(): if "vlan_tag" in v.keys(): if (v["vlan_tag"] == str(vid)): json_data["Port"][k].pop("vlan_mode") json_data["Port"][k].pop("vlan_tag") ''' Adding interfaces to VLAN ''' for item in interfaces: item = item.strip() if (len(item.encode('utf-8')) > 8) or (not bool( re.match('^[a-zA-Z0-9/]+$', item))): module.fail_json(msg='Interface ' + item + ' is not valid.') encode_interface = item.replace('/', '%2F') if encode_interface not in json_data["Port"]: json_data["Port"][encode_interface] = {} json_data["Port"][encode_interface]["interfaces"] = [ encode_interface ] json_data["Port"][encode_interface]["name"] = item json_data["Port"][encode_interface]["vlan_mode"] = "access" json_data["Port"][encode_interface]["vlan_tag"] = str(vid) if encode_interface not in json_data["System"]["bridge"][ "Bridge1"].setdefault("ports", []): json_data["System"]["bridge"]["Bridge1"]["ports"].append( encode_interface) ''' Disable routing on interface ''' if encode_interface in json_data["System"]["vrfs"].setdefault("default", {}).\ setdefault("ports", []): json_data["System"]["vrfs"]["default"]["ports"].remove( encode_interface) if not json_data["System"]["vrfs"]["default"]["ports"]: json_data["System"]["vrfs"].pop("default") ''' Checking if change is idempotent ''' if get_json != json_data: result["changed"] = True connection.put_running_config(json.dumps(json_data)) else: module.log("========No Change=========") ''' Writing debugging file ''' with open('/tmp/debugging_running_config.json', 'w') as to_file: json.dump(json_data, to_file, indent=4) to_file.write("\n") module.exit_json(**result)