def porter(self): ip = input('What IP do you want to scan: ') utils.colour_print('(colour_prompt)Doing TCP First...') try: results = subprocess.check_output(['nmap', '-Pn', ip]) except subprocess.CalledProcessError as e: utils.error(e.output) utils.line_break() utils.colour_print('(colour_success)TCP Results') utils.colour_print('(colour_clear)' + str(results.decode('utf8'))) utils.line_break() utils.colour_print('(colour_prompt)Now doing UDP...') utils.colour_print( '(colour_warning)WARNING: ' '(colour_clear)This will require the sudo password for (colour_rocky)Rocky(colour_clear).' ) password = getpass.getpass('Enter sudo password: '******'echo "{password}" | ' 'sudo -S nmap -Pn -sU ' '--host-timeout 5s ' + ip, shell=True) except subprocess.CalledProcessError as e: utils.error(e.output) utils.line_break() utils.colour_print('(colour_success)UDP Results') utils.colour_print('(colour_clear)' + str(results.decode('utf8'))) utils.line_break()
def process_juno_hosts(self, hostname, hostip, host_user, password): """ Process Juno Hosts """ hostfile = settings.DEVICE_CONFIG_PATH + hostname + '.set' try: client = paramiko.SSHClient() client.load_system_host_keys() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.connect(hostip, port=22, username=host_user, password=password) stdin, stdout, stderr = client.exec_command( 'show configuration | display set') output = str(stdout.read().decode('utf8')) utils.colour_print(output) stdin, stdout, stderr = client.exec_command( 'show chassis hardware') output = output + str(stdout.read().decode('utf8')) + '\n' + '\n' utils.colour_print(output) stdin, stdout, stderr = client.exec_command('show configuration') output = output + str(stdout.read().decode('utf8')) utils.colour_print(output) with open(hostfile, 'w+') as textfile: textfile.write(output) except (paramiko.SSHException, socket.error, paramiko.AuthenticationException) as e: utils.error(f'Couldn\'t connect to host {hostname}: {e}') finally: client.close()
def nmap(self): ra = input('What IP Range do you want to scan: ') port = input('What port(s) do you want to scan: ') try: results = subprocess.check_output( ['nmap', '-Pn', '-p', port, '--open', ra]) except subprocess.CalledProcessError as e: utils.error(e.output) return ips = re.findall( r'(?:[\d]{1,3})\.(?:[\d]{1,3})\.(?:[\d]{1,3})\.(?:[\d]{1,3})', results.decode('utf8')) utils.colour_print(', '.join(ips))
def process_palo_alto_hosts(self, hostname, hostip, host_user, password): """ Process Palo Alto hosts """ hostfile = settings.DEVICE_CONFIG_PATH + hostname try: client = paramiko.SSHClient() client.load_system_host_keys() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) try: client.connect(hostip, port=22, username=host_user, password=password) except paramiko.AuthenticationException: password = getpass.getpass( 'Error with Password. Please enter Plain Text PW: ') client.connect(hostip, port=22, username=host_user, password=password) remote_conn = client.invoke_shell() remote_conn.send('set cli pager off\n') remote_conn.send('show config running\n') time.sleep(5) conf_data = cloud.recv_timeout(remote_conn) try: conf_data = conf_data.split('> show config running')[1] conf_data = conf_data.split('admin' + hostip + '(active)>')[0] except IndexError: pass print(conf_data) except (paramiko.SSHException, socket.error, paramiko.AuthenticationException) as e: utils.error(f'Couldn\'t connect to host {hostname}: {e}') client.close() return finally: client.close() if conf_data: with open(hostfile + '.conf', 'w+') as textfile: textfile.write(conf_data)
def ping(self, param): if not cloud.valid_ip_range(param): utils.error('Invalid IP Address Range') return utils.colour_print('(colour_clear)Now scanning:(colour_prompt) ' + param) try: ipset = netaddr.IPSet([param]) except (netaddr.AddrFormatError, netaddr.AddrConversionError): utils.error('Invalid IP Address Range') return for ip in ipset: try: sh.ping(ip, '-w1 -c1') utils.colour_print('(colour_clear)Ping to ' + str(ip) + ' (colour_success)OK(colour_clear)') except sh.ErrorReturnCode_1: utils.error('No response from ' + str(ip)) except sh.ErrorReturnCode_2 as e: utils.error('Error from ping command: ' + e.stderr.decode())
def learner(self, password: str): self.prompt() confirm = input(' ').lower() if confirm != 'y': return None line_break() for host in self.juniper_hosts: print( host['host_name'], host['ip'], host['username'], ) dev = Device( host=host['ip'], user=host['username'], password=password, port=22, ) try: dev.open() interfaces = dev.rpc.get_interface_information(terse=True, ) dev.close() interfaces = etree.tostring(interfaces) parsed_dict = dict(xmltodict.parse(interfaces)) parsed_dict = parsed_dict['interface-information'] parsed_list = parsed_dict['physical-interface'] with open(f'{settings.PORTS_PATH}{host["host_name"]}.json', 'w+') as file: for item in parsed_list: try: del item['logical-interface'] except KeyError: pass file.write(f'{json.dumps(item)}\n') print(f'{settings.PORTS_PATH}{host["host_name"]}.json saved') line_break() except Exception as err: error(f'Unable to find the Host {err}') line_break() line_break() for host in self.rocky_hosts: print( host['host_name'], host['ip'], host['username'], ) # call devices dev = Device( host=host['ip'], user=host['username'], password=password, port=22, ) try: dev.open() interfaces = dev.rpc.get_interface_information(terse=True, ) dev.close() interfaces = etree.tostring(interfaces) parsed_dict = dict(xmltodict.parse(interfaces)) # Strip out only 'interface-information' parsed_dict = parsed_dict['interface-information'] # Strip out only 'physical-interface' parsed_list = parsed_dict['physical-interface'] # Storing port properties with open(f'{settings.PORTS_PATH}{host["host_name"]}.json', 'w+') as file: for item in parsed_list: # If logical interfaces, delete them. try: del item['logical-interface'] except KeyError: pass # format for storing each port-configuration falls in # each column file.write(f'{json.dumps(item)}\n') print(f'{settings.PORTS_PATH}{host["host_name"]}.json saved') line_break() except Exception as err: print(f'Unable to find Host {err}') line_break()
def show(self, arg: str): if arg == '': utils.colour_print( 'Use (colour_cmd)help show (colour_clear)to see available ' 'subcommands for (colour_cmd)show(colour_clear).') return split = arg.split() if split[0] == 'regions': cloud.regions() elif split[0] == 'routers': if len(split) == 1: cloud.routers() else: try: cloud.routers(int(split[1])) except ValueError: utils.error('idProject not valid') elif split[0] == 'vms': if len(split) == 1: cloud.vm() else: try: if int(split[1]) == 0: utils.error('idProject not valid') return cloud.vm(int(split[1])) except ValueError: utils.error('idProject not valid') elif split[0] == 'subnets': if len(split) == 1: cloud.subnet() else: try: cloud.subnet(int(split[1])) except ValueError: utils.error('idRegion not valid') elif split[0] == 'apilist': cloud.apilist() elif split[0] == 'apiread': cloud.apiread() elif split[0] == 'vrfs': if len(split) == 1: cloud.vrf() else: try: cloud.vrf(int(split[1])) except ValueError: utils.error('idRouter not valid') elif split[0] == 'ipaddress': if len(split) == 1: cloud.ipaddress() else: try: cloud.ipaddress(int(split[1])) except ValueError: utils.error('idVRF not valid') else: utils.colour_print('(colour_clear)I didn\'t understand that!') utils.colour_print( '(colour_clear)Type (colour_cmd)help show (colour_clear)to see valid show commands' )
def run_router(self): try: os.environ.setdefault('CLOUDCIX_SETTINGS_MODULE', 'settings') from cloudcix import api from cloudcix.auth import get_admin_token self.prompt() if input() not in ['Y', 'y']: return access_addrs = rocky.SETTINGS['MGMT_ACCESS_LIST'] mgmt_access_addresses = [] for key in access_addrs: key_pattern = ADDRESS_NAME_SUB_PATTERN.sub( '-', access_addrs[key]) mgmt_access_addresses.append( [access_addrs[key], key, key_pattern]) set_data: Optional[Dict[str, Any]] set_data = { 'name_servers': rocky.SETTINGS['ROUTER_NAME_SERVERS'], 'mgmt_access_addresses': mgmt_access_addresses, } addresses = cloud.service_entity_list('Membership', 'address', {'search[member_id]': '2'}) # Display the regions valid_ids = set() print() utils.colour_print( '┌────────────────────────────────────────────────────────────────┐' ) utils.colour_print( '│ All regions under idMember = 2 │' ) utils.colour_print( '├────────┬───────────────────────────────────────────────────────┤' ) utils.colour_print( '│ ID │ Name │ City │' ) utils.colour_print( '├────────┼───────────────────────────────────────────────────────┤' ) for address in addresses: utils.colour_print( f'│{address["id"]:^8}│{address["name"]:^32}│{address["city"]:^22}│' ) valid_ids.add(str(address['id'])) utils.colour_print( '└────────┴────────────────────────────────┴──────────────────────┘' ) # choose a region utils.colour_print( 'Please choose a region ID from the (colour_cmd)ID (colour_clear)list above: ' ) try: region = int(input('')) except TypeError: utils.error('Incorrect region ID format') return router_region = [ address['name'] for address in addresses if address['idAddress'] == region ] if len(router_region) == 0: utils.colour_print( '(colour_warning)Chosen incorrect region ID, exiting, retry carefully.' ) return routers = cloud.service_entity_list('IAAS', 'router', {'region': region}) if len(routers) == 0: utils.colour_print( f'(colour_warning)No Routers found in region #{region}, exiting.' ) return region_name = router_region[0] utils.line_break() print() # Get router's data router_ids = [] router_rmpf = {} rmpf_ids = [] asset_ids = [] for router in routers: router_ids.append(router['idRouter']) ports = cloud.service_entity_list('IAAS', 'port', {}, router_id=router['idRouter']) rmpf_ids.append(ports[0]['model_port_id']) router_rmpf[router['idRouter']] = ports[0]['model_port_id'] asset_ids.append(router['idAsset']) # Get the Router Model Port Function instances rmpf_params = {'model_port_id__in': rmpf_ids} rmpfs = cloud.service_entity_list('IAAS', 'router_model_port_function', params=rmpf_params) # Get the Router Models rmpf_model = {} for rmpf in rmpfs: rmpf_model[rmpf['model_port_id']] = rmpf['router_model_id'] router_model_ids = [rmpf['router_model_id'] for rmpf in rmpfs] model_params = {'router_model_id__in': router_model_ids} router_models = cloud.service_entity_list('IAAS', 'router_model', params=model_params) # model <-> model data model_data = {} for router_model in router_models: model_data[router_model['router_model_id']] = [ router_model['model'], router_model['vrMax'] ] # router's location and oob ip as {'asset_id': [location, oob_ip]} assets_params = {'id__in': asset_ids} assets = cloud.service_entity_list('Asset', 'asset', params=assets_params) assets_data = {} for asset in assets: location = asset['location'] asset_details = cloud.get_idrac_details(location) assets_data[asset['id']] = [location, asset_details['ip']] # Print the details label = f'Routers in region #{region}' utils.colour_print( '┌──────────────────────────────────────────────────────────┐') utils.colour_print(f'│{label:^58}│') utils.colour_print( '├────────┬─────────────────────┬──────────┬────────────────┤') utils.colour_print( '│ ID │ Model │ Capacity │ Location │') utils.colour_print( '├────────┼─────────────────────┼──────────┼────────────────┤') for router in routers: # final: router <-> model data model, vr_max = model_data[rmpf_model[router_rmpf[ router['idRouter']]]] location = assets_data[router['idAsset']][0] utils.colour_print( f'│{router["idRouter"]:^8}│{model:^21}│{vr_max:^10}│{location:^16}│' ) utils.colour_print( '└────────┴─────────────────────┴──────────┴────────────────┘') print() # choose a router utils.colour_print( 'Please choose a router ID from the (colour_cmd)Router (colour_clear)list above: ' ) try: router_id = int(input()) except TypeError: utils.error('Invalid Router ID.') return if router_id not in router_ids: utils.error( 'Chosen incorrect option, exiting. Retry carefully.') return utils.line_break() print() # asset data of this router asset_id = [ router['idAsset'] for router in routers if router['idRouter'] == router_id ][0] router_oob_ip = assets_data[asset_id][1] # router data for set config template set_data['router'] = { 'router_id': router_id, 'router_model': model_data[rmpf_model[router_rmpf[router_id]]][0], 'region_name': region_name, } # PORTS data set_data['ports'] = [] router_ports = cloud.service_entity_list('IAAS', 'port', {}, router_id=router_id) if not router_ports: utils.error( f'Router #{router_id} has no ports defined in database') return # Get the rmpfs of ports router_rmpf_ids = [ router_port['model_port_id'] for router_port in router_ports ] rmpfs_params = {'model_port_id__in': router_rmpf_ids} router_rmpfs = cloud.service_entity_list( 'IAAS', 'router_model_port_function', params=rmpfs_params) # Get the Port function instances pf_ids = [ router_rmpf['port_function_id'] for router_rmpf in router_rmpfs ] pf_params = {'port_function_id__in': pf_ids} port_functions = cloud.service_entity_list('IAAS', 'port_function', params=pf_params) # port_id <-> [port name, port_function] port_rmpf_pfs = {} # type: dict for port in router_ports: for router_rmpf in router_rmpfs: for port_function in port_functions: if port['model_port_id'] == router_rmpf['model_port_id'] and \ router_rmpf['port_function_id'] == port_function['port_function_id']: port_rmpf_pfs[port['port_id']] = [ router_rmpf['port_name'], port_function['function'] ] break # Port <-> IPAddresses port_configs = [] for port in router_ports: port_configs.extend( cloud.service_entity_list('IAAS', 'port_config', {}, port_id=port['port_id'])) port_config_ip_ids = [ port_config['port_ip_id'] for port_config in port_configs ] port_config_ip_params = {'idIPAddress__in': port_config_ip_ids} port_config_ips = cloud.service_entity_list( 'IAAS', 'ipaddress', params=port_config_ip_params) # Get the nature of ip addresses addresses = [ port_config_ip['address'] for port_config_ip in port_config_ips ] ip_addresses = ','.join(address for address in addresses) result = api.IAAS.ip_validator.list(token=get_admin_token(), params={ 'ipAddresses': ip_addresses }).json() ip_subnet_ids = [ port_config_ip['idSubnet'] for port_config_ip in port_config_ips ] subnets = cloud.service_entity_list( 'IAAS', 'subnet', params={'idSubnet__in': ip_subnet_ids}) ips_data = {} # ips <-> ips_data relation for port_config_ip in port_config_ips: address = port_config_ip['address'] ip_type = 'inet' if result['ipAddresses'][address]['result']['ipv6']: ip_type = 'inet6' for subnet in subnets: if port_config_ip['idSubnet'] == subnet['idSubnet']: ips_data[address] = { 'ip': address, 'type': ip_type, 'address_range': subnet['addressRange'], 'mask': subnet['addressRange'].split('/')[1], 'gateway': subnet['gateway'], } break port_ips_data = {} for port in router_ports: port_ips_data[port['port_id']] = [] for port_config in port_configs: for port_config_ip in port_config_ips: if port_config_ip['idIPAddress'] == port_config['port_ip_id'] and \ port_config['port_id'] == port['port_id']: port_ips_data[port['port_id']].append( ips_data[port_config_ip['address']]) # oob ip in not stored in db so requesting user to enter and compare it with ip deduced from location for port in router_ports: if port_rmpf_pfs[port['port_id']][1] == 'OOB': ip = input( 'Please enter correct OOB IP Address of the router (IPV4): ' ) if not router_oob_ip == ip: utils.error( 'Entered OOB IP Address is not correct, please try again.' ) return utils.colour_print('(colour_success)OK(colour_clear)') utils.colour_print( 'Entered OOB IP Address is correct and processing...') addr_range = router_oob_ip + '/16' addr_octs = addr_range.split('.') gateway = addr_octs[0] + '.' + addr_octs[1] + '.0.1' ips_data[router_oob_ip] = { 'ip': router_oob_ip, 'type': 'inet', 'address_range': addr_range, 'mask': '16', 'gateway': gateway, } port_ips_data[port['port_id']] = [ips_data[router_oob_ip]] break # Ports and their ips label = f'Router #{router_id} ports and IPs' utils.colour_print( '┌─────────────────────────────────────────────────────────────────────────────────┐' ) utils.colour_print(f'│{label:^81}│') utils.colour_print( '├────────┬──────────────┬─────────────────────────────┬───────────────────────────┤' ) utils.colour_print( '│ ID │ Name │ Function │ IPs │' ) utils.colour_print( '├────────┼──────────────┼─────────────────────────────┼───────────────────────────┤' ) for port in router_ports: name = port_rmpf_pfs[port['port_id']][0] function = port_rmpf_pfs[port['port_id']][1] ips = port_ips_data[port['port_id']] for i, ip in enumerate(ips): # proper print if i == 0: utils.colour_print( f'│{port["port_id"]:^8}│{name:^14}│{function:^29}│{ip["ip"]:^27}│' ) if port_rmpf_pfs[port['port_id']][1] == 'Management': set_data['router']['router_ip'] = ip['ip'] else: utils.colour_print( f'│{"":^8}│{"":^14}│{"":^29}│{ip["ip"]:^27}│') utils.colour_print( '└────────┴──────────────┴─────────────────────────────┴───────────────────────────┘' ) utils.line_break() # Gather port data for set config for port in router_ports: name = port_rmpf_pfs[port['port_id']][0] function = port_rmpf_pfs[port['port_id']][1] set_data['ports'].append( { 'name': name, 'function': function, 'ip_confs': port_ips_data[port['port_id']], }, ) utils.line_break() RouterUpdate.update(set_data) except: utils.error('An error occurred while executing router') traceback.print_exc()
def update_pass(self, hosts, password): for host in hosts: try: utils.colour_print(f'Connecting to device: {host["host_name"]}') utils.line_break() dev = Device(host=host['ip'], user=host['username'], password=self.password) dev.open() except ConnectError as e: utils.error(f'Cannot connect to device: {e}') utils.colour_print(f'Configuration changes for device {host["host_name"]} unsuccessful!') return with Config(dev) as cu: try: cu.lock() except LockError: utils.error('Unable to lock configuration') utils.colour_print( f'Configuration changes for device {host["host_name"]} unsuccessful!', ) return try: cu.load( 'set system login user ' f'{host["username"]} authentication plain-text-password-value {password}') except ConfigLoadError as err: utils.error(f'Unable to load a (colour_cmd)set (colour_clear) command: {err}') utils.colour_print( f'Configuration changes for device {host["host_name"]} unsuccessful!', ) utils.colour_print('Unlocking the configuration') cu.unlock() return try: cu.commit(comment='Update by Rocky on ' + time.ctime()) except CommitError as err: utils.error(f'Unable to commit: {err}') utils.colour_print( f'Configuration changes for device {host["host_name"]}' 'successful but unable to commit!') try: utils.colour_print(f'Rolling back the configuration device {host["host_name"]}') cu.rollback(rb_id=1) utils.colour_print('Committing the configuration') cu.commit() except CommitError as err: utils.error(f'Unable to commit configuration: {err}') cu.unlock() return except RpcError as err: utils.error(f'Unable to rollback configuration changes: {err}') cu.unlock() return try: cu.unlock() except LockError as err: utils.error(f'Unable to unlock configuration: {err}') finally: dev.close() utils.colour_print( '(colour_clear)Password change for junos device {juniper_host_name[i]}' '(colour_success)successful(colour_clear)!') print()
def run_router(self): try: self.prompt() if input() not in ['Y', 'y']: return utils.line_break() print() # loading settings data utils.colour_print('Reading the settings file...') # validating map_access_list utils.colour_print('Validating MAP_ACCESS_LIST ...') map_access_list = settings.MAP_ACCESS_LIST for firewall in map_access_list: self.validate_firewall(firewall) clouds = settings.clouds if clouds[0]['name'] in ['', None]: utils.error( f'Invalid cloud name, Please edit the settings file correctly' ) return label = f'All available clouds in the settings file are:' utils.colour_print( '┌─────────────────────────────────────────────────┐', ) utils.colour_print(f'│{label:^49}│') utils.colour_print( '├───────────┬─────────────────────────────────────┤', ) utils.colour_print( '│ id │ Name │', ) utils.colour_print( '├───────────┼─────────────────────────────────────┤', ) cloud_ids = [] for cloud in clouds: cloud_ids.append(cloud['id']) utils.colour_print(f'│{cloud["id"]:^11}│{cloud["name"]:^37}│') utils.colour_print( '└───────────┴─────────────────────────────────────┘', ) cloud_id = input( utils.colour( '(colour_warning)Select the cloud by entering "id" of the cloud.(colour_clear): ' ), ) if cloud_id not in cloud_ids: utils.error( 'Invalid cloud id, exiting. Please try again with correct cloud id.' ) return the_cloud = None for cloud in clouds: if cloud['id'] == cloud_id: the_cloud = cloud # validating the cloud settings utils.colour_print('Validating COP_ACCESS_LIST ...') cop_access_list = the_cloud['COP_ACCESS_LIST'] for firewall in cop_access_list: self.validate_firewall(firewall) pods = the_cloud['pods'] label = f'All available pods from the cloud #{the_cloud["name"]} are:' utils.colour_print( '┌───────────────────────────────────────────────────────────┐', ) utils.colour_print(f'│{label:^59}│') utils.colour_print( '├───────────┬────────────────────────────────────┬──────────┤', ) utils.colour_print( '│ id │ Name │ Type │', ) utils.colour_print( '├───────────┼────────────────────────────────────┼──────────┤', ) pod_ids = [] for pod in pods: pod_ids.append(pod['id']) utils.colour_print( f'│{pod["id"]:^11}│{pod["name"]:^36}│{pod["type"]:^10}│') utils.colour_print( '└───────────┴────────────────────────────────────┴──────────┘', ) pod_id = input( utils.colour( '(colour_warning)Select the pod by entering "id" of the pod.(colour_clear): ' ), ) if pod_id not in pod_ids: utils.error( 'Invalid pod id, exiting. Please try again with correct pod id.' ) return the_pod = None for pod in pods: if pod['id'] == pod_id: the_pod = pod public_port_config = [] # validating the pod settings utils.colour_print('validating IPv4_link_subnet...') for subnet in the_pod['IPv4_link_subnet']: if subnet['address_range'] != '': if not self.validate_address(subnet['address_range']): utils.error( f'Invalid address_range in IPv4_link_subnet #{subnet}' ) exit() if not self.validate_address(subnet['gateway']): utils.error( f'Invalid gateway in IPv4_link_subnet #{subnet}') exit() public_port_config.append(subnet) utils.colour_print('validating IPv4_pod_subnets...') for subnet in the_pod['IPv4_pod_subnets']: if not self.validate_address(subnet['address_range']): utils.error( f'Invalid address_range in IPv4_pod_subnets #{subnet}') exit() if not self.validate_address(subnet['gateway']): utils.error( f'Invalid gateway in IPv4_link_subnet #{subnet}') exit() public_port_config.append(subnet) utils.colour_print('validating IPv6_link_subnet...') for subnet in the_pod['IPv6_link_subnet']: if not self.validate_address(subnet['address_range']): utils.error( f'Invalid address_range in IPv6_link_subnet #{subnet}') exit() if not self.validate_address(subnet['gateway']): utils.error( f'Invalid gateway in IPv6_link_subnet #{subnet}') exit() public_port_config.append(subnet) mgmt_port_config = [] utils.colour_print('validating IPv6_pod_subnets...') for subnet in the_pod['IPv6_pod_subnets']: if not self.validate_address(subnet['address_range']): utils.error( f'Invalid address_range in IPv6_pod_subnets #{subnet}') exit() address = subnet['address_range'].split('/') subnet['address_range'] = f'{address[0]}10:0:1/64' subnet['gateway'] = f'{address[0]}10:0:1' mgmt_port_config.append(subnet) utils.colour_print('validating IPv4_RFC1918_subnets...') for subnet in the_pod['IPv4_RFC1918_subnets']: if not self.validate_address(subnet['address_range']): utils.error( f'Invalid address_range in IPv4_RFC1918_subnets #{subnet}' ) exit() if not self.validate_address(subnet['gateway']): utils.error( f'Invalid gateway in IPv4_RFC1918_subnets #{subnet}') exit() mgmt_port_config.append(subnet) access_addrs = map_access_list + cop_access_list mgmt_access_addresses = [] for item in access_addrs: # an address is defined with name in router, the name can be any unique so is taken from ip address # itself by converting its non integers like '.' , '/', ':' to '-'. item['source_address_name'] = ADDRESS_NAME_SUB_PATTERN.sub( '-', item['source_address']) item[ 'destination_address_name'] = ADDRESS_NAME_SUB_PATTERN.sub( '-', item['destination_address']) mgmt_access_addresses.append(item) template_data: Optional[Dict[str, Any]] template_data = { 'name_servers': settings.ROUTER_NAME_SERVERS, 'mgmt_access_addresses': mgmt_access_addresses, 'robot_rsa': settings.ROBOT_RSA, 'rocky_rsa': settings.ROCKY_RSA, 'administrator_encryp_pass': settings.ADMINISTRATOR_ENCRYP_PASS, 'api_user': settings.API_USER_PASS, 'radius_server_address': settings.RADIUS_SERVER_ADDRESS, 'radius_server_secret': settings.RADIUS_SERVER_SECRET, 'location': the_pod['location'], 'name': the_pod['name'], } utils.line_break() print() # Get the oob router utils.colour_print( '(colour_prompt)Please enter correct OOB ip of the router to be scrubbed(colour_clear).' ) utils.colour_print( '\r - e.g 10.S.R.U where S:site number; R:rack number; U:unit location' ) utils.colour_print('\r - each must be in range 0-254') oob_ip = self.user_input_valid_address('') utils.line_break() print() # SSHing into router for router model utils.colour_print( '(colour_prompt)Fetching the router model...(colour_clear)') router_model = RouterScrub.router_model(oob_ip) if not router_model: utils.error( f'Failed to fetch router model for given ip #{oob_ip}, Check the oob ip and try again.' ) return utils.colour_print( f'The router model for given ip #{oob_ip} is (colour_success){router_model}(colour_clear)', ) utils.line_break() print() # oob 10.S.R.U S:site; R:rack; U:unit template_data['router'] = { 'router_ip': oob_ip, 'router_location': oob_ip.replace('.', ''), # 10SRU 'router_model': router_model, } # sshing into router for root encrypted password utils.colour_print( '(colour_prompt)Fetching the root encrypted password...(colour_clear)' ) root_encrypt_password = RouterScrub.root_encrypted_password(oob_ip) if not root_encrypt_password: utils.error( f'Failed to fetch root encrypted password from router.') return utils.colour_print( f'Found root encrypted password of router #{oob_ip}', ) template_data['root_encrypted_password'] = root_encrypt_password utils.line_break() print() # confirm if router model is fibre or copper in case SRX345-DUAL-AC if router_model in ['SRX345-DUAL-AC', 'SRX345']: router_model = 'SRX345' utils.colour_print('(colour_prompt)Type of router cabling: ') utils.colour_print('(colour_prompt)\r - 1. Copper') utils.colour_print('(colour_prompt)\r - 2. Fibre') option = '' while option not in ['1', '2']: option = utils.user_input_validate( utils.colour( '(colour_warning)Please enter "1" for Copper or "2" for Fibre.(colour_clear)' ), ) if str(option) == '1': router_model = f'{router_model}-Copper' utils.colour_print( f'(colour_prompt)Preparing router scrub for {router_model}...(colour_clear)' ) if str(option) == '2': router_model = f'{router_model}-Fibre' utils.colour_print( f'(colour_prompt)Preparing router scrub for {router_model}...(colour_clear)' ) else: utils.colour_print( f'(colour_prompt)Preparing router scrub for {router_model}...(colour_clear)' ) utils.line_break() print() # Prepare the router's specs from json. try: with open('data/router_specs.json', 'r') as f: template_data['ports'] = json.load( f)['routers'][f'{router_model}'] except: utils.error('An error occurred while preparing router scrub') traceback.print_exc() return # Collect the template data. for port in template_data['ports']: # oob is already taken if port['function'] == 'OOB': port['port_configs'].append( { 'ip': oob_ip, 'mask': 16, # /16 for oob is by design, if changes should reflect here. 'type': 'inet', 'gateway': f'10.{oob_ip.split(".")[1]}.0.1', }, ) # Management if port['function'] == 'Management': for address in mgmt_port_config: ip = address['address_range'].split('/') port['port_configs'].append( { 'ip': ip[0], 'mask': ip[1], 'type': 'inet6' if netaddr.IPAddress(ip[0]).version == 6 else 'inet', 'gateway': address['gateway'], }, ) # Public if port['function'] == 'Floating': for address in public_port_config: ip = address['address_range'].split('/') port['port_configs'].append( { 'ip': ip[0], 'mask': ip[1], 'type': 'inet6' if netaddr.IPAddress(ip[0]).version == 6 else 'inet', 'gateway': address['gateway'], }, ) # All data check label = f'Router #{router_model} {oob_ip} ports and IPs' utils.colour_print( '┌─────────────────────────────────────────────────────────────────────────────────────────┐', ) utils.colour_print(f'│{label:^89}│') utils.colour_print( '├───────────┬─────────────┬───────────────────────────┬───────┬───────────────────────────┤', ) utils.colour_print( '│ Name │ Function │ IPs │ Mask │ Gateway │', ) utils.colour_print( '├───────────┼─────────────┼───────────────────────────┼───────┼───────────────────────────┤', ) for port in template_data['ports']: function = port['function'] name = port['name'] if function != 'Private': port_configs = port['port_configs'] for i, ip in enumerate(port_configs): # proper print if i == 0: utils.colour_print( f'│{name:^11}│{function:^13}│{ip["ip"]:^27}│{ip["mask"]:^7}│{ip["gateway"]:^27}│', ) else: utils.colour_print( f'│{"":^11}│{"":^13}│{ip["ip"]:^27}│{ip["mask"]:^7}│{ip["gateway"]:^27}│', ) else: utils.colour_print( f'│{name:^11}│{function:^13}│{"-":^27}│{"-":^7}│{"-":^27}│', ) utils.colour_print( '└───────────┴─────────────┴───────────────────────────┴───────┴───────────────────────────┘' ) utils.line_break() yes = input( utils.colour( 'If you want to continue press Y or y, else press any key to stop.: ' ), ) utils.line_break() print() if yes in ['Y', 'y']: RouterScrub.scrub(template_data) except: utils.error('An error occurred while configuring ports on router') traceback.print_exc()
def validate_firewall(cls, firewall): """ takes a firewall rule dict with source address, destination address, port and protocol :param firewall: :return: nothing if everything is right otherwise fails gracefully """ if 'source_address' not in firewall.keys(): utils.error( f'"source_address" is not defined for firewall # {firewall}') exit() if firewall['source_address'] == 'any': pass elif not cls.validate_address(firewall['source_address']): utils.error(f'Invalid "source_address" for firewall # {firewall}') exit() if 'destination_address' not in firewall.keys(): utils.error( f'"destination_address" is not defined for firewall # {firewall}' ) exit() if firewall['destination_address'] == 'any': pass elif not cls.validate_address(firewall['destination_address']): utils.error( f'Invalid "destination_address" for firewall # {firewall}') exit() if 'port' not in firewall.keys(): utils.error(f'"port" is not defined for firewall #{firewall}') exit() if firewall['port'] == 'any': pass else: ports = firewall['port'].split('-') for port in ports: if int(port) not in range(65536): utils.error( f'Invalid port value # {port} of firewall #{firewall}, it must be in range 0 to 65536' ) exit() if 'protocol' not in firewall.keys(): utils.error(f'"protocol" is not defined for firewall #{firewall}') exit() if firewall['protocol'] not in ['tcp', 'upd', 'any']: utils.error( f'Invalid protocol for firewall #{firewall}, it can only be "tcp" or "udp", or "any".' ) exit()
def checker(self, password: str): for host in self.rocky_hosts: line_break() colour_print( f'(colour_cmd){host["host_name"]} {host["ip"]} {host["username"]} ', ) line_break() dev = Device( host=host['ip'], user=host['username'], password=password, port=22, ) try: dev.open() interfaces = dev.rpc.get_interface_information(terse=True, ) dev.close() convert_to_string = etree.tostring(interfaces) parsed_dict = dict(xmltodict.parse(convert_to_string)) # Strip out only 'interface-information' parsed_dict = parsed_dict['interface-information'] # Strip out only 'physical-interface' scanned_device = parsed_dict['physical-interface'] for port in scanned_device: # If logical interfaces, delete them. try: del port['logical-interface'] except KeyError: pass # Get the Learned device data try: # if a new device is added but its learned json file from # ports dir is missing so it throws error learned_device = [] filename = f'{settings.PORTS_PATH}{host["host_name"]}.json' with open(filename, 'r') as port_json: for line in port_json: learned_device.append(json.loads(line)) # Comparison starts pass_count = 0 fail_count = 0 added_count = 0 removed_count = 0 # Loop for Port finding for scanned_port in scanned_device: port_check = 'notfound' for learned_port in learned_device: if scanned_port['name'] == learned_port[ 'name']: # Port matching port_check = 'found' # Port properties matching oper_status = (scanned_port['oper-status'] == learned_port['oper-status'], ) admin_status = (scanned_port['admin-status'] == learned_port['admin-status'], ) if oper_status and admin_status: pass_count += 1 self.pass_count_total += 1 else: fail_count += 1 self.fail_count_total += 1 # TODO: come back to this colour_print( '(colour_clear)Learned:-> (colour_success)' ) self._port_print(learned_port) colour_print( '(colour_clear)Scanned:-> (colour_warning)' ) self._port_print(learned_port) break if port_check == 'found': # deleting found ports, then left over ports are # removed ports learned_device.remove(learned_port) else: added_count += 1 self.added_count_total += 1 colour_print('(colour_prompt)ADDED:->') self._port_print(scanned_port) if len(learned_device) != 0: for removed_port in learned_device: removed_count += 1 self.removed_count_total += 1 colour_print('(colour_warning)REMOVED:->') colour_print( f'{self._port_print(removed_port)}(colour_cmd)\n' ) self._summary_print( pass_count, fail_count, added_count, removed_count, ) except Exception: # NOQA # New device found, so displays it's ports configuration colour_print( '(colour_warning)Newly Added Device and it\'s ports are: ' ) colour_print('(colour_cmd)') for new_port in scanned_device: self._port_print(new_port) self.added_count_total += 1 line_break() except: error(f'Unable to connect to the Host') traceback.print_exc() line_break() print(f'SUMMARY: {len(self.rocky_hosts)} DEVICE(S) SCANNED\nTotal: ') self._summary_print( self.pass_count_total, self.fail_count_total, self.added_count_total, self.removed_count_total, ) # loop around devices for host in self.juniper_hosts: print( host['host_name'], host['ip'], host['username'], ) line_break() # call devices dev = Device( host=host['ip'], user=host['username'], password=password, port=22, ) try: # in case device goes down it throws error dev.open() interfaces = dev.rpc.get_interface_information(terse=True, ) dev.close() convert_to_string = etree.tostring(interfaces) parsed_dict = dict(xmltodict.parse(convert_to_string)) # Strip out only 'interface-information' parsed_dict = parsed_dict['interface-information'] # Strip out only 'physical-interface' scanned_device = parsed_dict['physical-interface'] for port in scanned_device: # list of dictionaries # If logical interfaces, delete them. try: del port['logical-interface'] except KeyError: pass # Get the Learned device data try: # if a new device is added but its learned json file from # ports dir is missing so it throws error learned_device = [] filename = f'{settings.PORTS_PATH}{host["host_name"]}.json' with open(filename, 'r') as port_json: for line in port_json: learned_device.append(json.loads(line)) # Comparison starts fail_count = 0 pass_count = 0 added_count = 0 removed_count = 0 # Loop for Port finding for scanned_port in scanned_device: port_check = 'notfound' for learned_port in learned_device: if scanned_port['name'] == learned_port[ 'name']: # Port matching port_check = 'found' # Port properties matching oper_status = (scanned_port['oper-status'] == learned_port['oper-status']) admin_status = (scanned_port['admin-status'] == learned_port['admin-status']) if oper_status and admin_status: pass_count += 1 self.pass_count_total += 1 else: fail_count += 1 self.fail_count_total += 1 colour_print('(colour_prompt)Learned:-> ') self._port_print(learned_port) colour_print('(colour_warning)Scanned:-> ') self._port_print(scanned_port) break if port_check == 'found': # deleting found ports, then left over ports are # removed ports learned_device.remove(learned_port) else: added_count += 1 self.added_count_total += 1 colour_print('(colour_prompt)ADDED:->') self._port_print(scanned_port) if len(learned_device) != 0: for removed_port in learned_device: removed_count += 1 self.removed_count_total += 1 colour_print('(colour_warning)REMOVED:->') self._port_print(removed_port) self._summary_print( pass_count, fail_count, added_count, removed_count, ) except Exception: # NOQA # New device found, so displays it's ports configuration colour_print( '(colour_warning)Newly Added Device and it\'s ports are: ' ) colour_print('(colour_cmd)') for new_port in scanned_device: {self._port_print(new_port)} self.added_count_total += 1 line_break() except: colour_print( f'(colour_warning)Unable to connect to Host(colour_cmd)') traceback.print_exc() line_break() print(f'SUMMARY: {len(self.juniper_hosts)} DEVICE(S) SCANNED\nTotal:') self._summary_print( self.pass_count_total, self.fail_count_total, self.added_count_total, self.removed_count_total, )