Пример #1
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 = []
        for key, value in iteritems(
            flatten_dict(dict_delete(have, remove_empties(want)))
        ):
            cmd = self._compute_commands(key, value, remove=True)
            if cmd:
                commands.append(cmd)

        return commands
Пример #2
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')
        config['port_priority'] = utils.parse_conf_arg(conf, 'port-priority')
        config['rate'] = utils.parse_conf_arg(conf, 'rate')

        return utils.remove_empties(config)
Пример #3
0
 def _render_ospf_param(self, want, have, opr=True):
     """
     This function forms the set/delete commands for ospf leaf attributes
     and triggers the process for other child attributes.
     for firewall_global attributes.
     :param w: the desired config.
     :param h: the target config.
     :param opr: True/False.
     :return: generated commands list.
     """
     commands = []
     w = deepcopy(remove_empties(want))
     if w:
         for key, val in iteritems(w):
             commands.extend(self._render_child_param(w, have, key, opr))
     return commands
Пример #4
0
    def _state_deleted(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 = []

        for key, value in iteritems(flatten_dict(dict_delete(have, remove_empties(want)))):
            commands.append(Lacp_interfaces._compute_commands(key, value, remove=True))

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

        return commands
Пример #5
0
    def parse_attribs(self, attribs, conf):
        config = {}
        for item in attribs:
            value = utils.parse_conf_arg(conf, item)
            if value and item == 'mtu':
                config[item] = int(value.strip("'"))
            elif value:
                config[item] = value.strip("'")
            else:
                config[item] = None
        if 'disable' in conf:
            config['enabled'] = False
        else:
            config['enabled'] = True

        return utils.remove_empties(config)
Пример #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)

        vms = []
        conf_config = conf[0][
            "extreme-virtual-service:virtual-services-config"]
        conf_state = conf[1]["extreme-virtual-service:virtual-services-state"]
        if conf_config.get("virtual-service-config") and conf_state.get(
                "virtual-service-state"):
            conf_config = conf_config["virtual-service-config"]
            conf_state = conf_state["virtual-service-state"]
            for d in range(len(conf_config)):
                config["auto_start"] = conf_config[d]["enable"]
                config["image"] = conf_state[d]["package-info"]["path"] + str(
                    '/') + conf_state[d]["package-info"]["name"]
                config["memory_size"] = conf_config[d]["memory-size"]
                config["name"] = conf_config[d]["name"]
                config["num_cores"] = conf_config[d]["num-cores"]
                config["operational_state"] = "started" if conf_state[d][
                    "state"]["state"] == 1 else "stopped"
                config["virtual_ports"] = []
                if conf_config[d].get("vports"):
                    conf_vport = conf_config[d]["vports"]["vport"]
                    for num in range(len(conf_config[d]["vports"]["vport"])):
                        config_vport = {}
                        config_vport["name"] = conf_vport[num].get("name")
                        config_vport["type"] = conf_vport[num].get(
                            "connect-type").lower()
                        config_vport["port"] = conf_vport[num].get("port")
                        if conf_vport[num].get("vlans"):
                            config_vport["vlan_id"] = conf_vport[num]["vlans"][
                                "vlan"][0]["id"]
                        config["virtual_ports"].append(config_vport)
                config["vnc"]["enabled"] = False if conf_config[d][
                    "vnc-port"] == 0 else True
                config["vnc"]["port"] = conf_config[d]["vnc-port"]
                vms.append(utils.remove_empties(config))
        return vms
Пример #7
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>
                    <protocols>
                        <lldp>
                            <interface>
                            </interface>
                        </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")
            )

        self._resources = data.xpath("configuration/protocols/lldp/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["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
Пример #8
0
    def set_state(self, want, have):
        """ Select the appropriate function based on the state provided

        :param want: the desired configuration as a dictionary
        :param have: the current configuration as a dictionary
        :rtype: A list
        :returns: the commands necessary to migrate the current configuration
                  to the desired configuration
        """
        state = self._module.params['state']
        commands = []

        if state in ('overridden', 'merged', 'replaced',
                     'rendered') and not want:
            self._module.fail_json(
                msg='value of config parameter must not be empty for state {0}'
                .format(state))

        if state == 'overridden':
            commands.extend(self._state_overridden(want, have))

        elif state == 'deleted':
            if not want:
                for intf in have:
                    commands.extend(self._state_deleted({}, intf))
            else:
                for item in want:
                    obj_in_have = search_obj_in_list(item['name'], have) or {}
                    commands.extend(
                        self._state_deleted(remove_empties(item), obj_in_have))

        else:
            # Instead of passing entire want and have
            # list of dictionaries to the respective
            # _state_* methods we are passing the want
            # and have dictionaries per interface
            for item in want:
                name = item['name']
                obj_in_have = search_obj_in_list(name, have) or {}

                if state == 'merged' or state == 'rendered':
                    commands.extend(self._state_merged(item, obj_in_have))

                elif state == 'replaced':
                    commands.extend(self._state_replaced(item, obj_in_have))

        return commands
Пример #9
0
    def populate_facts(self, connection, ansible_facts, data=None):
        """Populate the facts for Prefix_lists network resource

        :param connection: the device connection
        :param ansible_facts: Facts dictionary
        :param data: previously collected conf

        :rtype: dictionary
        :returns: facts
        """
        facts = {}

        if not data:
            data = self.get_config(connection)

        # parse native config using the Prefix_lists template
        prefix_lists_parser = Prefix_listsTemplate(lines=data.splitlines(),
                                                   module=self._module)
        objs = prefix_lists_parser.parse()
        if objs:
            for afi, pl in iteritems(objs):
                if "prefix_lists" in pl:
                    pl["prefix_lists"] = sorted(
                        list(pl["prefix_lists"].values()),
                        key=lambda k, sk="name": k[sk],
                    )
                    for plist in pl["prefix_lists"]:
                        for en in plist:
                            if "entries" in en:
                                plist["entries"] = sorted(
                                    list(plist["entries"].values()),
                                    key=lambda k, sk="sequence": k[sk],
                                )
            objs = sorted(list(objs.values()), key=lambda k, sk="afi": k[sk])
        else:
            objs = []
        ansible_facts["ansible_network_resources"].pop("prefix_lists", None)

        params = utils.remove_empties(
            prefix_lists_parser.validate_config(self.argument_spec,
                                                {"config": objs},
                                                redact=True))

        facts["prefix_lists"] = params.get("config", [])
        ansible_facts["ansible_network_resources"].update(facts)

        return ansible_facts
Пример #10
0
    def render_config(self, spec, conf, vlan_info):
        """
        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)

        if vlan_info == "Name" and "VLAN Name" not in conf:
            conf = list(filter(None, conf.split(" ")))
            config["vlan_id"] = int(conf[0])
            config["name"] = conf[1]
            try:
                if len(conf[2].split("/")) > 1:
                    if conf[2].split("/")[0] == "sus":
                        config["state"] = "suspend"
                    elif conf[2].split("/")[0] == "act":
                        config["state"] = "active"
                    config["shutdown"] = "enabled"
                else:
                    if conf[2] == "suspended":
                        config["state"] = "suspend"
                    elif conf[2] == "active":
                        config["state"] = "active"
                    config["shutdown"] = "disabled"
            except IndexError:
                pass
        elif vlan_info == "Type" and "VLAN Type" not in conf:
            conf = list(filter(None, conf.split(" ")))
            config["mtu"] = int(conf[3])
        elif vlan_info == "Remote":
            if len(conf.split(",")) > 1 or conf.isdigit():
                remote_span_vlan = []
                if len(conf.split(",")) > 1:
                    remote_span_vlan = conf.split(",")
                else:
                    remote_span_vlan.append(conf)
                remote_span = []
                for each in remote_span_vlan:
                    remote_span.append(int(each))
                config["remote_span"] = remote_span

        return utils.remove_empties(config)
Пример #11
0
    def populate_facts(self, connection, ansible_facts, data=None):
        """ Populate the facts for ospfv2
        :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_ospfv2_data(connection)

        ipv4 = {"processes": []}
        rmmod = NetworkTemplate(lines=data.splitlines(),
                                tmplt=Ospfv2Template())
        current = rmmod.parse()

        # convert some of the dicts to lists
        for key, sortv in [("processes", "process_id")]:
            if key in current and current[key]:
                current[key] = current[key].values()
                current[key] = sorted(current[key],
                                      key=lambda k, sk=sortv: k[sk])

        for process in current.get("processes", []):
            if "areas" in process:
                process["areas"] = list(process["areas"].values())
                process["areas"] = sorted(process["areas"],
                                          key=lambda k, sk="area_id": k[sk])
                for area in process["areas"]:
                    # if 'ranges' in area:
                    #     area['ranges'] = sorted(area['ranges'],
                    #                             key=lambda k, s='ranges': k[s])
                    if "filters" in area:
                        area["filters"].sort()
            ipv4["processes"].append(process)

        ansible_facts["ansible_network_resources"].pop("ospfv2", None)
        facts = {}
        if current:
            params = utils.validate_config(self.argument_spec,
                                           {"config": ipv4})
            params = utils.remove_empties(params)

            facts["ospfv2"] = params["config"]

            ansible_facts["ansible_network_resources"].update(facts)
        return ansible_facts
Пример #12
0
    def populate_facts(self, connection, ansible_facts, data=None):
        """ Populate the facts for acls
        :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)

        # split the config into instances of the resource
        find_pattern = r'(?:^|\n)(?:ip|ipv6) access\-list.*?(?=(?:^|\n)(?:ip|ipv6) access\-list|$)'
        resources = [p for p in re.findall(find_pattern, data, re.DOTALL)]

        objs = []
        ipv4list = []
        ipv6list = []
        for resource in resources:
            if "ipv6" in resource:
                ipv6list.append(resource)
            else:
                ipv4list.append(resource)
        ipv4list = ["\n".join(ipv4list)]
        ipv6list = ["\n".join(ipv6list)]
        for resource in ipv4list:
            if resource:
                obj = self.render_config(self.generated_spec, resource)
                if obj:
                    objs.append(obj)
        for resource in ipv6list:
            if resource:
                obj = self.render_config(self.generated_spec, resource)
                if obj:
                    objs.append(obj)

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

        ansible_facts['ansible_network_resources'].update(facts)
        return ansible_facts
Пример #13
0
    def populate_facts(self, connection, ansible_facts, data=None):
        """Populate the facts for Bgp_global network resource

        :param connection: the device connection
        :param ansible_facts: Facts dictionary
        :param data: previously collected conf

        :rtype: dictionary
        :returns: facts
        """
        facts = {}
        objs = {}
        config_lines = []

        if not data:
            data = self.get_device_data(connection)

        for resource in data.splitlines():
            if "address-family" not in resource:
                config_lines.append(re.sub("'", "", resource))

        bgp_global_parser = Bgp_globalTemplate(lines=config_lines,
                                               module=self._module)
        objs = bgp_global_parser.parse()

        if "neighbor" in objs:
            objs["neighbor"] = list(objs["neighbor"].values())
            objs["neighbor"] = sorted(objs["neighbor"],
                                      key=lambda k: k["address"])
        if "network" in objs:
            objs["network"] = sorted(objs["network"],
                                     key=lambda k: k["address"])
        if "aggregate_address" in objs:
            objs["aggregate_address"] = sorted(objs["aggregate_address"],
                                               key=lambda k: k["prefix"])

        ansible_facts["ansible_network_resources"].pop("bgp_global", None)

        params = utils.remove_empties(
            bgp_global_parser.validate_config(self.argument_spec,
                                              {"config": objs},
                                              redact=True))

        facts["bgp_global"] = params.get("config", [])
        ansible_facts["ansible_network_resources"].update(facts)

        return ansible_facts
Пример #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"
            )
        else:
            running_config = data.split("\n\n")
            structured, run_cfg_output = running_config[0], running_config[1]

        # 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 static_routes
        :param connection: the device connection
        :param ansible_facts: Facts dictionary
        :param data: previously collected conf
        :rtype: dictionary
        :returns: facts
        """
        if not HAS_LXML:
            self._module.fail_json(msg="lxml is not installed.")
        if not HAS_XMLTODICT:
            self._module.fail_json(msg="xmltodict is not installed.")

        if not data:
            config_filter = """
                <configuration>
                  <routing-instances/>
                  <routing-options/>
                </configuration>
                """
            data = connection.get_configuration(filter=config_filter)

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

        resources = data.xpath("configuration/routing-options")
        vrf_resources = data.xpath("configuration/routing-instances")
        resources.extend(vrf_resources)

        objs = []
        for resource in resources:
            if resource is not None:
                xml = self._get_xml_dict(resource)
                obj = self.render_config(self.generated_spec, xml)
                if obj:
                    objs.append(obj)

        facts = {}
        if objs:
            facts["static_routes"] = []
            params = utils.validate_config(self.argument_spec,
                                           {"config": objs})
            for cfg in params["config"]:
                facts["static_routes"].append(utils.remove_empties(cfg))
        ansible_facts["ansible_network_resources"].update(facts)
        return ansible_facts
Пример #16
0
    def populate_facts(self, connection, ansible_facts, data=None):
        """ Populate the facts for acls
        :param connection: the device connection
        :param ansible_facts: Facts dictionary
        :param data: previously collected conf
        :rtype: dictionary
        :returns: facts
        """
        if not HAS_LXML:
            self._module.fail_json(msg=missing_required_lib("lxml"))

        if not data:
            config_filter = """
                <configuration>
                  <firewall/>
                </configuration>
                """
            data = connection.get_configuration(filter=config_filter)

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

        resources = data.xpath("configuration/firewall")

        objs = []
        for resource in resources:
            if resource:
                xml = self._get_xml_dict(resource)
                for family, sub_dict in xml["firewall"]["family"].items():
                    sub_dict["family"] = family
                    obj = self.render_config(self.generated_spec,
                                             dict(firewall=sub_dict))
                    if obj:
                        objs.append(obj)

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

        ansible_facts["ansible_network_resources"].update(facts)
        return ansible_facts
Пример #17
0
    def set_config(self, existing_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"])})
                want.append(remove_empties(w))
        have = deepcopy(existing_interfaces_facts)
        resp = self.set_state(want, have)
        return to_list(resp)
Пример #18
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
Пример #19
0
    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
        """
        vif_conf = "\n".join(filter(lambda x: ("vif" in x), conf))
        eth_conf = "\n".join(filter(lambda x: ("vif" not in x), conf))
        config = self.parse_attribs(["description", "speed", "mtu", "duplex"],
                                    eth_conf)
        config["vifs"] = self.parse_vifs(vif_conf)

        return utils.remove_empties(config)
Пример #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 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_mode = utils.parse_conf_arg(conf, 'switchport mode')
            if has_mode:
                config['mode'] = has_mode
            has_access = utils.parse_conf_arg(conf, 'switchport access vlan')
            if has_access:
                config["access"] = {"vlan": int(has_access)}

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

            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)
Пример #21
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

        # Get the configured IPV4 details
        ipv4 = []
        ipv4_all = re.findall(r"ipv4 address (\S+.*)", conf)
        for each in ipv4_all:
            each_ipv4 = dict()
            if "secondary" in each:
                each_ipv4["address"] = each.split(" secondary")[0]
                each_ipv4["secondary"] = True
            else:
                each_ipv4["address"] = each
            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()
            each_ipv6["address"] = each
            ipv6.append(each_ipv6)
            config["ipv6"] = ipv6

        return utils.remove_empties(config)
Пример #22
0
    def populate_facts(self, connection, ansible_facts, data=None):
        """ Populate the facts for bgp_global
        :param connection: the device connection
        :param ansible_facts: Facts dictionary
        :param data: previously collected conf
        :rtype: dictionary
        :returns: facts
        """
        if not HAS_LXML:
            self._module.fail_json(msg="lxml is not installed.")

        if not data:
            config_filter = """
                <configuration>
                    <protocols>
                        <bgp>
                        </bgp>
                    </protocols>
                </configuration>
                """
            data = self.get_connection(connection, config_filter)

        if isinstance(data, string_types):
            data = etree.fromstring(
                to_bytes(data, errors="surrogate_then_replace"))
        objs = {}
        resources = data.xpath("configuration/protocols/bgp")
        autonomous_system = data.xpath(
            "configuration/routing-options/autonomous-system")
        if autonomous_system:
            self.autonomous_system = self._get_xml_dict(
                autonomous_system.pop())
        else:
            self.autonomous_system = ""
        for resource in resources:
            if resource:
                xml = self._get_xml_dict(resource)
                objs = self.render_config(self.generated_spec, xml)
        facts = {}
        if objs:
            facts["bgp_global"] = {}
            params = utils.validate_config(self.argument_spec,
                                           {"config": objs})
            facts["bgp_global"] = utils.remove_empties(params["config"])
        ansible_facts["ansible_network_resources"].update(facts)
        return ansible_facts
def main():
    api_keys_list_spec = {
        "key_name": dict(type="str"),
        "id": dict(type="str"),
        "description": dict(type="str"),
        "locale": dict(type="str", choices=["en-US", "ja-JP"]),
        "role_id": dict(type="int"),
        "time_zone": dict(type="str"),
        "active": dict(type="bool"),
        "created": dict(type="int"),
        "last_sign_in": dict(type="int"),
        "unlock_time": dict(type="int"),
        "unsuccessful_sign_in_attempts": dict(type="int"),
        "expiry_date": dict(type="int"),
        "secret_key": dict(no_log=True, type="str"),
        "service_account": dict(type="bool"),
        "current": dict(type="bool"),
    }

    argspec = dict(
        state=dict(choices=["present", "absent", "gathered"],
                   default="present"),
        api_keys=dict(
            type="list",
            elements="dict",
            options=api_keys_list_spec,
            no_log=False,
        ),
    )

    module = AnsibleModule(argument_spec=argspec, supports_check_mode=True)
    deepsec_request = DeepSecurityRequest(module)
    module.params = utils.remove_empties(module.params)

    if module.params["state"] == "gathered":
        display_gathered_result(argspec=argspec,
                                module=module,
                                deepsec_request=deepsec_request)
    elif module.params["state"] == "absent":
        delete_module_api_config(argspec=argspec,
                                 module=module,
                                 deepsec_request=deepsec_request)
    elif module.params["state"] == "present":
        configure_module_api(argspec=argspec,
                             module=module,
                             deepsec_request=deepsec_request)
Пример #24
0
    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
        """
        vif_conf = '\n'.join(filter(lambda x: ('vif' in x), conf))
        eth_conf = '\n'.join(filter(lambda x: ('vif' not in x), conf))
        config = self.parse_attribs(['description', 'speed', 'mtu', 'duplex'],
                                    eth_conf)
        config['vifs'] = self.parse_vifs(vif_conf)

        return utils.remove_empties(config)
    def _state_deleted(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 = []

        for x in [
            k
            for k in have.get("system", {})
            if k not in remove_empties(want.get("system", {}))
        ]:
            commands.append("no lacp system {0}".format(x))

        return commands
Пример #26
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['access_groups'] = []
        acl_v4_config = {}
        acl_v6_config = {}

        def common_iter_code(cmd, conf):
            # Common code for IPV4 and IPV6 config parsing
            acls = []
            re_cmd = cmd + ' (\\S+.*)'
            ip_all = re.findall(re_cmd, conf)
            for each in ip_all:
                acl = {}
                access_grp_config = each.split(' ')
                acl['name'] = access_grp_config[0]
                acl['direction'] = access_grp_config[1]
                acls.append(acl)
            return acls

        if 'ip' in conf:
            acls = common_iter_code('ip access-group', conf)
            acl_v4_config['afi'] = 'ipv4'
            acl_v4_config['acls'] = acls
            config['access_groups'].append(acl_v4_config)
        if 'ipv6' in conf:
            acls = common_iter_code('ipv6 traffic-filter', conf)
            acl_v6_config['afi'] = 'ipv6'
            acl_v6_config['acls'] = acls
            config['access_groups'].append(acl_v6_config)

        return utils.remove_empties(config)
Пример #27
0
    def populate_facts(self, connection, ansible_facts, data=None):
        """Populate the facts for Logging_global network resource

        :param connection: the device connection
        :param ansible_facts: Facts dictionary
        :param data: previously collected conf

        :rtype: dictionary
        :returns: facts
        """
        facts = {}
        objs = []
        sev_map = get_logging_sevmap()

        if not data:
            data = self.get_config(connection)

        # parse native config using the Logging_global template
        logging_global_parser = Logging_globalTemplate(lines=data.splitlines(),
                                                       module=self._module)
        objs = logging_global_parser.parse()

        if objs:
            for k in ("console", "history", "logfile", "module", "monitor"):
                if "severity" in objs.get(k, {}):
                    objs[k]["severity"] = sev_map[objs[k]["severity"]]
            # pre-sort list of dictionaries
            pkey = {"hosts": "host", "facilities": "facility"}
            for x in ("hosts", "facilities"):
                if x in objs:
                    for item in objs[x]:
                        if "severity" in item:
                            item["severity"] = sev_map[item["severity"]]
                    objs[x] = sorted(objs[x], key=lambda k: k[pkey[x]])

        ansible_facts["ansible_network_resources"].pop("logging_global", None)

        params = utils.remove_empties(
            logging_global_parser.validate_config(self.argument_spec,
                                                  {"config": objs},
                                                  redact=True))

        facts["logging_global"] = params.get("config", {})
        ansible_facts["ansible_network_resources"].update(facts)

        return ansible_facts
Пример #28
0
    def _state_merged(self, 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 = []
        want_copy = deepcopy(remove_empties(want))
        have_copy = deepcopy(have)

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

        updates = dict_diff(have_copy, want_copy)

        if updates:
            for key, value in iteritems(updates):
                commands.append(
                    self._compute_commands(key=key,
                                           value=value,
                                           interface=want_copy["name"]))

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

                vif_updates = dict_diff(have_vif, want_vif)
                if vif_updates:
                    for key, value in iteritems(vif_updates):
                        commands.append(
                            self._compute_commands(
                                key=key,
                                value=value,
                                interface=want_copy["name"],
                                vif=want_vif["vlan_id"],
                            ))

        return commands
Пример #29
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 = []

        if not want:
            want = [{'afi': 'ipv4'}, {'afi': 'ipv6'}]

        for item in want:
            item = remove_empties(item)
            have_item = search_obj_in_list(item['afi'], have, key='afi') or {}
            if 'acls' not in item:
                if have_item:
                    for acl in have_item['acls']:
                        commands.append('no {0} access-list {1}'.format(
                            have_item['afi'], acl['name']))
            else:
                for want_acl in item['acls']:
                    have_acl = search_obj_in_list(
                        want_acl['name'], have_item.get('acls', [])) or {}
                    if have_acl:
                        if 'aces' not in want_acl:
                            commands.append('no {0} access-list {1}'.format(
                                have_item['afi'], have_acl['name']))
                        else:
                            acl_updates = []
                            for want_ace in want_acl['aces']:
                                have_ace = search_obj_in_list(
                                    want_ace.get('sequence'),
                                    have_acl.get('aces', []),
                                    key='sequence') or {}
                                if have_ace:
                                    acl_updates.append('no {0}'.format(
                                        have_ace['sequence']))

                            if acl_updates:
                                acl_updates.insert(
                                    0, '{0} access-list {1}'.format(
                                        have_item['afi'], have_acl['name']))
                                commands.extend(acl_updates)

        return commands
Пример #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 {}
        config["name"] = intf
        config["access_groups"] = []
        acl_v4_config = {}
        acl_v6_config = {}

        def common_iter_code(cmd, conf):
            # Common code for IPV4 and IPV6 config parsing
            acls = []
            re_cmd = cmd + " (\\S+.*)"
            ip_all = re.findall(re_cmd, conf)
            for each in ip_all:
                acl = {}
                access_grp_config = each.split(" ")
                acl["name"] = access_grp_config[0]
                acl["direction"] = access_grp_config[1]
                acls.append(acl)
            return acls

        if "ip" in conf:
            acls = common_iter_code("ip access-group", conf)
            acl_v4_config["afi"] = "ipv4"
            acl_v4_config["acls"] = acls
            config["access_groups"].append(acl_v4_config)
        if "ipv6" in conf:
            acls = common_iter_code("ipv6 traffic-filter", conf)
            acl_v6_config["afi"] = "ipv6"
            acl_v6_config["acls"] = acls
            config["access_groups"].append(acl_v6_config)

        return utils.remove_empties(config)