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 main(): """entry point for module execution """ element_spec = dict(name=dict(), configured_password=dict(no_log=True), nopassword=dict(type='bool', default=False), update_password=dict(default='always', choices=['on_create', 'always']), privilege=dict(type='str', choices=['0', '4', '5']), access_time=dict(type='str'), 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['name'] = dict(required=True) remove_default_spec(aggregate_spec) argument_spec = dict(aggregate=dict(type='list', elements='dict', options=aggregate_spec, aliases=['users', 'collection']), purge=dict(type='bool', default=False)) argument_spec.update(element_spec) mutually_exclusive = [('name', 'aggregate')] module = AnsibleModule(argument_spec=argument_spec, mutually_exclusive=mutually_exclusive, supports_check_mode=True) result = {'changed': False} exec_command(module, 'skip') want = map_params_to_obj(module) have = map_config_to_obj(module) commands = map_obj_to_commands(update_objects(want, have), module) if module.params['purge']: want_users = [x['name'] for x in want] have_users = [x['name'] for x in have] for item in set(have_users).difference(want_users): if item != 'admin': commands.append(user_del_cmd(item)) result["commands"] = commands if commands: if not module.check_mode: load_config(module, commands) result['changed'] = True module.exit_json(**result)
def main(): """ main entry point for module execution """ element_spec = dict( name=dict(), ipv4=dict(), ipv6=dict(), replace=dict(choices=['yes', 'no']), mode=dict(choices=['dynamic', 'ospf-ignore', 'ospf-passive']), secondary=dict(choices=['yes', 'no']), check_running_config=dict( default=True, type='bool', fallback=(env_fallback, ['ANSIBLE_CHECK_ICX_RUNNING_CONFIG'])), state=dict(default='present', choices=['present', 'absent']), ) aggregate_spec = deepcopy(element_spec) aggregate_spec['name'] = dict(required=True) 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'], ['secondary', 'replace'], ['secondary', 'mode']] module = AnsibleModule(argument_spec=argument_spec, required_one_of=required_one_of, mutually_exclusive=mutually_exclusive, supports_check_mode=True) warnings = list() result = {'changed': False} exec_command(module, 'skip') want = map_params_to_obj(module) have = map_config_to_obj(module) commands = map_obj_to_commands((want, have), module) if commands: if not module.check_mode: resp = load_config(module, commands) warnings.extend((out for out in resp if out)) result['changed'] = True if warnings: result['warnings'] = warnings result['commands'] = commands module.exit_json(**result)
def main(): element_spec = dict(group=dict(type='int'), name=dict(type='str'), mode=dict(choices=['dynamic', 'static']), members=dict(type='list'), 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['group'] = dict(required=True, type='int') required_one_of = [['group', 'aggregate']] required_together = [['name', 'group']] mutually_exclusive = [['group', 'aggregate']] remove_default_spec(aggregate_spec) argument_spec = dict(aggregate=dict(type='list', elements='dict', options=aggregate_spec, required_together=required_together), purge=dict(default=False, type='bool')) argument_spec.update(element_spec) module = AnsibleModule(argument_spec=argument_spec, required_one_of=required_one_of, required_together=required_together, mutually_exclusive=mutually_exclusive, supports_check_mode=True) warnings = list() result = {'changed': False} exec_command(module, 'skip') if warnings: result['warnings'] = warnings want = map_params_to_obj(module) have = map_config_to_obj(module) commands = map_obj_to_commands((want, have), module) result["commands"] = commands if commands: if not module.check_mode: load_config(module, commands) result['changed'] = True module.exit_json(**result)
def copy_files_to_trusted(self): cmd1 = 'cat /config/httpd/conf/ssl.crt/{0} >> /config/big3d/client.crt'.format( self.want.cert_name) cmd2 = 'cat /config/httpd/conf/ssl.crt/{0} >> /config/gtm/server.crt'.format( self.want.cert_name) rc, out, err = exec_command(self.module, cmd1) if rc != 0: raise F5ModuleError(err) rc, out, err = exec_command(self.module, cmd2) if rc != 0: raise F5ModuleError(err)
def configure_new_cert(self): cmd1 = 'tmsh modify sys httpd ssl-certkeyfile /config/httpd/conf/ssl.key/{1}' \ 'ssl-certfile /config/httpd/conf/ssl.crt/{0}'.format(self.want.cert_name, self.want.key_name) cmd2 = 'tmsh save /sys config partitions all' rc, out, err = exec_command(self.module, cmd1) if rc != 0: raise F5ModuleError(err) rc, out, err = exec_command(self.module, cmd2) if rc != 0: raise F5ModuleError(err)
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: module.fail_json(msg=to_text(err, errors='surrogate_then_replace'), command=command, rc=rc) exec_command(module, 'end')
def generate_cert_key(self): cmd = 'openssl req -x509 -nodes -days {3} -newkey rsa:{4} -keyout {0}/ssl.key/{2} ' \ '-out {0}/ssl.crt/{1} -subj "{5}"'.format('/config/httpd/conf', self.want.cert_name, self.want.key_name, self.want.days_valid, self.want.key_size, self.want.issuer) rc, out, err = exec_command(self.module, cmd) if rc != 0: raise F5ModuleError(err)
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 update_certificate(self): self.create_csr() cmd = 'openssl x509 -req -in {0}/ssl.csr/{3}.csr -signkey {0}/ssl.key/{2} -days {4} -out {0}/ssl.crt/{1}'.\ format('/config/httpd/conf', self.want.cert_name, self.want.key_name, os.path.splitext(self.want.cert_name)[0], self.want.days_valid) rc, out, err = exec_command(self.module, cmd) if rc != 0: raise F5ModuleError(err)
def create_csr(self): cmd = 'openssl x509 -x509toreq -in {0}/ssl.crt/{1} -out {0}/ssl.csr/{3}.csr -signkey {0}/ssl.key/{2}'.format( '/config/httpd/conf', self.want.cert_name, self.want.key_name, os.path.splitext(self.want.cert_name)[0]) rc, out, err = exec_command(self.module, cmd) if rc != 0: raise F5ModuleError(err)
def read_current_certificate(self): result = dict() command = 'openssl x509 -in /config/httpd/conf/ssl.crt/{0} -dates -issuer -noout'.format( self.want.cert_name) rc, out, err = exec_command(self.module, command) if rc == 0: result['epoch'] = self._parse_cert_date(out) return ApiParameters(params=result)
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, command) 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): 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 | include 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 run_commands(module, commands, check_rc=True): 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_or_strict'), rc=rc) responses = (to_text(out, errors='surrogate_or_strict')) return rc, out, err
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 parse_vlan_brief(module, vlan_id): command = 'show run vlan %s' % vlan_id rc, out, err = exec_command(module, command) lines = out.split('\n') untagged_ports = list() untagged_lags = list() tagged_ports = list() tagged_lags = list() for line in lines: if 'tagged' in line.split(): lags = line.split(" lag ") ports = lags[0].split(" ethe ") del ports[0] del lags[0] for port in ports: if "to" in port: p = port.split(" to ") pr = int(p[1].split('/')[2]) - int(p[0].split('/')[2]) for i in range(0, pr + 1): tagged_ports.append((int(p[0].split('/')[2]) + i)) else: tagged_ports.append(int(port.split('/')[2])) for lag in lags: if "to" in lag: l = lag.split(" to ") lr = int(l[1]) - int(l[0]) for i in range(0, lr + 1): tagged_lags.append((int(l[0]) + i)) else: tagged_lags.append(int(lag)) if 'untagged' in line.split(): lags = line.split(" lag ") ports = lags[0].split(" ethe ") del ports[0] del lags[0] for port in ports: if "to" in port: p = port.split(" to ") pr = int(p[1].split('/')[2]) - int(p[0].split('/')[2]) for i in range(0, pr + 1): untagged_ports.append((int(p[0].split('/')[2]) + i)) else: untagged_ports.append(int(port.split('/')[2])) for lag in lags: if "to" in lag: l = lag.split(" to ") lr = int(l[1]) - int(l[0]) for i in range(0, lr + 1): untagged_lags.append((int(l[0]) + i)) else: untagged_lags.append(int(lag)) return untagged_ports, untagged_lags, tagged_ports, tagged_lags
def map_config_to_obj(module): compare = module.params.get('check_running_config') obj = { 'banner': module.params['banner'], 'state': 'absent', 'enterkey': False } exec_command(module, 'skip') output_text = '' output_re = '' out = get_config(module, flags=['| begin banner %s' % module.params['banner']], compare=module.params['check_running_config']) if out: try: output_re = re.search( r'banner %s( require-enter-key)' % module.params['banner'], out, re.S).group(0) obj['enterkey'] = True except BaseException: pass try: output_text = re.search( r'banner %s (\$([^\$])+\$){1}' % module.params['banner'], out, re.S).group(1).strip('$\n') except BaseException: pass else: output_text = None if output_text: obj['text'] = output_text obj['state'] = 'present' if module.params['check_running_config'] is False: obj = { 'banner': module.params['banner'], 'state': 'absent', 'enterkey': False, 'text': 'JUNK' } return obj
def get_defaults_flag(module): rc, out, err = exec_command(module, 'display 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 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=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_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 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(module, want, result): failed_conditions = [] have_neighbors = 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' % 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', 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', 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 = [] 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('Local Interface: ') short_name = w['name'].replace('Ethernet', 'Eth') for line in lines: field = line.split('\n') if field[0].split('(')[0].strip() == short_name: for item in field: if item.startswith('System Name:'): have_host.append(item.split(':')[1].strip()) if item.startswith('Remote Interface:'): have_port.append(item.split(':')[1].split('(')[0].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 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 main(): """ main entry point for module execution """ element_spec = dict( dest=dict(type='str', choices=[ 'on', 'host', 'console', 'buffered', 'persistence', 'rfc5424' ]), name=dict(type='str'), udp_port=dict(), level=dict(type='list', choices=[ 'alerts', 'critical', 'debugging', 'emergencies', 'errors', 'informational', 'notifications', 'warnings' ]), facility=dict(type='str', choices=[ 'auth', 'cron', 'daemon', 'kern', 'local0', 'local1', 'local2', 'local3', 'local4', 'local5', 'local6', 'local7', 'user', 'lpr', 'mail', 'news', 'syslog', 'sys9', 'sys10', 'sys11', 'sys12', 'sys13', 'sys14', 'user', 'uucp' ]), 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) remove_default_spec(aggregate_spec) argument_spec = dict(aggregate=dict(type='list', elements='dict', options=aggregate_spec), ) argument_spec.update(element_spec) required_if = [('dest', 'host', ['name']), ('dest', 'buffered', ['level'])] module = AnsibleModule(argument_spec=argument_spec, required_if=required_if, supports_check_mode=True) result = {'changed': False} warnings = list() exec_command(module, 'skip') if warnings: result['warnings'] = warnings want = map_params_to_obj(module, required_if=required_if) have = map_config_to_obj(module) result['want'] = want result['have'] = 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 module.exit_json(**result)
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 """ 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 restart_daemon(self): cmd = 'tmsh restart /sys service httpd' rc, out, err = exec_command(self.module, cmd) if rc != 0: raise F5ModuleError(err)