示例#1
0
    def populate_facts(self, connection, ansible_facts, data=None):
        """ Populate the facts for lag_interfaces
        :param connection: the device connection
        :param data: previously collected configuration
        :rtype: dictionary
        :returns: facts
        """
        if not data:
            data = connection.get('show running-config | section ^interface')

        # 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:
                    group_name = obj['name']
                    if group_name in objs and "members" in obj:
                        config = objs[group_name]
                        if "members" not in config:
                            config["members"] = []
                        objs[group_name]['members'].extend(obj['members'])
                    else:
                        objs[group_name] = obj
        objs = list(objs.values())
        facts = {}
        if objs:
            params = utils.validate_config(self.argument_spec,
                                           {'config': objs})
            facts['lag_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 configuration
        :rtype: dictionary
        :returns: The generated config
        """
        config = deepcopy(spec)
        config['holdtime'] = utils.parse_conf_arg(conf, 'holdtime')
        config['reinit'] = utils.parse_conf_arg(conf, 'reinit')
        config['timer'] = utils.parse_conf_arg(conf, 'timer')

        for match in re.findall(r'^(no)? lldp tlv-select (\S+)', conf,
                                re.MULTILINE):
            tlv_option = match[1].replace("-", "_")
            config['tlv_select'][tlv_option] = bool(match[0] != "no")

        return utils.remove_empties(config)
示例#3
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['severity'] = conf.get('severity')

        syslog_value = conf.get('syslog')
        if syslog_value != None:
            syslog = []
            for each in syslog_value['host']:
                syslog.append(each['address'])
            config['syslog'] = syslog

        return utils.remove_empties(config)
示例#4
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['bfd'] = utils.parse_conf_cmd_arg(conf, 'hsrp bfd', 'enable',
                                                 'disable')

        return utils.remove_empties(config)
示例#5
0
 def populate_facts(self, connection, ansible_facts, data=None):
     """ Populate the facts for lacp
     :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("show running-config | include lacp")
     resources = data.strip()
     objs = self.render_config(self.generated_spec, resources)
     ansible_facts["ansible_network_resources"].pop("lacp", None)
     facts = {}
     if objs:
         params = utils.validate_config(
             self.argument_spec, {"config": objs}
         )
         facts["lacp"] = utils.remove_empties(params["config"])
     ansible_facts["ansible_network_resources"].update(facts)
     return ansible_facts
示例#6
0
    def _state_merged(want, have):
        """ The command generator when state is merged

        :rtype: A list
        :returns: the commands necessary to merge the provided into
                  the current configuration
        """
        commands = []

        if not have:
            have = {"name": want["name"]}

        for key, value in iteritems(
            flatten_dict(remove_empties(dict_diff(have, want)))
        ):
            commands.append(Lacp_interfaces._compute_commands(key, value))

        if commands:
            pad_commands(commands, want["name"])

        return commands
    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
        """
        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:
                    if not obj.get("members"):
                        obj.update({"members": []})
                    objs.append(obj)

        # for appending members configured with same channel-group
        for each in range(len(objs)):
            if each < (len(objs) - 1):
                if objs[each]["name"] == objs[each + 1]["name"]:
                    objs[each]["members"].append(objs[each + 1]["members"][0])
                    del objs[each + 1]
        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
示例#8
0
    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
        """
        objs = []

        if not data:
            data = connection.get('display eth-trunk')
        # operate on a collection of resource x
        config = re.split(r'\n\s*\n', data)
        for conf in config:
            if conf:
                obj = self.render_config(self.generated_spec, conf)
                if obj:
                    if not obj.get('members'):
                        obj.update({'members': []})
                    objs.append(obj)

        # for appending members configured with same eth-trunk
        for each in range(len(objs)):
            if each < (len(objs) - 1):
                if objs[each]['name'] == objs[each + 1]['name']:
                    objs[each]['members'].append(objs[each + 1]['members'][0])
                    del objs[each + 1]
        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
示例#9
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)
        status = ''
        holdtime_multiplier = ''
        timer = ''
        reinit = ''
        match = re.search(r'LLDP Status\s+:\s*(\S+)', conf)
        if match:
            status = match.group(1)

        match = re.search(r'LLDP Message Tx Interval\s+:\s*(\d+)', conf)
        if match:
            timer = int(match.group(1))

        match = re.search(r'LLDP Message Tx Hold Multiplier\s+:\s*(\d+)', conf)
        if match:
            holdtime_multiplier = int(match.group(1))

        match = re.search(r'LLDP Refresh Delay\s+:\s*(\d+)', conf)
        if match:
            reinit = match.group(1)

        if holdtime_multiplier:
            config['holdtime_multiplier'] = int(holdtime_multiplier)
        if status:
            config['enabled'] = True
        if timer:
            config['timer'] = int(timer)
        if reinit:
            config['reinit'] = int(reinit)

        return utils.remove_empties(config)
示例#10
0
    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 update in self._get_updates(have_copy, want_copy):
            for key, value in iteritems(update):
                commands.append(
                    self._compute_commands(key=key,
                                           value=value,
                                           interface=want_copy['name'],
                                           remove=True))

        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']}

                for update in self._get_updates(have_vif, want_vif):
                    for key, value in iteritems(update):
                        commands.append(
                            self._compute_commands(key=key,
                                                   interface=want_copy['name'],
                                                   value=value,
                                                   vif=want_vif['vlan_id'],
                                                   remove=True))

        return commands
示例#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)
        name = conf[0].strip()
        config['name'] = normalize_interface(name)
        config['access_groups'] = []
        v4 = {'afi': 'ipv4', 'acls': []}
        v6 = {'afi': 'ipv6', 'acls': []}
        for c in conf[1:]:
            if c:
                acl4 = re.search(r'ip( port)? access-group (\w*) (\w*)', c)
                acl6 = re.search(r'ipv6( port)? traffic-filter (\w*) (\w*)', c)
                if acl4:
                    acl = {
                        'name': acl4.group(2).strip(),
                        'direction': acl4.group(3).strip()
                    }
                    if acl4.group(1):
                        acl.update({'port': True})
                    v4['acls'].append(acl)
                elif acl6:
                    acl = {'name': acl6.group(2), 'direction': acl6.group(3)}
                    if acl6.group(1):
                        acl.update({'port': True})
                    v6['acls'].append(acl)

        if len(v4['acls']) > 0:
            config['access_groups'].append(v4)
        if len(v6['acls']) > 0:
            config['access_groups'].append(v6)

        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>
                    <interfaces/>
                </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'))

        self._resources = data.xpath('configuration/interfaces/interface')

        objs = []
        for resource in self._resources:
            if resource is not None:
                obj = self.render_config(self.generated_spec, resource)
                if obj:
                    objs.append(obj)
        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
示例#13
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 {}

        if intf.upper()[:2] in ('HU', 'FO', 'TW', 'TE', 'GI', 'FA', 'ET',
                                'PO'):
            # populate the facts from the configuration
            config['name'] = normalize_interface(intf)

            has_access = utils.parse_conf_arg(conf, 'switchport access vlan')
            if has_access:
                config["access"] = {"vlan": int(has_access)}

            trunk = dict()
            trunk["encapsulation"] = utils.parse_conf_arg(
                conf, 'encapsulation')
            native_vlan = utils.parse_conf_arg(conf, 'native vlan')
            if native_vlan:
                trunk["native_vlan"] = int(native_vlan)
            allowed_vlan = utils.parse_conf_arg(conf, 'allowed vlan')
            if allowed_vlan:
                trunk["allowed_vlans"] = allowed_vlan.split(',')
            pruning_vlan = utils.parse_conf_arg(conf, 'pruning vlan')
            if pruning_vlan:
                trunk['pruning_vlans'] = pruning_vlan.split(',')

            config['trunk'] = trunk

        return utils.remove_empties(config)
示例#14
0
    def populate_facts(self, connection, ansible_facts, data=None):
        """ Populate the facts for vlans
        :param connection: the device connection
        :param data: previously collected conf
        :rtype: dictionary
        :returns: facts
        """
        objs = []
        # **TBD**
        # N7K EOL/legacy image 6.2 does not support show vlan | json output.
        # If support is still required for this image then:
        # - Wrapp the json calls below in a try/except
        # - When excepted, use a helper method to parse the run_cfg_output,
        #   using the run_cfg_output data to generate compatible json data that
        #   can be read by normalize_table_data.
        if not data:
            # Use structured for most of the vlan parameter states.
            # This data is consistent across the supported nxos platforms.
            structured = self.get_device_data(connection, 'show vlan | json')

            # Raw cli config is needed for mapped_vni, which is not included in structured.
            run_cfg_output = self.get_device_data(connection, 'show running-config | section ^vlan')

            # Create a single dictionary from all data sources
            data = self.normalize_table_data(structured, run_cfg_output)

        for vlan in data:
            obj = self.render_config(self.generated_spec, vlan)
            if obj:
                objs.append(obj)

        ansible_facts['ansible_network_resources'].pop('vlans', None)
        facts = {}
        if objs:
            facts['vlans'] = []
            params = utils.validate_config(self.argument_spec, {'config': objs})
            for cfg in params['config']:
                facts['vlans'].append(utils.remove_empties(cfg))
        ansible_facts['ansible_network_resources'].update(facts)
        return ansible_facts
示例#15
0
    def populate_facts(self, connection, ansible_facts, data=None):
        """ Populate the facts for acl_interfaces
        :param connection: the device connection
        :param ansible_facts: Facts dictionary
        :param data: previously collected conf
        :rtype: dictionary
        :returns: facts
        """
        if not data:
            data = self.get_device_data(connection)
        data = data.split('interface')

        resources = []
        for i in range(len(data)):
            intf = data[i].split('\n')
            for l in range(1, len(intf)):
                if not re.search(
                        'ip(v6)?( port)? (access-group|traffic-filter)',
                        intf[l]):
                    intf[l] = ''
            intf = list(filter(None, intf))
            resources.append(intf)

        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('acl_interfaces', None)
        facts = {}
        if objs:
            params = utils.validate_config(self.argument_spec,
                                           {'config': objs})
            params = utils.remove_empties(params)
            facts['acl_interfaces'] = params['config']

        ansible_facts['ansible_network_resources'].update(facts)
        return ansible_facts
示例#16
0
    def set_config(self, existing_lldp_interfaces_facts):
        """ Collect the configuration from the args passed to the module,
            collect the current configuration (as a dict from facts)

        :rtype: A list
        :returns: the commands necessary to migrate the current configuration
                  to the desired configuration
        """
        config = self._module.params['config']
        want = []
        if config:
            for w in config:
                if get_interface_type(w['name']) not in ('management',
                                                         'ethernet'):
                    self._module.fail_json(
                        msg=
                        'This module works with either management or ethernet')
                w.update({'name': normalize_interface(w['name'])})
                want.append(remove_empties(w))
        have = existing_lldp_interfaces_facts
        resp = self.set_state(want, have)
        return to_list(resp)
示例#17
0
    def set_config(self, existing_l3_interfaces_facts):
        """ Collect the configuration from the args passed to the module,
            collect the current configuration (as a dict from facts)

        :rtype: A list
        :returns: the commands necessary to migrate the current configuration
                  to the desired configuration
        """
        config = self._module.params.get('config')
        want = []
        if config:
            for w in config:
                w.update({'name': normalize_interface(w['name'])})
                if get_interface_type(w['name']) == 'management':
                    self._module.fail_json(
                        msg=
                        "The 'management' interface is not allowed to be managed by this module"
                    )
                want.append(remove_empties(w))
        have = existing_l3_interfaces_facts
        resp = self.set_state(want, have)
        return to_list(resp)
示例#18
0
 def populate_facts(self, connection, ansible_facts, data=None):
     """ Populate the facts for firewall_global
     :param connection: the device connection
     :param ansible_facts: Facts dictionary
     :param data: previously collected conf
     :rtype: dictionary
     :returns: facts
     """
     if not data:
         # typically data is populated from the current device configuration
         # data = connection.get('show running-config | section ^interface')
         # using mock data instead
         data = self.get_device_data(connection)
     objs = {}
     firewalls = findall(r'^set firewall .*$', data, M)
     if firewalls:
         objs = self.render_config(firewalls)
     facts = {}
     params = utils.validate_config(self.argument_spec, {'config': objs})
     facts['firewall_global'] = utils.remove_empties(params['config'])
     ansible_facts['ansible_network_resources'].update(facts)
     return ansible_facts
示例#19
0
    def set_config(self, existing_interfaces_facts, default_intf_list):
        """ Collect the configuration from the args passed to the module,
            collect the current configuration (as a dict from facts)

        :rtype: A list
        :returns: the commands necessary to migrate the current configuration
                  to the desired configuration
        """
        config = self._module.params.get('config')
        want = []
        if config:
            for w in config:
                w.update({'name': normalize_interface(w['name'])})
                want.append(remove_empties(w))
        have = deepcopy(existing_interfaces_facts)
        for i in want:
            # 'have' does not include objects from the default_interfaces list.
            # Add any 'want' names from default_interfaces to the 'have' list.
            if i['name'] in default_intf_list:
                have.append({'name': i['name']})
        resp = self.set_state(want, have)
        return to_list(resp)
示例#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)
        vlans = []

        vlan_list = vlan_to_list(utils.parse_conf_arg(conf, 'vlan'))
        for vlan in vlan_list:
            config['vlan_id'] = vlan
            config['name'] = utils.parse_conf_arg(conf, 'name')
            config['state'] = utils.parse_conf_arg(conf, 'state')

            vlans.append(utils.remove_empties(config))

        return vlans
示例#21
0
    def __init__(self, *_args, **kwargs):
        self._empty_fact_val = kwargs.get('empty_fact_val', [])
        self._facts_module = kwargs.get('facts_module', None)
        self._gather_subset = kwargs.get('gather_subset', ['!all', '!min'])
        self._module = kwargs.get('module', None)
        self._resource = kwargs.get('resource', None)
        self._tmplt = kwargs.get('tmplt', None)

        self._connection = None
        self.state = self._module.params['state']

        self.before = self.gather_current()
        self.changed = False
        self.commands = []
        self.warnings = []

        self.have = deepcopy(self.before)
        self.want = remove_empties(
            self._module.params).get('config', self._empty_fact_val)

        self._get_connection()
        super(RmModule, self).__init__(tmplt=self._tmplt)
    def populate_facts(self, connection, ansible_facts, data=None):
        """ Populate the facts for bfd_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|^feature bfd'"
            )

        # Some of the bfd attributes
        if "feature bfd" in data.split("\n"):
            resources = data.split("interface ")
            resources.pop(0)
        else:
            resources = []
        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("bfd_interfaces", None)
        facts = {}
        if objs:
            facts["bfd_interfaces"] = []
            params = utils.validate_config(
                self.argument_spec, {"config": objs}
            )
            for cfg in params["config"]:
                facts["bfd_interfaces"].append(utils.remove_empties(cfg))

        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"^(\S+)", conf)
        intf = match.group(1)
        if get_interface_type(intf) == "unknown":
            return {}
        config["name"] = intf
        config["port_priority"] = utils.parse_conf_arg(conf,
                                                       "lacp port-priority")
        config["rate"] = utils.parse_conf_arg(conf, "lacp rate")
        config["mode"] = utils.parse_conf_arg(conf, "mode")
        suspend_individual = re.search(r"no lacp suspend-individual", conf)
        if suspend_individual:
            config["suspend_individual"] = False
        max_links = utils.parse_conf_arg(conf, "lacp max-bundle")
        if max_links:
            config["links"]["max"] = max_links
        min_links = utils.parse_conf_arg(conf, "lacp min-links")
        if min_links:
            config["links"]["min"] = min_links
        graceful = re.search(r"no lacp graceful-convergence", conf)
        if graceful:
            config["convergence"]["gracefule"] = False
        vpc = re.search(r"lacp vpc-convergence", conf)
        if vpc:
            config["convergence"]["vpc"] = True

        return utils.remove_empties(config)
    def render_config(self, 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 = {}
        location = {}

        civic_conf = "\n".join(filter(lambda x: ("civic-based" in x), conf))
        elin_conf = "\n".join(filter(lambda x: ("elin" in x), conf))
        coordinate_conf = "\n".join(
            filter(lambda x: ("coordinate-based" in x), conf)
        )
        disable = "\n".join(filter(lambda x: ("disable" in x), conf))

        coordinate_based_conf = self.parse_attribs(
            ["altitude", "datum", "longitude", "latitude"], coordinate_conf
        )
        elin_based_conf = self.parse_lldp_elin_based(elin_conf)
        civic_based_conf = self.parse_lldp_civic_based(civic_conf)
        if disable:
            config["enable"] = False
        if coordinate_conf:
            location["coordinate_based"] = coordinate_based_conf
            config["location"] = location
        elif civic_based_conf:
            location["civic_based"] = civic_based_conf
            config["location"] = location
        elif elin_conf:
            location["elin"] = elin_based_conf
            config["location"] = location

        return utils.remove_empties(config)
示例#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 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['description'] = utils.parse_conf_arg(conf, 'description')
        config['speed'] = utils.parse_conf_arg(conf, 'speed')
        config['mtu'] = utils.parse_conf_arg(conf, 'mtu')
        config['duplex'] = utils.parse_conf_arg(conf, 'duplex')
        config['mode'] = utils.parse_conf_cmd_arg(conf, 'switchport', 'layer2',
                                                  'layer3')

        config['enabled'] = utils.parse_conf_cmd_arg(conf, 'shutdown', False,
                                                     True)

        # Capture the default 'enabled' state, which may be interface-specific
        config['enabled_def'] = default_intf_enabled(name=intf,
                                                     sysdefs=self.sysdefs,
                                                     mode=config['mode'])

        config['fabric_forwarding_anycast_gateway'] = utils.parse_conf_cmd_arg(
            conf, 'fabric forwarding mode anycast-gateway', True)
        config['ip_forward'] = utils.parse_conf_cmd_arg(
            conf, 'ip forward', True)

        interfaces_cfg = utils.remove_empties(config)
        return interfaces_cfg
示例#26
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
        """
        if not data:
            data = connection.get_config()

        # operate on a collection of resource x
        objs = []
        interface_names = re.findall(
            r"set interfaces (?:ethernet|bonding|vti|vxlan) (?:\'*)(\S+)(?:\'*)",
            data,
            re.M,
        )
        if interface_names:
            for interface in set(interface_names):
                intf_regex = r" %s .+$" % interface
                cfg = re.findall(intf_regex, data, re.M)
                obj = self.render_config(cfg)
                obj["name"] = interface.strip("'")
                if obj:
                    objs.append(obj)

        ansible_facts["ansible_network_resources"].pop("l3_interfaces", None)
        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
示例#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)

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

        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)
示例#28
0
 def _add_global_attr(self, w, h, opr=True):
     """
     This function forms the set/delete commands based on the 'opr' type
     for firewall_global attributes.
     :param w: the desired config.
     :param h: the target config.
     :param opr: True/False.
     :return: generated commands list.
     """
     commands = []
     w_fg = deepcopy(remove_empties(w))
     l_set = ('config_trap', 'validation', 'log_martians', 'syn_cookies',
              'twa_hazards_protection')
     if w_fg:
         for key, val in iteritems(w_fg):
             if opr and key in l_set and not (h and self._is_w_same(
                     w_fg, h, key)):
                 commands.append(
                     self._form_attr_cmd(attr=key,
                                         val=self._bool_to_str(val),
                                         opr=opr))
             elif not opr:
                 if key and self._is_del(l_set, h):
                     commands.append(
                         self._form_attr_cmd(attr=key,
                                             key=self._bool_to_str(val),
                                             opr=opr))
                     continue
                 elif key in l_set and not (h and self._in_target(
                         h, key)) and not self._is_del(l_set, h):
                     commands.append(
                         self._form_attr_cmd(attr=key,
                                             val=self._bool_to_str(val),
                                             opr=opr))
             else:
                 commands.extend(self._render_attr_config(
                     w_fg, h, key, opr))
     return commands
示例#29
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['port_priority'] = utils.parse_conf_arg(conf,
                                                       'lacp port-priority')
        config['rate'] = utils.parse_conf_arg(conf, 'lacp rate')
        config['mode'] = utils.parse_conf_arg(conf, 'mode')
        suspend_individual = re.search(r'no lacp suspend-individual', conf)
        if suspend_individual:
            config['suspend_individual'] = False
        max_links = utils.parse_conf_arg(conf, 'lacp max-bundle')
        if max_links:
            config['links']['max'] = max_links
        min_links = utils.parse_conf_arg(conf, 'lacp min-links')
        if min_links:
            config['links']['min'] = min_links
        graceful = re.search(r'no lacp graceful-convergence', conf)
        if graceful:
            config['convergence']['gracefule'] = False
        vpc = re.search(r'lacp vpc-convergence', conf)
        if vpc:
            config['convergence']['vpc'] = True

        return utils.remove_empties(config)
示例#30
0
    def render_config(self, spec, con):
        """
        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 = []
        global_afi_list = []
        global_af = []
        global_dest_list = []
        if con:
            for conf in con:
                if conf.startswith('vrf context'):
                    svrf = re.match('vrf context (\S+)\n', conf).group(1)
                    afi_list = []
                    af = []
                    dest_list = []
                    config_dict = {'vrf': svrf, 'address_families': []}
                    conf = conf.split('\n')
                    # considering from the second line as first line is 'vrf context..'
                    conf = conf[1:]
                    for c in conf:
                        if 'ip route' in c or 'ipv6 route' in c:
                            self.get_command(c, afi_list, dest_list, af)
                            config_dict['address_families'] = af
                    config.append(config_dict)
                else:
                    if 'ip route' in conf or 'ipv6 route' in conf:
                        self.get_command(conf, global_afi_list,
                                         global_dest_list, global_af)
            config.append(utils.remove_empties({'address_families':
                                                global_af}))
        return config