Esempio n. 1
0
    def _parse(raw_cli_output, cmd, nos):
        # Boilerplate code to get the parser functional
        # tb = Testbed()
        device = Device("new_device", os=nos)

        device.custom.setdefault("abstraction", {})["order"] = ["os"]
        device.cli = AttrDict({"execute": None})

        # User input checking of the command provided. Does the command have a Genie parser?
        try:
            get_parser(cmd, device)
        except Exception as e:
            raise AnsibleFilterError(
                "genie_parse: {0} - Available parsers: {1}".format(
                    to_native(e),
                    "https://pubhub.devnetcloud.com/media/pyats-packages/docs/genie/genie_libs/#/parsers"
                ))

        try:
            parsed_output = device.parse(cmd, output=raw_cli_output)
            return parsed_output
        except Exception as e:
            raise AnsibleFilterError(
                "genie_parse: {0} - Failed to parse command output.".format(
                    to_native(e)))
Esempio n. 2
0
    def genie_parser(self, cli_output, command, os):
        if not PY3:
            raise AnsibleFilterError("Genie requires Python 3")

        if not HAS_GENIE:
            raise AnsibleFilterError(
                "Genie not found. Run 'pip install genie'")

        if not HAS_PYATS:
            raise AnsibleFilterError(
                "pyATS not found. Run 'pip install pyats'")

        device = Device("new_device", os=os)

        device.custom.setdefault("abstraction", {})["order"] = ["os"]
        device.cli = AttrDict({"execute": None})

        try:
            get_parser(command, device)
        except Exception as e:
            raise AnsibleFilterError(
                "Unable to find parser for command '{0}' ({1})".format(
                    command, e))

        try:
            parsed_output = device.parse(command, output=cli_output)
        except Exception as e:
            raise AnsibleFilterError(
                "Unable to parse output for command '{0}' ({1})".format(
                    command, e))

        if parsed_output:
            return parsed_output
        else:
            return None
Esempio n. 3
0
def get_structured_data_genie(raw_output: str, platform: str,
                              command: str) -> Union[str, Dict[str, Any]]:
    if not sys.version_info >= (3, 4):
        raise ValueError("Genie requires Python >= 3.4")

    if not GENIE_INSTALLED:
        msg = (
            "\nGenie and PyATS are not installed. Please PIP install both Genie and PyATS:\n"
            "pip install genie\npip install pyats\n")
        raise ValueError(msg)

    if "cisco" not in platform:
        return raw_output

    genie_device_mapper = {
        "cisco_ios": "ios",
        "cisco_xe": "iosxe",
        "cisco_xr": "iosxr",
        "cisco_nxos": "nxos",
        "cisco_asa": "asa",
    }

    os = None
    # platform might be _ssh, _telnet, _serial strip that off
    if platform.count("_") > 1:
        base_list = platform.split("_")[:-1]
        base_platform = "_".join(base_list)
    else:
        base_platform = platform

    os = genie_device_mapper.get(base_platform)
    if os is None:
        return raw_output

    # Genie specific construct for doing parsing (based on Genie in Ansible)
    device = Device("new_device", os=os)
    device.custom.setdefault("abstraction", {})
    device.custom["abstraction"]["order"] = ["os"]
    device.cli = AttrDict({"execute": None})
    try:
        # Test whether there is a parser for given command (return Exception if fails)
        get_parser(command, device)
        parsed_output: Dict[str, Any] = device.parse(command,
                                                     output=raw_output)
        return parsed_output
    except Exception:
        return raw_output
Esempio n. 4
0
    def test_disable_no_instance(self):

        tb = Genie.testbed = Testbed()
        dev = Device(testbed=tb, name='PE1', os='nxos')

        rip = Rip(instance_id=1)
        rip.add_force_vrf(None)
        dev.add_feature(rip)

        # Default configuration, let's make sure it works
        output = rip.build_unconfig(unconfig_feature=True, apply=False)
        self.assertMultiLineDictEqual(output, {'PE1': 'no feature rip'})
        # Set a mock
        dev.cli = Mock()
        dev.configure = Mock()
        output = rip.build_unconfig(unconfig_feature=True, apply=True)

        expected_output = None
        self.assertEqual(output, expected_output)
    def parse(self, *_args, **_kwargs):
        """Std entry point for a cli_parse parse execution

        :return: Errors or parsed text as structured data
        :rtype: dict

        :example:

        The parse function of a parser should return a dict:
        {"errors": [a list of errors]}
        or
        {"parsed": obj}
        """
        errors = self._check_reqs()
        errors.extend(self._check_vars())
        if errors:
            return {"errors": errors}

        command = self._task_args.get("parser").get("command")
        network_os = (
            self._task_args.get("parser").get("os")
            or self._transform_ansible_network_os()
        )
        cli_output = self._task_args.get("text")

        device = Device("new_device", os=network_os)
        device.custom.setdefault("abstraction", {})["order"] = ["os"]
        device.cli = AttrDict({"execute": None})

        try:
            parsed = device.parse(command, output=cli_output)
        except Exception as exc:
            msg = "The pyats library return an error for '{cmd}' for '{os}'. Error: {err}."
            return {
                "errors": [
                    (
                        msg.format(
                            cmd=command, os=network_os, err=to_native(exc)
                        )
                    )
                ]
            }
        return {"parsed": parsed}
Esempio n. 6
0
    def _parse_generic_tabular(cli_output, os, headers, key_index):
        # Boilerplate code to get the parser functional
        tb = Testbed()
        device = Device("new_device", os=os)

        device.custom.setdefault("abstraction", {})["order"] = ["os"]
        device.cli = AttrDict({"execute": None})

        # Do the parsing
        # result = parsergen.oper_fill_tabular(device_output=cli_output, device_os=nos, header_
        # fields=headers, index=[key])
        result = parsergen.oper_fill_tabular(device_output=cli_output,
                                             device_os=os,
                                             header_fields=headers,
                                             index=key_index)

        # Structured data, but it has a blank entry because of the first line of the output
        # being blank under the headers.
        parsed_output = result.entries

        return parsed_output
Esempio n. 7
0
    def test_uncfg(self):

        tb = Genie.testbed = Testbed()
        dev = Device(testbed=tb, name='PE1', os='nxos')

        rip = Rip(instance_id=1)
        rip.add_force_vrf(None)
        # Default configuration, let's make sure it works
        output = rip.build_unconfig(apply=False)
        # There was nothing to unconfigure
        self.assertMultiLineDictEqual(output, {})

        dev.add_feature(rip)
        output = rip.build_unconfig(apply=False)
        self.assertMultiLineDictEqual(output, {'PE1': 'feature rip\nno router rip 1'})

        # Set a mock
        dev.cli = Mock()
        dev.configure = Mock()
        output = rip.build_unconfig(apply=True)

        expected_output = None
        self.assertEqual(output, expected_output)
Esempio n. 8
0
def pyats_parser(cli_output, command, os):
    if not PY3:
        raise AnsibleFilterError("Genie requires Python 3")

    if GENIE_IMPORT_ERROR:
        raise_from(
            AnsibleError('genie must be installed to use this plugin'),
            GENIE_IMPORT_ERROR)

    if PYATS_IMPORT_ERROR:
        raise_from(
            AnsibleError('pyats must be installed to use this plugin'),
            PYATS_IMPORT_ERROR)

    # Translate from ansible_network_os values to pyATS
    if os in ansible_os_map.keys():
        os = ansible_os_map[os]

    device = Device("uut", os=os)

    device.custom.setdefault("abstraction", {})["order"] = ["os"]
    device.cli = AttrDict({"execute": None})

    try:
        get_parser(command, device)
    except Exception as e:
        raise AnsibleFilterError("Unable to find parser for command '{0}' ({1})".format(command, e))

    try:
        parsed_output = device.parse(command, output=cli_output)
    except Exception as e:
        raise AnsibleFilterError("Unable to parse output for command '{0}' ({1})".format(command, e))

    if parsed_output:
        return parsed_output
    else:
        return None
Esempio n. 9
0
def main():
    argument_spec = dict(command=dict(type='str', required=True),
                prompt=dict(type='list', required=False),
                answer=dict(type='list', required=False),
                compare=dict(type='dict', required=False),
                sendonly=dict(type='bool', default=False, required=False),
                # newline=dict(type='bool', default=True, required=False),
                # check_all=dict(type='bool', default=False, required=False),
    )
    required_together = [['prompt', 'answer']]
    module = AnsibleModule(argument_spec=argument_spec, required_together=required_together,
                           supports_check_mode=True)

    if not PY3:
        module.fail_json(msg="pyATS/Genie requires Python 3")

    if not HAS_GENIE:
        module.fail_json(msg="Genie not found. Run 'pip install genie'")

    if not HAS_PYATS:
        module.fail_json(msg="pyATS not found. Run 'pip install pyats'")

    if module.check_mode and not module.params['command'].startswith('show'):
        module.fail_json(
            msg='Only show commands are supported when using check_mode, not '
            'executing %s' % module.params['command']
        )

    warnings = list()
    result = {'changed': False, 'warnings': warnings}

    connection = Connection(module._socket_path)

    capabilities = json.loads(connection.get_capabilities())

    if capabilities['device_info']['network_os'] == 'ios':
        genie_os = 'iosxe'
    else:
        genie_os = capabilities['device_info']['network_os']

    compare = module.params.pop('compare')

    response = ''
    try:
        response = connection.get(**module.params)
    except ConnectionError as exc:
        module.fail_json(msg=to_text(exc, errors='surrogate_then_replace'))

    device = Device("uut", os=genie_os)

    device.custom.setdefault("abstraction", {})["order"] = ["os"]
    device.cli = AttrDict({"execute": None})

    try:
        get_parser(module.params['command'], device)
    except Exception as e:
        module.fail_json(msg="Unable to find parser for command '{0}' ({1})".format(module.params['command'], e))

    try:
        parsed_output = device.parse(module.params['command'], output=response)
    except Exception as e:
        module.fail_json(msg="Unable to parse output for command '{0}' ({1})".format(module.params['command'], e))

    # import sys;
    # sys.stdin = open('/dev/tty')
    # import pdb;
    # pdb.set_trace()


    if compare:
        diff = Diff(parsed_output, compare, exclude=get_parser_exclude(module.params['command'], device))
        diff.findDiff()
    else:
        diff = None


    if not module.params['sendonly']:
        try:
            result['json'] = module.from_json(response)
        except ValueError:
            pass

        result.update({
            'stdout': response,
            'structured': parsed_output,
            'diff': "{0}".format(diff),
            'exclude': get_parser_exclude(module.params['command'], device),
        })

    module.exit_json(**result)
Esempio n. 10
0
    def test_cfg(self):

        tb = Genie.testbed = Testbed()
        dev = Device(testbed=tb, name='PE1', os='nxos')

        rip = Rip(instance_id=1)
        rip.add_force_vrf(None)
        dev.add_feature(rip)
        rip.device_attr['PE1']

        output = rip.build_config(apply=False)

        self.assertMultiLineDictEqual(output, {'PE1':
            'feature rip\n'
            'router rip 1\n'
            ' address-family ipv4 unicast\n'
            '  exit\n'
            ' exit'
            })

        vrf1 = Vrf('vrf1')
        intf1 = Interface(device=dev, name='Ethernet0/0', vrf=vrf1)
        intf1.add_feature(rip)
        rip.address_families |= {AddressFamily.ipv6_unicast}
        rip.shutdown = False
        rip.device_attr['PE1'].vrf_attr[None].address_family_attr['ipv4 unicast'].maximum_paths = 2
        rip.device_attr['PE1'].vrf_attr[None].address_family_attr['ipv4 unicast'].default_metric = 1
        rip.device_attr['PE1'].vrf_attr[None].address_family_attr['ipv4 unicast'].distance = 120
        rip.device_attr['PE1'].vrf_attr[None].address_family_attr['ipv4 unicast'].redistribute_direct_rmap\
            = 'rmap1'
        rip.device_attr['PE1'].vrf_attr[None].address_family_attr['ipv4 unicast'].redistribute_static_rmap\
            = 'rmap2'
        rip.device_attr['PE1'].vrf_attr[None].address_family_attr['ipv4 unicast'].redistribute_lisp_rmap\
            = 'rmap3'
        rip.device_attr['PE1'].vrf_attr[None].address_family_attr['ipv6 unicast'].maximum_paths = 7
        rip.device_attr['PE1'].vrf_attr[None].address_family_attr['ipv6 unicast'].default_metric = 3
        rip.device_attr['PE1'].vrf_attr[None].address_family_attr['ipv6 unicast'].distance = 120
        rip.device_attr['PE1'].vrf_attr[None].address_family_attr['ipv6 unicast'].redistribute_direct_rmap\
            = 'rmap4'
        rip.device_attr['PE1'].vrf_attr[None].address_family_attr['ipv6 unicast'].redistribute_static_rmap\
            = 'rmap5'
        rip.device_attr['PE1'].vrf_attr[None].address_family_attr['ipv6 unicast'].redistribute_lisp_rmap\
            = 'rmap6'
        rip.device_attr['PE1'].vrf_attr['vrf1'].address_family_attr['ipv6 unicast'].\
            maximum_paths = 10
        rip.device_attr['PE1'].vrf_attr['vrf1'].address_family_attr['ipv6 unicast'].\
            default_metric = 7
        rip.device_attr['PE1'].vrf_attr['vrf1'].address_family_attr['ipv6 unicast'].\
            distance = 127
        rip.device_attr['PE1'].vrf_attr['vrf1'].address_family_attr['ipv6 unicast'].\
            redistribute_direct_rmap = 'rmap14'
        rip.device_attr['PE1'].vrf_attr['vrf1'].address_family_attr['ipv6 unicast'].\
            redistribute_static_rmap = 'rmap15'
        rip.device_attr['PE1'].vrf_attr['vrf1'].address_family_attr['ipv6 unicast'].\
            redistribute_lisp_rmap = 'rmap16'

        # rip.build_config(apply=False)
        output = rip.build_config(apply=False)

        expected_output = {'PE1': '''\
router rip 1
 no shutdown
 address-family ipv4 unicast
  default-metric 1
  distance 120
  maximum-paths 2
  redistribute lisp route-map rmap3
  redistribute direct route-map rmap1
  redistribute static route-map rmap2
  exit
 address-family ipv6 unicast
  default-metric 3
  distance 120
  maximum-paths 7
  redistribute lisp route-map rmap6
  redistribute direct route-map rmap4
  redistribute static route-map rmap5
  exit
 vrf vrf1
  address-family ipv4 unicast
   exit
  address-family ipv6 unicast
   default-metric 7
   distance 127
   maximum-paths 10
   redistribute lisp route-map rmap16
   redistribute direct route-map rmap14
   redistribute static route-map rmap15
   exit
  exit
 exit'''}
        self.maxDiff = None
        self.assertMultiLineDictEqual(output, expected_output)

        # Set a mock
        dev.cli = Mock()
        dev.configure = Mock()
        dev.add_feature(rip)
        # Mock config

        output = rip.build_config(apply=True)
Esempio n. 11
0
    def test_multi_device_configuration(self):
        tb = Genie.testbed = Testbed()
        dev1 = Device(testbed=tb, name='dev1', os='nxos')
        dev2 = Device(testbed=tb, name='dev2', os='nxos')

        rip = Rip(instance_id=1)
        rip.add_force_vrf(None)
        dev1.cli = Mock()
        dev1.configure = Mock()
        dev2.cli = Mock()
        dev2.configure = Mock()
        dev1.add_feature(rip)
        dev2.add_feature(rip)

        # Default configuration, let's make sure it works
        output = rip.build_config(apply=False)
        self.assertMultiLineDictEqual(output, {
            'dev1':
            'feature rip\n'
            'router rip 1\n'
            ' address-family ipv4 unicast\n'
            '  exit\n'
            ' exit',
            'dev2':
            'feature rip\n'
            'router rip 1\n'
            ' address-family ipv4 unicast\n'
            '  exit\n'
            ' exit'})

        rip.address_families |= {AddressFamily.ipv6_unicast}
        rip.shutdown = True
        rip.device_attr['dev1'].vrf_attr[None].address_family_attr['ipv4 unicast'].maximum_paths = 2
        rip.device_attr['dev1'].vrf_attr[None].address_family_attr['ipv4 unicast'].default_metric = 1
        rip.device_attr['dev1'].vrf_attr[None].address_family_attr['ipv4 unicast'].distance = 120
        rip.device_attr['dev1'].vrf_attr[None].address_family_attr['ipv4 unicast'].redistribute_direct_rmap\
            = 'rmap1'
        rip.device_attr['dev1'].vrf_attr[None].address_family_attr['ipv4 unicast'].redistribute_static_rmap\
            = 'rmap2'
        rip.device_attr['dev1'].vrf_attr[None].address_family_attr['ipv4 unicast'].redistribute_lisp_rmap\
            = 'rmap3'
        rip.device_attr['dev1'].vrf_attr[None].address_family_attr['ipv6 unicast'].maximum_paths = 7
        rip.device_attr['dev1'].vrf_attr[None].address_family_attr['ipv6 unicast'].default_metric = 3
        rip.device_attr['dev1'].vrf_attr[None].address_family_attr['ipv6 unicast'].distance = 120
        rip.device_attr['dev1'].vrf_attr[None].address_family_attr['ipv6 unicast'].redistribute_direct_rmap\
            = 'rmap4'
        rip.device_attr['dev1'].vrf_attr[None].address_family_attr['ipv6 unicast'].redistribute_static_rmap\
            = 'rmap5'
        rip.device_attr['dev1'].vrf_attr[None].address_family_attr['ipv6 unicast'].redistribute_lisp_rmap\
            = 'rmap6'

        rip.device_attr['dev2'].vrf_attr[None].address_family_attr['ipv4 unicast'].maximum_paths = 4
        rip.device_attr['dev2'].vrf_attr[None].address_family_attr['ipv4 unicast'].default_metric = 3
        rip.device_attr['dev2'].vrf_attr[None].address_family_attr['ipv4 unicast'].distance = 122
        rip.device_attr['dev2'].vrf_attr[None].address_family_attr['ipv4 unicast'].redistribute_direct_rmap\
            = 'rmap_direct'
        rip.device_attr['dev2'].vrf_attr[None].address_family_attr['ipv4 unicast'].redistribute_static_rmap\
            = 'rmap_static'
        rip.device_attr['dev2'].vrf_attr[None].address_family_attr['ipv4 unicast'].redistribute_lisp_rmap\
            = 'rmap_lisp'
        rip.device_attr['dev2'].vrf_attr[None].address_family_attr['ipv6 unicast'].maximum_paths = 7
        rip.device_attr['dev2'].vrf_attr[None].address_family_attr['ipv6 unicast'].default_metric = 3
        rip.device_attr['dev2'].vrf_attr[None].address_family_attr['ipv6 unicast'].distance = 120
        rip.device_attr['dev2'].vrf_attr[None].address_family_attr['ipv6 unicast'].redistribute_direct_rmap\
            = 'rmap_direct_ipv6'
        rip.device_attr['dev2'].vrf_attr[None].address_family_attr['ipv6 unicast'].redistribute_static_rmap\
            = 'rmap_static_ipv6'
        rip.device_attr['dev2'].vrf_attr[None].address_family_attr['ipv6 unicast'].redistribute_lisp_rmap\
            = 'rmap_lisp_ipv6'

        output = rip.build_config(apply=False)
        expected_output = {'dev1': '''\
router rip 1
 shutdown
 address-family ipv4 unicast
  default-metric 1
  distance 120
  maximum-paths 2
  redistribute lisp route-map rmap3
  redistribute direct route-map rmap1
  redistribute static route-map rmap2
  exit
 address-family ipv6 unicast
  default-metric 3
  distance 120
  maximum-paths 7
  redistribute lisp route-map rmap6
  redistribute direct route-map rmap4
  redistribute static route-map rmap5
  exit
 exit''',
'dev2': '''\
router rip 1
 shutdown
 address-family ipv4 unicast
  default-metric 3
  distance 122
  maximum-paths 4
  redistribute lisp route-map rmap_lisp
  redistribute direct route-map rmap_direct
  redistribute static route-map rmap_static
  exit
 address-family ipv6 unicast
  default-metric 3
  distance 120
  maximum-paths 7
  redistribute lisp route-map rmap_lisp_ipv6
  redistribute direct route-map rmap_direct_ipv6
  redistribute static route-map rmap_static_ipv6
  exit
 exit'''}
        self.maxDiff = None
        self.assertMultiLineDictEqual(output, expected_output)
        output = rip.build_config(apply=True)
Esempio n. 12
0
    def test_basic_uncfg(self):
        testbed = Genie.testbed = Testbed()
        dev1 = Device(testbed=testbed, name='PE1', os='nxos')
        dev2 = Device(testbed=testbed, name='PE2', os='nxos')
        intf1 = Interface(name='Ethernet0/0/1', device=dev1, layer=Layer.L3)
        intf2 = Interface(name='Ethernet0/0/2', device=dev2, layer=Layer.L2)
        link = Link(name='1_2_1', testbed=testbed)
        link.connect_interface(interface=intf1)
        link.connect_interface(interface=intf2)
        vlan = Vlan()
        link.add_feature(vlan)
        vlan.vlan_id = 100
        access_map_id = 'ed'
        vlan_configuration_id = '3'

        vlan.device_attr[dev1]
        vlan.device_attr[dev2]
        vlan.device_attr[dev1].access_map_attr[access_map_id]
        vlan.device_attr[dev2].access_map_attr[access_map_id]
        vlan.device_attr[dev1].interface_attr[intf1]
        vlan.device_attr[dev2].interface_attr[intf2]
        vlan.device_attr[dev2].interface_attr[intf2].switchport_mode = \
            L2_type.TRUNK
        vlan.device_attr[dev2].interface_attr[intf2].sw_trunk_allowed_vlan = \
            '200-201'
        vlan.device_attr[dev1].vlan_configuration_attr[vlan_configuration_id]
        vlan.device_attr[dev2].vlan_configuration_attr[vlan_configuration_id]

        # Defining attributes section
        vlan.shutdown = False
        with self.assertRaises(ValueError):
            vlan.media = 'invalid'
        vlan.media = 'enet'
        self.assertIs(type(vlan.media), Vlan.Media)
        vlan.egress_port_channel_load_balance_random = True
        vlan.device_attr[dev1].access_map_action = 'drop'
        vlan.datalink_flow_monitor = True

        # Unconfig testing
        # Set a mock
        dev1.cli = Mock()
        dev1.configure = Mock()
        dev2.cli = Mock()
        dev2.configure = Mock()
        dev1.add_feature(vlan)
        dev2.add_feature(vlan)
        # Mock config

        output = vlan.build_config(apply=True)

        uncfg1 = vlan.build_unconfig(apply=False)
        self.assertCountEqual(uncfg1.keys(), ['PE1', 'PE2'])
        self.assertMultiLineEqual(
            str(uncfg1['PE1']),
            '\n'.join([
                'no vlan 100',
                'no vlan access-map ed',
                'no vlan configuration 3',
            ]))

        self.assertMultiLineEqual(
            str(uncfg1['PE2']),
            '\n'.join([
                'no vlan 100',
                'no vlan access-map ed',
                'no vlan configuration 3',
                'interface Ethernet0/0/2',
                ' no switchport mode trunk',
                ' no switchport trunk allowed vlan 200-201',
                ' exit',
            ]))

        partial_uncfg1 = vlan.build_unconfig(apply=False,
                                             attributes={'device_attr': \
                                                             {'*': "media"}})
        self.assertCountEqual(partial_uncfg1.keys(), ['PE1', 'PE2'])
        self.assertMultiLineEqual(
            str(partial_uncfg1['PE1']),
            '\n'.join([
                'vlan 100',
                ' no media enet',
                ' exit',
            ]))

        partial_unconfigure = vlan.build_unconfig(apply=False,
                                                  attributes={'device_attr': \
                                                                  {'*': {'access_map_attr': \
                                                                             {'*': "access_map_action"}}}})
        self.assertCountEqual(partial_unconfigure.keys(), ['PE1', 'PE2'])
        self.assertMultiLineEqual(
            str(partial_unconfigure['PE1']),
            '\n'.join([
                'vlan access-map ed',
                ' no action drop',
                ' exit',
            ]))

        all_vlan_interface_uncfg = vlan.build_unconfig(apply=False,
                                                       attributes={ \
                                                           'device_attr': {'*': { \
                                                               'interface_attr': '*'}}})
        self.assertCountEqual(all_vlan_interface_uncfg.keys(), ['PE1', 'PE2'])
        self.assertMultiLineEqual(
            str(all_vlan_interface_uncfg['PE2']),
            '\n'.join([
                'interface Ethernet0/0/2',
                ' no switchport mode trunk',
                ' no switchport trunk allowed vlan 200-201',
                ' exit',
            ]))

        partial_vlan_interface_uncfg = vlan.build_unconfig(apply=False,
                                                           attributes={ \
                                                               'device_attr': {'*': \
                                                                                   {'interface_attr': \
                                                                                        {
                                                                                            '*': "sw_trunk_allowed_vlan"}}}})
        self.assertCountEqual(partial_vlan_interface_uncfg.keys(), ['PE1', 'PE2'])
        self.assertMultiLineEqual(
            str(partial_vlan_interface_uncfg['PE2']),
            '\n'.join([
                'interface Ethernet0/0/2',
                ' no switchport trunk allowed vlan 200-201',
                ' exit',
            ]))
Esempio n. 13
0
    def test_basic_uncfg(self):
        testbed = Genie.testbed = Testbed()
        dev1 = Device(testbed=testbed, name='PE1', os='iosxr')
        dev2 = Device(testbed=testbed, name='PE2', os='iosxr')
        intf1 = Interface(name='GigabitEthernet0/0/1', device=dev1)
        intf2 = Interface(name='GigabitEthernet0/0/2', device=dev2)
        intf3 = Interface(name='GigabitEthernet0/0/3', device=dev1)
        link = Link(name='1_2_1', testbed=testbed)
        link.connect_interface(interface=intf1)
        link.connect_interface(interface=intf2)
        vlan = Vlan()
        link.add_feature(vlan)

        # Defining attributes section
        vlan.device_attr[dev1]
        vlan.device_attr[dev2]
        vlan.device_attr[dev1].interface_attr[intf1]
        vlan.device_attr[dev1].interface_attr[intf1].eth_encap_type1 = 'dot1q'
        vlan.device_attr[dev1].interface_attr[intf1].eth_encap_val1 = 2
        vlan.device_attr[dev1].interface_attr[
            intf1].eth_encap_type2 = 'second-dot1q'
        vlan.device_attr[dev1].interface_attr[intf1].eth_encap_val2 = 5

        # Unconfig testing
        # Set a mock
        dev1.cli = Mock()
        dev1.configure = Mock()
        dev2.cli = Mock()
        dev2.configure = Mock()
        dev1.add_feature(vlan)
        dev2.add_feature(vlan)
        # Mock config

        output = vlan.build_config(apply=True)

        uncfg = vlan.build_unconfig(apply=False)
        self.assertMultiLineEqual(
            str(uncfg['PE1']), '\n'.join([
                'interface GigabitEthernet0/0/1',
                ' no encapsulation dot1q 2 second-dot1q 5',
                ' exit',
            ]))

        all_vlan_interface_uncfg = vlan.build_unconfig(apply=False,
                                                       attributes={'device_attr':\
                                                       {'*':{'interface_attr':'*'}}})
        self.assertCountEqual(all_vlan_interface_uncfg.keys(), ['PE1', 'PE2'])
        self.assertMultiLineEqual(
            str(all_vlan_interface_uncfg['PE1']), '\n'.join([
                'interface GigabitEthernet0/0/1',
                ' no encapsulation dot1q 2 second-dot1q 5',
                ' exit',
            ]))

        partial_vlan_interface_uncfg = vlan.build_unconfig(apply=False,
                                                           attributes={'device_attr':\
                                                           {'*':{'interface_attr':\
                                                           {'*':"eth_encap_type1"}}}})
        self.assertCountEqual(partial_vlan_interface_uncfg.keys(),
                              ['PE1', 'PE2'])
        self.assertMultiLineEqual(
            str(partial_vlan_interface_uncfg['PE1']), '\n'.join([
                'interface GigabitEthernet0/0/1',
                ' no encapsulation dot1q 2 second-dot1q 5',
                ' exit',
            ]))