def execute_module(self): """ Execute the module :rtype: A dictionary :returns: The result from module execution """ result = {'changed': False} commands = list() warnings = list() state = self._module.params['state'] if 'overridden' in state: self._module.fail_json( msg='State <overridden> is invalid for this module.') # When state is 'deleted', the module_params should not contain data # under the 'config' key if 'deleted' in state and self._module.params.get('config'): self._module.fail_json( msg='Remove config key from playbook when state is <deleted>') if self._module.params['config'] is None: self._module.params['config'] = {} # Normalize interface name. int = self._module.params['config'].get('source_interface') if int: self._module.params['config'][ 'source_interface'] = normalize_interface(int) existing_telemetry_facts = self.get_telemetry_facts() commands.extend(self.set_config(existing_telemetry_facts)) if commands: if not self._module.check_mode: self.edit_config(commands) # TODO: edit_config is only available for network_cli. Once we # add support for httpapi, we will need to switch to load_config # or add support to httpapi for edit_config # # self._connection.load_config(commands) result['changed'] = True result['commands'] = commands changed_telemetry_facts = self.get_telemetry_facts() result['before'] = existing_telemetry_facts if result['changed']: result['after'] = changed_telemetry_facts result['warnings'] = warnings return result
def populate_structured_neighbors_lldp(self, data): objects = dict() data = data['TABLE_nbor']['ROW_nbor'] if isinstance(data, dict): data = [data] for item in data: local_intf = normalize_interface(item['l_port_id']) objects[local_intf] = list() nbor = dict() nbor['port'] = item['port_id'] nbor['host'] = nbor['sysname'] = item['chassis_id'] objects[local_intf].append(nbor) return objects
def set_config(self, existing_hsrp_interfaces_facts): """ Collect the configuration from the args passed to the module, collect the current configuration (as a dict from facts) :rtype: A list :returns: the commands necessary to migrate the current configuration to the desired configuration """ config = self._module.params['config'] want = [] if config: for w in config: w.update({'name': normalize_interface(w['name'])}) want.append(w) have = existing_hsrp_interfaces_facts resp = self.set_state(want, have) return to_list(resp)
def set_config(self, existing_lag_interfaces_facts): """ Collect the configuration from the args passed to the module, collect the current configuration (as a dict from facts) :rtype: A list :returns: the commands necessary to migrate the current configuration to the desired configuration """ want = self._module.params.get('config') if want: for w in want: w.update(remove_empties(w)) if 'members' in w and w['members']: for item in w['members']: item.update( {'member': normalize_interface(item['member'])}) have = existing_lag_interfaces_facts resp = self.set_state(want, have) return to_list(resp)
def get_members(self, id, connection): """ Returns members associated with a channel-group :param name: The channel group :rtype: list :returns: Members """ members = [] data = connection.get('show port-channel summary') match = re.search(r'{0} (.+)(|\n)'.format(id), data) if match: interfaces = re.search(r'Eth\d(.+)$', match.group()) if interfaces: for i in interfaces.group().split(): if get_interface_type(i[:-3]) != 'unknown': members.append(normalize_interface(i[:-3])) return members
def set_config(self, existing_l2_interfaces_facts): """ Collect the configuration from the args passed to the module, collect the current configuration (as a dict from facts) :rtype: A list :returns: the commands necessary to migrate the current configuration to the desired configuration """ config = self._module.params.get('config') want = [] if config: for w in config: w.update({'name': normalize_interface(w['name'])}) self.expand_trunk_allowed_vlans(w) want.append(remove_empties(w)) have = existing_l2_interfaces_facts for h in have: self.expand_trunk_allowed_vlans(h) resp = self.set_state(want, have) return to_list(resp)
def populate_neighbors(self, data): objects = dict() # if there are no neighbors the show command returns # ERROR: No neighbour information if data.startswith('ERROR'): return dict() regex = re.compile(r'(\S+)\s+(\S+)\s+\d+\s+\w+\s+(\S+)') for item in data.split('\n')[4:-1]: match = regex.match(item) if match: nbor = dict() nbor['host'] = nbor['sysname'] = match.group(1) nbor['port'] = match.group(3) local_intf = normalize_interface(match.group(2)) if local_intf not in objects: objects[local_intf] = [] objects[local_intf].append(nbor) return objects
def set_config(self, existing_interfaces_facts, default_intf_list): """ Collect the configuration from the args passed to the module, collect the current configuration (as a dict from facts) :rtype: A list :returns: the commands necessary to migrate the current configuration to the desired configuration """ config = self._module.params.get('config') want = [] if config: for w in config: w.update({'name': normalize_interface(w['name'])}) want.append(remove_empties(w)) have = deepcopy(existing_interfaces_facts) for i in want: # 'have' does not include objects from the default_interfaces list. # Add any 'want' names from default_interfaces to the 'have' list. if i['name'] in default_intf_list: have.append({'name': i['name']}) resp = self.set_state(want, have) return to_list(resp)
def set_config(self, existing_l3_interfaces_facts): """ Collect the configuration from the args passed to the module, collect the current configuration (as a dict from facts) :rtype: A list :returns: the commands necessary to migrate the current configuration to the desired configuration """ config = self._module.params.get('config') want = [] if config: for w in config: w.update({'name': normalize_interface(w['name'])}) if get_interface_type(w['name']) == 'management': self._module.fail_json( msg= "The 'management' interface is not allowed to be managed by this module" ) want.append(remove_empties(w)) have = deepcopy(existing_l3_interfaces_facts) self.init_check_existing(have) resp = self.set_state(want, have) return to_list(resp)
def set_config(self, existing_lacp_interfaces_facts): """ Collect the configuration from the args passed to the module, collect the current configuration (as a dict from facts) :rtype: A list :returns: the commands necessary to migrate the current configuration to the desired configuration """ config = self._module.params.get('config') want = [] if config: for w in config: if get_interface_type(w['name']) not in ('portchannel', 'ethernet'): self._module.fail_json( msg= 'This module works with either portchannel or ethernet' ) w.update({'name': normalize_interface(w['name'])}) want.append(remove_empties(w)) have = existing_lacp_interfaces_facts resp = self.set_state(want, have) return to_list(resp)