Beispiel #1
0
def _delete_ipv6_address(port_name, ip, **kwargs):
    """
    Perform a DELETE call to remove an IPv6 address from an Interface.

    :param port_name: Alphanumeric Interface name
    :param ip: IPv6 address assigned to the interface that will be removed.
    :param kwargs:
        keyword s: requests.session object with loaded cookie jar
        keyword url: URL in main() function
    :return: Nothing
    """
    if ip in interface.get_ipv6_addresses(port_name, **kwargs):
        port_name_percents = common_ops._replace_special_characters(port_name)
        ip_address = common_ops._replace_special_characters(ip)
        target_url = kwargs["url"] + "system/interfaces/%s/ip6_addresses/%s" % (
            port_name_percents, ip_address)

        response = kwargs["s"].delete(target_url, verify=False)

        if not common_ops._response_ok(response, "DELETE"):
            print(
                "FAIL: Deleting IPv6 Address '%s' from Port table entry '%s' failed with status code %d"
                % (ip, port_name, response.status_code))
        else:
            print(
                "SUCCESS: Deleting IPv6 Address '%s' from Port table entry '%s' succeeded"
                % (ip, port_name))
    else:
        print(
            "SUCCESS: No need to delete IPv6 Address '%s' from Port table entry '%s' since it does not exist"
            % (ip, port_name))
Beispiel #2
0
def _clear_port_acl_in(port_name, list_type, **kwargs):
    """
    Perform GET and PUT calls to clear a Port's Ingress ACL

    :param port_name: Alphanumeric name of the Port
    :param kwargs:
        keyword s: requests.session object with loaded cookie jar
        keyword url: URL in main() function
    :return: Nothing
    """
    port_name_percents = common_ops._replace_special_characters(port_name)

    port_data = interface.get_interface(port_name,
                                        depth=1,
                                        selector="writable",
                                        **kwargs)
    if list_type is "ipv6":
        port_data.pop('aclv6_in_cfg', None)
        port_data.pop('aclv6_in_cfg_version', None)
    elif list_type is "ipv4":
        port_data.pop('aclv4_in_cfg', None)
        port_data.pop('aclv4_in_cfg_version', None)

    target_url = kwargs["url"] + "system/interface/%s" % port_name_percents
    put_data = json.dumps(port_data, sort_keys=True, indent=4)
    response = kwargs["s"].put(target_url, data=put_data, verify=False)

    if not common_ops._response_ok(response, "PUT"):
        print(
            "FAIL: Clearing %s Ingress ACL on Port '%s' failed with status code %d"
            % (list_type, port_name, response.status_code))
    else:
        print("SUCCESS: Clearing %s Ingress ACL on Port '%s' succeeded" %
              (list_type, port_name))
def _update_port_loop_protect(interface_name, action="", vlan_list=[], **kwargs):
    """
    Perform GET and PUT calls to apply Loop-protect options on an interface.  Note that Loop-protect requires that
    the interface is L2, so this function will also update the interface to reflect that.

    :param interface_name: Alphanumeric String that is the name of the interface that will apply loop-protect options
    :param action: Alphanumeric String that will specify the actions for the Loop-protect interface.  The options are
        "do-not-disable", "tx-disable", "tx-rx-disable", or None.
    :param vlan_list: List of VLANs that will be configured for Loop-protect on the interface
    :param kwargs:
        keyword s: requests.session object with loaded cookie jar
        keyword url: URL in main() function
    :return: Nothing
    """
    int_name_percents = common_ops._replace_special_characters(interface_name)
    int_data = interface.get_interface(int_name_percents, depth=1, selector="writable", **kwargs)

    if interface_name.startswith('lag'):
        if int_data['interfaces']:
            int_data['interfaces'] = common_ops._dictionary_to_list_values(int_data['interfaces'])

    if int_data['vlan_trunks']:
        int_data['vlan_trunks'] = common_ops._dictionary_to_list_values(int_data['vlan_trunks'])
    if int_data['loop_protect_vlan']:
        int_data['loop_protect_vlan'] = common_ops._dictionary_to_list_values(int_data['loop_protect_vlan'])

    int_data['loop_protect_enable'] = True
    # make interface L2
    int_data['routing'] = False

    # strings appended to output prints for status
    action_output = ""
    vlan_output = ""

    if action not in ['do-not-disable', 'tx-disable', 'tx-rx-disable', None]:
        raise Exception("ERROR: Action should be 'do-not-disable', 'tx-disable', 'tx-rx-disable' or None")
    elif action:
        int_data['loop_protect_action'] = action
        action_output = " with Action %s " % action

    if vlan_list:
        vlan_output = " with VLAN(s) ["
        for vlan in vlan_list:
            vlan_url = "/rest/v10.04/system/vlans/%s" % vlan
            if vlan_url not in int_data['loop_protect_vlan']:
                int_data['loop_protect_vlan'].append(vlan_url)
                vlan_output += (str(vlan) + " ")
        vlan_output += "] "

    target_url = kwargs["url"] + "system/interfaces/%s" % int_name_percents
    put_data = json.dumps(int_data, sort_keys=True, indent=4)

    response = kwargs["s"].put(target_url, data=put_data, verify=False)

    if not common_ops._response_ok(response, "PUT"):
        print("FAIL: Applying Loop-protect to Interface '%s'%s%s failed with status code %d"
              % (interface_name, action_output, vlan_output, response.status_code))
    else:
        print("SUCCESS: Applying Loop-protect to Interface '%s'%s%s succeeded"
              % (interface_name, action_output, vlan_output))
Beispiel #4
0
def delete_port(port_name, **kwargs):
    """
    Perform a DELETE call to delete a Port table entry.

    :param port_name: Port table entry name
    :param kwargs:
        keyword s: requests.session object with loaded cookie jar
        keyword url: URL in main() function
    :return: Nothing
    """

    port_name_percents = common_ops._replace_special_characters(port_name)

    ports_list = get_all_ports(**kwargs)

    if "/rest/v1/system/ports/%s" % port_name_percents in ports_list:

        target_url = kwargs["url"] + "system/ports/%s" % port_name_percents

        response = kwargs["s"].delete(target_url, verify=False)

        if not common_ops._response_ok(response, "DELETE"):
            print("FAIL: Deleting Port '%s' failed with status code %d" %
                  (port_name, response.status_code))
        else:
            print("SUCCESS: Deleting Port '%s' succeeded" % port_name)
    else:
        print("SUCCESS: No need to remove  Port '%s' since it doesn't exist" %
              port_name)
def _clear_port_loop_protect_v1(port_name, **kwargs):
    """
    Perform GET and PUT calls to clear a Port's Loop-protect settings

    :param port_name: Alphanumeric name of the Port
    :param kwargs:
        keyword s: requests.session object with loaded cookie jar
        keyword url: URL in main() function
    :return: Nothing
    """
    port_name_percents = common_ops._replace_special_characters(port_name)

    port_data = port.get_port(port_name, depth=0, selector="configuration", **kwargs)

    port_data.pop('loop_protect_enable', None)
    port_data.pop('loop_protect_action', None)
    port_data['loop_protect_vlan'] = []

    # must remove these fields from the data since they can't be modified
    port_data.pop('name', None)
    port_data.pop('origin', None)

    target_url = kwargs["url"] + "system/ports/%s" % port_name_percents
    put_data = json.dumps(port_data, sort_keys=True, indent=4)

    response = kwargs["s"].put(target_url, data=put_data, verify=False)

    if not common_ops._response_ok(response, "PUT"):
        print("FAIL: Clearing Loop-protect options on Port '%s' failed with status code %d"
              % (port_name, response.status_code))
    else:
        print("SUCCESS: Clearing the Loop-protect options on Port '%s' succeeded"
              % (port_name))
Beispiel #6
0
def add_l2_port(port_name, port_desc=None, port_admin_state="up", **kwargs):
    """
    Perform a POST call to create a Port table entry for physical L2 interface.  If the Port table entry exists, this
    function will perform a PUT call to update the entry with the given parameters.

    :param port_name: Alphanumeric Port name
    :param port_desc: Optional description for the interface. Defaults to nothing if not specified.
    :param port_admin_state: Optional administratively-configured state of the port.
        Defaults to "up" if not specified
    :param kwargs:
        keyword s: requests.session object with loaded cookie jar
        keyword url: URL in main() function
    :return: Nothing
    """
    ports_list = get_all_ports(**kwargs)

    port_name_percents = common_ops._replace_special_characters(port_name)
    port_data = {
        "admin": port_admin_state,
        "interfaces": ["/rest/v1/system/interfaces/%s" % port_name_percents],
        "name": port_name,
        "routing": False
    }

    if port_desc is not None:
        port_data['description'] = port_desc

    if "/rest/v1/system/ports/%s" % port_name_percents not in ports_list:
        target_url = kwargs["url"] + "system/ports"
        payload_data = json.dumps(port_data, sort_keys=True, indent=4)
        response = kwargs["s"].post(target_url,
                                    data=payload_data,
                                    verify=False)

        if not common_ops._response_ok(response, "POST"):
            print(
                "FAIL: Adding Port table entry '%s' failed with status code %d"
                % (port_name, response.status_code))
        else:
            print("SUCCESS: Adding Port table entry '%s' succeeded" %
                  port_name)
    else:
        target_url = kwargs["url"] + "system/ports/%s" % port_name_percents
        port_data.pop(
            'name', None
        )  # must remove this item from the json since name can't be modified
        payload_data = json.dumps(port_data, sort_keys=True, indent=4)
        response = kwargs["s"].put(target_url, data=payload_data, verify=False)

        if not common_ops._response_ok(response, "PUT"):
            print(
                "FAIL: Updating Port table entry '%s' failed with status code %d"
                % (port_name, response.status_code))
        else:
            print("SUCCESS: Updating Port table entry '%s' succeeded" %
                  port_name)
Beispiel #7
0
def add_l3_ipv4_port(port_name,
                     ip_address=None,
                     port_desc=None,
                     port_admin_state="up",
                     vrf="default",
                     **kwargs):
    """
    Perform a POST call to create a Port table entry for a physical L3 interface. If the port already exists, the
    function will enable routing on the port and update the IPv4 address if given.

    :param port_name: Alphanumeric Port name
    :param ip_address: IPv4 address to assign to the interface. Defaults to nothing if not specified.
    :param port_desc: Optional description for the interface. Defaults to nothing if not specified.
    :param port_admin_state: Optional administratively-configured state of the port.
        Defaults to "up" if not specified
    :param vrf: Name of the VRF to which the Port belongs. Defaults to "default" if not specified.
    :param kwargs:
        keyword s: requests.session object with loaded cookie jar
        keyword url: URL in main() function
    :return: Nothing
    """
    ports_list = get_all_ports(**kwargs)

    port_name_percents = common_ops._replace_special_characters(port_name)

    port_data = {
        "admin": port_admin_state,
        "interfaces": ["/rest/v1/system/interfaces/%s" % port_name_percents],
        "name": port_name,
        "routing": True,
        "vrf": "/rest/v1/system/vrfs/%s" % vrf
    }

    if port_desc is not None:
        port_data['description'] = port_desc

    if ip_address is not None:
        port_data['ip4_address'] = ip_address

    if "/rest/v1/system/ports/%s" % port_name_percents not in ports_list:
        target_url = kwargs["url"] + "system/ports"
        payload_data = json.dumps(port_data, sort_keys=True, indent=4)
        response = kwargs["s"].post(target_url,
                                    data=payload_data,
                                    verify=False)

        if not common_ops._response_ok(response, "POST"):
            print(
                "FAIL: Adding IPv4 Port table entry '%s' failed with status code %d"
                % (port_name, response.status_code))
        else:
            print("SUCCESS: Adding IPv4 Port table entry '%s' succeeded" %
                  port_name)
    else:
        update_port_ipv4(port_name, ip_address, port_admin_state, vrf,
                         **kwargs)
Beispiel #8
0
def _update_port_acl_in_v1(interface_name, acl_name, list_type, **kwargs):
    """
    Perform GET and PUT calls to apply ACL on an interface. This function specifically applies an ACL
    to Ingress traffic of the interface

    :param interface_name: Alphanumeric String that is the name of the interface on which the ACL
        is applied to
    :param acl_name: Alphanumeric String that is the name of the ACL
    :param list_type: Alphanumeric String of ipv4 or ipv6 to specify the type of ACL
    :param kwargs:
        keyword s: requests.session object with loaded cookie jar
        keyword url: URL in main() function
    :return: Nothing
    """
    port_name_percents = common_ops._replace_special_characters(interface_name)

    port_data = port.get_port(port_name_percents,
                              depth=0,
                              selector="configuration",
                              **kwargs)

    # must remove these fields from the data since they can't be modified
    port_data.pop('name', None)
    port_data.pop('origin', None)

    acl_url = "/rest/v1/system/acls/%s/%s" % (acl_name, list_type)

    if list_type is "ipv6":
        port_data['aclv6_in_cfg'] = acl_url
        port_data['aclv6_in_cfg_version'] = random.randint(
            -9007199254740991, 9007199254740991)
    elif list_type is "ipv4":
        port_data['aclv4_in_cfg'] = acl_url
        port_data['aclv4_in_cfg_version'] = random.randint(
            -9007199254740991, 9007199254740991)

    target_url = kwargs["url"] + "system/ports/%s" % port_name_percents
    put_data = json.dumps(port_data, sort_keys=True, indent=4)

    response = kwargs["s"].put(target_url, data=put_data, verify=False)

    if not common_ops._response_ok(response, "PUT"):
        print(
            "FAIL: Applying ACL '%s' to Ingress of Interface '%s' failed with status code %d"
            % (acl_name, interface_name, response.status_code))
    else:
        print(
            "SUCCESS: Applying ACL '%s' to Ingress of Interface '%s' succeeded"
            % (acl_name, interface_name))
Beispiel #9
0
def _enable_disable_port(port_name, state="up", **kwargs):
    """
    Perform GET and PUT calls to either enable or disable the port by setting Port's admin state to
        "up" or "down"

    :param port_name: Alphanumeric name of the interface
    :param state: State to set the interface to
    :param kwargs:
        keyword s: requests.session object with loaded cookie jar
        keyword url: URL in main() function
    :return: Nothing
    """
    if state not in ['up', 'down']:
        raise Exception(
            "Administratively-configured state of interface should be 'up' or 'down'"
        )

    port_name_percents = common_ops._replace_special_characters(port_name)

    port_data = get_port(port_name,
                         depth=0,
                         selector="configuration",
                         **kwargs)

    if port_data:
        port_data['admin'] = state

        port_data.pop('name', None)
        port_data.pop('origin', None)

        target_url = kwargs["url"] + "system/ports/%s" % port_name_percents
        put_data = json.dumps(port_data, sort_keys=True, indent=4)

        response = kwargs["s"].put(target_url, data=put_data, verify=False)

        if not common_ops._response_ok(response, "PUT"):
            print("FAIL: Updating Port '%s' with admin-configured state '%s' "
                  "failed with status code %d" %
                  (port_name, state, response.status_code))
        else:
            print(
                "SUCCESS: Updating Port '%s' with admin-configured state '%s' "
                "succeeded" % (port_name, state))
    else:
        print(
            "Unable to update Port '%s' because operation could not find existing Port"
            % port_name)
Beispiel #10
0
def _update_port_acl_in(interface_name, acl_name, list_type, **kwargs):
    """
    Perform GET and PUT calls to apply ACL on an interface. This function specifically applies an ACL
    to Ingress traffic of the interface.  This function's minimum supported version is v10.04 and later

    :param interface_name: Alphanumeric name of the interface on which the ACL is applied to
    :param acl_name: Alphanumeric name of the ACL
    :param kwargs:
        keyword s: requests.session object with loaded cookie jar
        keyword url: URL in main() function
    :return: Nothing
    """
    int_name_percents = common_ops._replace_special_characters(interface_name)
    int_data = interface.get_interface(int_name_percents,
                                       depth=1,
                                       selector="writable",
                                       **kwargs)

    acl_key = "{},{}".format(acl_name, list_type)
    acl_value = kwargs["url"] + "system/acls/" + acl_key

    if interface_name.startswith('lag'):
        if int_data['interfaces']:
            int_data['interfaces'] = common_ops._dictionary_to_list_values(
                int_data['interfaces'])

    if list_type is "ipv6":
        int_data['aclv6_in_cfg'] = {acl_key: acl_value}
        int_data['aclv6_in_cfg_version'] = random.randint(
            -9007199254740991, 9007199254740991)
    elif list_type is "ipv4":
        int_data['aclv4_in_cfg'] = {acl_key: acl_value}
        int_data['aclv4_in_cfg_version'] = random.randint(
            -9007199254740991, 9007199254740991)

    target_url = kwargs["url"] + "system/interfaces/%s" % int_name_percents
    put_data = json.dumps(int_data, sort_keys=True, indent=4)

    response = kwargs["s"].put(target_url, data=put_data, verify=False)

    if not common_ops._response_ok(response, "PUT"):
        print(
            "FAIL: Updating ACL %s on Ingress for Port '%s' failed with status code %d"
            % (acl_name, interface_name, response.status_code))
    else:
        print("SUCCESS: Updating ACL %s on Ingress for Port '%s' succeeded" %
              (acl_name, interface_name))
Beispiel #11
0
def update_port_ipv4(port_name, ipv4, port_admin_state, vrf, **kwargs):
    """
    Perform GET and PUT calls to update an L3 interface's ipv4 address

    :param port_name: Alphanumeric name of the Port
    :param ipv4: IPv4 address to associate with the VLAN Port
    :param port_admin_state: Administratively-configured state of the port.
    :param vrf: Name of the VRF to which the Port belongs.
    :param kwargs:
        keyword s: requests.session object with loaded cookie jar
        keyword url: URL in main() function
    :return: Nothing
    """
    port_name_percents = common_ops._replace_special_characters(port_name)
    port_data = get_port(port_name,
                         depth=0,
                         selector="configuration",
                         **kwargs)

    port_data['ip4_address'] = ipv4
    port_data['routing'] = True
    port_data['admin'] = port_admin_state
    port_data['vrf'] = "/rest/v1/system/vrfs/%s" % vrf

    port_data.pop(
        'name', None
    )  # must remove this item from the json since name can't be modified
    port_data.pop(
        'origin', None
    )  # must remove this item from the json since origin can't be modified

    target_url = kwargs["url"] + "system/ports/%s" % port_name_percents
    put_data = json.dumps(port_data, sort_keys=True, indent=4)

    response = kwargs["s"].put(target_url, data=put_data, verify=False)

    if not common_ops._response_ok(response, "PUT"):
        print(
            "FAIL: Updating IPv4 addresses for Port '%s' to '%s' failed with status code %d"
            % (port_name, repr(ipv4), response.status_code))
    else:
        print(
            "SUCCESS: Updating IPv4 addresses for Port '%s' to '%s' succeeded"
            % (port_name, repr(ipv4)))
Beispiel #12
0
def _port_set_vlan_mode(l2_port_name, vlan_mode, **kwargs):
    """
    Perform GET and PUT calls to set an L2 interface's VLAN mode (native-tagged, native-untagged, or access)

    :param l2_port_name: L2 interface's Port table entry name
    :param vlan_mode: A string, either 'native-tagged', 'native-untagged', or 'access', specifying the desired VLAN
        mode
    :param kwargs:
        keyword s: requests.session object with loaded cookie jar
        keyword url: URL in main() function
    :return: Nothing
    """

    if vlan_mode not in ['native-tagged', 'native-untagged', 'access']:
        raise Exception(
            "ERROR: VLAN mode should be 'native-tagged', 'native-untagged', or 'access'"
        )

    l2_port_name_percents = common_ops._replace_special_characters(
        l2_port_name)
    port_data = get_port(l2_port_name_percents,
                         depth=0,
                         selector="configuration",
                         **kwargs)

    port_data.pop('name', None)
    port_data.pop('origin', None)
    port_data.pop('vrf', None)

    port_data['vlan_mode'] = vlan_mode
    port_data['routing'] = False

    target_url = kwargs["url"] + "system/ports/%s" % l2_port_name_percents
    put_data = json.dumps(port_data, sort_keys=True, indent=4)

    response = kwargs["s"].put(target_url, data=put_data, verify=False)

    if not common_ops._response_ok(response, "PUT"):
        print(
            "FAIL: Setting port '%s' VLAN mode to '%s' failed with status code %d"
            % (l2_port_name, vlan_mode, response.status_code))
    else:
        print("SUCCESS: Setting port '%s' VLAN mode to '%s' succeeded" %
              (l2_port_name, vlan_mode))
Beispiel #13
0
def _clear_port_acl_in_v1(port_name, list_type, **kwargs):
    """
    Perform GET and PUT calls to clear a Port's Ingress ACL

    :param port_name: Alphanumeric name of the Port
    :param kwargs:
        keyword s: requests.session object with loaded cookie jar
        keyword url: URL in main() function
    :return: Nothing
    """
    port_name_percents = common_ops._replace_special_characters(port_name)

    port_data = port.get_port(port_name,
                              depth=0,
                              selector="configuration",
                              **kwargs)

    if not port_data:
        print(
            "FAIL: Unable to clear %s Ingress ACL on Port '%s' because Port not found"
            % (list_type, port_name))
    else:
        if list_type is "ipv6":
            port_data.pop('aclv6_in_cfg', None)
            port_data.pop('aclv6_in_cfg_version', None)
        elif list_type is "ipv4":
            port_data.pop('aclv4_in_cfg', None)
            port_data.pop('aclv4_in_cfg_version', None)
        # must remove these fields from the data since they can't be modified
        port_data.pop('name', None)
        port_data.pop('origin', None)

        target_url = kwargs["url"] + "system/ports/%s" % port_name_percents
        put_data = json.dumps(port_data, sort_keys=True, indent=4)

        response = kwargs["s"].put(target_url, data=put_data, verify=False)

        if not common_ops._response_ok(response, "PUT"):
            print(
                "FAIL: Clearing %s Ingress ACL on Port '%s' failed with status code %d"
                % (list_type, port_name, response.status_code))
        else:
            print("SUCCESS: Clearing %s Ingress ACL on Port '%s' succeeded" %
                  (list_type, port_name))
Beispiel #14
0
def _clear_port_acl(port_name, acl_type="aclv4_out", **kwargs):
    """
    Perform GET and PUT calls to clear a Port's Ingress ACL

    :param port_name: Alphanumeric name of the Port
    :param acl_type: Type of ACL, options are between 'aclv4_out', 'aclv4_in', and 'aclv6_in'
    :param kwargs:
        keyword s: requests.session object with loaded cookie jar
        keyword url: URL in main() function
    :return: Nothing
    """
    if acl_type not in ['aclv4_out', 'aclv4_in', 'aclv6_in']:
        raise Exception(
            "ERROR: acl_type should be 'aclv4_out', 'aclv4_in', or 'aclv6_in'")

    port_name_percents = common_ops._replace_special_characters(port_name)

    port_data = get_port(port_name,
                         depth=0,
                         selector="configuration",
                         **kwargs)

    cfg_type = acl_type + '_cfg'
    cfg_version = acl_type + '_cfg_version'

    port_data.pop(cfg_type, None)
    port_data.pop(cfg_version, None)

    # must remove these fields from the data since they can't be modified
    port_data.pop('name', None)
    port_data.pop('origin', None)

    target_url = kwargs["url"] + "system/ports/%s" % port_name_percents
    put_data = json.dumps(port_data, sort_keys=True, indent=4)

    response = kwargs["s"].put(target_url, data=put_data, verify=False)

    if not common_ops._response_ok(response, "PUT"):
        print("FAIL: Clearing %s ACL on Port '%s' failed with status code %d" %
              (cfg_type, port_name, response.status_code))
    else:
        print("SUCCESS: Clearing %s ACL on Port '%s' succeeded" %
              (cfg_type, port_name))
Beispiel #15
0
def _port_set_untagged_vlan(l2_port_name, vlan_id, **kwargs):
    """
    Perform GET and PUT/POST calls to set a VLAN on an access port

    :param l2_port_name: L2 interface's Port table entry name
    :param vlan_id: Numeric ID of VLAN to set on access port
    :param kwargs:
        keyword s: requests.session object with loaded cookie jar
        keyword url: URL in main() function
    :return: Nothing
    """

    l2_port_name_percents = common_ops._replace_special_characters(
        l2_port_name)

    port_data = get_port(l2_port_name_percents,
                         depth=0,
                         selector="configuration",
                         **kwargs)

    port_data.pop('name', None)
    port_data.pop('origin', None)
    port_data.pop('vrf', None)

    port_data['vlan_mode'] = "access"
    port_data['vlan_tag'] = "/rest/v1/system/vlans/%s" % vlan_id
    port_data['routing'] = False

    target_url = kwargs["url"] + "system/ports/%s" % l2_port_name_percents
    put_data = json.dumps(port_data, sort_keys=True, indent=4)

    response = kwargs["s"].put(target_url, data=put_data, verify=False)

    if not (common_ops._response_ok(response, "PUT")
            or common_ops._response_ok(response, "POST")):
        print(
            "FAIL: Setting Port '%s' access VLAN to VLAN ID '%d' failed with status code %d"
            % (l2_port_name, vlan_id, response.status_code))
    else:
        print(
            "SUCCESS: Setting Port '%s' access VLAN to VLAN ID '%d' succeeded"
            % (l2_port_name, vlan_id))
Beispiel #16
0
def update_port_ipv6(port_name,
                     ip_address,
                     addr_type="global-unicast",
                     **kwargs):
    """
    Perform a POST call to create an IPv6 address entry to update an L3 interface's ipv6 address

    :param port_name: Alphanumeric name of the Port
    :param ipv6: IPv6 address to associate with the Port
    :param addr_type: Type of IPv6 address. Defaults to "global-unicast" if not specified.
    :param kwargs:
        keyword s: requests.session object with loaded cookie jar
        keyword url: URL in main() function
    :return: Nothing
    """
    port_name_percents = common_ops._replace_special_characters(port_name)
    ipv6_data = {
        "address": ip_address,
        "node_address": True,
        "origin": "configuration",
        "ra_prefix": True,
        "route_tag": 0,
        "type": addr_type
    }

    target_url = kwargs[
        "url"] + "system/ports/%s/ip6_addresses" % port_name_percents
    post_data = json.dumps(ipv6_data, sort_keys=True, indent=4)

    response = kwargs["s"].post(target_url, data=post_data, verify=False)

    if not common_ops._response_ok(response, "POST"):
        print(
            "FAIL: Creating IPv6 address to update Port '%s' to '%s' failed with status code %d"
            % (port_name, ip_address, response.status_code))
    else:
        print(
            "SUCCESS: Creating IPv6 address to update Port '%s' to '%s' succeeded"
            % (port_name, ip_address))
Beispiel #17
0
def _delete_vlan_port(l2_port_name, vlan_id, **kwargs):
    """
    Perform GET and PUT calls to remove a VLAN from a trunk port

    :param l2_port_name: L2 interface's Port table entry name
    :param vlan_id: Numeric ID of VLAN to remove from trunk port
    :param kwargs:
        keyword s: requests.session object with loaded cookie jar
        keyword url: URL in main() function
    :return: Nothing
    """
    l2_port_name_percents = common_ops._replace_special_characters(
        l2_port_name)

    port_data = get_port(l2_port_name,
                         depth=0,
                         selector="configuration",
                         **kwargs)

    port_data.pop('name', None)
    port_data.pop('origin', None)
    port_data.pop('vrf', None)

    if "/rest/v1/system/vlans/%s" % vlan_id in port_data['vlan_trunks']:
        # remove vlan from 'vlan_trunks'
        port_data['vlan_trunks'].remove("/rest/v1/system/vlans/%s" % vlan_id)

    target_url = kwargs["url"] + "system/ports/%s" % l2_port_name_percents
    put_data = json.dumps(port_data, sort_keys=True, indent=4)

    response = kwargs["s"].put(target_url, data=put_data, verify=False)

    if not common_ops._response_ok(response, "PUT"):
        print(
            "FAIL: Removing VLAN ID '%d' from Port '%s' trunk failed with status code %d"
            % (vlan_id, l2_port_name, response.status_code))
    else:
        print("SUCCESS: Removing VLAN ID '%d' from Port '%s' trunk succeeded" %
              (vlan_id, l2_port_name))
Beispiel #18
0
def _update_port_acl_out(interface_name, acl_name, **kwargs):
    """
    Perform GET and PUT calls to apply ACL on an interface. This function specifically applies an ACL
    to Egress traffic of the interface, which must be a routing interface.  This function will set the interface
    to enable routing.

    :param interface_name: Alphanumeric name of the interface on which the ACL is applied to
    :param acl_name: Alphanumeric name of the ACL
    :param kwargs:
        keyword s: requests.session object with loaded cookie jar
        keyword url: URL in main() function
    :return: Nothing
    """
    port_name_percents = common_ops._replace_special_characters(interface_name)
    port_data = interface.get_interface(port_name_percents,
                                        depth=1,
                                        selector="writable",
                                        **kwargs)

    acl_key = "{},ipv4".format(acl_name)
    acl_value = kwargs["url"] + "system/acls/" + acl_key
    port_data['aclv4_out_cfg'] = {acl_key: acl_value}
    port_data['aclv4_out_cfg_version'] = random.randint(
        -9007199254740991, 9007199254740991)
    port_data['routing'] = True

    target_url = kwargs["url"] + "system/interfaces/%s" % port_name_percents
    put_data = json.dumps(port_data, sort_keys=True, indent=4)

    response = kwargs["s"].put(target_url, data=put_data, verify=False)

    if not common_ops._response_ok(response, "PUT"):
        print(
            "FAIL: Applying ACL '%s' to Egress on Interface '%s' failed with status code %d"
            % (acl_name, interface_name, response.status_code))
    else:
        print(
            "SUCCESS: Applying ACL '%s' to Egress on Interface '%s' succeeded"
            % (acl_name, interface_name))
Beispiel #19
0
def _get_port(port_name, depth=0, selector=None, **kwargs):
    """
    Perform a GET call to retrieve data for a Port table entry

    :param port_name: Alphanumeric name of the port
    :param kwargs:
        keyword s: requests.session object with loaded cookie jar
        keyword url: URL in main() function
    :return: Dictionary containing port data
    """
    if selector not in [
            'configuration', 'status', 'statistics', 'writable', None
    ]:
        raise Exception(
            "ERROR: Selector should be 'configuration', 'status', 'statistics', or 'writable'"
        )

    payload = {"depth": depth, "selector": selector}

    port_name_percents = common_ops._replace_special_characters(port_name)

    target_url = kwargs["url"] + "system/ports/%s" % port_name_percents
    response = kwargs["s"].get(target_url,
                               verify=False,
                               params=payload,
                               timeout=2)

    port_name = common_ops._replace_percents(port_name_percents)
    if not common_ops._response_ok(response, "GET"):
        print(
            "FAIL: Getting Port table entry '%s' failed with status code %d" %
            (port_name, response.status_code))
        output = {}
    else:
        print("SUCCESS: Getting Port table entry '%s' succeeded" % port_name)
        output = response.json()

    return output
Beispiel #20
0
def initialize_port_entry(port_name, **kwargs):
    """
    Perform a PUT call on the Port to initialize it to it's default state, then initialize the Interface entry.

    :param port_name: Alphanumeric name of the system port
    :param kwargs:
        keyword s: requests.session object with loaded cookie jar
        keyword url: URL in main() function
    :return: Nothing
    """
    port_name_percents = common_ops._replace_special_characters(port_name)
    port_data = {}
    target_url = kwargs["url"] + "system/ports/%s" % port_name_percents
    put_data = json.dumps(port_data, sort_keys=True, indent=4)

    response = kwargs["s"].put(target_url, data=put_data, verify=False)

    if not common_ops._response_ok(response, "PUT"):
        print("FAIL: Initializing port '%s' failed with status code %d" %
              (port_name, response.status_code))
    else:
        print("SUCCESS: Initializing port '%s' succeeded" % port_name)
        interface.initialize_interface_entry(port_name, **kwargs)
def _clear_port_loop_protect(interface_name, **kwargs):
    """
    Perform GET and PUT calls to clear an Interface's Loop-protect settings

    :param interface_name: Alphanumeric name of the Interface
    :param kwargs:
        keyword s: requests.session object with loaded cookie jar
        keyword url: URL in main() function
    :return: Nothing
    """
    int_name_percents = common_ops._replace_special_characters(interface_name)

    int_data = interface.get_interface(interface_name, depth=1, selector="writable", **kwargs)

    if interface_name.startswith('lag'):
        if int_data['interfaces']:
            int_data['interfaces'] = common_ops._dictionary_to_list_values(int_data['interfaces'])

    if int_data['vlan_trunks']:
        int_data['vlan_trunks'] = common_ops._dictionary_to_list_values(int_data['vlan_trunks'])

    int_data['loop_protect_enable'] = None
    int_data['loop_protect_action'] = "tx-disable"
    int_data['loop_protect_vlan'] = []

    target_url = kwargs["url"] + "system/interfaces/%s" % int_name_percents
    put_data = json.dumps(int_data, sort_keys=True, indent=4)

    response = kwargs["s"].put(target_url, data=put_data, verify=False)

    if not common_ops._response_ok(response, "PUT"):
        print("FAIL: Clearing Loop-protect options on Interface '%s' failed with status code %d"
              % (interface_name, response.status_code))
    else:
        print("SUCCESS: Clearing the Loop-protect options on Interface '%s' succeeded"
              % (interface_name))
Beispiel #22
0
def _port_set_native_vlan(l2_port_name, vlan_id, tagged=True, **kwargs):
    """
    Perform GET and PUT/POST calls to set a VLAN to be the native VLAN on the trunk. Also gives the option to set
    the VLAN as tagged.

    :param l2_port_name: L2 interface's Port table entry name
    :param vlan_id: Numeric ID of VLAN to add to trunk port
    :param tagged: Boolean to determine if the native VLAN will be set as the tagged VLAN.  If False, the VLAN
        will be set as the native untagged VLAN
    :param kwargs:
        keyword s: requests.session object with loaded cookie jar
        keyword url: URL in main() function
    :return: Nothing
    """
    if tagged:
        vlan_mode = "native-tagged"
    else:
        vlan_mode = "native-untagged"

    # need to create port resource for physical port if it doesn't exist
    ports_list = get_all_ports(**kwargs)
    l2_port_name_percents = common_ops._replace_special_characters(
        l2_port_name)

    if "/rest/v1/system/ports/%s" % l2_port_name_percents not in ports_list:
        # if Port table entry doesn't exist, create it
        port_data = {
            "name": l2_port_name,
            "interfaces":
            ["/rest/v1/system/interfaces/%s" % l2_port_name_percents],
            "vlan_mode": vlan_mode,
            "vlan_tag": "/rest/v1/system/vlans/%s" % vlan_id,
            "vlan_trunks": [],
            "routing": False
        }

        target_url = kwargs["url"] + "system/ports"
        post_data = json.dumps(port_data, sort_keys=True, indent=4)

        response = kwargs["s"].post(target_url, data=post_data, verify=False)

    else:
        # otherwise just update the physical port
        port_data = get_port(l2_port_name_percents,
                             depth=0,
                             selector="configuration",
                             **kwargs)

        port_data.pop('name', None)
        port_data.pop('origin', None)
        port_data.pop('vrf', None)

        port_data['vlan_tag'] = "/rest/v1/system/vlans/%s" % vlan_id
        port_data['routing'] = False
        port_data['vlan_mode'] = vlan_mode

        if (port_data['vlan_trunks']) and ("/rest/v1/system/vlans/%s" % vlan_id
                                           not in port_data['vlan_trunks']):
            port_data['vlan_trunks'].append("/rest/v1/system/vlans/%s" %
                                            vlan_id)

        target_url = kwargs["url"] + "system/ports/%s" % l2_port_name_percents
        put_data = json.dumps(port_data, sort_keys=True, indent=4)

        response = kwargs["s"].put(target_url, data=put_data, verify=False)

    if not (common_ops._response_ok(response, "PUT")
            or common_ops._response_ok(response, "POST")):
        print(
            "FAIL: Setting native VLAN ID '%d' to Port '%s' failed with status code %d"
            % (vlan_id, l2_port_name, response.status_code))
    else:
        print("SUCCESS: Setting native VLAN ID '%d' to Port '%s' succeeded" %
              (vlan_id, l2_port_name))
Beispiel #23
0
def _port_add_vlan_trunks(l2_port_name, vlan_trunk_ids=[], **kwargs):
    """
    Perform GET and PUT/POST calls to add specified VLANs to a trunk port. By default, this will also set the port to
    have 'no routing' and if there is not a native VLAN, will set the native VLAN to VLAN 1.

    :param l2_port_name: L2 interface's Port table entry name
    :param vlan_trunk_ids: List of VLANs to specify as allowed on the trunk port.  If empty, the interface will
        allow all VLANs on the trunk.
    :param kwargs:
        keyword s: requests.session object with loaded cookie jar
        keyword url: URL in main() function
    :return: Nothing
    """
    # need to create port resource for physical port if it doesn't exist
    ports_list = get_all_ports(**kwargs)
    l2_port_name_percents = common_ops._replace_special_characters(
        l2_port_name)

    trunk_list = []
    for x in vlan_trunk_ids:
        trunk_list.append("/rest/v1/system/vlans/%d" % x)

    if "/rest/v1/system/ports/%s" % l2_port_name_percents not in ports_list:
        # if Port table entry doesn't exist, create it
        port_data = {
            "name": l2_port_name,
            "interfaces":
            ["/rest/v1/system/interfaces/%s" % l2_port_name_percents],
            "vlan_mode": "native-untagged",
            "vlan_tag": "/rest/v1/system/vlans/1",
            "vlan_trunks": trunk_list,
            "routing": False
        }

        target_url = kwargs["url"] + "system/ports"
        post_data = json.dumps(port_data, sort_keys=True, indent=4)

        response = kwargs["s"].post(target_url, data=post_data, verify=False)

    else:
        # otherwise just update the physical port
        port_data = get_port(l2_port_name_percents,
                             depth=0,
                             selector="configuration",
                             **kwargs)

        port_data.pop('name', None)
        port_data.pop('origin', None)
        port_data.pop('vrf', None)

        if 'vlan_tag' not in port_data:
            port_data['vlan_tag'] = "/rest/v1/system/vlans/1"
        if 'vlan_mode' not in port_data:
            port_data['vlan_mode'] = "native-untagged"
        port_data['routing'] = False

        if not trunk_list:
            port_data['vlan_trunks'] = []
        else:
            for y in trunk_list:
                if y not in port_data['vlan_trunks']:
                    port_data['vlan_trunks'].append(y)

        target_url = kwargs["url"] + "system/ports/%s" % l2_port_name_percents
        put_data = json.dumps(port_data, sort_keys=True, indent=4)
        response = kwargs["s"].put(target_url, data=put_data, verify=False)

    if not (common_ops._response_ok(response, "PUT")
            or common_ops._response_ok(response, "POST")):
        print(
            "FAIL: Adding VLANs '%s' to Port '%s' trunk failed with status code %d"
            % (vlan_trunk_ids, l2_port_name, response.status_code))
    else:
        print("SUCCESS: Adding VLANs '%s' to Port '%s' trunk succeeded" %
              (vlan_trunk_ids, l2_port_name))
Beispiel #24
0
def _create_l2_lag_interface_v1(name, phys_ports, lacp_mode="passive", mc_lag=False, fallback_enabled=False,
                                vlan_ids_list=[], desc=None, admin_state="up", **kwargs):
    """
    Perform a POST call to create a Port table entry for L2 LAG interface.

    :param name: Alphanumeric name of LAG Port
    :param phys_ports: List of physical ports to aggregate (e.g. ["1/1/1", "1/1/2", "1/1/3"])
    :param lacp_mode: Should be either "passive" or "active." Defaults to "passive" if not specified.
    :param mc_lag: Boolean to determine if the LAG is multi-chassis. Defaults to False if not specified.
    :param fallback_enabled: Boolean to determine if the LAG uses LACP fallback. Defaults to False if not specified.
    :param vlan_ids_list: Optional list of integer VLAN IDs to add as trunk VLANS. Defaults to empty list if not specified.
    :param desc: Optional description for the interface. Defaults to nothing if not specified.
    :param admin_state: Optional administratively-configured state of the port.
        Defaults to "up" if not specified
    :param kwargs:
        keyword s: requests.session object with loaded cookie jar
        keyword url: URL in main() function
    :return: Nothing
    """
    ports_list = port.get_all_ports(**kwargs)

    port_name_percents = common_ops._replace_special_characters(name)
    if "/rest/v1/system/ports/%s" % port_name_percents not in ports_list:

        # Extract LAG ID from LAG name
        lag_id = int(re.search('\d+', name).group())

        # For each port, add LAG ID to the Interface table entry, and delete the Port table entry
        for phys_port in phys_ports:
            interface.add_port_to_lag(phys_port, lag_id, **kwargs)

        interfaces = ["/rest/v1/system/interfaces/%s" % common_ops._replace_special_characters(phys_port)
                      for phys_port in phys_ports]
        port_data = {"admin": admin_state,
                     "interfaces": interfaces,
                     "name": name,
                     "routing": False,
                     "vlan_trunks": ["/rest/v1/system/vlans/%d" % vlan_id for vlan_id in vlan_ids_list],
                     "lacp": lacp_mode,
                     "other_config": {
                         "mclag_enabled": mc_lag,
                         "lacp-fallback": fallback_enabled
                        },
                     "vlan_mode": "native-untagged",
                     "vlan_tag": "/rest/v1/system/vlans/1"
                     }

        if desc is not None:
            port_data['description'] = desc

        target_url = kwargs["url"] + "system/ports"
        post_data = json.dumps(port_data, sort_keys=True, indent=4)

        response = kwargs["s"].post(target_url, data=post_data, verify=False)

        if not common_ops._response_ok(response, "POST"):
            print("FAIL: Adding Port table entry '%s' failed with status code %d"
                  % (name, response.status_code))
        else:
            print("SUCCESS: Adding Port table entry '%s' succeeded" % name)

        return response.content
    else:
        print("SUCCESS: No need to add Port table entry '%s' because it already exists"
              % name)
Beispiel #25
0
def add_l3_ipv6_port(port_name,
                     ip_address=None,
                     port_desc=None,
                     port_admin_state="up",
                     vrf="default",
                     **kwargs):
    """
    Perform a POST call to create a Port table entry for a physical L3 interface. If the port already exists, the
    function will perform a PUT call to update the Port table entry to enable routing on the port and update
    the IPv6 address if given.

    :param port_name: Alphanumeric Port name
    :param ip_address: IPv6 address to assign to the interface. Defaults to nothing if not specified.
    :param port_desc: Optional description for the interface. Defaults to nothing if not specified.
    :param port_admin_state: Optional administratively-configured state of the port.
        Defaults to "up" if not specified
    :param vrf: Name of the VRF to which the Port belongs. Defaults to "default" if not specified.
    :param kwargs:
        keyword s: requests.session object with loaded cookie jar
        keyword url: URL in main() function
    :return: Nothing
    """
    ports_list = get_all_ports(**kwargs)

    port_name_percents = common_ops._replace_special_characters(port_name)

    port_data = {
        "admin": port_admin_state,
        "interfaces": ["/rest/v1/system/interfaces/%s" % port_name_percents],
        "name": port_name,
        "routing": True,
        "vrf": "/rest/v1/system/vrfs/%s" % vrf
    }

    if port_desc is not None:
        port_data['description'] = port_desc

    if "/rest/v1/system/ports/%s" % port_name_percents not in ports_list:
        target_url = kwargs["url"] + "system/ports"
        payload_data = json.dumps(port_data, sort_keys=True, indent=4)
        response = kwargs["s"].post(target_url,
                                    data=payload_data,
                                    verify=False)

        if not common_ops._response_ok(response, "POST"):
            print(
                "FAIL: Adding L3 IPv6 Port table entry '%s' failed with status code %d"
                % (port_name, response.status_code))
        else:
            print("SUCCESS: Adding L3 IPv6 Port table entry '%s' succeeded" %
                  port_name)
            # IPv6 defaults
            ipv6_data = {
                "address": ip_address,
                "node_address": True,
                "origin": "configuration",
                "ra_prefix": True,
                "route_tag": 0,
                "type": "global-unicast"
            }

            target_url = kwargs[
                "url"] + "system/interfaces/%s/ip6_addresses" % port_name_percents
            post_data = json.dumps(ipv6_data, sort_keys=True, indent=4)

            response = kwargs["s"].put(target_url,
                                       data=post_data,
                                       verify=False)
            if not common_ops._response_ok(response, "POST"):
                print(
                    "FAIL: Final configuration of L3 IPv6 Port table entry '%s' failed with status code %d"
                    % (port_name, response.status_code))
            else:
                print(
                    "SUCCESS: Final configuration of L3 IPv6 Port table entry '%s' succeeded"
                    % port_name)
    else:
        port_data.pop(
            'name', None
        )  # must remove this item from the json since name can't be modified
        target_url = kwargs["url"] + "system/ports/%s" % port_name_percents
        payload_data = json.dumps(port_data, sort_keys=True, indent=4)
        response = kwargs["s"].put(target_url, data=payload_data, verify=False)

        if not common_ops._response_ok(response, "PUT"):
            print(
                "FAIL: Updating L3 IPv6 Port table entry '%s' failed with status code %d"
                % (port_name, response.status_code))
        else:
            print("SUCCESS: Updating L3 IPv6 Port table entry '%s' succeeded" %
                  port_name)
            update_port_ipv6(port_name, ip_address, **kwargs)
Beispiel #26
0
def _create_vsx(role,
                isl_port,
                keepalive_peer,
                keepalive_src,
                keepalive_vrf,
                vsx_mac,
                keepalive_port=7678,
                **kwargs):
    """
    Perform a POST call to create VSX commands
    :param role: Alphanumeric role that the system will be in the VSX pair.  The options are "primary" or "secondary"
    :param isl_port: Alphanumeric name of the interface that will function as the inter-switch link
    :param keepalive_peer: Alphanumeric IP address of the VSX Peer that will be reached as the keepalive connection.
    :param keepalive_src: Alphanumeric IP address on the switch that will function as the keepalive connection source.
    :param keepalive_vrf: Alphanumeric name of the VRF that the keepalive connection will reside on.
    :param vsx_mac: Alphanumeric MAC address that will function as the VSX System MAC.
    :param kwargs:
        keyword s: requests.session object with loaded cookie jar
        keyword url: URL in main() function
    :return: Nothing
    """
    current_vsx = system.get_system_info(**kwargs)

    if 'vsx' in current_vsx:
        print(
            "FAIL: Creating VSX Role '%s' on vrf %s.  There is already an existing VSX setup."
            % (role, keepalive_vrf))
    else:
        if role not in ['primary', 'secondary']:
            raise Exception(
                "ERROR: VSX role should be 'primary' or 'secondary'")

        # Checks if the ISL Port is a physical interface or a Lag.  If an interface, replace the slashes
        if isl_port[0].isdigit():
            isl_port = common_ops._replace_special_characters(isl_port)

        isl_port_uri = "/rest/v10.04/system/interfaces/" + isl_port

        vsx_data = {
            "config_sync_disable": False,
            "config_sync_features": [],
            "device_role": role,
            "isl_port": {
                isl_port: isl_port_uri
            },
            "isl_timers": {
                "hello_interval": 1,
                "hold_time": 0,
                "peer_detect_interval": 300,
                "timeout": 20
            },
            "keepalive_peer_ip": keepalive_peer,
            "keepalive_src_ip": keepalive_src,
            "keepalive_timers": {
                "dead_interval": 3,
                "hello_interval": 1
            },
            "keepalive_udp_port": keepalive_port,
            "keepalive_vrf": {
                keepalive_vrf: "/rest/v10.04/system/vrfs/" + keepalive_vrf,
            },
            "linkup_delay_timer": 180,
            "split_recovery_disable": False,
            "system_mac": vsx_mac
        }

        target_url = kwargs["url"] + "system/vsx"
        post_data = json.dumps(vsx_data, sort_keys=True, indent=4)
        response = kwargs["s"].post(target_url,
                                    data=post_data,
                                    verify=False,
                                    timeout=2)

        if not common_ops._response_ok(response, "POST"):
            print(
                "FAIL: Creating VSX Role '%s' on vrf %s failed with status code %d"
                % (role, keepalive_vrf, response.status_code))
        else:
            print("SUCCESS: Creating VSX Role '%s' succeeded on vrf %s" %
                  (role, keepalive_vrf))
Beispiel #27
0
def _create_l3_lag_interface(name, phys_ports, ipv4, lacp_mode="passive", mc_lag=False, fallback_enabled=False,
                             desc=None, admin_state="up", vrf="default", **kwargs):
    """
    Perform a POST call to create a Port table entry for L3 LAG interface.

    :param name: Alphanumeric Port name
    :param phys_ports: List of physical ports to aggregate (e.g. ["1/1/1", "1/1/2", "1/1/3"])
    :param ipv4: IPv4 address to assign to the interface. Defaults to nothing if not specified.
    :param lacp_mode: Should be either "passive" or "active." Defaults to "passive" if not specified.
    :param mc_lag: Boolean to determine if the LAG is multi-chassis. Defaults to False if not specified.
    :param fallback_enabled: Boolean to determine if the LAG uses LACP fallback. Defaults to False if not specified.
    :param desc: Optional description for the interface. Defaults to nothing if not specified.
    :param admin_state: Optional administratively-configured state of the port.
        Defaults to "up" if not specified
    :param vrf: Name of the VRF to which the Port belongs. Defaults to "default" if not specified.
    :param kwargs:
        keyword s: requests.session object with loaded cookie jar
        keyword url: URL in main() function
    :return: Nothing
    """

    ints_dict = interface.get_all_interfaces(**kwargs)

    if name not in ints_dict:

        interfaces = ["/rest/v10.04/system/interfaces/%s" % common_ops._replace_special_characters(phys_port)
                      for phys_port in phys_ports]
        int_data = {"admin": admin_state,
                    "interfaces": interfaces,
                    "name": name,
                    "type": "lag",
                    "vrf": "/rest/v10.04/system/vrfs/%s" % vrf,
                    "routing": True,
                    "ip4_address": ipv4,
                    "lacp": lacp_mode,
                    # "other_config": {
                    #    "mclag_enabled": mc_lag,
                    #    "lacp-fallback": fallback_enabled
                    #    }

                    }
        """commented out the other_config since it causes error"""

        if desc is not None:
            int_data['description'] = desc

        target_url = kwargs["url"] + "system/interfaces"
        post_data = json.dumps(int_data, sort_keys=True, indent=4)

        response = kwargs["s"].post(target_url, data=post_data, verify=False)

        if not common_ops._response_ok(response, "POST"):
            print("FAIL: Adding Interface table entry '%s' failed with status code %d"
                  % (name, response.status_code))
        else:
            print("SUCCESS: Adding Interface table entry '%s' succeeded" % name)

        return response.content
    else:
        print("SUCCESS: No need to add Interface table entry '%s' because it already exists"
              % name)