Beispiel #1
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 = []
        want_afi = [w['afi'] for w in want]
        for h in have:
            if h['afi'] in want_afi:
                w = search_obj_in_list(h['afi'], want, 'afi')
                for h_acl in h['acls']:
                    w_acl = search_obj_in_list(h_acl['name'], w['acls'],
                                               'name')
                    if not w_acl:
                        del_dict = {
                            'afi': h['afi'],
                            'acls': [{
                                'name': h_acl['name']
                            }]
                        }
                        commands.extend(self._state_deleted([del_dict], have))
            else:
                # if afi is not in want
                commands.extend(self._state_deleted([{'afi': h['afi']}], have))
        for w in want:
            commands.extend(self._state_replaced(w, have))
        return commands
    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
        """
        # overridden is the same as replaced behavior except for the scope.
        cmds = []
        existing_interfaces = []
        for h in have:
            existing_interfaces.append(h['name'])
            obj_in_want = search_obj_in_list(h['name'], want, 'name')
            if obj_in_want:
                if h != obj_in_want:
                    replaced_cmds = self._state_replaced(obj_in_want, [h])
                    if replaced_cmds:
                        cmds.extend(replaced_cmds)
            else:
                cmds.extend(self.del_attribs(h))

        for w in want:
            if w['name'] not in existing_interfaces:
                # This is an object that was excluded from the 'have' list
                # because all of its params are currently set to default states
                # -OR- it's a new object that does not exist on the device yet.
                cmds.extend(self.add_commands(w))
        return cmds
    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
        """
        cmds = []
        obj_in_have = search_obj_in_list(want['name'], have, 'name')
        if obj_in_have:
            diff = dict_diff(want, obj_in_have)
        else:
            diff = want
        merged_cmds = self.set_commands(want, have)
        if 'name' not in diff:
            diff['name'] = want['name']

        replaced_cmds = []
        if obj_in_have:
            replaced_cmds = self.del_attribs(diff)
        if replaced_cmds or merged_cmds:
            for cmd in set(replaced_cmds).intersection(set(merged_cmds)):
                merged_cmds.remove(cmd)
            cmds.extend(replaced_cmds)
            cmds.extend(merged_cmds)
        return cmds
Beispiel #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 = []
        for h in have:
            h = flatten_dict(h)
            obj_in_want = flatten_dict(
                search_obj_in_list(h['name'], want, 'name'))
            if h == obj_in_want:
                continue
            for w in want:
                w = flatten_dict(w)
                if h['name'] == w['name']:
                    wkeys = w.keys()
                    hkeys = h.keys()
                    for k in wkeys:
                        if k in self.exclude_params and k in hkeys:
                            del h[k]
            commands.extend(self.del_attribs(h))
        for w in want:
            commands.extend(self.set_commands(flatten_dict(w), have, True))
        return commands
Beispiel #5
0
    def _state_overridden(self, want, have):
        """ The command generator when state is overridden
        Scope includes all interface objects on the device.

        :rtype: A list
        :returns: the commands necessary to migrate the current configuration
                  to the desired configuration
        """
        # overridden behavior is the same as replaced except for scope.
        cmds = []
        existing_vlans = []
        for i in have:
            obj_in_want = search_obj_in_list(i['name'], want, 'name')
            if obj_in_want:
                if i != obj_in_want:
                    v4_cmds = self._v4_cmds(obj_in_want.pop('ipv4', []), i.pop('ipv4', []), state='overridden')
                    replaced_cmds = self._state_replaced(obj_in_want, [i])
                    replaced_cmds.extend(v4_cmds)
                    self.cmd_order_fixup(replaced_cmds, obj_in_want['name'])
                    cmds.extend(replaced_cmds)
            else:
                deleted_cmds = self.generate_delete_commands(i)
                self.cmd_order_fixup(deleted_cmds, i['name'])
                cmds.extend(deleted_cmds)

        for i in want:
            if [item for item in have if i['name'] == item['name']]:
                continue
            cmds.extend(self.add_commands(i, name=i['name']))

        return cmds
Beispiel #6
0
    def set_commands(self, w, have, replace=False):
        commands = []

        obj_in_have = flatten_dict(search_obj_in_list(w['name'], have, 'name'))
        if not obj_in_have:
            commands = self.add_commands(w)
        else:
            diff = self.diff_of_dicts(w, obj_in_have)
            if diff and not replace:
                if 'mode' in diff.keys() and diff['mode']:
                    commands = self.add_commands(diff)
                if "allowed_vlans" in diff.keys() and diff["allowed_vlans"]:
                    vlan_tobe_added = diff["allowed_vlans"].split(',')
                    vlan_list = vlan_tobe_added[:]
                    if obj_in_have.get("allowed_vlans"):
                        have_vlans = obj_in_have["allowed_vlans"].split(',')
                    else:
                        have_vlans = []
                    for w_vlans in vlan_list:
                        if w_vlans in have_vlans:
                            vlan_tobe_added.pop(vlan_tobe_added.index(w_vlans))
                    if vlan_tobe_added:
                        diff.update(
                            {"allowed_vlans": ','.join(vlan_tobe_added)})
                        if have_vlans:
                            commands = self.add_commands(diff, True)
                        else:
                            commands = self.add_commands(diff)
                    return commands
            commands = self.add_commands(diff)
        return commands
Beispiel #7
0
    def _state_replaced(self, w, 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 = []
        obj_in_have = search_obj_in_list(w['name'], have, 'name')
        if obj_in_have:
            diff = dict_diff(w, obj_in_have)
        else:
            diff = w
        merged_commands = self.set_commands(w, have)
        if 'name' not in diff:
            diff['name'] = w['name']
        wkeys = w.keys()
        dkeys = diff.keys()
        for k in wkeys:
            if k in self.exclude_params and k in dkeys:
                del diff[k]
        replaced_commands = self.del_attribs(diff)

        if merged_commands:
            cmds = set(replaced_commands).intersection(set(merged_commands))
            for cmd in cmds:
                merged_commands.remove(cmd)
            commands.extend(replaced_commands)
            commands.extend(merged_commands)
        return commands
Beispiel #8
0
    def _state_overridden(self, want, have):
        """ The command generator when state is overridden.
        Scope includes all vlan objects on the device.
        :rtype: A list
        :returns: the minimum command set required to migrate the current
                  configuration to the desired configuration.
        """
        # overridden behavior is the same as replaced except for scope.
        cmds = []
        existing_vlans = []
        for h in have:
            existing_vlans.append(h['vlan_id'])
            obj_in_want = search_obj_in_list(h['vlan_id'], want, 'vlan_id')
            if obj_in_want:
                if h != obj_in_want:
                    replaced_cmds = self._state_replaced(obj_in_want, [h])
                    if replaced_cmds:
                        cmds.extend(replaced_cmds)
            else:
                cmds.append('no vlan %s' % h['vlan_id'])

        # Add wanted vlans that don't exist on the device yet
        for w in want:
            if w['vlan_id'] not in existing_vlans:
                new_vlan = ['vlan %s' % w['vlan_id']]
                cmds.extend(new_vlan + self.add_commands(w))
        return cmds
Beispiel #9
0
    def _state_replaced(self, want, have):
        """ The command generator when state is replaced.
        Scope is limited to vlan objects defined in the playbook.
        :rtype: A list
        :returns: The minimum command set required to migrate the current
                  configuration to the desired configuration.
        """
        obj_in_have = search_obj_in_list(want['vlan_id'], have, 'vlan_id')
        if obj_in_have:
            # ignore states that are already reset, then diff what's left
            obj_in_have = self.remove_default_states(obj_in_have)
            diff = dict_diff(want, obj_in_have)
            # Remove merge items from diff; what's left will be used to
            # remove states not specified in the playbook
            for k in dict(set(want.items()) - set(obj_in_have.items())).keys():
                diff.pop(k, None)
        else:
            diff = want

        # merged_cmds: 'want' cmds to update 'have' states that don't match
        # replaced_cmds: remaining 'have' cmds that need to be reset to default
        merged_cmds = self.set_commands(want, have)
        replaced_cmds = []
        if obj_in_have:
            # Remaining diff items are used to reset states to default
            replaced_cmds = self.del_attribs(diff)
        cmds = []
        if replaced_cmds or merged_cmds:
            cmds += ['vlan %s' % str(want['vlan_id'])]
            cmds += merged_cmds + replaced_cmds
        return cmds
Beispiel #10
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 = []
        del_commands = []
        delete_dict = {}
        obj_in_have = flatten_dict(
            search_obj_in_list(want['name'], have, 'name'))
        for k1 in obj_in_have.keys():
            if k1 not in want.keys():
                delete_dict.update({k1: obj_in_have[k1]})

        if delete_dict:
            delete_dict.update({'name': want['name']})
            del_commands = self.del_commands(delete_dict)
        merged_commands = self.set_commands(want, have)

        if merged_commands:
            cmds = set(del_commands).intersection(set(merged_commands))
            for cmd in cmds:
                merged_commands.remove(cmd)

        commands.extend(del_commands)
        commands.extend(merged_commands)
        return commands
 def set_commands(self, want, have):
     cmds = []
     obj_in_have = search_obj_in_list(want['name'], have, 'name')
     if not obj_in_have:
         cmds = self.add_commands(want, obj_in_have)
     else:
         diff = self.diff_of_dicts(want, obj_in_have)
         cmds = self.add_commands(diff, obj_in_have)
     return cmds
Beispiel #12
0
 def set_commands(self, w, have):
     commands = []
     obj_in_have = search_obj_in_list(w['name'], have, 'name')
     if not obj_in_have:
         commands = self.add_commands(w)
     else:
         diff = self.diff_of_dicts(w, obj_in_have)
         commands = self.add_commands(diff)
     return commands
Beispiel #13
0
 def del_intf_commands(self, w, have):
     commands = []
     obj_in_have = search_obj_in_list(w['name'], have, 'name')
     if obj_in_have:
         lst_to_del = self.intersect_list_of_dicts(w['members'], obj_in_have['members'])
         if lst_to_del:
             for item in lst_to_del:
                 commands.append('interface' + ' ' + item['member'])
                 commands.append('no channel-group')
     return commands
Beispiel #14
0
    def set_commands(self, want, have, deleted=False):
        commands = []
        have_name = search_obj_in_list(want['name'], have, 'name')
        if have_name and have_name.get('access_groups'):
            if want.get('access_groups'):
                for w_afi in want['access_groups']:
                    ip = 'ipv6'
                    if w_afi['afi'] == 'ipv4':
                        ip = 'ip'
                    have_afi = search_obj_in_list(
                        w_afi['afi'], have_name['access_groups'], 'afi')
                    if have_afi:
                        new_acls = []
                        if deleted:
                            if w_afi.get('acls') and have_afi.get('acls'):
                                new_acls = [
                                    acl for acl in w_afi.get('acls') if acl in have_afi.get('acls')]
                            elif 'acls' not in w_afi.keys():
                                new_acls = have_afi.get('acls')
                        else:
                            if w_afi.get('acls'):
                                new_acls = [
                                    acl for acl in w_afi['acls'] if acl not in have_afi['acls']]
                        commands.extend(self.process_acl(
                            new_acls, ip, deleted))
                    else:
                        if not deleted:
                            if w_afi.get('acls'):
                                commands.extend(
                                    self.process_acl(w_afi['acls'], ip))
            else:
                # only name is given to delete
                if deleted and 'access_groups' in have_name.keys():
                    commands.extend(self.process_access_group(have_name, True))
        else:
            if not deleted:  # and 'access_groups' in have_name.keys():
                commands.extend(self.process_access_group(want))

        if len(commands) > 0:
            commands.insert(0, 'interface ' + want['name'])
        return commands
Beispiel #15
0
 def set_commands(self, want, have):
     commands = []
     obj_in_have = flatten_dict(
         search_obj_in_list(want['name'], have, 'name'))
     if not obj_in_have:
         commands = self.add_commands(flatten_dict(want))
     else:
         diff = dict_diff(obj_in_have, want)
         if diff:
             diff.update({'name': want['name']})
             commands = self.add_commands(diff)
     return commands
Beispiel #16
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
        """
        new_commands = []
        del_dict = {'name': want['name'], 'access_groups': []}
        obj_in_have = search_obj_in_list(want['name'], have, 'name')
        if obj_in_have != want:
            commands = []
            if obj_in_have and 'access_groups' in obj_in_have.keys():
                for ag in obj_in_have['access_groups']:
                    want_afi = []
                    if want.get('access_groups'):
                        want_afi = search_obj_in_list(
                            ag['afi'], want['access_groups'], 'afi')
                    if not want_afi:
                        # whatever in have is not in want
                        del_dict['access_groups'].append(ag)
                    else:
                        del_acl = []
                        for acl in ag['acls']:
                            if want_afi.get('acls'):
                                if acl not in want_afi['acls']:
                                    del_acl.append(acl)
                            else:
                                del_acl.append(acl)
                        afi = want_afi['afi']
                        del_dict['access_groups'].append(
                            {'afi': afi, 'acls': del_acl})

            commands.extend(self._state_deleted([del_dict], have))
            commands.extend(self._state_merged(want, have))
            new_commands.append(commands[0])
            commands = [commands[i]
                        for i in range(1, len(commands)) if commands[i] != commands[0]]
            new_commands.extend(commands)
        return new_commands
    def _state_replaced(self, w, 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 = []
        name = w['name']
        obj_in_have = search_obj_in_list(name, have, 'name')
        if obj_in_have:
            # If 'w' does not specify mode then intf may need to change to its
            # default mode, however default mode may depend on sysdef.
            if not w.get('mode') and re.search('Ethernet|port-channel', name):
                sysdefs = self.intf_defs['sysdefs']
                sysdef_mode = sysdefs['mode']
                if obj_in_have.get('mode') != sysdef_mode:
                    w['mode'] = sysdef_mode
            diff = dict_diff(w, obj_in_have)
        else:
            diff = w

        merged_commands = self.set_commands(w, have)
        if merged_commands:
            # merged_commands:
            #   - These commands are changes specified by the playbook.
            #   - merged_commands apply to both existing and new objects
            # replaced_commands:
            #   - These are the unspecified commands, used to reset any params
            #     that are not already set to default states
            #   - replaced_commands should only be used on 'have' objects
            #     (interfaces that already exist)
            if obj_in_have:
                if 'name' not in diff:
                    diff['name'] = name
                wkeys = w.keys()
                dkeys = diff.keys()
                for k in wkeys:
                    if k in self.exclude_params and k in dkeys:
                        del diff[k]
                replaced_commands = self.del_attribs(diff)
                cmds = set(replaced_commands).intersection(
                    set(merged_commands))
                for cmd in cmds:
                    merged_commands.remove(cmd)
                commands.extend(replaced_commands)

            commands.extend(merged_commands)
        return commands
Beispiel #18
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 = []
        for h in have:
            obj_in_want = search_obj_in_list(h['name'], want, 'name')
            if h == obj_in_want:
                continue
            commands.extend(self.del_all_commands(h))
        for w in want:
            commands.extend(self.set_commands(w, have))
        return commands
Beispiel #19
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 want:
            for w in want:
                obj_in_have = search_obj_in_list(w['vrf'], have, 'vrf')
                if obj_in_have:
                    commands.extend(self.del_commands([obj_in_have]))
        else:
            if have:
                commands = self.del_commands(have)
        return commands
Beispiel #20
0
 def set_commands(self, w, have):
     commands = []
     obj_in_have = search_obj_in_list(w['name'], have, 'name')
     if not obj_in_have:
         commands = self.add_commands(w, w['name'])
     else:
         diff = {}
         diff.update({
             'ipv4':
             self.diff_list_of_dicts(w.get('ipv4'), obj_in_have.get('ipv4'))
         })
         diff.update({
             'ipv6':
             self.diff_list_of_dicts(w.get('ipv6'), obj_in_have.get('ipv6'))
         })
         commands = self.add_commands(diff, w['name'])
     return commands
Beispiel #21
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 want:
            for w in want:
                obj_in_have = search_obj_in_list(w['name'], have, 'name')
                commands.extend(self.del_attribs(obj_in_have))
        else:
            if not have:
                return commands
            for h in have:
                commands.extend(self.del_attribs(h))
        return commands
Beispiel #22
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 want:
            for w in want:
                obj_in_have = search_obj_in_list(w['vlan_id'], have, 'vlan_id')
                commands.append('no vlan ' + str(obj_in_have['vlan_id']))
        else:
            if not have:
                return commands
            for h in have:
                commands.append('no vlan ' + str(h['vlan_id']))
        return commands
Beispiel #23
0
    def set_commands(self, w, have):
        commands = []
        name = w['name']
        obj_in_have = search_obj_in_list(name, have, 'name')
        if not obj_in_have:
            commands = self.add_commands(w, name=name)
        else:
            # lists of dicts must be processed separately from non-list attrs
            v4_cmds = self._v4_cmds(w.pop('ipv4', []), obj_in_have.pop('ipv4', []), state='merged')
            v6_cmds = self._v6_cmds(w.pop('ipv6', []), obj_in_have.pop('ipv6', []), state='merged')

            # diff remaining attrs
            diff = self.diff_of_dicts(w, obj_in_have)
            commands = self.add_commands(diff, name=name)
            commands.extend(v4_cmds)
            commands.extend(v6_cmds)

        self.cmd_order_fixup(commands, name)
        return commands
Beispiel #24
0
 def del_delta_attribs(self, w, have):
     commands = []
     obj_in_have = search_obj_in_list(w['name'], have, 'name')
     if obj_in_have:
         lst_to_del = []
         ipv4_intersect = self.intersect_list_of_dicts(
             w.get('ipv4'), obj_in_have.get('ipv4'))
         ipv6_intersect = self.intersect_list_of_dicts(
             w.get('ipv6'), obj_in_have.get('ipv6'))
         if ipv4_intersect:
             lst_to_del.append({'ipv4': ipv4_intersect})
         if ipv6_intersect:
             lst_to_del.append({'ipv6': ipv6_intersect})
         if lst_to_del:
             for item in lst_to_del:
                 commands.extend(self.generate_delete_commands(item))
         else:
             commands.extend(self.generate_delete_commands(obj_in_have))
         if commands:
             commands.insert(0, 'interface ' + obj_in_have['name'])
     return commands
    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
        """
        cmds = []
        for h in have:
            # Check existing states, set to default if not in want or different than want
            h = flatten_dict(h)
            obj_in_want = search_obj_in_list(h['name'], want, 'name')
            if obj_in_want:
                # Let the 'want' loop handle all vals for this interface
                continue
            cmds.extend(self.del_attribs(h))
        for w in want:
            # Update any want attrs if needed. The overridden state considers
            # the play as the source of truth for the entire device, therefore
            # set any unspecified attrs to their default state.
            w = self.set_none_vals_to_defaults(flatten_dict(w))
            cmds.extend(self.set_commands(w, have))
        return cmds
Beispiel #26
0
    def _state_replaced(self, want, have):
        """ The command generator when state is replaced
        Scope is limited to interface objects defined in the playbook.

        :rtype: A list
        :returns: the commands necessary to migrate the current configuration
                  to the desired configuration
        """
        cmds = []
        name = want['name']
        obj_in_have = search_obj_in_list(want['name'], have, 'name')

        have_v4 = obj_in_have.pop('ipv4', []) if obj_in_have else []
        have_v6 = obj_in_have.pop('ipv6', []) if obj_in_have else []

        # Process lists of dicts separately
        v4_cmds = self._v4_cmds(want.pop('ipv4', []), have_v4, state='replaced')
        v6_cmds = self._v6_cmds(want.pop('ipv6', []), have_v6, state='replaced')

        # Process remaining attrs
        if obj_in_have:
            # Find 'want' changes first
            diff = self.diff_of_dicts(want, obj_in_have)
            rmv = {'name': name}
            haves_not_in_want = set(obj_in_have.keys()) - set(want.keys()) - set(diff.keys())
            for i in haves_not_in_want:
                rmv[i] = obj_in_have[i]
            cmds.extend(self.generate_delete_commands(rmv))
        else:
            diff = want

        cmds.extend(self.add_commands(diff, name=name))
        cmds.extend(v4_cmds)
        cmds.extend(v6_cmds)
        self.cmd_order_fixup(cmds, name)
        return cmds
Beispiel #27
0
    def set_commands(self, want, have):
        commands = []
        have_afi = search_obj_in_list(want['afi'], have, 'afi')
        ip = ''
        if 'v6' in want['afi']:
            ip = 'ipv6 '
        else:
            ip = 'ip '

        if have_afi:
            if want.get('acls'):
                for w_acl in want['acls']:
                    have_acl = search_obj_in_list(w_acl['name'],
                                                  have_afi['acls'], 'name')
                    name = w_acl['name']
                    flag = 0
                    ace_commands = []
                    if have_acl != w_acl:
                        if have_acl:
                            ace_list = []
                            if w_acl.get('aces') and have_acl.get('aces'):
                                # case 1 --> sequence number not given in want --> new ace
                                # case 2 --> new sequence number in want --> new ace
                                # case 3 --> existing sequence number given --> update rule (only for merged state.
                                #            For replaced and overridden, rule is deleted in the state's config)

                                ace_list = [
                                    item for item in w_acl['aces']
                                    if 'sequence' not in item.keys()
                                ]  # case 1

                                want_seq = [
                                    item['sequence'] for item in w_acl['aces']
                                    if 'sequence' in item.keys()
                                ]

                                have_seq = [
                                    item['sequence']
                                    for item in have_acl['aces']
                                ]

                                new_seq = list(set(want_seq) - set(have_seq))
                                common_seq = list(
                                    set(want_seq).intersection(set(have_seq)))

                                temp_list = [
                                    item for item in w_acl['aces']
                                    if 'sequence' in item.keys()
                                    and item['sequence'] in new_seq
                                ]  # case 2
                                ace_list.extend(temp_list)
                                for w in w_acl['aces']:
                                    self.argument_spec = AclsArgs.argument_spec
                                    params = utils.validate_config(
                                        self.argument_spec, {
                                            'config': [{
                                                'afi':
                                                want['afi'],
                                                'acls': [{
                                                    'name': name,
                                                    'aces': ace_list
                                                }]
                                            }]
                                        })
                                    if 'sequence' in w.keys(
                                    ) and w['sequence'] in common_seq:
                                        temp_obj = search_obj_in_list(
                                            w['sequence'], have_acl['aces'],
                                            'sequence')  # case 3
                                        if temp_obj != w:
                                            for key, val in w.items():
                                                temp_obj[key] = val
                                            ace_list.append(temp_obj)
                                            if self._module.params[
                                                    'state'] == 'merged':
                                                ace_commands.append(
                                                    'no ' + str(w['sequence']))
                                        # remove existing rule to update it
                            elif w_acl.get('aces'):
                                # 'have' has ACL defined without any ACE
                                ace_list = [item for item in w_acl['aces']]
                            for w_ace in ace_list:
                                ace_commands.append(
                                    self.process_ace(w_ace).strip())
                                flag = 1

                            if flag:
                                ace_commands.insert(0,
                                                    ip + 'access-list ' + name)

                        else:
                            commands.append(ip + 'access-list ' + name)
                            if 'aces' in w_acl.keys():
                                for w_ace in w_acl['aces']:
                                    commands.append(
                                        self.process_ace(w_ace).strip())
                    commands.extend(ace_commands)
        else:
            if want.get('acls'):
                for w_acl in want['acls']:
                    name = w_acl['name']
                    commands.append(ip + 'access-list ' + name)
                    if 'aces' in w_acl.keys():
                        for w_ace in w_acl['aces']:
                            commands.append(self.process_ace(w_ace).strip())

        return commands
Beispiel #28
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 = []
        delete_commands = []
        merged_commands = []
        q(have)
        obj_in_have = search_obj_in_list(want['vrf'], have, 'vrf')
        q(obj_in_have)
        if obj_in_have and obj_in_have != {'vrf': '__global__'}:
            afi_list = [w['afi'] for w in want['address_families']]
            q(afi_list)
            for h in obj_in_have['address_families']:
                if h['afi'] in afi_list:
                    q(h['afi'], want)
                    want_afi = search_obj_in_list(h['afi'],
                                                  want['address_families'],
                                                  'afi')
                    q(want_afi)
                    want_dest_list = [w['dest'] for w in want_afi['routes']]
                    for ro in h['routes']:
                        if ro['dest'] in want_dest_list:
                            q(ro)
                            want_dest = search_obj_in_list(
                                ro['dest'], want_afi['routes'], 'dest')
                            want_next_hops = [
                                nh for nh in want_dest['next_hops']
                            ]
                            q(want_next_hops)
                            for next_hop in ro['next_hops']:
                                if next_hop in want_next_hops:
                                    {}
                                else:
                                    q(next_hop)
                                    if obj_in_have['vrf'] is '__global__':
                                        obj_in_have['vrf'] = 'default'
                                    if h['afi'] == 'ipv4':
                                        com = 'no ip route ' + \
                                            ro['dest'] + ' ' + \
                                            self.add_commands(next_hop)
                                        q(com)

                                    else:
                                        com = 'no ipv6 route ' + \
                                            ro['dest'] + ' ' + \
                                            self.add_commands(next_hop)
                                    delete_commands.append(com.strip())
                                    # string = 'vrf context ' + \
                                    #     str(obj_in_have['vrf'])
                                    # if string not in delete_commands:
                                    #     delete_commands.insert(0, string)
                                    # delete next_hop
                        else:
                            delete_dict = {
                                'vrf':
                                obj_in_have['vrf'],
                                'address_families': [{
                                    'afi': h['afi'],
                                    'routes': [ro]
                                }]
                            }
                            q(delete_dict)
                            delete_commands.extend(
                                self.del_commands([delete_dict]))
                            # delete ro['dest']
                else:
                    q(h)
                    delete_commands.extend(
                        self.del_commands([{
                            'address_families': [h],
                            'vrf': obj_in_have['vrf']
                        }]))
                    # delete h['afi']
        q(delete_commands)
        final_delete_commands = []
        for d in delete_commands:
            if d not in final_delete_commands:
                final_delete_commands.append(d)
        # if there are two afis, 'vrf context..' is added twice fom del_commands. set() gets unique commands
        merged_commands = (self.set_commands(want, have))
        q(merged_commands)
        if merged_commands:
            cmds = set(final_delete_commands).intersection(
                set(merged_commands))
            for cmd in cmds:
                merged_commands.remove(cmd)
        q(merged_commands)
        commands.extend(final_delete_commands)
        commands.extend(merged_commands)
        q(commands)
        return commands
Beispiel #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 want:  # and have != want:
            for w in want:
                ip = 'ipv6' if w['afi'] == 'ipv6' else 'ip'
                acl_names = []
                have_afi = search_obj_in_list(w['afi'], have, 'afi')
                # if want['afi] not in have, ignore
                if have_afi:
                    if w.get('acls'):
                        for acl in w['acls']:
                            if 'aces' in acl.keys():
                                have_name = search_obj_in_list(
                                    acl['name'], have_afi['acls'], 'name')
                                if have_name:
                                    ace_commands = []
                                    flag = 0
                                    for ace in acl['aces']:
                                        if list(ace.keys()) == ['sequence']:
                                            # only sequence number is specified to be deleted
                                            if 'aces' in have_name.keys():
                                                for h_ace in have_name['aces']:
                                                    if h_ace[
                                                            'sequence'] == ace[
                                                                'sequence']:
                                                        ace_commands.append(
                                                            'no ' +
                                                            str(ace['sequence']
                                                                ))
                                                        flag = 1
                                        else:
                                            if 'aces' in have_name.keys():
                                                for h_ace in have_name['aces']:
                                                    # when want['ace'] does not have seq number
                                                    if 'sequence' not in ace.keys(
                                                    ):
                                                        del h_ace['sequence']
                                                    if ace == h_ace:
                                                        ace_commands.append(
                                                            'no ' +
                                                            self.process_ace(
                                                                ace))
                                                        flag = 1
                                    if flag:
                                        ace_commands.insert(
                                            0,
                                            ip + ' access-list ' + acl['name'])
                                    commands.extend(ace_commands)
                            else:
                                # only name given
                                for h in have_afi['acls']:
                                    if h['name'] == acl['name']:
                                        acl_names.append(acl['name'])
                        for name in acl_names:
                            commands.append('no ' + ip + ' access-list ' +
                                            name)

                    else:
                        # 'only afi is given'
                        if have_afi.get('acls'):
                            for h in have_afi['acls']:
                                acl_names.append(h['name'])
                            for name in acl_names:
                                commands.append('no ' + ip + ' access-list ' +
                                                name)
        else:
            v6 = []
            v4 = []
            v6_local = v4_local = None
            for h in have:
                if h['afi'] == 'ipv6':
                    v6 = (acl['name'] for acl in h['acls'])
                    if 'match_local_traffic' in h.keys():
                        v6_local = True
                else:
                    v4 = (acl['name'] for acl in h['acls'])
                    if 'match_local_traffic' in h.keys():
                        v4_local = True

            self.no_commands(v4, commands, v4_local, 'ip')
            self.no_commands(v6, commands, v6_local, 'ipv6')

            for name in v6:
                commands.append('no ipv6 access-list ' + name)
            if v4_local:
                commands.append('no ipv6 access-list match-local-traffic')

        return commands
Beispiel #30
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 = []
        have_afi = search_obj_in_list(want['afi'], have, 'afi')
        del_dict = {'acls': []}
        want_names = []
        if have_afi != want:
            if have_afi:
                del_dict.update({'afi': have_afi['afi'], 'acls': []})
                if want.get('acls'):
                    want_names = [w['name'] for w in want['acls']]
                    have_names = [h['name'] for h in have_afi['acls']]
                    want_acls = want.get('acls')
                    for w in want_acls:
                        acl_commands = []
                        if w['name'] not in have_names:
                            # creates new ACL in replaced state
                            merge_dict = {'afi': want['afi'], 'acls': [w]}
                            commands.extend(
                                self._state_merged(merge_dict, have))
                        else:
                            # acl in want exists in have
                            have_name = search_obj_in_list(
                                w['name'], have_afi['acls'], 'name')
                            have_aces = have_name.get('aces') if have_name.get(
                                'aces') else []
                            merge_aces = []
                            del_aces = []
                            w_aces = w.get('aces') if w.get('aces') else []

                            for ace in have_aces:
                                if ace not in w_aces:
                                    del_aces.append(ace)
                            for ace in w_aces:
                                if ace not in have_aces:
                                    merge_aces.append(ace)
                            merge_dict = {
                                'afi': want['afi'],
                                'acls': [{
                                    'name': w['name'],
                                    'aces': merge_aces
                                }]
                            }
                            del_dict = {
                                'afi': want['afi'],
                                'acls': [{
                                    'name': w['name'],
                                    'aces': del_aces
                                }]
                            }
                            if del_dict['acls']:
                                acl_commands.extend(
                                    self._state_deleted([del_dict], have))
                            acl_commands.extend(
                                self._state_merged(merge_dict, have))

                            for i in range(1, len(acl_commands)):
                                if acl_commands[i] == acl_commands[0]:
                                    acl_commands[i] = ''
                            commands.extend(acl_commands)
                else:
                    acls = []
                    # no acls given in want, so delete all have acls
                    for acl in have_afi['acls']:
                        acls.append({'name': acl['name']})
                    del_dict['acls'] = acls
                    if del_dict['acls']:
                        commands.extend(self._state_deleted([del_dict], have))

            else:
                # want_afi is not present in have
                commands.extend(self._state_merged(want, have))

        commands = list(filter(None, commands))
        return commands