Example #1
0
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)
Example #3
0
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)