def populate_facts(self, connection, ansible_facts, data=None):
        """ Populate the facts for lldp_global
        :param connection: the device connection
        :param ansible_facts: Facts dictionary
        :param data: previously collected conf
        :rtype: dictionary
        :returns: facts
        """
        objs = dict()
        if not data:
            data = connection.get('show running-config | section ^lldp')
        # operate on a collection of resource x
        config = data.split('\n')
        for conf in config:
            if conf:
                obj = self.render_config(self.generated_spec, conf)
                if obj:
                    objs.update(obj)
        facts = {}

        if objs:
            params = utils.validate_config(
                self.argument_spec, {'config': utils.remove_empties(objs)})
            facts['lldp_global'] = utils.remove_empties(params['config'])
        ansible_facts['ansible_network_resources'].update(facts)

        return ansible_facts
    def _purge_attribs(self, intf):
        """ The command generator for purging attributes
        :rtype: A list
        :returns: the commands necessary to purge attributes
        """
        commands = []
        have_copy = deepcopy(intf)
        members = have_copy.pop('members', [])

        to_delete = dict_delete(have_copy, remove_empties({'name': have_copy['name']}))
        if to_delete:
            for key, value in iteritems(flatten_dict(remove_empties(to_delete))):
                commands.append(self._compute_commands(key=key, value=value, remove=True))

        if commands:
            pad_commands(commands, intf['name'])

        if members:
            members = param_list_to_dict(deepcopy(members), unique_key='member')
            for key in members:
                member_cmd = ['no bundle id']
                pad_commands(member_cmd, key)
                commands.extend(member_cmd)

        return commands
Example #3
0
    def populate_facts(self, connection, ansible_facts, data=None):
        """ Populate the facts for interfaces
        :param connection: the device connection
        :param data: previously collected configuration as lxml ElementTree root instance
                     or valid xml sting
        :rtype: dictionary
        :returns: facts
        """
        if not HAS_LXML:
            self._module.fail_json(msg='lxml is not installed.')

        if not data:
            config_filter = """
                <configuration>
                    <chassis>
                        <aggregated-devices>
                            <ethernet>
                                <lacp>
                                </lacp>
                            </ethernet>
                        </aggregated-devices>
                    </chassis>
                </configuration>
                """
            data = get_resource_config(connection, config_filter=config_filter)

        if isinstance(data, string_types):
            data = etree.fromstring(
                to_bytes(data, errors='surrogate_then_replace'))

        facts = {}
        config = deepcopy(self.generated_spec)
        resources = data.xpath(
            'configuration/chassis/aggregated-devices/ethernet/lacp')
        if resources:

            lacp_root = resources[0]
            config['system_priority'] = utils.get_xml_conf_arg(
                lacp_root, 'system-priority')

            if utils.get_xml_conf_arg(lacp_root,
                                      'link-protection/non-revertive',
                                      data='tag'):
                config['link_protection'] = "non-revertive"

            elif utils.get_xml_conf_arg(lacp_root, 'link-protection'):
                config['link_protection'] = "revertive"

        params = utils.validate_config(
            self.argument_spec, {'config': utils.remove_empties(config)})
        facts['lacp'] = {}
        facts['lacp'].update(utils.remove_empties(params['config']))

        ansible_facts['ansible_network_resources'].update(facts)

        return ansible_facts
    def populate_facts(self, connection, ansible_facts, data=None):
        """ Populate the facts for hsrp_interfaces
        :param connection: the device connection
        :param ansible_facts: Facts dictionary
        :param data: previously collected conf
        :rtype: dictionary
        :returns: facts
        """
        objs = []

        if not data:
            data = connection.get('show running-config | section ^interface')

        resources = data.split('interface ')
        for resource in resources:
            if resource:
                obj = self.render_config(self.generated_spec, resource)
                if obj and len(obj.keys()) > 1:
                    objs.append(obj)

        ansible_facts['ansible_network_resources'].pop('hsrp_interfaces', None)
        facts = {}
        if objs:
            facts['hsrp_interfaces'] = []
            params = utils.validate_config(self.argument_spec,
                                           {'config': objs})
            for cfg in params['config']:
                facts['hsrp_interfaces'].append(utils.remove_empties(cfg))

        ansible_facts['ansible_network_resources'].update(facts)
        return ansible_facts
    def populate_facts(self, connection, ansible_facts, data=None):
        """ Populate the facts for interfaces
        :param connection: the device connection
        :param ansible_facts: Facts dictionary
        :param data: previously collected conf
        :rtype: dictionary
        :returns: facts
        """
        if not data:
            data = connection.get_config(flags=['| grep interfaces'])

        objs = []
        interface_names = findall(r'^set interfaces (?:ethernet|bonding|vti|loopback|vxlan) (?:\'*)(\S+)(?:\'*)',
                                  data, M)
        if interface_names:
            for interface in set(interface_names):
                intf_regex = r' %s .+$' % interface.strip("'")
                cfg = findall(intf_regex, data, M)
                obj = self.render_config(cfg)
                obj['name'] = interface.strip("'")
                if obj:
                    objs.append(obj)
        facts = {}
        if objs:
            facts['interfaces'] = []
            params = utils.validate_config(self.argument_spec, {'config': objs})
            for cfg in params['config']:
                facts['interfaces'].append(utils.remove_empties(cfg))

        ansible_facts['ansible_network_resources'].update(facts)
        return ansible_facts
Example #6
0
    def render_config(self, spec, conf):
        """
        Render config as dictionary structure and delete keys
          from spec for null values
        :param spec: The facts tree, generated from the argspec
        :param conf: The configuration
        :rtype: dictionary
        :returns: The generated config
        """
        config = deepcopy(spec)

        match = re.search(r'^(\S+)', conf)
        intf = match.group(1)
        if get_interface_type(intf) == 'unknown':
            return {}

        config['name'] = intf
        config['ip_forward'] = utils.parse_conf_arg(conf, 'ip forward')
        config['access']['vlan'] = utils.parse_conf_arg(
            conf, 'switchport access vlan')
        config['trunk']['allowed_vlans'] = utils.parse_conf_arg(
            conf, 'switchport trunk allowed vlan')
        config['trunk']['native_vlan'] = utils.parse_conf_arg(
            conf, 'switchport trunk native vlan')

        return utils.remove_empties(config)
Example #7
0
    def populate_facts(self, connection, ansible_facts, data=None):
        """ Populate the facts for lacp_interfaces
        :param connection: the device connection
        :param ansible_facts: Facts dictionary
        :param data: previously collected configuration
        :rtype: dictionary
        :returns: facts
        """
        if not data:
            data = self.get_device_data(connection)

        # split the config into instances of the resource
        resource_delim = 'interface'
        find_pattern = r'(?:^|\n)%s.*?(?=(?:^|\n)%s|$)' % (resource_delim, resource_delim)
        resources = [p.strip() for p in re.findall(find_pattern, data, re.DOTALL)]

        objs = []
        for resource in resources:
            if resource:
                obj = self.render_config(self.generated_spec, resource)
                if obj:
                    objs.append(obj)

        ansible_facts['ansible_network_resources'].pop('lacp_interfaces', None)
        facts = {}
        if objs:
            params = utils.validate_config(self.argument_spec, {'config': objs})
            facts['lacp_interfaces'] = [utils.remove_empties(cfg) for cfg in params['config']]

        ansible_facts['ansible_network_resources'].update(facts)
        return ansible_facts
    def render_config(self, spec, conf):
        """
        Render config as dictionary structure and delete keys
          from spec for null values

        :param spec: The facts tree, generated from the argspec
        :param conf: The ElementTree instance of configuration object
        :rtype: dictionary
        :returns: The generated config
        """
        config = deepcopy(spec)
        config['name'] = utils.get_xml_conf_arg(conf, 'name')
        config['description'] = utils.get_xml_conf_arg(conf, 'description')
        mtu = utils.get_xml_conf_arg(conf, 'mtu')
        config['mtu'] = int(mtu) if mtu else None
        config['speed'] = utils.get_xml_conf_arg(conf, 'speed')
        config['duplex'] = utils.get_xml_conf_arg(conf, 'link-mode')
        config['hold_time']['down'] = utils.get_xml_conf_arg(
            conf, 'hold-time/down')
        config['hold_time']['up'] = utils.get_xml_conf_arg(
            conf, 'hold-time/up')
        disable = utils.get_xml_conf_arg(conf, 'disable', data='tag')
        if disable:
            config['enabled'] = False
        else:
            config['enabled'] = True
        return utils.remove_empties(config)
Example #9
0
    def populate_facts(self, connection, ansible_facts, data=None):
        """ Populate the facts for lldp_global
        :param connection: the device connection
        :param ansible_facts: Facts dictionary
        :param data: previously collected conf
        :rtype: dictionary
        :returns: facts
        """
        if not data:
            data = connection.get_config()

        objs = {}
        lldp_output = findall(r'^set service lldp (\S+)', data, M)
        if lldp_output:
            for item in set(lldp_output):
                lldp_regex = r' %s .+$' % item
                cfg = findall(lldp_regex, data, M)
                obj = self.render_config(cfg)
                if obj:
                    objs.update(obj)
        lldp_service = findall(r"^set service (lldp)?('lldp')", data, M)
        if lldp_service or lldp_output:
            lldp_obj = {}
            lldp_obj['enable'] = True
            objs.update(lldp_obj)

        facts = {}
        params = utils.validate_config(self.argument_spec, {'config': objs})
        facts['lldp_global'] = utils.remove_empties(params['config'])

        ansible_facts['ansible_network_resources'].update(facts)

        return ansible_facts
    def render_config(self, spec, conf):
        """
        Render config as dictionary structure and delete keys
          from spec for null values
        :param spec: The facts tree, generated from the argspec
        :param conf: The ElementTree instance of configuration object
        :rtype: dictionary
        :returns: The generated config
        """
        config = deepcopy(spec)
        config['name'] = utils.get_xml_conf_arg(conf, 'name')
        config['period'] = utils.get_xml_conf_arg(
            conf, 'aggregated-ether-options/lacp/periodic')
        config['sync_reset'] = utils.get_xml_conf_arg(
            conf, 'aggregated-ether-options/lacp/sync-reset')
        force_up = utils.get_xml_conf_arg(
            conf, 'ether-options/ieee-802.3ad/lacp/force-up', data='tag')
        if force_up:
            config['force_up'] = True
        config['port_priority'] = utils.get_xml_conf_arg(
            conf, 'ether-options/ieee-802.3ad/lacp/port-priority')
        config['system']['priority'] = utils.get_xml_conf_arg(
            conf, 'aggregated-ether-options/lacp/system-priority')
        address = utils.get_xml_conf_arg(
            conf, 'aggregated-ether-options/lacp/system-id')
        if address:
            config['system'].update({'mac': {'address': address}})

        lacp_intf_cfg = utils.remove_empties(config)
        # if lacp config is not present for interface return empty dict
        if len(lacp_intf_cfg) == 1:
            return {}
        else:
            return lacp_intf_cfg
Example #11
0
    def render_config(self, spec, conf):
        """
        Render config as dictionary structure and delete keys
          from spec for null values

        :param spec: The facts tree, generated from the argspec
        :param conf: The configuration
        :rtype: dictionary
        :returns: The generated config
        """
        config = deepcopy(spec)

        config['name'] = utils.parse_conf_arg(conf, 'interface')

        matches = re.findall(r'.*ip address (.+)$', conf, re.MULTILINE)
        if matches:
            config["ipv4"] = []
            for match in matches:
                address, dummy, remainder = match.partition(" ")
                ipv4 = {"address": address}
                if remainder == "secondary":
                    ipv4["secondary"] = True
                config['ipv4'].append(ipv4)

        matches = re.findall(r'.*ipv6 address (.+)$', conf, re.MULTILINE)
        if matches:
            config["ipv6"] = []
            for match in matches:
                address, dummy, remainder = match.partition(" ")
                ipv6 = {"address": address}
                config['ipv6'].append(ipv6)

        return utils.remove_empties(config)
    def render_config(self, spec, vlan):
        """
        Render config as dictionary structure and delete keys
          from spec for null values
        :param spec: The facts tree, generated from the argspec
        :param vlan: structured data vlan settings (dict) and raw cfg from device
        :rtype: dictionary
        :returns: The generated config
        Sample inputs: test/units/modules/network/nxos/fixtures/nxos_vlans/show_vlan
        """
        obj = deepcopy(spec)

        obj['vlan_id'] = vlan['vlan_id']

        # name: 'VLAN000x' (default name) or custom name
        name = vlan['vlanshowbr-vlanname']
        if name and re.match("VLAN%04d" % int(vlan['vlan_id']), name):
            name = None
        obj['name'] = name

        # mode: 'ce-vlan' or 'fabricpath-vlan'
        obj['mode'] = vlan['vlanshowinfo-vlanmode'].replace('-vlan', '')

        # enabled: shutdown, noshutdown
        obj['enabled'] = True if 'noshutdown' in vlan[
            'vlanshowbr-shutstate'] else False

        # state: active, suspend
        obj['state'] = vlan['vlanshowbr-vlanstate']

        # non-structured data
        obj['mapped_vni'] = parse_conf_arg(vlan['run_cfg'], 'vn-segment')

        return utils.remove_empties(obj)
    def render_config(self, spec, conf):
        """
        Render config as dictionary structure and delete keys
          from spec for null values

        :param spec: The facts tree, generated from the argspec
        :param conf: The configuration
        :rtype: dictionary
        :returns: The generated config
        """
        config = deepcopy(spec)
        match = re.search(r'^(\S+)', conf)
        intf = match.group(1)
        if get_interface_type(intf) == 'unknown':
            return {}

        config['name'] = normalize_interface(intf)
        port_priority = utils.parse_conf_arg(conf, 'lacp port-priority')
        max_bundle = utils.parse_conf_arg(conf, 'lacp max-bundle')
        if port_priority:
            config['port_priority'] = int(port_priority)
        if 'lacp fast-switchover' in conf:
            config['fast_switchover'] = True
        if max_bundle:
            config['max_bundle'] = int(max_bundle)

        return utils.remove_empties(config)
    def populate_facts(self, connection, ansible_facts, data=None):
        """ Populate the facts for lldp_interfaces
        :param connection: the device connection
        :param ansible_facts: Facts dictionary
        :param data: previously collected conf
        :rtype: dictionary
        :returns: facts
        """

        if not data:
            data = connection.get_config(flags='interface')
            interfaces = data.split('interface ')

        objs = []
        for interface in interfaces:
            obj = self.render_config(self.generated_spec, interface)
            if obj:
                objs.append(obj)

        ansible_facts['ansible_network_resources'].pop('lldp_interfaces', None)
        facts = {}

        if objs:
            facts['lldp_interfaces'] = []
            params = utils.validate_config(self.argument_spec,
                                           {'config': objs})
            for cfg in params['config']:
                facts['lldp_interfaces'].append(utils.remove_empties(cfg))

        ansible_facts['ansible_network_resources'].update(facts)
        return ansible_facts
Example #15
0
    def populate_facts(self, connection, ansible_facts, data=None):
        """ Populate the facts for l3 interfaces
        :param connection: the device connection
        :param ansible_facts: Facts dictionary
        :param data: previously collected conf
        :rtype: dictionary
        :returns: facts
        """
        objs = []

        if not data:
            data = connection.get('show running-config | section ^interface')
        # operate on a collection of resource x
        config = data.split('interface ')
        for conf in config:
            if conf:
                obj = self.render_config(self.generated_spec, conf)
                if obj:
                    objs.append(obj)
        facts = {}

        if objs:
            facts['l3_interfaces'] = []
            params = utils.validate_config(self.argument_spec, {'config': objs})
            for cfg in params['config']:
                facts['l3_interfaces'].append(utils.remove_empties(cfg))
        ansible_facts['ansible_network_resources'].update(facts)

        return ansible_facts
Example #16
0
    def populate_facts(self, connection, ansible_facts, data=None):
        """ Populate the facts for lldp
        :param connection: the device connection
        :param ansible_facts: Facts dictionary
        :param data: previously collected conf
        :rtype: dictionary
        :returns: facts
        """
        if not data:
            data = connection.get_config(flags='lldp')

        obj = {}
        if data:
            lldp_obj = self.render_config(self.generated_spec, data)
            if lldp_obj:
                obj = lldp_obj

        ansible_facts['ansible_network_resources'].pop('lldp_global', None)
        facts = {}

        params = utils.validate_config(self.argument_spec, {'config': obj})
        facts['lldp_global'] = utils.remove_empties(params['config'])

        ansible_facts['ansible_network_resources'].update(facts)
        return ansible_facts
    def render_config(self, spec, conf):
        """
        Render config as dictionary structure and delete keys
          from spec for null values

        :param spec: The facts tree, generated from the argspec
        :param conf: The configuration
        :rtype: dictionary
        :returns: The generated config
        """
        config = deepcopy(spec)

        match = re.search(
            r'(GigabitEthernet|Bundle-Ether|TenGigE|FortyGigE|HundredGigE)(\S+)',
            conf, re.M)
        if match:
            config['name'] = match.group(1) + match.group(2)

            for key in ['receive', 'transmit']:
                config[key] = False if (
                    '{0} disable'.format(key)) in conf else None

            for x in ['ieee-nearest-bridge', 'ieee-nearest-non-tmpr-bridge']:
                if x in conf:
                    config['destination']['mac_address'] = x

        return utils.remove_empties(config)
    def render_config(self, spec, conf):
        """
        Render config as dictionary structure and delete keys
          from spec for null values

        :param spec: The facts tree, generated from the argspec
        :param conf: The configuration
        :rtype: dictionary
        :returns: The generated config
        """
        config = deepcopy(spec)

        match = re.search(r'^(\S+)', conf)
        intf = match.group(1)
        if get_interface_type(intf) == 'unknown':
            return {}
        config['name'] = intf
        # 'bfd'/'bfd echo' do not nvgen when enabled thus set to 'enable' when None.
        # 'bfd' is not supported on some platforms
        config['bfd'] = utils.parse_conf_cmd_arg(conf, 'bfd', 'enable',
                                                 'disable') or 'enable'
        config['echo'] = utils.parse_conf_cmd_arg(conf, 'bfd echo', 'enable',
                                                  'disable') or 'enable'

        return utils.remove_empties(config)
    def populate_facts(self, connection, ansible_facts, data=None):
        """ Populate the facts for lag_interfaces
        :param connection: the device connection
        :param data: previously collected conf
        :rtype: dictionary
        :returns: facts
        """
        objs = []
        if not data:
            data = connection.get('show running-config | include channel-group')
        config = re.split('(\n  |)channel-group ', data)
        config = list(dict.fromkeys(config))
        for conf in config:
            if conf:
                obj = self.render_config(self.generated_spec, conf, connection)
                if obj and len(obj.keys()) > 1:
                    objs.append(obj)

        ansible_facts['ansible_network_resources'].pop('lag_interfaces', None)
        facts = {}
        if objs:
            facts['lag_interfaces'] = []
            params = utils.validate_config(self.argument_spec, {'config': objs})
            for cfg in params['config']:
                facts['lag_interfaces'].append(utils.remove_empties(cfg))

        ansible_facts['ansible_network_resources'].update(facts)
        return ansible_facts
Example #20
0
    def render_config(self, spec, conf):
        """
        Render config as dictionary structure and delete keys from spec for null values
        :param spec: The facts tree, generated from the argspec
        :param conf: The configuration
        :rtype: dictionary
        :returns: The generated config
        """

        config = deepcopy(spec)
        match = re.search(r'^(\S+)', conf)

        intf = match.group(1)
        if match.group(1).lower() == "preconfigure":
            match = re.search(r'^(\S+) (.*)', conf)
            if match:
                intf = match.group(2)

        if get_interface_type(intf) == 'unknown':
            return {}
        # populate the facts from the configuration
        config['name'] = intf
        config['description'] = utils.parse_conf_arg(conf, 'description')
        if utils.parse_conf_arg(conf, 'speed'):
            config['speed'] = int(utils.parse_conf_arg(conf, 'speed'))
        if utils.parse_conf_arg(conf, 'mtu'):
            config['mtu'] = int(utils.parse_conf_arg(conf, 'mtu'))
        config['duplex'] = utils.parse_conf_arg(conf, 'duplex')
        enabled = utils.parse_conf_cmd_arg(conf, 'shutdown', False)
        config['enabled'] = enabled if enabled is not None else True

        return utils.remove_empties(config)
    def render_config(self, spec, conf, connection):
        """
        Render config as dictionary structure and delete keys
          from spec for null values

        :param spec: The facts tree, generated from the argspec
        :param conf: The configuration
        :rtype: dictionary
        :returns: The generated config
        """
        config = deepcopy(spec)
        match = re.search(r'(\d+)( |)(force )?(mode \S+)?', conf, re.M)
        if match:
            matches = match.groups()
            config['name'] = 'port-channel' + str(matches[0])
            config['members'] = []
            members = self.get_members(config['name'].strip('port-channel'), connection)
            if members:
                for m in members:
                    m_dict = {}
                    if matches[2]:
                        m_dict['force'] = matches[2]
                    if matches[3]:
                        m_dict['mode'] = matches[3][5:]
                    m_dict['member'] = m
                    config['members'].append(m_dict)
        else:
            config = {}

        lag_intf_cfg = utils.remove_empties(config)
        # if lag interfaces config is not present return empty dict
        if len(lag_intf_cfg) == 1:
            return {}
        else:
            return lag_intf_cfg
    def render_config(self, spec, conf):
        """
        Render config as dictionary structure and delete keys
          from spec for null values

        :param spec: The facts tree, generated from the argspec
        :param conf: The configuration
        :rtype: dictionary
        :returns: The generated config
        """
        config = deepcopy(spec)

        p_match = re.search(r'lacp system-priority (\d+)', conf, re.M)
        if p_match:
            config['system']['priority'] = p_match.group(1)

        a_match = re.search(r'lacp system-mac (\S+)', conf, re.M)
        if a_match:
            address = a_match.group(1)
            config['system']['mac']['address'] = address
            r_match = re.search(
                r'lacp system-mac {0} role (\S+)'.format(address), conf, re.M)
            if r_match:
                config['system']['mac']['role'] = r_match.group(1)

        return utils.remove_empties(config)
    def render_config(self, spec, conf):
        """
        Render config as dictionary structure and delete keys from spec for null values

        :param spec: The facts tree, generated from the argspec
        :param conf: The configuration
        :rtype: dictionary
        :returns: The generated config
        """
        config = deepcopy(spec)

        # populate the facts from the configuration
        config['name'] = re.match(r'(\S+)', conf).group(1).replace('"', '')

        has_access = re.search(r"switchport access vlan (\d+)", conf)
        if has_access:
            config["access"] = {"vlan": int(has_access.group(1))}

        has_trunk = re.findall(r"switchport trunk (.+)", conf)
        if has_trunk:
            trunk = {}
            for match in has_trunk:
                has_native = re.match(r"native vlan (\d+)", match)
                if has_native:
                    trunk["native_vlan"] = int(has_native.group(1))
                    continue

                has_allowed = re.match(r"allowed vlan (\S+)", match)
                if has_allowed:
                    # TODO: listify?
                    trunk["trunk_allowed_vlans"] = has_allowed.group(1)
                    continue
            config['trunk'] = trunk

        return utils.remove_empties(config)
Example #24
0
    def render_config(self, spec, conf):
        """
        Render config as dictionary structure and delete keys
          from spec for null values
        :param spec: The facts tree, generated from the argspec
        :param conf: The configuration
        :rtype: dictionary
        :returns: The generated config
        """
        config = deepcopy(spec)
        match = re.search(r'^(\S+)', conf)
        intf = match.group(1)
        if get_interface_type(intf) == 'unknown':
            return {}
        config['name'] = intf
        config['dot1q'] = utils.parse_conf_arg(conf, 'encapsulation dot1[qQ]')
        config['redirects'] = utils.parse_conf_cmd_arg(conf, 'no ip redirects',
                                                       False, True)
        config['unreachables'] = utils.parse_conf_cmd_arg(
            conf, 'ip unreachables', True, False)
        ipv4_match = re.compile(r'\n  ip address (.*)')
        matches = ipv4_match.findall(conf)
        if matches:
            if matches[0]:
                config['ipv4'] = []
                for m in matches:
                    ipv4_conf = m.split()
                    addr = ipv4_conf[0]
                    if addr:
                        config_dict = {'address': addr}
                        if len(ipv4_conf) > 1:
                            d = ipv4_conf[1]
                            if d == 'secondary':
                                config_dict.update({'secondary': True})
                                if len(ipv4_conf) == 4:
                                    if ipv4_conf[2] == 'tag':
                                        config_dict.update(
                                            {'tag': int(ipv4_conf[-1])})
                            elif d == 'tag':
                                config_dict.update({'tag': int(ipv4_conf[-1])})
                        config['ipv4'].append(config_dict)

        ipv6_match = re.compile(r'\n  ipv6 address (.*)')
        matches = ipv6_match.findall(conf)
        if matches:
            if matches[0]:
                config['ipv6'] = []
                for m in matches:
                    ipv6_conf = m.split()
                    addr = ipv6_conf[0]
                    if addr:
                        config_dict = {'address': addr}
                        if len(ipv6_conf) > 1:
                            d = ipv6_conf[1]
                            if d == 'tag':
                                config_dict.update({'tag': int(ipv6_conf[-1])})
                        config['ipv6'].append(config_dict)

        return utils.remove_empties(config)
Example #25
0
    def render_config(self, spec, conf):
        """
        Render config as dictionary structure and delete keys
          from spec for null values
        :param spec: The facts tree, generated from the argspec
        :param conf: The ElementTree instance of configuration object
        :rtype: dictionary
        :returns: The generated config
        """
        config = deepcopy(spec)
        intf_name = utils.get_xml_conf_arg(conf, 'name')
        if intf_name.startswith('ae'):
            config['name'] = intf_name
            config['members'] = []
            for interface_obj in self._resources:
                lag_interface_member = utils.get_xml_conf_arg(
                    interface_obj,
                    "ether-options/ieee-802.3ad[bundle='%s']/../../name" %
                    intf_name)
                if lag_interface_member:
                    member_config = {}
                    member_config['member'] = lag_interface_member
                    if utils.get_xml_conf_arg(
                            interface_obj,
                            "ether-options/ieee-802.3ad/primary",
                            data='tag'):
                        member_config['link_type'] = "primary"
                    elif utils.get_xml_conf_arg(
                            interface_obj,
                            "ether-options/ieee-802.3ad/backup",
                            data='tag'):
                        member_config['link_type'] = "backup"

                    if member_config:
                        config['members'].append(member_config)

                for m in ['active', 'passive']:
                    if utils.get_xml_conf_arg(
                            conf,
                            "aggregated-ether-options/lacp/%s" % m,
                            data='tag'):
                        config['mode'] = m
                        break

                link_protection = utils.get_xml_conf_arg(
                    conf,
                    "aggregated-ether-options/link-protection",
                    data='tag')
                if link_protection:
                    config['link_protection'] = True

        lag_intf_cfg = utils.remove_empties(config)
        # if lag interfaces config is not present return empty dict
        if len(lag_intf_cfg) == 1:
            return {}
        else:
            return lag_intf_cfg
Example #26
0
 def parse_attribs(self, attribs, conf):
     config = {}
     for item in attribs:
         value = utils.parse_conf_arg(conf, item)
         if value:
             config[item] = value.strip("'")
         else:
             config[item] = None
     return utils.remove_empties(config)
Example #27
0
    def render_config(self, spec, conf):
        """
        Render config as dictionary structure and delete keys from spec for null values
        :param spec: The facts tree, generated from the argspec
        :param conf: The configuration
        :rtype: dictionary
        :returns: The generated config
        """
        config = deepcopy(spec)
        match = re.search(r'^(\S+)', conf)

        intf = match.group(1)

        if match.group(1).lower() == "preconfigure":
            match = re.search(r'^(\S+) (.*)', conf)
            if match:
                intf = match.group(2)

        if get_interface_type(intf) == 'unknown':
            return {}

        if intf.lower().startswith('gi'):
            config['name'] = intf

            # populate the facts from the configuration
            native_vlan = re.search(r"dot1q native vlan (\d+)", conf)
            if native_vlan:
                config["native_vlan"] = int(native_vlan.group(1))

            dot1q = utils.parse_conf_arg(conf, 'encapsulation dot1q')
            config['q_vlan'] = []
            if dot1q:
                config['q_vlan'].append(int(dot1q.split(' ')[0]))
                if len(dot1q.split(' ')) > 1:
                    config['q_vlan'].append(int(dot1q.split(' ')[2]))

            if utils.parse_conf_cmd_arg(conf, 'l2transport', True):
                config['l2transport'] = True
            if utils.parse_conf_arg(conf, 'propagate'):
                config['propagate'] = True
            config['l2protocol'] = []

            cdp = utils.parse_conf_arg(conf, 'l2protocol cdp')
            pvst = utils.parse_conf_arg(conf, 'l2protocol pvst')
            stp = utils.parse_conf_arg(conf, 'l2protocol stp')
            vtp = utils.parse_conf_arg(conf, 'l2protocol vtp')
            if cdp:
                config['l2protocol'].append({'cdp': cdp})
            if pvst:
                config['l2protocol'].append({'pvst': pvst})
            if stp:
                config['l2protocol'].append({'stp': stp})
            if vtp:
                config['l2protocol'].append({'vtp': vtp})

            return utils.remove_empties(config)
    def populate_facts(self, connection, ansible_facts, data=None):
        """ Populate the facts for interfaces
        :param connection: the device connection
        :param data: previously collected configuration as lxml ElementTree root instance
                     or valid xml sting
        :rtype: dictionary
        :returns: facts
        """
        if not HAS_LXML:
            self._module.fail_json(msg='lxml is not installed.')

        if not data:
            config_filter = """
                <configuration>
                    <protocols>
                        <lldp>
                        </lldp>
                    </protocols>
                </configuration>
                """
            data = get_resource_config(connection, config_filter=config_filter)

        if isinstance(data, string_types):
            data = etree.fromstring(to_bytes(data, errors='surrogate_then_replace'))

        facts = {}
        config = deepcopy(self.generated_spec)
        resources = data.xpath('configuration/protocols/lldp')
        if resources:
            lldp_root = resources[0]
            config['address'] = utils.get_xml_conf_arg(lldp_root, 'management-address')
            config['interval'] = utils.get_xml_conf_arg(lldp_root, 'advertisement-interval')
            config['transmit_delay'] = utils.get_xml_conf_arg(lldp_root, 'transmit-delay')
            config['hold_multiplier'] = utils.get_xml_conf_arg(lldp_root, 'hold-multiplier')
            if utils.get_xml_conf_arg(lldp_root, 'disable', data='tag'):
                config['enable'] = False

        params = utils.validate_config(self.argument_spec, {'config': utils.remove_empties(config)})

        facts['lldp_global'] = utils.remove_empties(params['config'])
        ansible_facts['ansible_network_resources'].update(facts)

        return ansible_facts
    def _state_deleted(self, want, have):
        """ The command generator when state is deleted

        :rtype: A list
        :returns: the commands necessary to remove the current configuration
                  of the provided objects
        """
        commands = []

        want_copy = deepcopy(remove_empties(want))
        have_copy = deepcopy(have)

        want_vifs = want_copy.pop('vifs', [])
        have_vifs = have_copy.pop('vifs', [])

        for key in dict_delete(have_copy, want_copy).keys():
            if key == 'enabled':
                continue
            commands.append(
                self._compute_commands(key=key,
                                       interface=want_copy['name'],
                                       remove=True))
        if have_copy['enabled'] is False:
            commands.append(
                self._compute_commands(key='enabled',
                                       value=True,
                                       interface=want_copy['name']))

        if have_vifs:
            for have_vif in have_vifs:
                want_vif = search_obj_in_list(have_vif['vlan_id'],
                                              want_vifs,
                                              key='vlan_id')
                if not want_vif:
                    want_vif = {
                        'vlan_id': have_vif['vlan_id'],
                        'enabled': True
                    }

                for key in dict_delete(have_vif, want_vif).keys():
                    if key == 'enabled':
                        continue
                    commands.append(
                        self._compute_commands(key=key,
                                               interface=want_copy['name'],
                                               vif=want_vif['vlan_id'],
                                               remove=True))
                if have_vif['enabled'] is False:
                    commands.append(
                        self._compute_commands(key='enabled',
                                               value=True,
                                               interface=want_copy['name'],
                                               vif=want_vif['vlan_id']))

        return commands
Example #30
0
    def render_config(self, spec, conf):
        """
        Render config as dictionary structure and delete keys from spec for null values
        :param spec: The facts tree, generated from the argspec
        :param conf: The configuration
        :rtype: dictionary
        :returns: The generated config
        """
        config = deepcopy(spec)
        match = re.search(r'^(\S+)', conf)
        intf = match.group(1)

        if get_interface_type(intf) == 'unknown':
            return {}
        # populate the facts from the configuration
        config['name'] = normalize_interface(intf)

        ipv4 = []
        ipv4_all = re.findall(r"ip address (\S+.*)", conf)
        for each in ipv4_all:
            each_ipv4 = dict()
            if 'secondary' not in each and 'dhcp' not in each:
                each_ipv4['address'] = each
            elif 'secondary' in each:
                each_ipv4['address'] = each.split(' secondary')[0]
                each_ipv4['secondary'] = True
            elif 'dhcp' in each:
                each_ipv4['address'] = 'dhcp'
                if 'client-id' in each:
                    each_ipv4['dhcp_client'] = int(each.split(' hostname ')[0].split('/')[-1])
                if 'hostname' in each:
                    each_ipv4["dhcp_hostname"] = each.split(' hostname ')[-1]
                if 'client-id' in each and each_ipv4['dhcp_client'] is None:
                    each_ipv4['dhcp_client'] = int(each.split('/')[-1])
                if 'hostname' in each and not each_ipv4["dhcp_hostname"]:
                    each_ipv4["dhcp_hostname"] = each.split(' hostname ')[-1]
            ipv4.append(each_ipv4)
        config['ipv4'] = ipv4

        # Get the configured IPV6 details
        ipv6 = []
        ipv6_all = re.findall(r"ipv6 address (\S+)", conf)
        for each in ipv6_all:
            each_ipv6 = dict()
            if 'autoconfig' in each:
                each_ipv6['autoconfig'] = True
            if 'dhcp' in each:
                each_ipv6['dhcp'] = True
            each_ipv6['address'] = each.lower()
            ipv6.append(each_ipv6)
        config['ipv6'] = ipv6

        return utils.remove_empties(config)