예제 #1
0
 def build_cmdref_objects(td):
     cmd_ref[td['type']]['ref'] = []
     saved_ids = []
     if want.get(td['name']):
         for playvals in want[td['name']]:
             valiate_input(playvals, td['name'], self._module)
             if playvals['id'] in saved_ids:
                 continue
             saved_ids.append(playvals['id'])
             resource_key = td['cmd'].format(playvals['id'])
             # Only build the NxosCmdRef object for the td['name'] module parameters.
             self._module.params[
                 'config'] = get_module_params_subsection(
                     ALL_MP, td['type'], playvals['id'])
             cmd_ref[td['type']]['ref'].append(
                 NxosCmdRef(self._module, td['obj']))
             ref = cmd_ref[td['type']]['ref'][-1]
             ref.set_context([resource_key])
             if td['type'] == 'TMS_SENSORGROUP' and get_setval_path(
                     self._module):
                 # Sensor group path setting can contain optional values.
                 # Call get_setval_path helper function to process any
                 # optional setval keys.
                 ref._ref['path']['setval'] = get_setval_path(
                     self._module)
             ref.get_existing(device_cache)
             ref.get_playvals()
             if td['type'] == 'TMS_DESTGROUP':
                 normalize_data(ref)
예제 #2
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']

        # The deleted case is very simple since we purge all telemetry config
        # and does not require any processing using NxosCmdRef objects.
        if state == 'deleted':
            return self._state_deleted(want, have)

        # Save off module params
        ALL_MP = self._module.params['config']

        cmd_ref = {}
        cmd_ref['TMS_GLOBAL'] = {}
        cmd_ref['TMS_DESTGROUP'] = {}
        cmd_ref['TMS_SENSORGROUP'] = {}
        cmd_ref['TMS_SUBSCRIPTION'] = {}

        # Get Telemetry Global Data
        cmd_ref['TMS_GLOBAL']['ref'] = []
        self._module.params['config'] = get_module_params_subsection(
            ALL_MP, 'TMS_GLOBAL')
        cmd_ref['TMS_GLOBAL']['ref'].append(
            NxosCmdRef(self._module, TMS_GLOBAL))
        ref = cmd_ref['TMS_GLOBAL']['ref'][0]
        ref.set_context()
        ref.get_existing()
        ref.get_playvals()
        device_cache = ref.cache_existing

        # Get Telemetry Destination Group Data
        if want.get('destination_groups'):
            td = {
                'name': 'destination_groups',
                'type': 'TMS_DESTGROUP',
                'obj': TMS_DESTGROUP,
                'cmd': 'destination-group {0}'
            }
            cmd_ref[td['type']]['ref'] = []
            saved_ids = []
            for playvals in want[td['name']]:
                valiate_input(playvals, td['name'], self._module)
                if playvals['id'] in saved_ids:
                    continue
                saved_ids.append(playvals['id'])
                resource_key = td['cmd'].format(playvals['id'])
                # Only build the NxosCmdRef object for the destination group module parameters.
                self._module.params['config'] = get_module_params_subsection(
                    ALL_MP, td['type'], playvals['id'])
                cmd_ref[td['type']]['ref'].append(
                    NxosCmdRef(self._module, td['obj']))
                ref = cmd_ref[td['type']]['ref'][-1]
                ref.set_context([resource_key])
                ref.get_existing(device_cache)
                ref.get_playvals()
                normalize_data(ref)

        # Get Telemetry Sensor Group Data
        if want.get('sensor_groups'):
            td = {
                'name': 'sensor_groups',
                'type': 'TMS_SENSORGROUP',
                'obj': TMS_SENSORGROUP,
                'cmd': 'sensor-group {0}'
            }
            cmd_ref[td['type']]['ref'] = []
            saved_ids = []
            for playvals in want[td['name']]:
                valiate_input(playvals, td['name'], self._module)
                if playvals['id'] in saved_ids:
                    continue
                saved_ids.append(playvals['id'])
                resource_key = td['cmd'].format(playvals['id'])
                # Only build the NxosCmdRef object for the sensor group module parameters.
                self._module.params['config'] = get_module_params_subsection(
                    ALL_MP, td['type'], playvals['id'])
                cmd_ref[td['type']]['ref'].append(
                    NxosCmdRef(self._module, td['obj']))
                ref = cmd_ref[td['type']]['ref'][-1]
                ref.set_context([resource_key])
                if get_setval_path(self._module):
                    # Sensor group path setting can contain optional values.
                    # Call get_setval_path helper function to process any
                    # optional setval keys.
                    ref._ref['path']['setval'] = get_setval_path(self._module)
                ref.get_existing(device_cache)
                ref.get_playvals()

        # Get Telemetry Subscription Data
        if want.get('subscriptions'):
            td = {
                'name': 'subscriptions',
                'type': 'TMS_SUBSCRIPTION',
                'obj': TMS_SUBSCRIPTION,
                'cmd': 'subscription {0}'
            }
            cmd_ref[td['type']]['ref'] = []
            saved_ids = []
            for playvals in want[td['name']]:
                valiate_input(playvals, td['name'], self._module)
                if playvals['id'] in saved_ids:
                    continue
                saved_ids.append(playvals['id'])
                resource_key = td['cmd'].format(playvals['id'])
                # Only build the NxosCmdRef object for the subscription module parameters.
                self._module.params['config'] = get_module_params_subsection(
                    ALL_MP, td['type'], playvals['id'])
                cmd_ref[td['type']]['ref'].append(
                    NxosCmdRef(self._module, td['obj']))
                ref = cmd_ref[td['type']]['ref'][-1]
                ref.set_context([resource_key])
                ref.get_existing(device_cache)
                ref.get_playvals()

        if state == 'overridden':
            if want == have:
                return []
            commands = self._state_overridden(cmd_ref, want, have)
        elif state == 'merged':
            if want == have:
                return []
            commands = self._state_merged(cmd_ref)
        elif state == 'replaced':
            if want == have:
                return []
            commands = self._state_replaced(cmd_ref)
        return commands
예제 #3
0
    def _state_replaced(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 = []
        massaged_have = massage_data(have)
        massaged_want = massage_data(want)

        ref = {}
        ref['tms_global'] = NxosCmdRef([], TMS_GLOBAL, ref_only=True)
        ref['tms_destgroup'] = NxosCmdRef([], TMS_DESTGROUP, ref_only=True)
        ref['tms_sensorgroup'] = NxosCmdRef([], TMS_SENSORGROUP, ref_only=True)
        ref['tms_subscription'] = NxosCmdRef([],
                                             TMS_SUBSCRIPTION,
                                             ref_only=True)

        # Order matters for state replaced.
        # First remove all subscriptions, followed by sensor-groups and destination-groups.
        # Second add all destination-groups, followed by sensor-groups and subscriptions
        add = {
            'TMS_GLOBAL': [],
            'TMS_DESTGROUP': [],
            'TMS_SENSORGROUP': [],
            'TMS_SUBSCRIPTION': []
        }
        delete = {
            'TMS_DESTGROUP': [],
            'TMS_SENSORGROUP': [],
            'TMS_SUBSCRIPTION': []
        }

        # Process Telemetry Global Want and Have Values
        # Possible states:
        # - want and have are (set) (equal: no action, not equal: replace with want)
        # - want (set) have (not set) (add want)
        # - want (not set) have (set) (delete have)
        # - want (not set) have (not set) (no action)
        # global_ctx = ref['tms_global']._ref['_template']['context']
        # property_ctx = ref['tms_global']._ref['certificate'].get('context')
        # setval = ref['tms_global']._ref['certificate']['setval']
        #
        all_global_properties = [
            'certificate', 'compression', 'source_interface', 'vrf'
        ]
        dest_profile_properties = ['compression', 'source_interface', 'vrf']
        dest_profile_remote_commands = []
        for property in all_global_properties:
            cmd = None
            global_ctx = ref['tms_global']._ref['_template']['context']
            property_ctx = ref['tms_global']._ref[property].get('context')
            setval = ref['tms_global']._ref[property]['setval']
            kind = ref['tms_global']._ref[property]['kind']
            if want.get(property) is not None:
                if have.get(property) is not None:
                    if want.get(property) != have.get(property):
                        if kind == 'dict':
                            cmd = [setval.format(**want.get(property))]
                        else:
                            cmd = [setval.format(want.get(property))]
                elif have.get(property) is None:
                    if kind == 'dict':
                        cmd = [setval.format(**want.get(property))]
                    else:
                        cmd = [setval.format(want.get(property))]
            elif want.get(property) is None:
                if have.get(property) is not None:
                    if kind == 'dict':
                        cmd = ['no ' + setval.format(**have.get(property))]
                    else:
                        cmd = ['no ' + setval.format(have.get(property))]
                    if property in dest_profile_properties:
                        dest_profile_remote_commands.extend(cmd)

            if cmd is not None:
                ctx = global_ctx
                if property_ctx is not None:
                    ctx.extend(property_ctx)
                add['TMS_GLOBAL'].extend(ctx)
                add['TMS_GLOBAL'].extend(cmd)

        add['TMS_GLOBAL'] = remove_duplicate_commands(add['TMS_GLOBAL'])
        # If all destination profile commands are being removed then just
        # remove the config context instead.
        if len(dest_profile_remote_commands) == 3:
            for item in dest_profile_remote_commands:
                add['TMS_GLOBAL'].remove(item)
            add['TMS_GLOBAL'].remove('destination-profile')
            add['TMS_GLOBAL'].extend(['no destination-profile'])

        # Process Telemetry destination_group, sensor_group and subscription Want and Have Values
        # Possible states:
        # - want (not set) have (set) (delete have)
        # - want and have are (set) (equal: no action, not equal: replace with want)
        # - want (set) have (not set) (add want)
        # - want (not set) have (not set) (no action)
        tms_resources = [
            'TMS_DESTGROUP', 'TMS_SENSORGROUP', 'TMS_SUBSCRIPTION'
        ]
        for resource in tms_resources:
            if resource == 'TMS_DESTGROUP':
                name = 'destination-group'
                cmd_property = 'destination'
                global_ctx = ref['tms_destgroup']._ref['_template']['context']
                setval = ref['tms_destgroup']._ref['destination']['setval']
                want_resources = massaged_want.get('destination_groups')
                have_resources = massaged_have.get('destination_groups')
            if resource == 'TMS_SENSORGROUP':
                name = 'sensor-group'
                global_ctx = ref['tms_sensorgroup']._ref['_template'][
                    'context']
                setval = {}
                setval['data_source'] = ref['tms_sensorgroup']._ref[
                    'data_source']['setval']
                setval['path'] = ref['tms_sensorgroup']._ref['path']['setval']
                want_resources = massaged_want.get('sensor_groups')
                have_resources = massaged_have.get('sensor_groups')
            if resource == 'TMS_SUBSCRIPTION':
                name = 'subscription'
                global_ctx = ref['tms_subscription']._ref['_template'][
                    'context']
                setval = {}
                setval['destination_group'] = ref['tms_subscription']._ref[
                    'destination_group']['setval']
                setval['sensor_group'] = ref['tms_subscription']._ref[
                    'sensor_group']['setval']
                want_resources = massaged_want.get('subscriptions')
                have_resources = massaged_have.get('subscriptions')

            if not want_resources and have_resources:
                # want not and have not set so delete have
                for key in have_resources.keys():
                    remove_context = ['{0} {1} {2}'.format('no', name, key)]
                    delete[resource].extend(global_ctx)
                    if remove_context[0] not in delete[resource]:
                        delete[resource].extend(remove_context)
            else:
                # want and have are set.
                # process wants:
                for want_key in want_resources.keys():
                    if want_key not in have_resources.keys():
                        # Want resource key not in have resource key so add it
                        property_ctx = ['{0} {1}'.format(name, want_key)]
                        for item in want_resources[want_key]:
                            if resource == 'TMS_DESTGROUP':
                                cmd = [setval.format(**item[cmd_property])]
                                add[resource].extend(global_ctx)
                                if property_ctx[0] not in add[resource]:
                                    add[resource].extend(property_ctx)
                                add[resource].extend(cmd)
                            if resource == 'TMS_SENSORGROUP':
                                cmd = {}
                                if item.get('data_source'):
                                    cmd['data_source'] = [
                                        setval['data_source'].format(
                                            item['data_source'])
                                    ]
                                if item.get('path'):
                                    setval['path'] = get_setval_path(
                                        item.get('path'))
                                    cmd['path'] = [
                                        setval['path'].format(**item['path'])
                                    ]
                                add[resource].extend(global_ctx)
                                if property_ctx[0] not in add[resource]:
                                    add[resource].extend(property_ctx)
                                if cmd.get('data_source'):
                                    add[resource].extend(cmd['data_source'])
                                if cmd.get('path'):
                                    add[resource].extend(cmd['path'])
                            if resource == 'TMS_SUBSCRIPTION':
                                cmd = {}
                                if item.get('destination_group'):
                                    cmd['destination_group'] = [
                                        setval['destination_group'].format(
                                            item['destination_group'])
                                    ]
                                if item.get('sensor_group'):
                                    cmd['sensor_group'] = [
                                        setval['sensor_group'].format(
                                            **item['sensor_group'])
                                    ]
                                add[resource].extend(global_ctx)
                                if property_ctx[0] not in add[resource]:
                                    add[resource].extend(property_ctx)
                                if cmd.get('destination_group'):
                                    add[resource].extend(
                                        cmd['destination_group'])
                                if cmd.get('sensor_group'):
                                    add[resource].extend(cmd['sensor_group'])

                    elif want_key in have_resources.keys():
                        # Want resource key exists in have resource keys but we need to
                        # inspect the individual items under the resource key
                        # for differences
                        for item in want_resources[want_key]:
                            if item not in have_resources[want_key]:
                                if item is None:
                                    continue
                                # item wanted but does not exist so add it
                                property_ctx = [
                                    '{0} {1}'.format(name, want_key)
                                ]
                                if resource == 'TMS_DESTGROUP':
                                    cmd = [setval.format(**item[cmd_property])]
                                    add[resource].extend(global_ctx)
                                    if property_ctx[0] not in add[resource]:
                                        add[resource].extend(property_ctx)
                                    add[resource].extend(cmd)
                                if resource == 'TMS_SENSORGROUP':
                                    cmd = {}
                                    if item.get('data_source'):
                                        cmd['data_source'] = [
                                            setval['data_source'].format(
                                                item['data_source'])
                                        ]
                                    if item.get('path'):
                                        setval['path'] = get_setval_path(
                                            item.get('path'))
                                        cmd['path'] = [
                                            setval['path'].format(
                                                **item['path'])
                                        ]
                                    add[resource].extend(global_ctx)
                                    if property_ctx[0] not in add[resource]:
                                        add[resource].extend(property_ctx)
                                    if cmd.get('data_source'):
                                        add[resource].extend(
                                            cmd['data_source'])
                                    if cmd.get('path'):
                                        add[resource].extend(cmd['path'])
                                if resource == 'TMS_SUBSCRIPTION':
                                    cmd = {}
                                    if item.get('destination_group'):
                                        cmd['destination_group'] = [
                                            setval['destination_group'].format(
                                                item['destination_group'])
                                        ]
                                    if item.get('sensor_group'):
                                        cmd['sensor_group'] = [
                                            setval['sensor_group'].format(
                                                **item['sensor_group'])
                                        ]
                                    add[resource].extend(global_ctx)
                                    if property_ctx[0] not in add[resource]:
                                        add[resource].extend(property_ctx)
                                    if cmd.get('destination_group'):
                                        add[resource].extend(
                                            cmd['destination_group'])
                                    if cmd.get('sensor_group'):
                                        add[resource].extend(
                                            cmd['sensor_group'])

                # process haves:
                for have_key in have_resources.keys():
                    if have_key not in want_resources.keys():
                        # Want resource key is not in have resource keys so remove it
                        cmd = ['no ' + '{0} {1}'.format(name, have_key)]
                        delete[resource].extend(global_ctx)
                        delete[resource].extend(cmd)
                    elif have_key in want_resources.keys():
                        # Have resource key exists in want resource keys but we need to
                        # inspect the individual items under the resource key
                        # for differences
                        for item in have_resources[have_key]:
                            if item not in want_resources[have_key]:
                                if item is None:
                                    continue
                                # have item not wanted so remove it
                                property_ctx = [
                                    '{0} {1}'.format(name, have_key)
                                ]
                                if resource == 'TMS_DESTGROUP':
                                    cmd = [
                                        'no ' +
                                        setval.format(**item[cmd_property])
                                    ]
                                    delete[resource].extend(global_ctx)
                                    if property_ctx[0] not in delete[resource]:
                                        delete[resource].extend(property_ctx)
                                    delete[resource].extend(cmd)
                                if resource == 'TMS_SENSORGROUP':
                                    cmd = {}
                                    if item.get('data_source'):
                                        cmd['data_source'] = [
                                            'no ' +
                                            setval['data_source'].format(
                                                item['data_source'])
                                        ]
                                    if item.get('path'):
                                        setval['path'] = get_setval_path(
                                            item.get('path'))
                                        cmd['path'] = [
                                            'no ' + setval['path'].format(
                                                **item['path'])
                                        ]
                                    delete[resource].extend(global_ctx)
                                    if property_ctx[0] not in delete[resource]:
                                        delete[resource].extend(property_ctx)
                                    if cmd.get('data_source'):
                                        delete[resource].extend(
                                            cmd['data_source'])
                                    if cmd.get('path'):
                                        delete[resource].extend(cmd['path'])
                                if resource == 'TMS_SUBSCRIPTION':
                                    cmd = {}
                                    if item.get('destination_group'):
                                        cmd['destination_group'] = [
                                            'no ' +
                                            setval['destination_group'].format(
                                                item['destination_group'])
                                        ]
                                    if item.get('sensor_group'):
                                        cmd['sensor_group'] = [
                                            'no ' +
                                            setval['sensor_group'].format(
                                                **item['sensor_group'])
                                        ]
                                    delete[resource].extend(global_ctx)
                                    if property_ctx[0] not in delete[resource]:
                                        delete[resource].extend(property_ctx)
                                    if cmd.get('destination_group'):
                                        delete[resource].extend(
                                            cmd['destination_group'])
                                    if cmd.get('sensor_group'):
                                        delete[resource].extend(
                                            cmd['sensor_group'])

            add[resource] = remove_duplicate_context(add[resource])
            delete[resource] = remove_duplicate_context(delete[resource])

        commands.extend(delete['TMS_SUBSCRIPTION'])
        commands.extend(delete['TMS_SENSORGROUP'])
        commands.extend(delete['TMS_DESTGROUP'])
        commands.extend(add['TMS_DESTGROUP'])
        commands.extend(add['TMS_SENSORGROUP'])
        commands.extend(add['TMS_SUBSCRIPTION'])
        commands.extend(add['TMS_GLOBAL'])
        commands = remove_duplicate_context(commands)

        return commands