def load_config(module, commands): rc, out, err = exec_command(module, 'configure terminal') if rc != 0: module.fail_json(msg='unable to enter configuration mode', err=to_text(err, errors='surrogate_or_strict')) for command in to_list(commands): if command == 'end': continue rc, out, err = exec_command(module, command) if rc != 0: module.fail_json(msg=to_text(err, errors='surrogate_or_strict'), command=command, rc=rc) exec_command(module, 'end')
def check_declarative_intent_params(module, want, result): failed_conditions = [] have_neighbors = None for w in want: want_state = w.get('state') want_neighbors = w.get('neighbors') if want_state not in ('up', 'down') and not want_neighbors: continue if result['changed']: sleep(w['delay']) command = 'show interfaces ethernet %s' % w['name'] rc, out, err = exec_command(module, command) if rc != 0: module.fail_json(msg=to_text(err, errors='surrogate_then_replace'), command=command, rc=rc) if want_state in ('up', 'down'): match = re.search(r'%s (\w+)' % 'state', out, re.M) have_state = None if match: have_state = match.group(1) if have_state is None or not conditional(want_state, have_state.strip().lower()): failed_conditions.append('state ' + 'eq(%s)' % want_state) if want_neighbors: have_host = [] have_port = [] if have_neighbors is None: rc, have_neighbors, err = exec_command(module, 'show lldp neighbors detail') if rc != 0: module.fail_json(msg=to_text(err, errors='surrogate_then_replace'), command=command, rc=rc) if have_neighbors: lines = have_neighbors.strip().split('Interface: ') for line in lines: field = line.split('\n') if field[0].split(',')[0].strip() == w['name']: for item in field: if item.strip().startswith('SysName:'): have_host.append(item.split(':')[1].strip()) if item.strip().startswith('PortDescr:'): have_port.append(item.split(':')[1].strip()) for item in want_neighbors: host = item.get('host') port = item.get('port') if host and host not in have_host: failed_conditions.append('host ' + host) if port and port not in have_port: failed_conditions.append('port ' + port) return failed_conditions
def load_config(module, commands): rc, out, err = exec_command(module, 'configure terminal') if rc != 0: module.fail_json(msg='unable to enter configuration mode', err=to_text(err, errors='surrogate_or_strict')) for command in to_list(commands): if command == 'end': continue cmd = {'command': command, 'prompt': WARNING_PROMPTS_RE, 'answer': 'yes'} rc, out, err = exec_command(module, module.jsonify(cmd)) if rc != 0: module.fail_json(msg=to_text(err, errors='surrogate_or_strict'), command=command, rc=rc) exec_command(module, 'end')
def map_config_to_obj(module): obj = [] rc, out, err = exec_command(module, 'show ip static route') match = re.search(r'.*Static local RIB for default\s*(.*)$', out, re.DOTALL) if match and match.group(1): for r in match.group(1).splitlines(): splitted_line = r.split() code = splitted_line[0] if code != 'M': continue cidr = ip_network(to_text(splitted_line[1])) prefix = str(cidr.network_address) mask = str(cidr.netmask) next_hop = splitted_line[4] admin_distance = splitted_line[2][1] obj.append({'prefix': prefix, 'mask': mask, 'next_hop': next_hop, 'admin_distance': admin_distance}) return obj
def run_commands(module, commands, check_rc=True): responses = list() for cmd in to_list(commands): rc, out, err = exec_command(module, cmd) if check_rc and rc != 0: module.fail_json(msg=to_text(err, errors='surrogate_or_strict'), rc=rc) responses.append(to_text(out, errors='surrogate_or_strict')) return responses
def map_config_to_obj(module): rc, out, err = exec_command(module, 'show banner %s' % module.params['banner']) if rc == 0: output = out else: rc, out, err = exec_command(module, 'show running-config | begin banner %s' % module.params['banner']) if out: output = re.search(r'\^C(.*)\^C', out, re.S).group(1).strip() else: output = None obj = {'banner': module.params['banner'], 'state': 'absent'} if output: obj['text'] = output obj['state'] = 'present' return obj
def run_commands(module, commands, check_rc=True): responses = list() commands = to_commands(module, to_list(commands)) for cmd in commands: cmd = module.jsonify(cmd) rc, out, err = exec_command(module, cmd) if check_rc and rc != 0: module.fail_json(msg=to_text(err, errors='surrogate_then_replace'), rc=rc) responses.append(to_text(out, errors='surrogate_then_replace')) return responses
def load_config(module, config, commit=False): exec_command(module, 'configure') for item in to_list(config): rc, out, err = exec_command(module, item) if rc != 0: module.fail_json(msg=str(err)) exec_command(module, 'top') rc, diff, err = exec_command(module, 'show | compare') if diff: if commit: exec_command(module, 'commit and-quit') else: for cmd in ['rollback 0', 'exit']: exec_command(module, cmd) return str(diff).strip()
def run_commands(module, commands, check_rc=True): responses = list() commands = to_commands(module, to_list(commands)) for cmd in commands: cmd = module.jsonify(cmd) rc, out, err = exec_command(module, cmd) if check_rc and rc != 0: raise F5ModuleError(to_text(err, errors='surrogate_then_replace')) result = to_text(out, errors='surrogate_then_replace') responses.append(result) return responses
def get_config(module, target='commands'): cmd = ' '.join(['show configuration', target]) try: return _DEVICE_CONFIGS[cmd] except KeyError: rc, out, err = exec_command(module, cmd) if rc != 0: module.fail_json(msg='unable to retrieve current config', stderr=to_text(err, errors='surrogate_or_strict')) cfg = to_text(out, errors='surrogate_or_strict').strip() _DEVICE_CONFIGS[cmd] = cfg return cfg
def get_defaults_flag(module): rc, out, err = exec_command(module, 'show running-config ?') out = to_text(out, errors='surrogate_then_replace') commands = set() for line in out.splitlines(): if line: commands.add(line.strip().split()[0]) if 'all' in commands: return 'all' else: return 'full'
def map_config_to_obj(module): cmd = 'show configuration system services netconf' rc, out, err = exec_command(module, cmd) if rc != 0: module.fail_json(msg='unable to retrieve current config', stderr=err) config = str(out).strip() obj = {'state': 'absent'} if 'ssh' in config: obj.update({ 'state': 'present', 'netconf_port': parse_port(config) }) return obj
def check_declarative_intent_params(module, want, result): failed_conditions = [] for w in want: want_state = w.get('state') want_tx_rate = w.get('tx_rate') want_rx_rate = w.get('rx_rate') if want_state not in ('up', 'down') and not want_tx_rate and not want_rx_rate: continue if result['changed']: sleep(w['delay']) command = 'show interfaces %s' % w['name'] rc, out, err = exec_command(module, command) if rc != 0: module.fail_json(msg=to_text(err, errors='surrogate_then_replace'), command=command, rc=rc) if want_state in ('up', 'down'): match = re.search(r'%s (\w+)' % 'line protocol is', out, re.M) have_state = None if match: have_state = match.group(1) if have_state.strip() == 'administratively': match = re.search(r'%s (\w+)' % 'administratively', out, re.M) if match: have_state = match.group(1) if have_state is None or not conditional(want_state, have_state.strip()): failed_conditions.append('state ' + 'eq(%s)' % want_state) if want_tx_rate: match = re.search(r'%s (\d+)' % 'output rate', out, re.M) have_tx_rate = None if match: have_tx_rate = match.group(1) if have_tx_rate is None or not conditional(want_tx_rate, have_tx_rate.strip(), cast=int): failed_conditions.append('tx_rate ' + want_tx_rate) if want_rx_rate: match = re.search(r'%s (\d+)' % 'input rate', out, re.M) have_rx_rate = None if match: have_rx_rate = match.group(1) if have_rx_rate is None or not conditional(want_rx_rate, have_rx_rate.strip(), cast=int): failed_conditions.append('rx_rate ' + want_rx_rate) return failed_conditions
def run_commands(module, commands, check_rc=True): responses = list() for cmd in to_list(commands): cmd = module.jsonify(cmd) rc, out, err = exec_command(module, cmd) if check_rc and rc != 0: module.fail_json(msg=err, rc=rc) try: out = module.from_json(out) except ValueError: out = str(out).strip() responses.append(out) return responses
def get_config(self, flags=None): """Retrieves the current config from the device or cache """ flags = [] if flags is None else flags cmd = 'display current-configuration ' cmd += ' '.join(flags) cmd = cmd.strip() rc, out, err = exec_command(self.module, cmd) if rc != 0: self.module.fail_json(msg=err) cfg = str(out).strip() return cfg
def get_config(module, flags=[]): cmd = 'show running-config ' cmd += ' '.join(flags) cmd = cmd.strip() try: return _DEVICE_CONFIGS[cmd] except KeyError: rc, out, err = exec_command(module, cmd) if rc != 0: module.fail_json(msg='unable to retrieve current config', stderr=to_text(err, errors='surrogate_or_strict')) cfg = to_text(out, errors='surrogate_or_strict').strip() _DEVICE_CONFIGS[cmd] = cfg return cfg
def map_config_to_obj(module): rc, out, err = exec_command( module, 'display current-configuration | begin header %s' % module.params['banner']) if out: output = re.search(r'"(.*)"', out, re.S).group(1).strip() #replace artifacts from output to normal new line symbol output = output.replace('\u001b\u0019', '\n') else: output = None obj = {'banner': module.params['banner'], 'state': 'absent'} if output: obj['text'] = output obj['state'] = 'present' return obj
def load_config(module, commands, warnings, commit=False, replace=False, comment=None): rc, out, err = exec_command(module, 'configure terminal') if rc != 0: module.fail_json(msg='unable to enter configuration mode', err=to_text(err, errors='surrogate_or_strict')) failed = False for command in to_list(commands): if command == 'end': continue rc, out, err = exec_command(module, command) if rc != 0: failed = True break if failed: exec_command(module, 'abort') module.fail_json(msg=to_text(err, errors='surrogate_or_strict'), commands=commands, rc=rc) rc, diff, err = exec_command(module, 'show commit changes diff') if rc != 0: # If we failed, maybe we are in an old version so # we run show configuration instead rc, diff, err = exec_command(module, 'show configuration') if module._diff: warnings.append('device platform does not support config diff') if commit: cmd = 'commit' if comment: cmd += ' comment {0}'.format(comment) else: cmd = 'abort' diff = None exec_command(module, cmd) return to_text(diff, errors='surrogate_or_strict')
def get_config(module, flags=[]): cmd = 'show configuration ' cmd += ' '.join(flags) cmd = cmd.strip() try: return _DEVICE_CONFIGS[cmd] except KeyError: rc, out, err = exec_command(module, cmd) if rc != 0: module.fail_json(msg='unable to retrieve current config', stderr=err) cfg = str(out).strip() _DEVICE_CONFIGS[cmd] = cfg return cfg
def get_config(module, flags=None): flags = [] if flags is None else flags cmd = 'show running-config ' cmd += ' '.join(flags) cmd = cmd.strip() try: return _DEVICE_CONFIGS[cmd] except KeyError: rc, out, err = exec_command(module, cmd) if rc != 0: module.fail_json(msg='unable to retrieve current config', stderr=to_text(err, errors='surrogate_or_strict')) cfg = to_text(out, errors='surrogate_or_strict').strip() _DEVICE_CONFIGS[cmd] = cfg return cfg
def get_config(module, flags=None): flags = [] if flags is None else flags cmd = 'show run-config commands ' cmd += ' '.join(flags) cmd = cmd.strip() try: return _DEVICE_CONFIGS[cmd] except KeyError: rc, out, err = exec_command(module, cmd) if rc != 0: module.fail_json(msg='unable to retrieve current config', stderr=to_text(err, errors='surrogate_then_replace')) cfg = sanitize(to_text(out, errors='surrogate_then_replace').strip()) _DEVICE_CONFIGS[cmd] = cfg return cfg
def parse_vlan_id(module): vlans = [] command = 'show vlan brief' rc, out, err = exec_command(module, command) lines = out.split('\n') for line in lines: if 'VLANs Configured :' in line: values = line.split(':')[1] vlans = [s for s in values.split() if s.isdigit()] s = re.findall(r"(?P<low>\d+)\sto\s(?P<high>\d+)", values) for ranges in s: low = int(ranges[0]) + 1 high = int(ranges[1]) while (high > low): vlans.append(str(low)) low = low + 1 return vlans
def check_declarative_intent_params(want, module): if module.params['interfaces']: name = module.params['name'] rc, out, err = exec_command(module, 'show vrf | include {0}'.format(name)) if rc == 0: data = out.strip().split() # data will be empty if the vrf was just added if not data: return vrf = data[0] interface = data[-1] for w in want: if w['name'] == vrf: for i in w['interfaces']: if get_interface_type(i) is not get_interface_type(interface): module.fail_json(msg="Interface %s not configured on vrf %s" % (interface, name))
def qos_profile_names(module, have): if 'qos mechanism strict' in have: qos_profile = ['qosp7', 'qosp6', 'qosp5', 'qosp4', 'qosp3', 'qosp2', 'qosp1', 'qosp0'] return qos_profile command = 'show qos-profile all' rc, out, err = exec_command(module, command) out = out.rstrip(',') qos_profile = [] if 'Unicast Traffic\n' and 'Multicast Traffic\n' in out: profile = out.split('Unicast Traffic\n')[1].split('Multicast Traffic\n')[0] for i in profile.strip().split('\n'): qos_profile.append(i.split(' ')[1]) else: profile = [] for i in out.strip().split('\n'): profile.append(i.split(' ')[1]) qos_profile = profile[1:] return qos_profile
def map_config_to_obj(module): obj = [] rc, out, err = exec_command(module, 'show ip static route') match = re.search(r'.*Static local RIB for default\s*(.*)$', out, re.DOTALL) if match and match.group(1): for r in match.group(1).splitlines(): splitted_line = r.split() cidr = ip_network(to_text(splitted_line[1])) prefix = str(cidr.network_address) mask = str(cidr.netmask) next_hop = splitted_line[4] admin_distance = splitted_line[2][1] obj.append({'prefix': prefix, 'mask': mask, 'next_hop': next_hop, 'admin_distance': admin_distance}) return obj
def get_startup_dict(self): """Retrieves the current config from the device or cache """ cmd = 'display startup' rc, out, err = exec_command(self.module, cmd) if rc != 0: self.module.fail_json(msg=err) cfg = str(out).strip() startup_info = dict() startup_info["StartupInfos"] = list() if not cfg: return startup_info else: re_find = re.findall( r'(.*)\s*' r'\s*Configured\s*startup\s*system\s*software:\s*(.*)' r'\s*Startup\s*system\s*software:\s*(.*)' r'\s*Next\s*startup\s*system\s*software:\s*(.*)' r'\s*Startup\s*saved-configuration\s*file:\s*(.*)' r'\s*Next\s*startup\s*saved-configuration\s*file:\s*(.*)' r'\s*Startup\s*paf\s*file:\s*(.*)' r'\s*Next\s*startup\s*paf\s*file:\s*(.*)' r'\s*Startup\s*patch\s*package:\s*(.*)' r'\s*Next\s*startup\s*patch\s*package:\s*(.*)', cfg) if re_find: for mem in re_find: startup_info["StartupInfos"].append( dict(nextStartupFile=mem[5], configSysSoft=mem[1], curentSysSoft=mem[2], nextSysSoft=mem[3], curentStartupFile=mem[4], curentPatchFile=mem[8], nextPatchFile=mem[9], postion=mem[0])) return startup_info return startup_info
def check_declarative_intent_params(want, module, result): if module.params["associated_interfaces"]: if result["changed"]: time.sleep(module.params["delay"]) name = module.params["name"] rc, out, err = exec_command(module, "show vrf | include {0}".format(name)) if rc == 0: data = out.strip().split() if not data: return vrf = data[0] interface = data[-1] for w in want: if w["name"] == vrf: if w.get("associated_interfaces") is None: continue for i in w["associated_interfaces"]: if get_interface_type(i) is not get_interface_type( interface): module.fail_json( msg="Interface %s not configured on vrf %s" % (interface, name))
def send_request(module, obj, check_rc=True, ignore_warning=True): request = tostring(obj) rc, out, err = exec_command(module, request) if rc != 0 and check_rc: error_root = fromstring(err) fake_parent = Element('root') fake_parent.append(error_root) error_list = fake_parent.findall('.//nc:rpc-error', NS_MAP) if not error_list: module.fail_json(msg=str(err)) warnings = [] for rpc_error in error_list: message = rpc_error.find('./nc:error-message', NS_MAP).text severity = rpc_error.find('./nc:error-severity', NS_MAP).text if severity == 'warning' and ignore_warning: warnings.append(message) else: module.fail_json(msg=str(err)) return warnings return fromstring(out)
def send_request(module, obj, check_rc=True): request = tostring(obj) rc, out, err = exec_command(module, request) if rc != 0 and check_rc: error_root = fromstring(err) fake_parent = Element('root') fake_parent.append(error_root) error_list = fake_parent.findall('.//nc:rpc-error', NS_MAP) if not error_list: module.fail_json(msg=str(err)) warnings = [] for rpc_error in error_list: message = rpc_error.find('./nc:error-message', NS_MAP).text severity = rpc_error.find('./nc:error-severity', NS_MAP).text if severity == 'warning': warnings.append(message) else: module.fail_json(msg=str(err)) return warnings return fromstring(out)
def load_config(module, commands): rc, out, err = exec_command(module, 'configure terminal') if rc != 0: module.fail_json(msg='unable to enter configuration mode', err=to_text(out, errors='surrogate_then_replace')) for command in to_list(commands): if command == 'end': continue rc, out, err = exec_command(module, command) if rc != 0: exec_command(module, 'end') module.fail_json(msg=to_text(err, errors='surrogate_then_replace'), command=command, rc=rc) exec_command(module, 'end')
def wait_for_device(self, start, end): while datetime.datetime.utcnow() < end: time.sleep(int(self.want.sleep)) # First we check if SSH connection is ready by repeatedly attempting to run a simple command rc, out, err = exec_command(self.module, 'date') if rc != 0: continue if self._device_is_rebooting(): # Wait for the reboot to happen and then start from the beginning # of the waiting. continue if self.want.type == "standard": if self._is_mprov_running_on_device(): self._wait_for_module_provisioning() elif self.want.type == "vcmp": self._is_vcmpd_running_on_device() if not self._rest_endpoints_ready(): self._wait_for_rest_interface() break else: elapsed = datetime.datetime.utcnow() - start self.module.fail_json(msg=self.want.msg or "Timeout when waiting for BIG-IP", elapsed=elapsed.seconds)
def check_declarative_intent_params(want, module, result): if module.params['associated_interfaces']: if result['changed']: time.sleep(module.params['delay']) name = module.params['name'] rc, out, err = exec_command(module, 'show vrf | include {0}'.format(name)) if rc == 0: data = out.strip().split() # data will be empty if the vrf was just added if not data: return vrf = data[0] interface = data[-1] for w in want: if w['name'] == vrf: if w.get('associated_interfaces') is None: continue for i in w['associated_interfaces']: if get_interface_type(i) is not get_interface_type(interface): module.fail_json(msg="Interface %s not configured on vrf %s" % (interface, name))
def main(): """ main entry point for module execution """ stp_spec = dict( type=dict(default='802-1w', choices=['802-1w', 'rstp']), priority=dict(), enabled=dict(type='bool'), ) inter_spec = dict(name=dict(type='list'), purge=dict(type='bool')) tagged_spec = dict(name=dict(type='list'), purge=dict(type='bool')) element_spec = dict(vlan_id=dict(type='int'), name=dict(), interfaces=dict(type='dict', options=inter_spec), tagged=dict(type='dict', options=tagged_spec), ip_dhcp_snooping=dict(type='bool'), ip_arp_inspection=dict(type='bool'), associated_interfaces=dict(type='list'), associated_tagged=dict(type='list'), delay=dict(default=10, type='int'), stp=dict(type='dict', options=stp_spec), state=dict(default='present', choices=['present', 'absent']), check_running_config=dict( default=True, type='bool', fallback=(env_fallback, ['ANSIBLE_CHECK_ICX_RUNNING_CONFIG']))) aggregate_spec = deepcopy(element_spec) aggregate_spec['vlan_id'] = dict(required=True) remove_default_spec(aggregate_spec) argument_spec = dict(aggregate=dict(type='list', elements='dict', options=aggregate_spec), purge=dict(default=False, type='bool')) argument_spec.update(element_spec) required_one_of = [['vlan_id', 'aggregate']] mutually_exclusive = [['vlan_id', 'aggregate']] module = AnsibleModule(argument_spec=argument_spec, required_one_of=required_one_of, mutually_exclusive=mutually_exclusive, supports_check_mode=True) warnings = list() result = {} result['changed'] = False if warnings: result['warnings'] = warnings exec_command(module, 'skip') want = map_params_to_obj(module) if module.params['check_running_config'] is False: have = [] else: have = map_config_to_obj(module) commands = map_obj_to_commands((want, have), module) result['commands'] = commands if commands: if not module.check_mode: output = load_config(module, commands) if output: check_fail(module, output) result['output'] = output result['changed'] = True check_declarative_intent_params(want, module, result) module.exit_json(**result)
def load_config(module, commands, commit=False, comment=None): rc, out, err = exec_command(module, 'configure') if rc != 0: module.fail_json(msg='unable to enter configuration mode', output=to_text(err, errors='surrogate_or_strict')) for cmd in to_list(commands): rc, out, err = exec_command(module, cmd) if rc != 0: # discard any changes in case of failure exec_command(module, 'exit discard') module.fail_json(msg='configuration failed') diff = None if module._diff: rc, out, err = exec_command(module, 'compare') out = to_text(out, errors='surrogate_or_strict') if not out.startswith('No changes'): rc, out, err = exec_command(module, 'show') diff = to_text(out, errors='surrogate_or_strict').strip() if commit: cmd = 'commit' if comment: cmd += ' comment "%s"' % comment rc, out, err = exec_command(module, cmd) if rc != 0: # discard any changes in case of failure exec_command(module, 'exit discard') module.fail_json(msg='commit failed: %s' % err) if not commit: exec_command(module, 'exit discard') else: exec_command(module, 'exit') if diff: return diff
def parse_name_argument(module, item): command = 'show vlan {0}'.format(item) rc, out, err = exec_command(module, command) match = re.search(r"Name (\S+),", out) if match: return match.group(1)
def restart_daemon(self): cmd = 'tmsh restart /sys service httpd' rc, out, err = exec_command(self.module, cmd) if rc != 0: raise F5ModuleError(err)
def load_config(module, commands): for command in to_list(commands): rc, out, err = exec_command(module, command) if rc != 0: module.fail_json(msg=to_text(err, errors='surrogate_or_strict'), command=command, rc=rc) exec_command(module, 'exit all')
def check_declarative_intent_params(module, want, result): failed_conditions = [] have_neighbors_lldp = None have_neighbors_cdp = None for w in want: want_state = w.get("state") want_tx_rate = w.get("tx_rate") want_rx_rate = w.get("rx_rate") want_neighbors = w.get("neighbors") if (want_state not in ("up", "down") and not want_tx_rate and not want_rx_rate and not want_neighbors): continue if result["changed"]: sleep(w["delay"]) command = "show interfaces %s" % w["name"] rc, out, err = exec_command(module, command) if rc != 0: module.fail_json( msg=to_text(err, errors="surrogate_then_replace"), command=command, rc=rc, ) if want_state in ("up", "down"): match = re.search("%s (\\w+)" % "line protocol is", out, re.M) have_state = None if match: have_state = match.group(1) if have_state is None or not conditional(want_state, have_state.strip()): failed_conditions.append("state " + "eq(%s)" % want_state) if want_tx_rate: match = re.search("%s (\\d+)" % "output rate", out, re.M) have_tx_rate = None if match: have_tx_rate = match.group(1) if have_tx_rate is None or not conditional( want_tx_rate, have_tx_rate.strip(), cast=int): failed_conditions.append("tx_rate " + want_tx_rate) if want_rx_rate: match = re.search("%s (\\d+)" % "input rate", out, re.M) have_rx_rate = None if match: have_rx_rate = match.group(1) if have_rx_rate is None or not conditional( want_rx_rate, have_rx_rate.strip(), cast=int): failed_conditions.append("rx_rate " + want_rx_rate) if want_neighbors: have_host = [] have_port = [] # Process LLDP neighbors if have_neighbors_lldp is None: rc, have_neighbors_lldp, err = exec_command( module, "show lldp neighbors detail") if rc != 0: module.fail_json( msg=to_text(err, errors="surrogate_then_replace"), command=command, rc=rc, ) if have_neighbors_lldp: lines = have_neighbors_lldp.strip().split("Local Intf: ") for line in lines: field = line.split("\n") if field[0].strip() == w["name"]: for item in field: if item.startswith("System Name:"): have_host.append(item.split(":")[1].strip()) if item.startswith("Port Description:"): have_port.append(item.split(":")[1].strip()) # Process CDP neighbors if have_neighbors_cdp is None: rc, have_neighbors_cdp, err = exec_command( module, "show cdp neighbors detail") if rc != 0: module.fail_json( msg=to_text(err, errors="surrogate_then_replace"), command=command, rc=rc, ) if have_neighbors_cdp: neighbors_cdp = re.findall( """Device ID: (.*?) .*?Interface: (.*?), Port ID .outgoing port.: (.*?) """, have_neighbors_cdp, re.S, ) for host, localif, remoteif in neighbors_cdp: if localif == w["name"]: have_host.append(host) have_port.append(remoteif) for item in want_neighbors: host = item.get("host") port = item.get("port") if host and host not in have_host: failed_conditions.append("host " + host) if port and port not in have_port: failed_conditions.append("port " + port) return failed_conditions
def check_declarative_intent_params(module, want, result): failed_conditions = [] have_neighbors_lldp = None have_neighbors_cdp = None for w in want: want_state = w.get('state') want_tx_rate = w.get('tx_rate') want_rx_rate = w.get('rx_rate') want_neighbors = w.get('neighbors') if want_state not in ('up', 'down') and not want_tx_rate and not want_rx_rate and not want_neighbors: continue if result['changed']: sleep(w['delay']) command = 'show interfaces %s' % w['name'] rc, out, err = exec_command(module, command) if rc != 0: module.fail_json(msg=to_text(err, errors='surrogate_then_replace'), command=command, rc=rc) if want_state in ('up', 'down'): match = re.search(r'%s (\w+)' % 'line protocol is', out, re.M) have_state = None if match: have_state = match.group(1) if have_state is None or not conditional(want_state, have_state.strip()): failed_conditions.append('state ' + 'eq(%s)' % want_state) if want_tx_rate: match = re.search(r'%s (\d+)' % 'output rate', out, re.M) have_tx_rate = None if match: have_tx_rate = match.group(1) if have_tx_rate is None or not conditional(want_tx_rate, have_tx_rate.strip(), cast=int): failed_conditions.append('tx_rate ' + want_tx_rate) if want_rx_rate: match = re.search(r'%s (\d+)' % 'input rate', out, re.M) have_rx_rate = None if match: have_rx_rate = match.group(1) if have_rx_rate is None or not conditional(want_rx_rate, have_rx_rate.strip(), cast=int): failed_conditions.append('rx_rate ' + want_rx_rate) if want_neighbors: have_host = [] have_port = [] # Process LLDP neighbors if have_neighbors_lldp is None: rc, have_neighbors_lldp, err = exec_command(module, 'show lldp neighbors detail') if rc != 0: module.fail_json(msg=to_text(err, errors='surrogate_then_replace'), command=command, rc=rc) if have_neighbors_lldp: lines = have_neighbors_lldp.strip().split('Local Intf: ') for line in lines: field = line.split('\n') if field[0].strip() == w['name']: for item in field: if item.startswith('System Name:'): have_host.append(item.split(':')[1].strip()) if item.startswith('Port Description:'): have_port.append(item.split(':')[1].strip()) # Process CDP neighbors if have_neighbors_cdp is None: rc, have_neighbors_cdp, err = exec_command(module, 'show cdp neighbors detail') if rc != 0: module.fail_json(msg=to_text(err, errors='surrogate_then_replace'), command=command, rc=rc) if have_neighbors_cdp: neighbors_cdp = re.findall('Device ID: (.*?)\n.*?Interface: (.*?), Port ID .outgoing port.: (.*?)\n', have_neighbors_cdp, re.S) for host, localif, remoteif in neighbors_cdp: if localif == w['name']: have_host.append(host) have_port.append(remoteif) for item in want_neighbors: host = item.get('host') port = item.get('port') if host and host not in have_host: failed_conditions.append('host ' + host) if port and port not in have_port: failed_conditions.append('port ' + port) return failed_conditions
def main(): """ main entry point for module execution """ power_spec = dict(by_class=dict(choices=['0', '1', '2', '3', '4']), limit=dict(type='str'), priority=dict(choices=['1', '2', '3']), enabled=dict(type='bool')) neighbors_spec = dict(host=dict(), port=dict()) element_spec = dict( name=dict(), description=dict(), enabled=dict(default=True, type='bool'), speed=dict(type='str', choices=[ '10-full', '10-half', '100-full', '100-half', '1000-full', '1000-full-master', '1000-full-slave', '10g-full', '10g-full-master', '10g-full-slave', '2500-full', '2500-full-master', '2500-full-slave', '5g-full', '5g-full-master', '5g-full-slave', 'auto' ]), stp=dict(type='bool'), tx_rate=dict(), rx_rate=dict(), neighbors=dict(type='list', elements='dict', options=neighbors_spec), delay=dict(default=10, type='int'), state=dict(default='present', choices=['present', 'absent', 'up', 'down']), power=dict(type='dict', elements='dict', options=power_spec), check_running_config=dict(type='bool')) aggregate_spec = deepcopy(element_spec) aggregate_spec['name'] = dict(required=True) # remove default in aggregate spec, to handle common arguments remove_default_spec(aggregate_spec) argument_spec = dict(aggregate=dict(type='list', elements='dict', options=aggregate_spec), ) argument_spec.update(element_spec) required_one_of = [['name', 'aggregate']] mutually_exclusive = [['name', 'aggregate']] module = AnsibleModule(argument_spec=argument_spec, required_one_of=required_one_of, mutually_exclusive=mutually_exclusive, supports_check_mode=True) warnings = list() result = {} result['changed'] = False if warnings: result['warnings'] = warnings exec_command(module, 'skip') want = map_params_to_obj(module) have = map_config_to_obj(module) print("yfygvhghvhgvuhvbjh", want) print("jhbuhjbjnb kn kmnkmnmln", have) commands = map_obj_to_commands((want, have)) result['commands'] = commands if commands: if not module.check_mode: load_config(module, commands) result['changed'] = True failed_conditions = check_declarative_intent_params(module, want, result) if failed_conditions: msg = 'One or more conditional statements have not been satisfied' module.fail_json(msg=msg, failed_conditions=failed_conditions) module.exit_json(**result)
def check_declarative_intent_params(module, want, result): failed_conditions = [] have_neighbors = None for w in want: want_state = w.get('state') want_neighbors = w.get('neighbors') if want_state not in ('up', 'down') and not want_neighbors: continue if result['changed']: sleep(w['delay']) command = 'show interfaces ethernet %s' % w['name'] rc, out, err = exec_command(module, command) if rc != 0: module.fail_json(msg=to_text(err, errors='surrogate_then_replace'), command=command, rc=rc) if want_state in ('up', 'down'): match = re.search(r'%s (\w+)' % 'state', out, re.M) have_state = None if match: have_state = match.group(1) if have_state is None or not conditional( want_state, have_state.strip().lower()): failed_conditions.append('state ' + 'eq(%s)' % want_state) if want_neighbors: have_host = [] have_port = [] if have_neighbors is None: rc, have_neighbors, err = exec_command( module, 'show lldp neighbors detail') if rc != 0: module.fail_json(msg=to_text( err, errors='surrogate_then_replace'), command=command, rc=rc) if have_neighbors: lines = have_neighbors.strip().split('Interface: ') for line in lines: field = line.split('\n') if field[0].split(',')[0].strip() == w['name']: for item in field: if item.strip().startswith('SysName:'): have_host.append(item.split(':')[1].strip()) if item.strip().startswith('PortDescr:'): have_port.append(item.split(':')[1].strip()) for item in want_neighbors: host = item.get('host') port = item.get('port') if host and host not in have_host: failed_conditions.append('host ' + host) if port and port not in have_port: failed_conditions.append('port ' + port) return failed_conditions
def parse_stp_arguments(module, item): rc, out, err = exec_command(module, 'show interfaces ' + item) match = re.search(r'STP configured to (\S+),', out, re.S) if match: return True if match.group(1) == "ON" else False
def check_declarative_intent_params(module, want, result): failed_conditions = [] have_neighbors_lldp = None have_neighbors_cdp = None for w in want: want_state = w.get('state') want_tx_rate = w.get('tx_rate') want_rx_rate = w.get('rx_rate') want_neighbors = w.get('neighbors') if want_state not in ( 'up', 'down' ) and not want_tx_rate and not want_rx_rate and not want_neighbors: continue if result['changed']: sleep(w['delay']) command = 'show interfaces %s' % w['name'] rc, out, err = exec_command(module, command) if rc != 0: module.fail_json(msg=to_text(err, errors='surrogate_then_replace'), command=command, rc=rc) if want_state in ('up', 'down'): match = re.search(r'%s (\w+)' % 'line protocol is', out, re.M) have_state = None if match: have_state = match.group(1) if have_state is None or not conditional(want_state, have_state.strip()): failed_conditions.append('state ' + 'eq(%s)' % want_state) if want_tx_rate: match = re.search(r'%s (\d+)' % 'output rate:', out, re.M) have_tx_rate = None if match: have_tx_rate = match.group(1) if have_tx_rate is None or not conditional( want_tx_rate, have_tx_rate.strip(), cast=int): failed_conditions.append('tx_rate ' + want_tx_rate) if want_rx_rate: match = re.search(r'%s (\d+)' % 'input rate:', out, re.M) have_rx_rate = None if match: have_rx_rate = match.group(1) if have_rx_rate is None or not conditional( want_rx_rate, have_rx_rate.strip(), cast=int): failed_conditions.append('rx_rate ' + want_rx_rate) if want_neighbors: have_host = [] have_port = [] # Process LLDP neighbors if have_neighbors_lldp is None: rc, have_neighbors_lldp, err = exec_command( module, 'show lldp neighbors detail') if rc != 0: module.fail_json(msg=to_text( err, errors='surrogate_then_replace'), command=command, rc=rc) if have_neighbors_lldp: lines = have_neighbors_lldp.strip().split('Local port: ') for line in lines: field = line.split('\n') if field[0].strip() == w['name'].split(' ')[1]: for item in field: match = re.search( r'\s*\+\s+System name\s+:\s+"(.*)"', item, re.M) if match: have_host.append(match.group(1)) match = re.search( r'\s*\+\s+Port description\s+:\s+"(.*)"', item, re.M) if match: have_port.append(match.group(1)) for item in want_neighbors: host = item.get('host') port = item.get('port') if host and host not in have_host: failed_conditions.append('host ' + host) if port and port not in have_port: failed_conditions.append('port ' + port) return failed_conditions
def main(): """ main entry point for module execution """ element_spec = dict( name=dict(), description=dict(), speed=dict(), mtu=dict(), duplex=dict(choices=['full', 'half']), enabled=dict(default=True, type='bool'), tx_rate=dict(), rx_rate=dict(), delay=dict(default=10, type='int'), state=dict(default='present', choices=['present', 'absent', 'up', 'down']) ) aggregate_spec = deepcopy(element_spec) aggregate_spec['name'] = dict(required=True) # remove default in aggregate spec, to handle common arguments remove_default_spec(aggregate_spec) argument_spec = dict( aggregate=dict(type='list', elements='dict', options=aggregate_spec), ) argument_spec.update(element_spec) argument_spec.update(iosxr_argument_spec) required_one_of = [['name', 'aggregate']] mutually_exclusive = [['name', 'aggregate']] module = AnsibleModule(argument_spec=argument_spec, required_one_of=required_one_of, mutually_exclusive=mutually_exclusive, supports_check_mode=True) warnings = list() check_args(module, warnings) result = {'changed': False} want = map_params_to_obj(module) have = map_config_to_obj(module) commands = map_obj_to_commands((want, have)) result['commands'] = commands result['warnings'] = warnings if commands: if not module.check_mode: load_config(module, commands, result['warnings'], commit=True) exec_command(module, 'exit') result['changed'] = True failed_conditions = check_declarative_intent_params(module, want, result) if failed_conditions: msg = 'One or more conditional statements have not been satisfied' module.fail_json(msg=msg, failed_conditions=failed_conditions) module.exit_json(**result)
def check_declarative_intent_params(module, want, result): failed_conditions = [] have_neighbors_lldp = None for w in want: want_state = w.get('state') want_tx_rate = w.get('tx_rate') want_rx_rate = w.get('rx_rate') want_neighbors = w.get('neighbors') if want_state not in ( 'up', 'down' ) and not want_tx_rate and not want_rx_rate and not want_neighbors: continue if result['changed']: sleep(w['delay']) command = 'show interface %s brief' % w['name'] rc, out, err = exec_command(module, command) if rc != 0: module.fail_json(msg=to_text(err, errors='surrogate_then_replace'), command=command, rc=rc) if want_state in ('up', 'down'): state_data = out.strip().lower().split(w['name']) have_state = None have_state = state_data[1].split()[3] if have_state is None or not conditional(want_state, have_state.strip()): failed_conditions.append('state ' + 'eq(%s)' % want_state) command = 'show interface %s' % w['name'] rc, out, err = exec_command(module, command) have_tx_rate = None have_rx_rate = None rates = out.splitlines() for s in rates: s = s.strip() if 'output rate' in s and 'input rate' in s: sub = s.split() if want_tx_rate: have_tx_rate = sub[8] if have_tx_rate is None or not conditional( want_tx_rate, have_tx_rate.strip(), cast=int): failed_conditions.append('tx_rate ' + want_tx_rate) if want_rx_rate: have_rx_rate = sub[2] if have_rx_rate is None or not conditional( want_rx_rate, have_rx_rate.strip(), cast=int): failed_conditions.append('rx_rate ' + want_rx_rate) if want_neighbors: have_host = [] have_port = [] # Process LLDP neighbors if have_neighbors_lldp is None: rc, have_neighbors_lldp, err = exec_command( module, 'show lldp neighbors detail') if rc != 0: module.fail_json(msg=to_text( err, errors='surrogate_then_replace'), command=command, rc=rc) if have_neighbors_lldp: lines = have_neighbors_lldp.strip().split('Local Port ID: ') for line in lines: field = line.split('\n') if field[0].strip() == w['name']: for item in field: if item.startswith('System Name:'): have_host.append(item.split(':')[1].strip()) if item.startswith('Port Description:'): have_port.append(item.split(':')[1].strip()) for item in want_neighbors: host = item.get('host') port = item.get('port') if host and host not in have_host: failed_conditions.append('host ' + host) if port and port not in have_port: failed_conditions.append('port ' + port) return failed_conditions
def exec_command(self, command): if isinstance(command, dict): command = self._module.jsonify(command) return exec_command(self._module, command)
def main(): """ main entry point for module execution """ element_spec = dict(name=dict(), description=dict(), speed=dict(), mtu=dict(), duplex=dict(choices=['full', 'half']), enabled=dict(default=True, type='bool'), tx_rate=dict(), rx_rate=dict(), delay=dict(default=10, type='int'), state=dict(default='present', choices=['present', 'absent', 'up', 'down'])) aggregate_spec = deepcopy(element_spec) aggregate_spec['name'] = dict(required=True) # remove default in aggregate spec, to handle common arguments remove_default_spec(aggregate_spec) argument_spec = dict(aggregate=dict(type='list', elements='dict', options=aggregate_spec), ) argument_spec.update(element_spec) argument_spec.update(iosxr_argument_spec) required_one_of = [['name', 'aggregate']] mutually_exclusive = [['name', 'aggregate']] module = AnsibleModule(argument_spec=argument_spec, required_one_of=required_one_of, mutually_exclusive=mutually_exclusive, supports_check_mode=True) warnings = list() check_args(module, warnings) result = {'changed': False} want = map_params_to_obj(module) have = map_config_to_obj(module) commands = map_obj_to_commands((want, have)) result['commands'] = commands result['warnings'] = warnings if commands: if not module.check_mode: load_config(module, commands, result['warnings'], commit=True) exec_command(module, 'exit') result['changed'] = True failed_conditions = check_declarative_intent_params(module, want, result) if failed_conditions: msg = 'One or more conditional statements have not been satisfied' module.fail_json(msg=msg, failed_conditions=failed_conditions) module.exit_json(**result)
def load_config(module, commands, commit=False, comment=None): rc, out, err = exec_command(module, 'configure') if rc != 0: module.fail_json(msg='unable to enter configuration mode', output=err) for cmd in to_list(commands): rc, out, err = exec_command(module, cmd, check_rc=False) if rc != 0: # discard any changes in case of failure exec_command(module, 'exit discard') module.fail_json(msg='configuration failed') diff = None if module._diff: rc, out, err = exec_command(module, 'compare') if not out.startswith('No changes'): rc, out, err = exec_command(module, 'show') diff = str(out).strip() if commit: cmd = 'commit' if comment: cmd += ' comment "%s"' % comment exec_command(module, cmd) if not commit: exec_command(module, 'exit discard') else: exec_command(module, 'exit') if diff: return diff
def check_declarative_intent_params(module, want, result): failed_conditions = [] have_neighbors = None for w in want: want_state = w.get("state") want_neighbors = w.get("neighbors") if want_state not in ("up", "down") and not want_neighbors: continue if result["changed"]: sleep(w["delay"]) command = "show interfaces ethernet %s" % w["name"] rc, out, err = exec_command(module, command) if rc != 0: module.fail_json( msg=to_text(err, errors="surrogate_then_replace"), command=command, rc=rc, ) if want_state in ("up", "down"): match = re.search(r"%s (\w+)" % "state", out, re.M) have_state = None if match: have_state = match.group(1) if have_state is None or not conditional( want_state, have_state.strip().lower()): failed_conditions.append("state " + "eq(%s)" % want_state) if want_neighbors: have_host = [] have_port = [] if have_neighbors is None: rc, have_neighbors, err = exec_command( module, "show lldp neighbors detail") if rc != 0: module.fail_json( msg=to_text(err, errors="surrogate_then_replace"), command=command, rc=rc, ) if have_neighbors: lines = have_neighbors.strip().split("Interface: ") for line in lines: field = line.split("\n") if field[0].split(",")[0].strip() == w["name"]: for item in field: if item.strip().startswith("SysName:"): have_host.append(item.split(":")[1].strip()) if item.strip().startswith("PortDescr:"): have_port.append(item.split(":")[1].strip()) for item in want_neighbors: host = item.get("host") port = item.get("port") if host and host not in have_host: failed_conditions.append("host " + host) if port and port not in have_port: failed_conditions.append("port " + port) return failed_conditions