def network(ipaddress, info_type, namespace):
    """Show IP (IPv4) BGP network"""

    if multi_asic.is_multi_asic() and namespace not in multi_asic.get_namespace_list():
        ctx = click.get_current_context()
        ctx.fail('-n/--namespace option required. provide namespace from list {}'\
            .format(multi_asic.get_namespace_list()))

    command = 'show ip bgp'
    if ipaddress is not None:
        if '/' in ipaddress:
            # For network prefixes then this all info_type(s) are available
            pass
        else:
            # For an ipaddress then check info_type, exit if specified option doesn't work.
            if info_type in ['longer-prefixes']:
                click.echo('The parameter option: "{}" only available if passing a network prefix'.format(info_type))
                click.echo("EX: 'show ip bgp network 10.0.0.0/24 longer-prefixes'")
                raise click.Abort()

        command += ' {}'.format(ipaddress)

        # info_type is only valid if prefix/ipaddress is specified
        if info_type is not None:
            command += ' {}'.format(info_type)

    output  =  bgp_util.run_bgp_command(command, namespace)
    click.echo(output.rstrip('\n'))
Beispiel #2
0
def state(ctx, module, identifier, db, table, key_map, verbose, namespace):
    """
    Dump the current state of the identifier for the specified module from Redis DB or CONFIG_FILE
    """
    if not multi_asic.is_multi_asic() and namespace != DEFAULT_NAMESPACE:
        click.echo("Namespace option is not valid for a single-ASIC device")
        ctx.exit()

    if multi_asic.is_multi_asic() and (namespace != DEFAULT_NAMESPACE
                                       and namespace
                                       not in multi_asic.get_namespace_list()):
        click.echo("Namespace option is not valid. Choose one of {}".format(
            multi_asic.get_namespace_list()))
        ctx.exit()

    if module not in plugins.dump_modules:
        click.echo("No Matching Plugin has been Implemented")
        ctx.exit()

    if verbose:
        os.environ["VERBOSE"] = "1"
    else:
        os.environ["VERBOSE"] = "0"

    ctx.module = module
    obj = plugins.dump_modules[module]()

    if identifier == "all":
        ids = obj.get_all_args(namespace)
    else:
        ids = identifier.split(",")

    params = {}
    collected_info = {}
    params['namespace'] = namespace
    for arg in ids:
        params[plugins.dump_modules[module].ARG_NAME] = arg
        try:
            collected_info[arg] = obj.execute(params)
        except ValueError as err:
            click.fail(f"Failed to execute plugin: {err}")

    if len(db) > 0:
        collected_info = filter_out_dbs(db, collected_info)

    vidtorid = extract_rid(collected_info, namespace)

    if not key_map:
        collected_info = populate_fv(collected_info, module, namespace)

    for id in vidtorid.keys():
        collected_info[id]["ASIC_DB"]["vidtorid"] = vidtorid[id]

    print_dump(collected_info, table, module, identifier, key_map)

    return
def neighbors(ipaddress, info_type, namespace):
    """Show IP (IPv4) BGP neighbors"""

    command = 'show ip bgp neighbor'
    if ipaddress is not None:
        if not bgp_util.is_ipv4_address(ipaddress):
            ctx = click.get_current_context()
            ctx.fail("{} is not valid ipv4 address\n".format(ipaddress))
        try:
            actual_namespace = bgp_util.get_namespace_for_bgp_neighbor(
                ipaddress)
            if namespace is not None and namespace != actual_namespace:
                click.echo(
                    "[WARNING]: bgp neighbor {} is present in namespace {} not in {}"
                    .format(ipaddress, actual_namespace, namespace))

            # save the namespace in which the bgp neighbor is configured
            namespace = actual_namespace

            command += ' {}'.format(ipaddress)

            # info_type is only valid if ipaddress is specified
            if info_type is not None:
                command += ' {}'.format(info_type)
        except ValueError as err:
            ctx = click.get_current_context()
            ctx.fail("{}\n".format(err))

    ns_list = multi_asic.get_namespace_list(namespace)
    output = ""
    for ns in ns_list:
        output += bgp_util.run_bgp_command(command, ns)

    click.echo(output.rstrip('\n'))
Beispiel #4
0
def neighbors(ipaddress, info_type, namespace):
    """Show IPv6 BGP neighbors"""

    if ipaddress is not None:
        if not bgp_util.is_ipv6_address(ipaddress):
            ctx = click.get_current_context()
            ctx.fail("{} is not valid ipv6 address\n".format(ipaddress))
        try:
            actual_namespace = bgp_util.get_namespace_for_bgp_neighbor(
                ipaddress)
            if namespace is not None and namespace != actual_namespace:
                click.echo(
                    "bgp neighbor {} is present in namespace {} not in {}"
                    .format(ipaddress, actual_namespace, namespace))

            # save the namespace in which the bgp neighbor is configured
            namespace = actual_namespace
        except ValueError as err:
            ctx = click.get_current_context()
            ctx.fail("{}\n".format(err))
    else:
        ipaddress = ""

    info_type = "" if info_type is None else info_type
    command = 'show bgp ipv6 neighbor {} {}'.format(
        ipaddress, info_type)

    ns_list = multi_asic.get_namespace_list(namespace)
    output = ""
    for ns in ns_list:
        output += bgp_util.run_bgp_command(command, ns)
    
    click.echo(output.rstrip('\n'))
Beispiel #5
0
def get_namespace_for_bgp_neighbor(neighbor_ip):
    namespace_list = multi_asic.get_namespace_list()
    for namespace in namespace_list:
        if is_bgp_neigh_present(neighbor_ip, namespace):
            return namespace

    # neighbor IP not present in any namespace
    raise ValueError(' Bgp neighbor {} not configured'.format(neighbor_ip))
    def show_thresholds(self, resource):
        """
        CRM Handler to display thresholds information.
        """

        configdb = self.cfgdb
        if configdb is None:
            # Get the namespace list
            namespaces = multi_asic.get_namespace_list()

            configdb = ConfigDBConnector(namespace=namespaces[0])
            configdb.connect()

        crm_info = configdb.get_entry('CRM', 'Config')

        header = ("Resource Name", "Threshold Type", "Low Threshold",
                  "High Threshold")
        data = []

        if crm_info:
            if resource == 'all':
                for res in [
                        "ipv4_route", "ipv6_route", "ipv4_nexthop",
                        "ipv6_nexthop", "ipv4_neighbor", "ipv6_neighbor",
                        "nexthop_group_member", "nexthop_group", "acl_table",
                        "acl_group", "acl_entry", "acl_counter", "fdb_entry",
                        "ipmc_entry", "snat_entry", "dnat_entry", "mpls_inseg",
                        "mpls_nexthop"
                ]:
                    try:
                        data.append([
                            res, crm_info[res + "_threshold_type"],
                            crm_info[res + "_low_threshold"],
                            crm_info[res + "_high_threshold"]
                        ])
                    except KeyError:
                        pass
            else:
                try:
                    data.append([
                        resource, crm_info[resource + "_threshold_type"],
                        crm_info[resource + "_low_threshold"],
                        crm_info[resource + "_high_threshold"]
                    ])
                except KeyError:
                    pass
        else:
            click.echo('\nError! Could not get CRM configuration.')

        click.echo()
        click.echo(
            tabulate(data, headers=header, tablefmt="simple", missingval=""))
        click.echo()
Beispiel #7
0
def get_acl_rule_counters(module):
    """
    @summary: Parse the output of CLI 'aclshow -a' to get counters value of all ACL rules.
    @param module: The AnsibleModule object
    @return: Return ACL rule counters data in dict
    """
    counter_aggrgeate_map = defaultdict(list)
    counters = []

    namespace_list = multi_asic.get_namespace_list()
    for ns in namespace_list:
        cmd = 'sudo ip netns exec {} '.format(ns) if ns else ''
        rc, stdout, stderr = module.run_command(cmd + 'aclshow -a')
        if rc != 0:
            module.fail_json(
                msg=
                'Failed to get acl counter data, rc=%s, stdout=%s, stderr=%s' %
                (rc, stdout, stderr))

        output_lines = stdout.splitlines()[
            2:]  # Skip the header lines in output
        for line in output_lines:
            line_expanded = line.split()
            if len(line_expanded) == 5:
                try:
                    packets_count = int(line_expanded[3])
                except ValueError:
                    packets_count = 0
                try:
                    bytes_count = int(line_expanded[4])
                except ValueError:
                    bytes_count = 0

                key = (line_expanded[0], line_expanded[1], line_expanded[2])
                if key in counter_aggrgeate_map:
                    counter_aggrgeate_map[key][
                        0] = packets_count + counter_aggrgeate_map[key][0]
                    counter_aggrgeate_map[key][
                        1] = bytes_count + counter_aggrgeate_map[key][1]
                else:
                    counter_aggrgeate_map[key].append(packets_count)
                    counter_aggrgeate_map[key].append(bytes_count)

    for k, v in counter_aggrgeate_map.items():
        counter = dict(rule_name=k[0],
                       table_name=k[1],
                       priority=k[2],
                       packets_count=v[0],
                       bytes_count=v[1])
        counters.append(counter)

    return counters
Beispiel #8
0
    def __static_checks(self):

        if not self.db and not self.file:
            return EXCEP_DICT["NO_SRC"]

        if self.db and self.file:
            return EXCEP_DICT["SRC_VAGUE"]

        if not self.db:
            try:
                with open(self.file) as f:
                    json.load(f)
            except Exception as e:
                return EXCEP_DICT["FILE_R_EXEP"] + str(e)

        if not self.file and self.db not in SonicDBConfig.getDbList():
            return EXCEP_DICT["INV_DB"]

        if not self.table:
            return EXCEP_DICT["NO_TABLE"]

        if not isinstance(self.return_fields, list):
            return EXCEP_DICT["BAD_FORMAT_RE_FIELDS"]

        if not self.just_keys and self.return_fields:
            return EXCEP_DICT["JUST_KEYS_COMPAT"]

        if self.field and not self.value:
            return EXCEP_DICT["NO_VALUE"]

        if self.ns != DEFAULT_NAMESPACE and self.ns not in multi_asic.get_namespace_list(
        ):
            return EXCEP_DICT["INV_NS"] + " Choose From {}".format(
                multi_asic.get_namespace_list())

        verbose_print("MatchRequest Checks Passed")

        return ""
Beispiel #9
0
    def run(self):
        """
        Run ACL capabilities facts collection.
        """
        self.facts['acl_capabilities'] = {}
        namespace_list = multi_asic.get_namespace_list()
        swsssdk.SonicDBConfig.load_sonic_global_db_config()
        conn = swsssdk.SonicV2Connector(namespace=namespace_list[0])
        conn.connect(conn.STATE_DB)
        keys = conn.keys(conn.STATE_DB, 'ACL_STAGE_CAPABILITY_TABLE|*') or []

        for key in keys:
            capab = conn.get_all(conn.STATE_DB, key)
            self.facts['acl_capabilities'][key.split('|')[-1]] = capab

        self.module.exit_json(ansible_facts=self.facts)
Beispiel #10
0
    def run(self):
        """
            Main method of the class
        """
        self.facts['switch_capabilities'] = {}
        namespace_list = multi_asic.get_namespace_list()
        swsssdk.SonicDBConfig.load_sonic_global_db_config()
        conn = swsssdk.SonicV2Connector(namespace=namespace_list[0])
        conn.connect(conn.STATE_DB)
        keys = conn.keys(conn.STATE_DB, 'SWITCH_CAPABILITY|*')

        for key in keys:
            capab = conn.get_all(conn.STATE_DB, key)
            self.facts['switch_capabilities'][key.split('|')[-1]] = capab

        self.module.exit_json(ansible_facts=self.facts)
Beispiel #11
0
 def get_po_names(self):
     '''
         Collect configured lag interface names
     '''
     namespace_list = multi_asic.get_namespace_list()
     for ns in namespace_list:
         rt, out, err = self.module.run_command(
             "sonic-cfggen -m /etc/sonic/minigraph.xml {} -v \"PORTCHANNEL.keys() | join(' ')\""
             .format('-n ' + ns if ns else ''))
         if rt != 0:
             fail_msg = "Command to retrieve portchannel names failed return=%d, out=%s, err=%s" % (
                 rt, out, err)
             self.module.fail_json(msg=fail_msg)
         else:
             for po in out.split():
                 if multi_asic.is_port_channel_internal(po):
                     continue
                 self.lag_names[po] = ns
     return
Beispiel #12
0
    def show_summary(self):
        """
        CRM Handler to display general information.
        """

        configdb = self.cfgdb
        if configdb is None:
            # Get the namespace list
            namespaces = multi_asic.get_namespace_list()

            configdb = swsssdk.ConfigDBConnector(namespace=namespaces[0])
            configdb.connect()

        crm_info = configdb.get_entry('CRM', 'Config')

        if crm_info:
            click.echo('\nPolling Interval: ' + crm_info['polling_interval'] +
                       ' second(s)\n')
        else:
            click.echo('\nError! Could not get CRM configuration.\n')
Beispiel #13
0
def parse_png(png, hname):
    neighbors = {}
    devices = {}
    neighbors_namespace = defaultdict(str)
    console_dev = ''
    console_port = ''
    mgmt_dev = ''
    mgmt_port = ''
    try:
        from sonic_py_common import multi_asic
        namespace_list = multi_asic.get_namespace_list()
    except ImportError:
        namespace_list = ['']

    for child in png:
        if child.tag == str(QName(ns, "DeviceInterfaceLinks")):
            for link in child.findall(str(QName(ns, "DeviceLinkBase"))):
                linktype = link.find(str(QName(ns, "ElementType"))).text
                if linktype != "DeviceInterfaceLink" and linktype != "UnderlayInterfaceLink":
                    continue

                enddevice = link.find(str(QName(ns, "EndDevice"))).text
                endport = link.find(str(QName(ns, "EndPort"))).text
                startdevice = link.find(str(QName(ns, "StartDevice"))).text
                startport = link.find(str(QName(ns, "StartPort"))).text

                if enddevice == hname:
                    if port_alias_to_name_map.has_key(endport):
                        endport = port_alias_to_name_map[endport]
                    if startdevice.lower() in namespace_list:
                        neighbors_namespace[endport] = startdevice.lower()
                    else:
                        neighbors[endport] = {
                            'name': startdevice,
                            'port': startport,
                            'namespace': ''
                        }
                elif startdevice == hname:
                    if port_alias_to_name_map.has_key(startport):
                        startport = port_alias_to_name_map[startport]
                    if enddevice.lower() in namespace_list:
                        neighbors_namespace[startport] = enddevice.lower()
                    else:
                        neighbors[startport] = {
                            'name': enddevice,
                            'port': endport,
                            'namespace': ''
                        }

        if child.tag == str(QName(ns, "Devices")):
            for device in child.findall(str(QName(ns, "Device"))):
                lo_addr = None
                # don't shadow type()
                d_type = None
                mgmt_addr = None
                hwsku = None
                if str(QName(ns3, "type")) in device.attrib:
                    d_type = device.attrib[str(QName(ns3, "type"))]

                for node in device:
                    if node.tag == str(QName(ns, "Address")):
                        lo_addr = node.find(str(QName(
                            ns2, "IPPrefix"))).text.split('/')[0]
                    elif node.tag == str(QName(ns, "ManagementAddress")):
                        mgmt_addr = node.find(str(QName(
                            ns2, "IPPrefix"))).text.split('/')[0]
                    elif node.tag == str(QName(ns, "Hostname")):
                        name = node.text
                    elif node.tag == str(QName(ns, "HwSku")):
                        hwsku = node.text

                if name.lower() in namespace_list:
                    continue

                devices[name] = {
                    'lo_addr': lo_addr,
                    'type': d_type,
                    'mgmt_addr': mgmt_addr,
                    'hwsku': hwsku
                }

        if child.tag == str(QName(ns, "DeviceInterfaceLinks")):
            for if_link in child.findall(str(QName(ns, 'DeviceLinkBase'))):
                if str(QName(ns3, "type")) in if_link.attrib:
                    link_type = if_link.attrib[str(QName(ns3, "type"))]
                    if link_type == 'DeviceSerialLink':
                        for node in if_link:
                            if node.tag == str(QName(ns, "EndPort")):
                                console_port = node.text.split()[-1]
                            elif node.tag == str(QName(ns, "EndDevice")):
                                console_dev = node.text
                    elif link_type == 'DeviceMgmtLink':
                        for node in if_link:
                            if node.tag == str(QName(ns, "EndPort")):
                                mgmt_port = node.text.split()[-1]
                            elif node.tag == str(QName(ns, "EndDevice")):
                                mgmt_dev = node.text

    for k, v in neighbors.iteritems():
        v['namespace'] = neighbors_namespace[k]

    return (neighbors, devices, console_dev, console_port, mgmt_dev, mgmt_port)
def multi_asic_ns_choices():
    if not multi_asic.is_multi_asic():
        return [constants.DEFAULT_NAMESPACE]
    choices = multi_asic.get_namespace_list()
    return choices
#!/usr/bin/python

import json
import sys
from ansible.module_utils.basic import *
try:
    from sonic_py_common import multi_asic
    NAMESPACE_LIST = multi_asic.get_namespace_list()
except ImportError:
    NAMESPACE_LIST = ['']
DOCUMENTATION = '''
---
module: lag_facts
Ansible_version_added: "2.0.0.2"
Sonic_version: "2.0"
short_description: Retrieve lag(LACP) information from a device 
description:
    - Retrieved facts will be inserted to:
        lag_facts:
          - 'names': [list all portchannel names] 
          - 'lags':  {portchannel: detailed portchannel information }
'''

EXAMPLES = '''
# Gather lab facts
 - name: Gather lag info
   lag_facts:  host=10.255.0.200 
 - name: display lag information
   debug: var=lag_facts
'''
Beispiel #16
0
def main():
    module = AnsibleModule(argument_spec=dict(
        up_ports=dict(type='raw', default={}),
        namespace=dict(default=None),
    ),
                           supports_check_mode=False)

    m_args = module.params
    up_ports = m_args['up_ports']
    namespace_passed = m_args['namespace']

    # Create a python script file in the DUT.
    with open(INTF_IP_GET_INFO_SCRIPT, "w") as f:
        f.write(INTF_IP_GET_INFO_CMDs)
        f.close()

    interfaces = dict()
    ips = dict(
        all_ipv4_addresses=[],
        all_ipv6_addresses=[],
    )

    # Initialize the cmd string which to invoke the python script which we created on the DUT.
    cmd_prefix = ''
    cmd = '/usr/bin/python {}'.format(INTF_IP_GET_INFO_SCRIPT)

    for namespace in multi_asic.get_namespace_list():
        if namespace_passed and namespace != namespace_passed:
            continue
        # If the user passed a namespace parameter invoke that script with the cmd_prefix
        if namespace:
            cmd_prefix = 'sudo ip netns exec {} '.format(namespace)
        rc, output, err = module.run_command(cmd_prefix + cmd,
                                             use_unsafe_shell=True)
        if rc != 0:
            module.fail_json(
                msg="Failed to run {}, rc={}, stdout={}, stderr={}".format(
                    cmd, rc, output, err))

        # Get the output from the gather interface info script.
        if output:
            ips_interfaces = json.loads(output)
            interfaces.update(ips_interfaces["interfaces"])
            ips.update(ips_interfaces["ips"])

    # Remove the file which was created earlier
    os.remove(INTF_IP_GET_INFO_SCRIPT)

    results = {}

    down_ports = []
    for name in up_ports:
        try:
            if not interfaces[name]['link']:
                down_ports += [name]
        except:
            down_ports += [name]
            pass

    results['ansible_interface_facts'] = interfaces
    results['ansible_interface_ips'] = ips
    results['ansible_interface_link_down_ports'] = down_ports
    module.exit_json(ansible_facts=results)