示例#1
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)
示例#2
0
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))
示例#3
0
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))
示例#4
0
def _get_dhcp_relay(vrf_name, port_name, **kwargs):
    """
    Perform a GET call to get DHCP data for an interface

    :param vrf_name: Alphanumeric name of VRF
    :param port_name: L3 interface's Port table entry name
    :param kwargs:
        keyword s: requests.session object with loaded cookie jar
        keyword url: URL in main() function
    :return: Dictionary containing DHCP Relay data for interface
    """
    payload = {"selector": "writable"}

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

    if not common_ops._response_ok(response, "GET"):
        print(
            "FAIL: Getting IPv4 DHCP helper(s) for Port '%s' failed with status code %d"
            % (port_name, response.status_code))
    else:
        print("SUCCESS: Getting IPv4 DHCP helper(s) for Port '%s' succeeded" %
              port_name)

    return response.json()
示例#5
0
def _delete_dhcp_relays(port_name, vrf_name="default", **kwargs):
    """
    Perform a DELETE call to delete all the IPv4 DHCP helper(s) for an L3 interface.

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

    dhcp_helpers_dict = get_all_dhcp_relays(**kwargs)

    if "%s,%s" % (vrf_name, port_name) in dhcp_helpers_dict:

        target_url = kwargs["url"] + "system/dhcp_relays/%s,%s" % (vrf_name,
                                                                   port_name)

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

        if not common_ops._response_ok(response, "DELETE"):
            print(
                "FAIL: Deleting all DHCP relays from interface Port '%s' failed with status code %d"
                % (port_name, response.status_code))
        else:
            print(
                "SUCCESS: Deleting all DHCP relays from interface Port '%s' succeeded"
                % port_name)

    else:
        print(
            "SUCCESS: No need to delete DHCP relays from SVI Port '%s' since they don't exist"
            % port_name)
示例#6
0
def get_mac_info(vlan_id, mac_type, mac_addr, **kwargs):
    """
    Perform a GET call to get MAC info

    :param vlan_id: Numeric ID of VLAN
    :param mac_type: The source of the MAC address. Must be "dynamic," "VSX," "static," "VRRP,"
        "port-access-security," "evpn," or "hsc"
    :param mac_addr: MAC address
    :param kwargs:
        keyword s: requests.session object with loaded cookie jar
        keyword url: URL in main() function
    :return: Dictionary containing MAC data
    """
    target_url = kwargs["url"] + "system/vlans/%d/macs/%s/%s" % (
        vlan_id, mac_type, mac_addr)

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

    if not common_ops._response_ok(response, "GET"):
        print(
            "FAIL: Getting data for MAC '%s' of VLAN ID '%d' failed with status code %d"
            % (mac_addr, vlan_id, response.status_code))
    else:
        print("SUCCESS: Getting data for MAC '%s' of VLAN ID '%d' succeeded" %
              (mac_addr, vlan_id))

    mac_data = response.json()
    return mac_data
示例#7
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))
示例#8
0
def delete_acl_entry(list_name, list_type, sequence_num, **kwargs):
    """
    Perform a DELETE call to delete an ACL entry

    :param list_name: Alphanumeric name of the ACL
    :param list_type: Type should be one of "ipv4," "ipv6," or "mac"
    :param sequence_num: Integer ID for the entry.
    :param kwargs:
        keyword s: requests.session object with loaded cookie jar
        keyword url: URL in main() function
    :return: Nothing
    """

    acl_entries_dict = get_all_acl_entries(list_name, list_type, **kwargs)

    if "/rest/v1/system/acls/%s/%s/cfg_aces/%d" % (
            list_name, list_type, sequence_num) in acl_entries_dict.values():

        target_url = kwargs["url"] + "system/acls/%s/%s/cfg_aces/%d" % (
            list_name, list_type, sequence_num)

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

        if not common_ops._response_ok(response, "DELETE"):
            print(
                "FAIL: Deleting entry %d in %s ACL '%s' failed with status code %d"
                % (sequence_num, list_type, list_name, response.status_code))
        else:
            print("SUCCESS: Deleting entry %d in %s ACL '%s' succeeded" %
                  (sequence_num, list_type, list_name))
    else:
        print(
            "SUCCESS: No need to delete entry %d in %s ACL '%s' since it doesn't exist"
            % (sequence_num, list_type, list_name))
示例#9
0
def _update_acl(list_name, list_type, **kwargs):
    """
    Perform a PUT call to version-up an ACL. This is required whenever entries of an ACL are changed
    in any way.

    :param list_name: Alphanumeric name of the ACL
    :param list_type: Type should be one of "ipv4," "ipv6," or "mac"
    :param kwargs:
        keyword s: requests.session object with loaded cookie jar
        keyword url: URL in main() function
    :return: Nothing
    """

    acl_data = get_acl(list_name, list_type, **kwargs)
    acl_key = "{},{}".format(list_name, list_type)

    acl_data['cfg_version'] = random.randint(-9007199254740991,
                                             9007199254740991)
    target_url = kwargs["url"] + "system/acls/%s" % acl_key
    put_data = json.dumps(acl_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 %s ACL '%s' failed with status code %d" %
              (list_type, list_name, response.status_code))
    else:
        print("SUCCESS: Updating %s ACL '%s' succeeded" %
              (list_type, list_name))
示例#10
0
def _add_vni_mapping(vni, vxlan, vlan, **kwargs):
    """
    Perform POST call to create a Virtual Network ID and Map it to VLANs for a supplied VXLAN
    :param vni: Integer representing the Virtual Network ID
    :param vxlan: Alphanumeric of the VXLAN that the VNI will be associated with
    :param vlan: VLAN that the VNI will be mapped to
    :param kwargs:
        keyword s: requests.session object with loaded cookie jar
        keyword url: URL in main() function
    :return: Nothing
    """
    vni_list = get_vni_list(**kwargs)

    if "vxlan_vni,%d" % vni not in vni_list:
        vni_data = {
          "id": vni,
          "interface": "/rest/v10.04/system/interfaces/%s" % vxlan,
          "type": "vxlan_vni",
          "vlan": "/rest/v10.04/system/vlans/%d" % vlan
        }

        target_url = kwargs["url"] + "system/virtual_network_ids"

        post_data = json.dumps(vni_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 VNI '%s' for VXLAN '%s' failed with status code %d"
                  % (vni, vxlan, response.status_code))
        else:
            print("SUCCESS: Creating VNI '%s' for VXLAN '%s' succeeded" % (vni, vxlan))
    else:
        print("SUCCESS: No need to create VNI '%s' for VXLAN '%s' as it already exists" % (vni, vxlan))
示例#11
0
def create_evpn_instance(**kwargs):
    """
    Perform POST calls to create an EVPN instance
    :param kwargs:
        keyword s: requests.session object with loaded cookie jar
        keyword url: URL in main() function
    :return: Nothing
    """
    current_evpn = get_evpn_info(**kwargs)

    if current_evpn:
        print(
            "SUCCESS: No need to create EVPN instance since it already exists")
    else:
        evpn_data = {}
        target_url = kwargs["url"] + "system/evpns"

        post_data = json.dumps(evpn_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 EVPN Instance failed with status code %d" %
                  response.status_code)
        else:
            print("SUCCESS: Creating EVPN Instance succeeded")
示例#12
0
def _get_all_acl_entries(list_name, list_type, **kwargs):
    """
    Perform a GET call to get all entries of an ACL

    :param list_name: Alphanumeric name of the ACL
    :param list_type: Type should be one of "ipv4," "ipv6," or "mac"
    :param kwargs:
        keyword s: requests.session object with loaded cookie jar
        keyword url: URL in main() function
    :return: Dictionary containing queue profile entry URIs
    """

    target_url = kwargs["url"] + "system/acls/%s,%s?attributes=cfg_aces" % (
        list_name, list_type)

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

    if not common_ops._response_ok(response, "GET"):
        print(
            "FAIL: Getting dictionary of URIS of entries in %s ACL '%s' failed with status code %d"
            % (list_type, list_name, response.status_code))
    else:
        print(
            "SUCCESS: Getting dictionary of URIs of entries in %s ACL '%s' succeeded"
            % (list_type, list_name))

    acl_entries = response.json()

    # for some reason, this API returns a list when empty, and a dictionary when there is data
    # make this function always return a dictionary,
    if not acl_entries:
        return {}
    else:
        return acl_entries
示例#13
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))
示例#14
0
def login(base_url, username=None, password=None):
    """

    Perform a POST call to login and gain access to other API calls.
    If either username or password is not specified, user will be prompted to enter the missing credential(s).

    :param base_url: URL in main() function
    :param username: username
    :param password: password
    :return: requests.session object with loaded cookie jar
    """
    if username is None and password is None:
        username = input('Enter username: '******'ERROR: Error connecting to host: connection attempt timed out.')
        exit(-1)
    # Response OK check needs to be passed "PUT" since this POST call returns 200 instead of conventional 201
    if not common_ops._response_ok(response, "PUT"):
        print("FAIL: Login failed with status code %d" % response.status_code)
        exit(-1)
    else:
        print("SUCCESS: Login succeeded")
        return s
示例#15
0
def delete_vrf(vrf_name, **kwargs):
    """
    Perform a DELETE call to delete a VRF.
    Note that this functions has logic that works for both v1 and v10.04

    :param vrf_name: Alphanumeric name of VRF
    :param kwargs:
        keyword s: requests.session object with loaded cookie jar
        keyword url: URL in main() function
    :return: Nothing
    """
    vrf_list = get_all_vrfs(**kwargs)

    if kwargs["url"].endswith("/v1/"):
        vrf_check = "/rest/v1/system/vrfs/%s" % vrf_name
    else:
        # Else logic designed for v10.04 and later
        vrf_check = vrf_name

    if vrf_check in vrf_list:
        target_url = kwargs["url"] + "system/vrfs/%s" % vrf_name
        response = kwargs["s"].delete(target_url, verify=False)

        if not common_ops._response_ok(response, "DELETE"):
            print("FAIL: Deleting VRF '%s' failed with status code %d" % (vrf_name, response.status_code))
        else:
            print("SUCCESS: Deleting VRF '%s' succeeded" % vrf_name)
    else:
        print("SUCCESS: No need to delete VRF '%s' since it doesn't exist"
              % vrf_name)
示例#16
0
def _get_vlan(vlan_id, depth=1, selector="writable", **kwargs):
    """
    Perform a GET call to retrieve data for a VLAN table entry
    :param depth: Integer deciding how many levels into the API JSON that references will be returned.
    :param selector: Alphanumeric option to select specific information to return.  The options are 'configuration',
        'status', or 'statistics'.  If running v10.04 or later, an additional option 'writable' is included.
    :param vlan_id: Numeric ID of VLAN
    :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'"
        )

    target_url = kwargs["url"] + "system/vlans/%d" % vlan_id
    payload = {"depth": depth, "selector": selector}
    response = kwargs["s"].get(target_url,
                               verify=False,
                               params=payload,
                               timeout=2)
    if not common_ops._response_ok(response, "GET"):
        print(
            "FAIL: Getting VLAN ID '%d' table entry failed with status code %d"
            % (vlan_id, response.status_code))
        output = {}
    else:
        print("SUCCESS: Getting VLAN ID '%d' table entry succeeded" % vlan_id)
        output = response.json()

    return output
示例#17
0
def _get_vrf(vrf_name, depth=1, selector=None, **kwargs):
    """
    Perform a GET call to get data for a VRF table entry

    :param vrf_name: Alphanumeric name of the VRF
    :param depth: Integer deciding how many levels into the API JSON that references will be returned.
    :param selector: Alphanumeric option to select specific information to return.  The options are 'configuration',
        'status', 'statistics' or 'writable'.
    :param kwargs:
        keyword s: requests.session object with loaded cookie jar
        keyword url: URL in main() function
    :return: Dictionary containing the VRF data
    """

    if selector not in ['configuration', 'status', 'statistics', 'writable', None]:
        raise Exception("ERROR: Selector should be 'configuration', 'status', 'statistics', or 'writable'")

    target_url = kwargs["url"] + "system/vrfs/%s" % vrf_name
    payload = {
        "depth": depth,
        "selector": selector
    }
    response = kwargs["s"].get(target_url, verify=False, params=payload, timeout=2)

    if not common_ops._response_ok(response, "GET"):
        print("FAIL: Getting VRF table entry '%s' failed with status code %d" % (vrf_name, response.status_code))
        vrf = []
    else:
        print("SUCCESS: Getting VRF table entry '%s' succeeded" % vrf_name)
        vrf = response.json()

    return vrf
示例#18
0
def _delete_vlan(vlan_id, **kwargs):
    """
    Perform a DELETE call to delete VLAN.

    :param vlan_id: Numeric ID of VLAN
    :param kwargs:
        keyword s: requests.session object with loaded cookie jar
        keyword url: URL in main() function
    :return: Nothing
    """

    vlans_dict = get_all_vlans(**kwargs)

    if str(vlan_id) in vlans_dict:

        target_url = kwargs["url"] + "system/vlans/%s" % vlan_id

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

        if not common_ops._response_ok(response, "DELETE"):
            print("FAIL: Deleting VLAN ID: '%s' failed with status code %d" %
                  (vlan_id, response.status_code))
        else:
            print("SUCCESS: Deleting VLAN ID: '%s' succeeded" % vlan_id)
    else:
        print(
            "SUCCESS: No need to remove VLAN ID '%d' since it doesn't exist" %
            vlan_id)
示例#19
0
def _get_acl(list_name, list_type, **kwargs):
    """
    Perform a GET call to get details of a particular ACL

    :param list_name: Alphanumeric name of the ACL
    :param list_type: Type should be one of "ipv4," "ipv6," or "mac"
    :param kwargs:
        keyword s: requests.session object with loaded cookie jar
        keyword url: URL in main() function
    :return: Dictionary containing data about a particular ACL
    """
    acl_key = "{},{}".format(list_name, list_type)
    target_url = kwargs[
        "url"] + "system/acls/%s?depth=2&selector=writable" % acl_key

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

    if not common_ops._response_ok(response, "GET"):
        print("FAIL: Getting %s ACL '%s' failed with status code %d" %
              (list_type, list_name, response.status_code))
    else:
        print("SUCCESS: Getting %s ACL '%s' succeeded" %
              (list_type, list_name))

    acl = response.json()
    return acl
示例#20
0
def _get_vsx_v1(depth, selector, **kwargs):
    """
    Perform a GET call to get get the current VSX information on a system.
    :param depth: Integer deciding how many levels into the API JSON that references will be returned.
    :param selector: Alphanumeric option to select specific information to return.  The options are 'configuration',
        'status', or 'statistics'.
    :param kwargs:
        keyword s: requests.session object with loaded cookie jar
        keyword url: URL in main() function
    :return: JSON of VSX information
    """
    if selector not in ['configuration', 'status', 'statistics', None]:
        raise Exception(
            "ERROR: Selector should be 'configuration', 'status', or 'statistics'"
        )

    target_url = kwargs["url"] + "system/vsx"
    payload = {"depth": depth, "selector": selector}
    response = kwargs["s"].get(target_url,
                               verify=False,
                               params=payload,
                               timeout=2)

    result = []
    if not common_ops._response_ok(response, "GET"):
        print("FAIL: Getting VSX failed with status code %d" %
              response.status_code)
        if response.status_code == 400:
            print("Possibly no VSX currently configured")
    else:
        print("SUCCESS: Getting VSX information succeeded")
        result = response.json()

    return result
示例#21
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)
示例#22
0
def _add_vrf(vrf_name, route_distinguisher=None, vrf_type="user", **kwargs):
    """
    Perform a POST call to create a new VRF, and add a route distinguisher if desired.

    :param vrf_name: name of VRF
    :param route_distinguisher: Optional route distinguisher to add. Defaults to nothing if not specified.
    :param vrf_type: Optional VRF type. Defaults to "user" if not specified.
    :param kwargs:
        keyword s: requests.session object with loaded cookie jar
        keyword url: URL in main() function
    :return: Nothing
    """
    vrfs_dict = get_all_vrfs(**kwargs)

    if vrf_name not in vrfs_dict:
        vrf_data = {"name": vrf_name, "type": vrf_type}

        if route_distinguisher is not None:
            vrf_data["rd"] = route_distinguisher

        target_url = kwargs["url"] + "system/vrfs"
        post_data = json.dumps(vrf_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 new VRF '%s' failed with status code %d" % (vrf_name, response.status_code))
        else:
            print("SUCCESS: Creating new VRF '%s' succeeded" % vrf_name)
    else:
        print("SUCCESS: No need to create VRF '%s' since it already exists" % vrf_name)
示例#23
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)
示例#24
0
def add_vlan_port(vlan_port_name,
                  vlan_id,
                  ipv4=None,
                  vrf_name="default",
                  vlan_port_desc=None,
                  port_admin_state="up",
                  **kwargs):
    """
    Perform a POST call to create a logical VLAN Port as part of SVI creation.

    :param vlan_port_name: Alphanumeric Port name
    :param vlan_id: Numeric ID of VLAN
    :param ipv4: Optional IPv4 address to assign to the interface.Defaults to nothing if not specified.
    :param vrf_name: VRF to attach the SVI to. Defaults to "default" if not specified
    :param vlan_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)

    if "/rest/v1/system/ports/%s" % vlan_port_name not in ports_list:
        vlan_port_data = {
            "admin": port_admin_state,
            "name": vlan_port_name,
            "vrf": "/rest/v1/system/vrfs/%s" % vrf_name,
            "vlan_tag": "/rest/v1/system/vlans/%s" % vlan_id
        }

        if vlan_port_desc is not None:
            vlan_port_data['description'] = vlan_port_desc

        if ipv4 is not None:
            vlan_port_data['ip4_address'] = ipv4

        target_url = kwargs["url"] + "system/ports"
        post_data = json.dumps(vlan_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' for SVI failed with status code %d"
                % (vlan_port_name, response.status_code))
        else:
            print("SUCCESS: Adding Port table entry '%s' for SVI succeeded" %
                  vlan_port_name)
    else:
        print(
            "SUCCESS: No need to create VLAN Port '%s' since it already exists"
            % vlan_port_name)
示例#25
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))
示例#26
0
def _update_vsx_interface_vlan(vlan_id, active_forwarding, vsx_sync,
                               act_gw_mac, act_gw_ip, **kwargs):
    """
    Perform PUT calls on a VLAN interface to configure VSX IPv4 settings
    :param vlan_id: Numeric ID of VLAN to that will be configured
    :param active_forwarding: True or False Boolean to set VSX active forwarding
    :param vsx_sync: Set of alphanumeric values to enable VSX configuration synchronization.  The options are
        any combination of 'active-gateways', 'irdp', and 'policies'
    :param act_gw_mac: Alphanumeric value of the Virtual MAC address for the interface active gateway
    :param act_gw_ip: Alphanumeric value of the Virtual IP address for the interface active gateway
    :param kwargs:
        keyword s: requests.session object with loaded cookie jar
        keyword url: URL in main() function
    :return: Nothing
    """
    ints_list = interface.get_all_interfaces(**kwargs)
    vlan_name = "vlan" + str(vlan_id)

    if vlan_name not in ints_list:
        print(
            "FAIL: Adding VSX information to VLAN Interface '%d' failed because "
            "VLAN Interface doesn't exist" % vlan_id)
    else:
        interface_vsx_data = interface.get_interface(vlan_name,
                                                     depth=2,
                                                     selector="writable",
                                                     **kwargs)

        vsx_sync_set = []
        if "active-gateways" in vsx_sync:
            vsx_sync_set.append("^vsx_virtual.*")
        if "irdp" in vsx_sync:
            vsx_sync_set.append(".irdp.*")
        if "policies" in vsx_sync:
            vsx_sync_set.append("^policy.*")

        interface_vsx_data["vsx_active_forwarding_enable"] = active_forwarding
        interface_vsx_data["vsx_sync"] = vsx_sync_set
        interface_vsx_data["vsx_virtual_gw_mac_v4"] = act_gw_mac
        interface_vsx_data["vsx_virtual_ip4"] = [act_gw_ip]

        target_url = kwargs["url"] + "system/interfaces/" + vlan_name
        put_data = json.dumps(interface_vsx_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: Adding VSX information to VLAN Interface '%d' failed with status code %d"
                % (vlan_id, response.status_code))
        else:
            print(
                "SUCCESS: Adding VSX information to VLAN Interface '%d' succeeded"
                % vlan_id)
示例#27
0
def add_vrf_address_family(vrf_name, family_type="ipv4_unicast", export_target=[], import_targets=[], **kwargs):
    """
    Perform a POST call to create a new VRF, and add a route distinguisher if desired.
    Note that this functions has logic that works for both v1 and v10.04

    :param vrf_name: Alphanumeric name of VRF
    :param family_type: Alphanumeric type of the Address Family.  The options are 'ipv4_unicast' and 'ipv6_unicast'.
        The default value is set to 'ipv4_unicast'.
    :param export_target: Optional list of export route targets.
    :param import_targets: Optional list of import route targets
    :param kwargs:
        keyword s: requests.session object with loaded cookie jar
        keyword url: URL in main() function
    :return: Nothing
    """
    vrf_list = get_all_vrfs(**kwargs)

    if family_type == "ipv4-unicast":
        family_type = "ipv4_unicast"
    elif family_type == "ipv6-unicast":
        family_type = "ipv6_unicast"

    if family_type not in ['ipv4_unicast', 'ipv6_unicast']:
        raise Exception("ERROR: family_type should be 'ipv4_unicast', or 'ipv6_unicast'")

    if kwargs["url"].endswith("/v1/"):
        vrf_check = "/rest/v1/system/vrfs/%s" % vrf_name
    else:
        # Else logic designed for v10.04 and later
        vrf_check = vrf_name

    if vrf_check in vrf_list:
        address_family_data = {
            "address_family": family_type,
            "export_route_targets": export_target,
            "import_route_targets": import_targets,
            "route_map": {}
        }

        target_url = kwargs["url"] + "system/vrfs/%s/vrf_address_families" % vrf_name
        post_data = json.dumps(address_family_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 '%s' Address Family on VRF '%s' failed with status code %d" % (family_type, vrf_name,
                                                                                                 response.status_code))
        else:
            print("SUCCESS: Creating '%s' Address Family on VRF '%s' succeeded" % (family_type, vrf_name))
    else:
        print("FAIL: Cannot add Address Family to VRF '%s' since the VRF has not been created yet" % vrf_name)
示例#28
0
def get_arp_entries(vrf_name, **kwargs):
    """
    Perform a GET call on Neighbors table to get ARP entries

    :param vrf_name: Alphanumeric name of VRF
    :param kwargs:
        keyword s: requests.session object with loaded cookie jar
        keyword url: URL in main() function
    :return: List of dictionaries each containing one ARP entry
    """

    queries = {"depth": 1}

    target_url = kwargs["url"] + "system/vrfs/%s/neighbors" % vrf_name
    response = kwargs["s"].get(target_url,
                               verify=False,
                               params=queries,
                               timeout=2)

    if not common_ops._response_ok(response, "GET"):
        print(
            "FAIL: Getting Neighbors table entries failed with status code %d"
            % response.status_code)
    else:
        print("SUCCESS: Getting Neighbors table entries succeeded")

    neighbor_info_list = response.json()

    arp_entries_list = []

    for neighbor_info in neighbor_info_list:
        arp_entry = {
            "IPv4 Address":
            neighbor_info['ip_address'],
            "MAC Address":
            neighbor_info['mac'],
            # For port and physical port: split string by '/', take last block, and replace any '%' characters
            "Port":
            common_ops._replace_percents(
                (neighbor_info['port'].split('/'))[-1]),
            "State":
            neighbor_info['state']
        }

        if 'phy_port' in neighbor_info:
            arp_entry['Physical Port'] = common_ops._replace_percents(
                (neighbor_info['phy_port'].split('/'))[-1])

        arp_entries_list.append(arp_entry)

    return arp_entries_list
示例#29
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))
示例#30
0
def logout(**kwargs):
    """
    Perform a POST call to logout and end session.

    :param kwargs:
        keyword s: requests.session object with loaded cookie jar
        keyword url: URL in main() function
    :return: Nothing
    """
    response = kwargs["s"].post(kwargs["url"] + "logout", verify=False)
    # Response OK check needs to be passed "PUT" since this POST call returns 200 instead of conventional 201
    if not common_ops._response_ok(response, "PUT"):
        print("FAIL: Logout failed with status code %d" % response.status_code)
    else:
        print("SUCCESS: Logout succeeded")