Esempio n. 1
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 = []

        # Drill each iteration of want n have and then based on dest and afi tyoe comparison take config call
        for w in want:
            for addr_want in w.get('address_families'):
                for route_want in addr_want.get('routes'):
                    check = False
                    for h in have:
                        if h.get('address_families'):
                            for addr_have in h.get('address_families'):
                                for route_have in addr_have.get('routes'):
                                    if route_want.get('dest') == route_have.get('dest')\
                                            and addr_want['afi'] == addr_have['afi']:
                                        check = True
                                        have_set = set()
                                        new_hops = []
                                        for each in route_want.get(
                                                'next_hops'):
                                            want_set = set()
                                            new_dict_to_set(
                                                each, [], want_set, 0)
                                            new_hops.append(want_set)
                                        new_dict_to_set(
                                            addr_have, [], have_set, 0)
                                        commands.extend(
                                            self._set_config(
                                                w, h, addr_want, route_want,
                                                route_have, new_hops,
                                                have_set))
                                if check:
                                    break
                            if check:
                                break
                    if not check:
                        # For configuring any non-existing want config
                        new_hops = []
                        for each in route_want.get('next_hops'):
                            want_set = set()
                            new_dict_to_set(each, [], want_set, 0)
                            new_hops.append(want_set)
                        commands.extend(
                            self._set_config(w, {}, addr_want, route_want, {},
                                             new_hops, set()))

        return commands
Esempio n. 2
0
    def _set_config(self, want, have, acl_want, afi):
        """ Function that sets the acls config based on the want and have config
        :param want: want config
        :param have: have config
        :param acl_want: want acls config
        :param afi: acls afi type
        :rtype: A list
        :returns: the commands generated based on input want/have params
        """
        commands = []
        change = False
        want_set = set()
        have_set = set()
        # Convert the want and have dict to its respective set for taking the set diff
        new_dict_to_set(want, [], want_set)
        new_dict_to_set(have, [], have_set)
        diff = want_set - have_set

        # Populate the config only when there's a diff b/w want and have config
        if diff:
            name = acl_want.get('name')
            if afi == 'ipv4':
                try:
                    name = int(name)
                    # If name is numbered acls
                    if name <= 99:
                        cmd = 'ip access-list standard {0}'.format(name)
                    elif name >= 100:
                        cmd = 'ip access-list extended {0}'.format(name)
                except ValueError:
                    # If name is named acls
                    acl_type = acl_want.get('acl_type')
                    if acl_type:
                        cmd = 'ip access-list {0} {1}'.format(acl_type, name)
                    else:
                        self._module.fail_json(
                            msg='ACL type value is required for Named ACL!')

            elif afi == 'ipv6':
                cmd = 'ipv6 access-list {0}'.format(name)

            # Get all of aces option values from diff dict
            sequence = want.get('sequence')
            grant = want.get('grant')
            source = want.get('source')
            destination = want.get('destination')
            po = want.get('protocol_options')
            protocol = want.get('protocol')
            dscp = want.get('dscp')
            fragments = want.get('fragments')
            log = want.get('log')
            log_input = want.get('log_input')
            option = want.get('option')
            precedence = want.get('precedence')
            time_range = want.get('time_range')
            tos = want.get('tos')
            ttl = want.get('ttl')

            if sequence:
                if afi == 'ipv6':
                    cmd = cmd + ' sequence {0}'.format(sequence)
                else:
                    cmd = cmd + ' {0}'.format(sequence)
            if grant:
                cmd = cmd + ' {0}'.format(grant)
            if po and isinstance(po, dict):
                po_key = list(po)[0]
                if protocol and protocol != po_key:
                    self._module.fail_json(
                        msg=
                        'Protocol value cannot be different from Protocol option protocol value!'
                    )
                cmd = cmd + ' {0}'.format(po_key)
                if po.get('icmp'):
                    po_val = po.get('icmp')
                elif po.get('igmp'):
                    po_val = po.get('igmp')
                elif po.get('tcp'):
                    po_val = po.get('tcp')
            elif protocol:
                cmd = cmd + ' {0}'.format(protocol)
            if source:
                cmd = self.source_dest_config(source, cmd, po)
            if destination:
                cmd = self.source_dest_config(destination, cmd, po)
            if po:
                cmd = cmd + ' {0}'.format(list(po_val)[0])
            if dscp:
                cmd = cmd + ' dscp {0}'.format(dscp)
            if fragments:
                cmd = cmd + ' fragments {0}'.format(fragments)
            if log:
                cmd = cmd + ' log {0}'.format(log)
            if log_input:
                cmd = cmd + ' log-input {0}'.format(log_input)
            if option:
                cmd = cmd + ' option {0}'.format(list(option)[0])
            if precedence:
                cmd = cmd + ' precedence {0}'.format(precedence)
            if time_range:
                cmd = cmd + ' time-range {0}'.format(time_range)
            if tos:
                for k, v in iteritems(tos):
                    if k == 'service_value':
                        cmd = cmd + ' tos {0}'.format(v)
                    else:
                        cmd = cmd + ' tos {0}'.format(v)
            if ttl:
                for k, v in iteritems(ttl):
                    if k == 'range' and v:
                        start = v.get('start')
                        end = v.get('start')
                        cmd = cmd + ' ttl {0} {1}'.format(start, end)
                    elif v:
                        cmd = cmd + ' ttl {0} {1}'.format(k, v)

            commands.append(cmd)
        if commands:
            change = True

        return commands, change
Esempio n. 3
0
    def _clear_config(self, want, have, addr_want, addr_have, route_want,
                      route_have):
        """
            Delete the interface config based on the want and have config
            :rtype: A list
            :returns: The commands necessary to configure the static routes
        """

        commands = []
        cmd = None

        vrf_diff = False
        topology_diff = False
        want_vrf = want.get("vrf")
        have_vrf = have.get("vrf")
        if want_vrf != have_vrf:
            vrf_diff = True
        want_topology = want.get("topology")
        have_topology = have.get("topology")
        if want_topology != have_topology:
            topology_diff = True

        want_set = set()
        new_dict_to_set(addr_want, [], want_set, 0)

        have_hops = []
        for each in route_have.get("next_hops"):
            temp_have_set = set()
            new_dict_to_set(each, [], temp_have_set, 0)
            have_hops.append(temp_have_set)

        # configure delete cmd for each hops under the same destination
        for each in have_hops:
            diff = each - want_set
            if vrf_diff:
                each.add(tuple(iteritems({"vrf": have_vrf})))
            if topology_diff:
                each.add(tuple(iteritems({"topology": want_topology})))
            if diff or vrf_diff or topology_diff:
                if want_vrf and not vrf_diff:
                    each.add(tuple(iteritems({"vrf": want_vrf})))
                if want_topology and not vrf_diff:
                    each.add(tuple(iteritems({"topology": want_topology})))
                if addr_want:
                    each.add(tuple(iteritems({"afi": addr_want.get("afi")})))
                else:
                    each.add(tuple(iteritems({"afi": addr_have.get("afi")})))
                if route_want:
                    each.add(tuple(iteritems({"dest":
                                              route_want.get("dest")})))
                else:
                    each.add(tuple(iteritems({"dest":
                                              route_have.get("dest")})))
                temp_want = {}
                for each_want in each:
                    temp_want.update(dict(each_want))

                if temp_want.get("afi") == "ipv4":
                    cmd = "no ip route "
                    vrf = temp_want.get("vrf")
                    if vrf:
                        cmd = cmd + "vrf {0} ".format(vrf)
                    cmd = self.prepare_config_commands(temp_want, cmd)
                elif temp_want.get("afi") == "ipv6":
                    cmd = "no ipv6 route "
                    cmd = self.prepare_config_commands(temp_want, cmd)
                commands.append(cmd)

        return commands
Esempio n. 4
0
    def _state_overridden(self, want, have):
        """ The command generator when state is overridden

        :rtype: A list
        :returns: the commands necessary to migrate the current configuration
                  to the desired configuration
        """

        commands = []
        # Creating a copy of want, so that want dict is intact even after delete operation
        # performed during override want n have comparison
        temp_want = copy.deepcopy(want)

        # Drill each iteration of want n have and then based on dest and afi tyoe comparison take config call
        for h in have:
            if h.get("address_families"):
                for addr_have in h.get("address_families"):
                    for route_have in addr_have.get("routes"):
                        check = False
                        for w in temp_want:
                            for addr_want in w.get("address_families"):
                                count = 0
                                for route_want in addr_want.get("routes"):
                                    if (route_want.get("dest")
                                            == route_have.get("dest")
                                            and addr_want["afi"]
                                            == addr_have["afi"]):
                                        check = True
                                        have_set = set()
                                        new_hops = []
                                        for each in route_want.get(
                                                "next_hops"):
                                            want_set = set()
                                            new_dict_to_set(
                                                each, [], want_set, 0)
                                            new_hops.append(want_set)
                                        new_dict_to_set(
                                            addr_have, [], have_set, 0)
                                        commands.extend(
                                            self._clear_config(
                                                w,
                                                h,
                                                addr_want,
                                                addr_have,
                                                route_want,
                                                route_have,
                                            ))
                                        commands.extend(
                                            self._set_config(
                                                w,
                                                h,
                                                addr_want,
                                                route_want,
                                                route_have,
                                                new_hops,
                                                have_set,
                                            ))
                                        del addr_want.get("routes")[count]
                                    count += 1
                                if check:
                                    break
                            if check:
                                break
                        if not check:
                            commands.extend(
                                self._clear_config({}, h, {}, addr_have, {},
                                                   route_have))
        # For configuring any non-existing want config
        for w in temp_want:
            for addr_want in w.get("address_families"):
                for route_want in addr_want.get("routes"):
                    new_hops = []
                    for each in route_want.get("next_hops"):
                        want_set = set()
                        new_dict_to_set(each, [], want_set, 0)
                        new_hops.append(want_set)
                    commands.extend(
                        self._set_config(w, {}, addr_want, route_want, {},
                                         new_hops, set()))
        # Arranging the cmds suct that all delete cmds are fired before all set cmds
        commands = [each for each in sorted(commands) if "no" in each] + [
            each for each in sorted(commands) if "no" not in each
        ]

        return commands
Esempio n. 5
0
    def _state_replaced(self, want, have):
        """ The command generator when state is replaced

        :rtype: A list
        :returns: the commands necessary to migrate the current configuration
                  to the desired configuration
        """

        commands = []

        # Drill each iteration of want n have and then based on dest and afi tyoe comparison take config call
        for w in want:
            for addr_want in w.get("address_families"):
                for route_want in addr_want.get("routes"):
                    check = False
                    for h in have:
                        if h.get("address_families"):
                            for addr_have in h.get("address_families"):
                                for route_have in addr_have.get("routes"):
                                    if (route_want.get("dest")
                                            == route_have.get("dest")
                                            and addr_want["afi"]
                                            == addr_have["afi"]):
                                        check = True
                                        have_set = set()
                                        new_hops = []
                                        for each in route_want.get(
                                                "next_hops"):
                                            want_set = set()
                                            new_dict_to_set(
                                                each, [], want_set, 0)
                                            new_hops.append(want_set)
                                        new_dict_to_set(
                                            addr_have, [], have_set, 0)
                                        # Check if the have dict next_hops value is diff from want dict next_hops
                                        have_dict = filter_dict_having_none_value(
                                            route_want.get("next_hops")[0],
                                            route_have.get("next_hops")[0],
                                        )
                                        # update the have_dict with forward_router_address
                                        have_dict.update({
                                            "forward_router_address":
                                            route_have.get("next_hops")[0].get(
                                                "forward_router_address")
                                        })
                                        # updating the have_dict with next_hops val that's not None
                                        new_have_dict = {}
                                        for k, v in have_dict.items():
                                            if v is not None:
                                                new_have_dict.update({k: v})

                                        # Set the new config from the user provided want config
                                        cmd = self._set_config(
                                            w,
                                            h,
                                            addr_want,
                                            route_want,
                                            route_have,
                                            new_hops,
                                            have_set,
                                        )

                                        if cmd:
                                            # since inplace update isn't allowed for static routes, preconfigured
                                            # static routes needs to be deleted before the new want static routes changes
                                            # are applied
                                            clear_route_have = copy.deepcopy(
                                                route_have)
                                            # inplace update is allowed in case of ipv6 static routes, so not deleting it
                                            # before applying the want changes
                                            if ":" not in route_want.get(
                                                    "dest"):
                                                commands.extend(
                                                    self._clear_config(
                                                        {},
                                                        h,
                                                        {},
                                                        addr_have,
                                                        {},
                                                        clear_route_have,
                                                    ))
                                        commands.extend(cmd)
                                if check:
                                    break
                            if check:
                                break
                    if not check:
                        # For configuring any non-existing want config
                        new_hops = []
                        for each in route_want.get("next_hops"):
                            want_set = set()
                            new_dict_to_set(each, [], want_set, 0)
                            new_hops.append(want_set)
                        commands.extend(
                            self._set_config(
                                w,
                                {},
                                addr_want,
                                route_want,
                                {},
                                new_hops,
                                set(),
                            ))
        commands = [each for each in commands if "no" in each
                    ] + [each for each in commands if "no" not in each]

        return commands
Esempio n. 6
0
    def _set_config(self, want, have, acl_want, afi):
        """ Function that sets the acls config based on the want and have config
        :param want: want config
        :param have: have config
        :param acl_want: want acls config
        :param afi: acls afi type
        :rtype: A list
        :returns: the commands generated based on input want/have params
        """
        commands = []
        change = False
        want_set = set()
        have_set = set()
        # Convert the want and have dict to its respective set for taking the set diff
        new_dict_to_set(want, [], want_set)
        new_dict_to_set(have, [], have_set)
        diff = want_set - have_set

        # Check Py Version and if its py35, verify the diff again
        if diff and sys.version[0:3] == "3.5":
            if not reverify_diff_py35(want_set, have_set):
                diff = set()

        # Populate the config only when there's a diff b/w want and have config
        if diff:
            name = acl_want.get("name")
            if afi == "ipv4":
                try:
                    name = int(name)
                    # If name is numbered acls
                    if name <= 99:
                        cmd = "ip access-list standard {0}".format(name)
                    elif name >= 100:
                        cmd = "ip access-list extended {0}".format(name)
                except ValueError:
                    # If name is named acls
                    acl_type = acl_want.get("acl_type")
                    if acl_type:
                        cmd = "ip access-list {0} {1}".format(acl_type, name)
                    else:
                        self._module.fail_json(
                            msg="ACL type value is required for Named ACL!"
                        )

            elif afi == "ipv6":
                cmd = "ipv6 access-list {0}".format(name)

            # Get all of aces option values from diff dict
            sequence = want.get("sequence")
            grant = want.get("grant")
            source = want.get("source")
            destination = want.get("destination")
            po = want.get("protocol_options")
            protocol = want.get("protocol")
            dscp = want.get("dscp")
            fragments = want.get("fragments")
            log = want.get("log")
            log_input = want.get("log_input")
            option = want.get("option")
            precedence = want.get("precedence")
            time_range = want.get("time_range")
            tos = want.get("tos")
            ttl = want.get("ttl")

            if sequence:
                if afi == "ipv6":
                    cmd = cmd + " sequence {0}".format(sequence)
                else:
                    cmd = cmd + " {0}".format(sequence)
            if grant:
                cmd = cmd + " {0}".format(grant)
            if po and isinstance(po, dict):
                po_key = list(po)[0]
                po_val = dict()
                if protocol and protocol != po_key:
                    self._module.fail_json(
                        msg="Protocol value cannot be different from Protocol option protocol value!"
                    )
                cmd = cmd + " {0}".format(po_key)
                if po.get("icmp"):
                    po_val = po.get("icmp")
                elif po.get("igmp"):
                    po_val = po.get("igmp")
                elif po.get("tcp"):
                    po_val = po.get("tcp")
            elif protocol:
                cmd = cmd + " {0}".format(protocol)
            if source:
                cmd = self.source_dest_config(source, cmd, po)
            if destination:
                cmd = self.source_dest_config(destination, cmd, po)
            if po and po_val:
                cmd = cmd + " {0}".format(list(po_val)[0])
            if dscp:
                cmd = cmd + " dscp {0}".format(dscp)
            if fragments:
                cmd = cmd + " fragments {0}".format(fragments)
            if log:
                cmd = cmd + " log {0}".format(log)
            if log_input:
                cmd = cmd + " log-input {0}".format(log_input)
            if option:
                cmd = cmd + " option {0}".format(list(option)[0])
            if precedence:
                cmd = cmd + " precedence {0}".format(precedence)
            if time_range:
                cmd = cmd + " time-range {0}".format(time_range)
            if tos:
                for k, v in iteritems(tos):
                    if k == "service_value":
                        cmd = cmd + " tos {0}".format(v)
                    else:
                        cmd = cmd + " tos {0}".format(v)
            if ttl:
                for k, v in iteritems(ttl):
                    if k == "range" and v:
                        start = v.get("start")
                        end = v.get("start")
                        cmd = cmd + " ttl {0} {1}".format(start, end)
                    elif v:
                        cmd = cmd + " ttl {0} {1}".format(k, v)

            commands.append(cmd)
        if commands:
            change = True

        return commands, change