def auditcreeper(): initialize.variables() controller = 'push_cfgs' commands = initialize.configuration auditcreeper_flag = True output = False remediation = True ### AUGUMENT_NODE WILL MATCH EVERY NODES IN THE LIST OF NODE_OBJECT argument_node = '.+' template_list = [] os.system('clear') ### NODE_OBJECT IS A LIST OF ALL THE NODES IN THE DATABASE WITH ALL ATTRIBUTES node_object = process_nodes() ### NODE_TEMPLATE IS A LIST OF ALL THE TEMPLATES BASED ON PLATFORMS AND DEVICE TYPE node_template = process_templates() ### MATCH_NODE IS A LIST OF NODES THAT MATCHES THE ARGUEMENTS PASSED IN BY USER match_node = search_node(argument_node, node_object) ### MATCH_TEMPLATE IS A LIST OF 'MATCH' AND/OR 'NO MATCH' IT WILL USE THE MATCH_NODE ### RESULT, RUN IT AGAINST THE NODE_OBJECT AND COMPARES IT WITH NODE_TEMPLATE DATABASE ### TO SEE IF THERE IS A TEMPLATE FOR THE SPECIFIC PLATFORM AND TYPE. match_template = search_template(template_list, match_node, node_template, node_object, auditcreeper_flag) node_create(match_node, node_object) auditdiff_engine(template_list, node_object, auditcreeper_flag, output, remediation) multithread_engine(initialize.ntw_device, controller, commands) threading.Timer(5.0, auditcreeper).start()
def pull_cfgs(args): redirect = [] auditcreeper = False commands = initialize.configuration argument_node = args.node output = False argument_node = args.node remediation = False with_remediation = False ### NODE_OBJECT IS A LIST OF ALL THE NODES IN THE DATABASE WITH ALL ATTRIBUTES node_object = process_nodes() ### MATCH_NODE IS A LIST OF NODES THAT MATCHES THE ARGUEMENTS PASSED IN BY USER match_node = search_node(argument_node,node_object) if(len(match_node) == 0): print("[+] [NO MATCHING NODES AGAINST DATABASE]") print("") else: node_element(match_node,node_object) node_create(match_node,node_object) for index in initialize.element: redirect.append('pull_cfgs') confirm(redirect,commands) print("")
def remove(args): database = process_nodes() index = 0 try: for element in database: if element['name'] == args.node or element['mgmt_ip4'] == args.node: break else: index = index + 1 """ Delete node from list. """ database.pop(index) updated_database = yaml.dump(database,default_flow_style = False) try: with open('{}/superloop_code/database/nodes.yaml'.format(get_home_directory()),'w') as file: file.write('---\n') file.write(updated_database) print('- Node successfully removed from database.') except FileNotFoundError as error: print("FileNotFoundError: file cannot be found") print(error) except IndexError as error: print('+ Node does not exist in database.') return None
def node_list(args): element_position = 1 argument_node = args.hostname template_list = [] template_list_copy = template_list auditcreeper_flag = True ### NODE_OBJECT IS A LIST OF ALL THE NODES IN THE DATABASE WITH ALL ATTRIBUTES node_object = process_nodes() ### MATCH_NODE IS A LIST OF NODES THAT MATCHES THE ARGUEMENTS PASSED IN BY USER match_node = search_node(argument_node,node_object) ### NODE_TEMPLATE IS A LIST OF ALL THE TEMPLATES BASED ON PLATFORMS AND DEVICE TYPE node_template = process_templates() ### MATCH_TEMPLATE IS A LIST OF 'MATCH' AND/OR 'NO MATCH' IT WILL USE THE MATCH_NODE ### RESULT, RUN IT AGAINST THE NODE_OBJECT AND COMPARES IT WITH NODE_TEMPLATE DATABASE ### TO SEE IF THERE IS A TEMPLATE FOR THE SPECIFIC PLATFORM AND TYPE. match_template = search_template(template_list,match_node,node_template,node_object,auditcreeper_flag) ### THIS WILL PARSE OUT THE GENERATED CONFIGS FROM THE *.JINJA2 FILE TO A LIST if(len(match_node) == 0): print("[+] [NO MATCHING NODES AGAINST DATABASE]") print("") else: print("[") template_list = template_list_copy[0] for index in initialize.element: print(" {") print("\t\"hostname\": \"{}\"\n" \ "\t\"mgmt_ip\": \"{}\"\n" \ "\t\"os\": \"{}\"\n" \ "\t\"platform\": \"{}\"\n" \ "\t\"type\": \"{}\"".format(node_object[index]['hostname'],node_object[index]['ip'],node_object[index]['opersys'],node_object[index]['platform'],node_object[index]['type']) + "\n" \ "\t\"data\": {\n" \ "\t \"managed_configs\": {" \ ) for template in template_list: print ("\t\t \"{}\"".format(template)) print("\t }") print("\t }") template_list = get_updated_list(template_list_copy) # if(len(template_list_copy) != 1): # template_list_copy.pop(0) # template_list = template_list_copy[0] if(element_position == len(initialize.element)): print(" }") else: print(" },") element_position = element_position + 1 print("]")
def push_local(args): controller = 'push_cfgs' commands = initialize.configuration argument_node = args.node filename = args.filename ### NODE_OBJECT IS A LIST OF ALL THE NODES IN THE DATABASE WITH ALL ATTRIBUTES node_object = process_nodes() ### MATCH_NODE IS A LIST OF NODES THAT MATCHES THE ARGUEMENTS PASSED IN BY USER match_node = search_node(argument_node, node_object) if (len(match_node) == 0): print("+ [NO MATCHING NODES AGAINST DATABASE]") print("") else: node_element(match_node, node_object) node_create(match_node, node_object) home_directory = os.path.expanduser('~') for index in initialize.element: config_list = [] f = open("{}/{}".format(home_directory, filename), "r") init_config = f.readlines() parse_commands(init_config) confirm_push(controller, commands)
def auditdiff(args): redirect = [] redirect.append('exec_cmd') index = 0 ext = '.jinja2' auditcreeper_flag = False output = True commands = initialize.configuration argument_node = args.node remediation = False if (args.file is None): # print("ARGS.FILE IS NONE") template_list = [] auditcreeper_flag = True else: # print("ARGS.FILE IS VALID") template = args.file + ext template_list = [] template_list.append(template) ### NODE_OBJECT IS A LIST OF ALL THE NODES IN THE DATABASE WITH ALL ATTRIBUTES node_object = process_nodes() ### NODE_TEMPLATE IS A LIST OF ALL THE TEMPLATES BASED ON PLATFORMS AND DEVICE TYPE node_template = process_templates() ### MATCH_NODE IS A LIST OF NODES THAT MATCHES THE ARGUEMENTS PASSED IN BY USER match_node = search_node(argument_node, node_object) ### MATCH_TEMPLATE IS A LIST OF 'MATCH' AND/OR 'NO MATCH' IT WILL USE THE MATCH_NODE ### RESULT, RUN IT AGAINST THE NODE_OBJECT AND COMPARES IT WITH NODE_TEMPLATE DATABASE ### TO SEE IF THERE IS A TEMPLATE FOR THE SPECIFIC PLATFORM AND TYPE. match_template = search_template(template_list, match_node, node_template, node_object, auditcreeper_flag) ### THIS WILL PARSE OUT THE GENERATED CONFIGS FROM THE *.JINJA2 FILE TO A LIST if (len(match_node) == 0): print("[+] [INVALID MATCHING NODES AGAINST DATABASE]") print("") elif ('NO MATCH' in match_template): # print("+ [NO MATCHING TEMPLATE AGAINST DATABASE]") print("") else: node_create(match_node, node_object) auditdiff_engine(template_list, node_object, auditcreeper_flag, output, remediation) # print ("THESE ARE THE COMMANDS: {}".format(commands)) if (len(initialize.configuration) == 0): pass else: if (remediation): confirm(redirect, commands) # multithread_engine(initialize.ntw_device,controller,commands) print("")
def auditcreeper(): argument_node = '.+' auditcreeper = True commands = initialize.configuration output = True redirect = [] template_list = [] with_remediation = True """ :param argument_node: Argument accepted as regular expression. :type augument_node: str :param auditcreeper: When auditcreeper is active/non-active. :type auditcreeper: bool :param commands: Referenced to global variable commands which keeps track of all commands per node. :type commands: list :param output: Flag to output to stdout. :type ext: bool :param redirect: A list of which method superloop will access. This variable is sent to the multithread_engine. Each element is a redirect per node. :type alt_key_file: list :param template_list_original: Take a duplicate copy of template_list :type template_list_original: list :param with_remediation: Current function to remediate or not remediate. :type ext: bool """ initialize.variables() redirect.append('push_cfgs') os.system('clear') node_object = process_nodes() node_template = process_templates() match_node = search_node(argument_node, node_object) match_template = search_template(template_list, match_node, node_template, node_object, auditcreeper) """ :param node_object: All node(s) in the database with all attributes. :type node_object: list :param node_template: All templates based on hardware_vendor and device type. :type node_template: list :param match_node: Nodes that matches the arguements passed in by user. :type match_node: list :param match_template: Return a list of 'match' and/or 'no match'. :type match_template: list """ node_create(match_node, node_object) mediator(template_list, node_object, auditcreeper, output, with_remediation) for index in initialize.element: redirect.append('push_cfgs') multithread_engine(initialize.ntw_device, redirect, commands) threading.Timer(5.0, auditcreeper).start()
def push_acl(args): ext = '.json' commands = initialize.configuration auditcreeper_flag = False output = False argument_node = args.node remediation = True with_remediation = True if (args.file is None): # print("ARGS.FILE IS NONE") policy_list = [] auditcreeper_flag = True else: # print("ARGS.FILE IS VALID") policy = args.file + ext policy_list = [] policy_list.append(policy) ### NODE_OBJECT IS A LIST OF ALL THE NODES IN THE DATABASE WITH ALL ATTRIBUTES node_object = process_nodes() ### NODE_POLICY IS A LIST OF ALL THE POLICY BASED ON PLATFORMS AND DEVICE TYPE node_policy = process_policies() # print("NODE_POLICY: {}".format(node_policy)) ### MATCH_NODE IS A LIST OF NODES THAT MATCHES THE ARGUEMENTS PASSED IN BY USER match_node = search_node(argument_node, node_object) ### MATCH_TEMPLATE IS A LIST OF 'MATCH' AND/OR 'NO MATCH' IT WILL USE THE MATCH_NODE ### RESULT, RUN IT AGAINST THE NODE_OBJECT AND COMPARES IT WITH NODE_TEMPLATE DATABASE ### TO SEE IF THERE IS A TEMPLATE FOR THE SPECIFIC PLATFORM AND TYPE. match_policy = search_policy(policy_list, match_node, node_policy, node_object, auditcreeper_flag) ### THIS WILL PARSE OUT THE GENERATED CONFIGS FROM THE *.JINJA2 FILE TO A LIST ### POLICY_LIST_COPY TAKE A COPY OF THE CURRENT POLICY_LIST policy_list_original = policy_list[:] policy_list_copy = policy_list ### THE BELOW LENGTH OF MATCH_POLICY != 0 WILL TAKE CARE OF INVALID MATCH OF FIREWALL NODES ### AGAINST NONE ARGS.FILE ARGUEMENT if (auditcreeper_flag and len(match_policy) != 0): policy_list = policy_list_copy[0] if (len(match_node) == 0): print("[!] [INVALID MATCHING NODE(S) AGAINST DATABASE]") print("") elif ((len(match_policy) == 0) or ('NO MATCH' in match_policy)): print( "[!] [INVALID FIREWALL NODE(S) ASSOCIATING WITH INVALID POLICY/POLICIES]" ) print("") else: node_create(match_node, node_object) policies(policy_list, node_policy, policy_list_copy, auditcreeper_flag)
def pull_cfgs(args): argument_confirm = args.confirm argument_node = args.node commands = initialize.configuration output = False redirect = [] authentication = True """ :param argument_configm: Argument accepted as boolean :type augument_confirm: bool :param argument_node: Argument accepted as regular expression. :type augument_node: str :param commands: Referenced to global variable commands which keeps track of all commands per node. :type commands: list :param output: Flag to output to stdout. :type ext: bool :param redirect: A list of which method superloop will access. This variable is sent to the multithread_engine. Each element is a redirect per node. :type alt_key_file: list """ try: if argument_confirm is None or argument_confirm.lower() == 'true': confirm_flag = True elif argument_confirm.lower() == 'false': confirm_flag = False else: raise argparse.ArgumentTypeError('Boolean value expected.') node_object = process_nodes() match_node = search_node(argument_node, node_object) """ :param node_object: All node(s) in the database with all attributes. :type node_object: list :param match_node: Nodes that matches the arguements passed in by user. :type match_node: list """ if len(match_node) == 0: print('+ No matching node(s) found in database.') print('') else: node_element(match_node, node_object) node_create(match_node, node_object) for index in initialize.element: redirect.append('pull_cfgs') if (confirm_flag): confirm(redirect, commands, authentication) else: multithread_engine(initialize.ntw_device, redirect, commands, authentication) print('') except Exception as error: print('ExceptionError: an exception occured') print(error) return None
def push_cfgs(args): redirect = [] ext = '.jinja2' commands = initialize.configuration auditcreeper_flag = False output = False argument_node = args.node remediation = True with_remediation = True if (args.file is None): # print("ARGS.FILE IS NONE") template_list = [] auditcreeper_flag = True else: # print("ARGS.FILE IS VALID") template = args.file + ext template_list = [] template_list.append(template) ### NODE_OBJECT IS A LIST OF ALL THE NODES IN THE DATABASE WITH ALL ATTRIBUTES node_object = process_nodes() ### NODE_TEMPLATE IS A LIST OF ALL THE TEMPLATES BASED ON PLATFORMS AND DEVICE TYPE node_template = process_templates() ### MATCH_NODE IS A LIST OF NODES THAT MATCHES THE ARGUEMENTS PASSED IN BY USER match_node = search_node(argument_node, node_object) ### MATCH_TEMPLATE IS A LIST OF 'MATCH' AND/OR 'NO MATCH' IT WILL USE THE MATCH_NODE ### RESULT, RUN IT AGAINST THE NODE_OBJECT AND COMPARES IT WITH NODE_TEMPLATE DATABASE ### TO SEE IF THERE IS A TEMPLATE FOR THE SPECIFIC PLATFORM AND TYPE. match_template = search_template(template_list, match_node, node_template, node_object, auditcreeper_flag) ### THIS WILL PARSE OUT THE GENERATED CONFIGS FROM THE *.JINJA2 FILE TO A LIST if (len(match_node) == 0): print("+ [NO MATCHING NODES AGAINST DATABASE]") print("") elif ('NO MATCH' in match_template): print("+ [NO MATCHING TEMPLATE AGAINST DATABASE]") print("") else: node_create(match_node, node_object) render(template_list, node_object, auditcreeper_flag, output, with_remediation) for index in initialize.element: redirect.append('push_cfgs') confirm_push(redirect, commands) print("")
def push_config(args): ext = '.jinja2' controller = 'push_config' commands = initialize.configuration auditcreeper_flag = False argument_node = args.node if(args.file is None): # print("ARGS.FILE IS NONE") template_list = [] auditcreeper_flag = True else: # print("ARGS.FILE IS VALID") template = args.file + ext template_list = [] template_list.append(template) ### NODE_OBJECT IS A LIST OF ALL THE NODES IN THE DATABASE WITH ALL ATTRIBUTES node_object = process_nodes() ### NODE_TEMPLATE IS A LIST OF ALL THE TEMPLATES BASED ON PLATFORMS AND DEVICE TYPE node_template = process_templates() ### MATCH_NODE IS A LIST OF NODES THAT MATCHES THE ARGUEMENTS PASSED IN BY USER match_node = search_node(argument_node,node_object) ### MATCH_TEMPLATE IS A LIST OF 'MATCH' AND/OR 'NO MATCH' IT WILL USE THE MATCH_NODE ### RESULT, RUN IT AGAINST THE NODE_OBJECT AND COMPARES IT WITH NODE_TEMPLATE DATABASE ### TO SEE IF THERE IS A TEMPLATE FOR THE SPECIFIC PLATFORM AND TYPE. match_template = search_template(template_list,match_node,node_template,node_object,auditcreeper_flag) ### THIS WILL PARSE OUT THE GENERATED CONFIGS FROM THE *.JINJA2 FILE TO A LIST if(len(match_node) == 0): print("+ [NO MATCHING NODES AGAINST DATABASE]") print("") elif('NO MATCH' in match_template): print("+ [NO MATCHING TEMPLATE AGAINST DATABASE]") print("") else: render(template_list,node_object,auditcreeper_flag) node_create(match_node,node_object) print("") proceed = raw_input("PROCEED? [Y/N]: ") if(proceed == 'y' or proceed == 'Y'): print("") print("PUSHING CODE...") multithread_engine(initialize.ntw_device,controller,commands) elif(proceed == 'n' or proceed == 'N'): print("ABORT...")
def append(args): argument_node = args.node database = process_nodes() index = 0 match_node = [] mgmt_ip4 = get_resolve_hostname(argument_node) # try: """ Check if new node currently exist in database. """ print(database) for node in database: if mgmt_ip4 == node['mgmt_ip4']: match_node.append('MATCH') break else: continue try: if 'MATCH' in match_node: print('+ Node currently present in database.') else: device = snmp(argument_node) new_node = yaml.dump(device,default_flow_style = False) with open('{}/superloop_code/database/nodes.yaml'.format(get_home_directory()),'a') as file: file.write(new_node) database = process_nodes() sorted_database = sortdb(database) updated_database = yaml.dump(sorted_database,default_flow_style = False) with open('{}/superloop_code/database/nodes.yaml'.format(get_home_directory()),'w') as file: file.write('---\n') file.write(updated_database) print('+ SNMP discovery successful.') print('+ New node appended to database.') except FileNotFoundError as error: print('FileNotFoundError: file cannot be found') print(error) # except Exception as error: # print('SNMP query timeout. Please ensure that FQDN or IP address is reachable via SNMP.') return None
def append(args): argument_node = args.ip device = snmp(argument_node) new_node = yaml.dump(device, default_flow_style=False) with open('/database/nodes.yaml', 'a') as f: f.write(new_node) database = process_nodes() database.sort() updated_database = yaml.dump(database, default_flow_style=False) with open('/database/nodes.yaml', 'w') as f: f.write(updated_database) print("[+] NEW NODE SUCCESSFULLY APPENDED TO DATABASE")
def ssh_connect(args): auditcreeper = False commands = initialize.configuration argument_node = args.hostname username = os.environ.get('USERNAME') ### NODE_OBJECT IS A LIST OF ALL THE NODES IN THE DATABASE WITH ALL ATTRIBUTES node_object = process_nodes() ### MATCH_NODE IS A LIST OF NODES THAT MATCHES THE ARGUEMENTS PASSED IN BY USER match_node = search_node(argument_node, node_object) if (len(match_node) == 0): print("[+] [NO MATCHING NODES AGAINST DATABASE]") print("") else: node_element(match_node, node_object) id = 1 ssh_id = 0 print("ID\tname\t\t\taddress\t\tplatform") for index in initialize.element: print("{}\t{}\t{}\t{}".format(id, node_object[index]['hostname'], node_object[index]['ip'], node_object[index]['platform'])) id = id + 1 port = get_port(node_object, initialize.element, ssh_id) if (len(initialize.element) == 1): subprocess.call("ssh {}@{} -p {}".format( username, node_object[initialize.element[ssh_id]]['ip'], port), shell=True) else: ssh_id = int(input("Enter ID to SSH to: ")) ### NODE_ID WILL MAP TO THE CORRECT NODE_OBJECT HOST TO CONNECT TO. ssh_id = ssh_id - 1 port = get_port(node_object, initialize.element, ssh_id) subprocess.call("ssh {}@{} -p {}".format( username, node_object[initialize.element[ssh_id]]['ip'], port), shell=True)
def append(args): argument_node = args.ip device = snmp(argument_node) new_node = yaml.dump(device, default_flow_style=False) with open('/database/nodes.yaml', 'a') as file: file.write(new_node) database = process_nodes() database.sort(key=sorted) updated_database = yaml.dump(database, default_flow_style=False) with open('/database/nodes.yaml', 'w') as file: file.write('---\n') file.write(updated_database) print('[\u2713] SNMP DISCOVERY SUCCESSFUL') print('[+] NEW NODE APPENDED TO DATABASE')
def push_local(args): argument_filename = args.filename argument_node = args.node commands = initialize.configuration redirect = [] authentication = True """ :param argument_filename: Argument accepted as template name. :type augument_filename: str :param argument_node: Argument accepted as regular expression. :type augument_node: str :param commands: Referenced to global variable commands which keeps track of all commands per node. :type commands: list :param redirect: A list of which method superloop will access. This variable is sent to the multithread_engine. Each element is a redirect per node. :type alt_key_file: list """ node_object = process_nodes() match_node = search_node(argument_node, node_object) """ :param node_object: All node(s) in the database with all attributes. :type node_object: list :param match_node: Nodes that matches the arguements passed in by user. :type match_node: list """ if len(match_node) == 0: print('+ No matching node(s) found in database.') print('') else: node_element(match_node, node_object) node_create(match_node, node_object) for index in initialize.element: redirect.append('push_cfgs') for index in initialize.element: config_list = [] with open('{}/{}'.format(get_home_directory(), argument_filename), 'r') as file: init_config = file.readlines() parse_commands(node_object[index], init_config, set_notation=True) confirm(redirect, commands, authentication) return None
def discover(args): argument_node = args.node database = process_nodes() match_node = search_node(argument_node,database) """ :param node_object: All node(s) in the database with all attributes. :type node_object: list :param match_node: Nodes that matches the arguements passed in by user. :type match_node: list """ if len(match_node) == 0: print('+ No matching node(s) found in database.') return None else: for node in match_node: print('{}'.format(node)) index = 0 try: for element in database: if element['name'] == node or element['mgmt_ip4'] == node: break else: index = index + 1 """ Identified node from list. """ device = snmp(node) print('') except Exception as error: print('SNMP query timeout. Please ensure that FQDN or IP address is reachable via SNMP.') for attribute in database[index]: if 'created_at' == attribute or 'created_by' == attribute: continue else: database[index][attribute] = device[0][attribute] database[index]['updated_at'] = timestamp() database[index]['updated_by'] = '{}'.format(os.environ.get('USER')) updated_database = yaml.dump(database,default_flow_style = False) with open('{}/superloop_code/database/nodes.yaml'.format(get_home_directory()),'w') as file: file.write('---\n') file.write(updated_database) print('+ SNMP discovery successful.')
def exec_cmd(args): argument_command = args.command argument_node = args.node redirect = [] authentication = True """ :param argument_command: Referenced to global variable commands which keeps track of all commands per node. :type commands: list :param argument_node: Argument accepted as regular expression. :type augument_node: str :param redirect: A list of which method superloop will access. This variable is sent to the multithread_engine. Each element is a redirect per node. :type alt_key_file: list """ redirect.append('exec_cmd') try: if argument_command == 'reload' or argument_command == 'reboot': print("superloopError: command not supported") return False else: node_object = process_nodes() match_node = search_node(argument_node,node_object) """ :param node_object: All node(s) in the database with all attributes. :type node_object: list :param match_node: Nodes that matches the arguements passed in by user. :type match_node: list """ if len(match_node) == 0: print('+ No matching node(s) found in database.') print() else: node_element(match_node,node_object) node_create(match_node,node_object) multithread_engine(initialize.ntw_device,redirect,argument_command,authentication) except Exception as error: print("ExceptionError: an exception occured") print(error) return None
def exec_command(args): controller = 'exec_command' command = args.argument argument_node = args.node ### NODE_OBJECT IS A LIST OF ALL THE NODES IN THE DATABASE WITH ALL ATTRIBUTES node_object = process_nodes() ### MATCH_NODE IS A LIST OF NODES THAT MATCHES THE ARGUEMENTS PASSED IN BY USER match_node = search_node(argument_node, node_object) if (len(match_node) == 0): print("+ [NO MATCHING NODES AGAINST DATABASE]") print("") else: node_element(match_node, node_object) node_create(match_node, node_object) multithread_engine(initialize.ntw_device, controller, command)
def update(args): argument_node = args.node argument_attribute = args.attribute argument_amend = args.amend database = process_nodes() index = 0 try: for element in database: if element['name'] == argument_node or element['mgmt_ip4'] == argument_node: break else: index = index + 1 """ Identified node from list. """ try: if argument_attribute == 'data': return print('+ Attribute \'data\' cannot be modified via host update.') else: check = str(input('Please confirm you would like to change the value from {} : {} : {} to {} : {} : {}. [y/N]: '.format(database[index]['name'],argument_attribute,database[index][argument_attribute],database[index]['name'],argument_attribute,argument_amend))) if check[0] == 'y': database[index][argument_attribute] = argument_amend database[index]['updated_at'] = timestamp() database[index]['updated_by'] = '{}'.format(os.environ.get('USER')) updated_database = yaml.dump(database,default_flow_style = False) try: with open('{}/superloop_code/database/nodes.yaml'.format(get_home_directory()),'w') as file: file.write('---\n') file.write(updated_database) print('+ Amendment to database was successful.') except FileNotFoundError as error: print("FileNotFoundError: file cannot be found") print(error) elif check[0] == 'N': return False else: print("RuntimeError: aborted at user request") except Exception as error: print('+ Invalid attribute \'{}\' for \'{}\'. Please check node details via \'superloop node list {}\''.format(argument_attribute,database[index]['name'],database[index]['name'])) except IndexError as error: print('+ Node does not exist in database.')
def remove(args): # RE-USING PREVIOUSLY CODED FUNCTION database = process_nodes() # TRACK WHICH ELEMENT MATCHES index = 0 for element in database: if (element['hostname'] == args.argument) or (element['ip'] == args.argument): break else: index = index + 1 # DELETES NODES FROM LIST database.pop(index) # WRITES TO DATABASE FILE updated_database = yaml.dump(database, default_flow_style=False) with open('/database/nodes.yaml', 'w') as f: f.write(updated_database) print("[-] NODE SUCCESSFULLY REMOVED FROM DATABASE")
def push_cfgs(args): argument_node = args.node auditcreeper = False commands = initialize.configuration ext = '.jinja2' output = False redirect = [] push_cfgs = False with_remediation = True authentication = False """ :param argument_node: Argument accepted as regular expression. :type augument_node: str :param auditcreeper: When auditcreeper is active/non-active. :type auditcreeper: bool :param commands: Referenced to global variable commands which keeps track of all commands per node. :type commands: list :param ext: File extention :type ext: str :param output: Flag to output to stdout. :type ext: bool :param redirect: A list of which method superloop will access. This variable is sent to the multithread_engine. Each element is a redirect per node. :type alt_key_file: list :param push_cfgs: This flag is to determine if a push is required for Cisco like platforms. Juniper will continue to push configs no matter if there are no diffs. :type ext: bool :param with_remediation: Current function to remediate or not remediate. :type ext: bool """ if(args.file is None): template_list = [] auditcreeper = True else: template = args.file + ext template_list = [] template_list.append(template) node_object = process_nodes() node_template = process_templates() match_node = search_node(argument_node,node_object) match_template = search_template(template_list,match_node,node_template,node_object,auditcreeper) """ :param node_object: All node(s) in the database with all attributes. :type node_object: list :param node_template: All templates based on hardware_vendor and device type. :type node_template: list :param match_node: Nodes that matches the arguements passed in by user. :type match_node: list :param match_template: Return a list of 'match' and/or 'no match'. :type match_template: list """ if len(match_node) == 0: print('+ No matching node(s) found in database.') print('') elif 'NO MATCH' in match_template: print('+ No matching template(s) found in database.') print('') else: node_create(match_node,node_object) for index in initialize.element: if node_object[index]['hardware_vendor'] == 'cisco': get_diff = True break if get_diff: mediator(template_list,node_object,auditcreeper,output,with_remediation) else: render(template_list,node_object,auditcreeper,output,with_remediation) for index in initialize.element: redirect.append('push_cfgs') for index in range(len(initialize.element)): if len(commands[index]) != 0: push_cfgs = True break else: push_cfgs = False if push_cfgs: confirm(redirect,commands,authentication) print('') return None
def push_acl(args): argument_node = args.node auditcreeper = False commands = initialize.configuration ext = '.json' output = False """ :param argument_node: Argument accepted as regular expression. :type augument_node: str :param auditcreeper: When auditcreeper is active/non-active. :type auditcreeper: bool :param commands: Referenced to global variable commands which keeps track of all commands per node. :type commands: list :param ext: File extention :type ext: str :param output: Flag to output to stdout. :type ext: bool """ if (args.file is None): policy_list = [] auditcreeper = True else: policy = args.file + ext policy_list = [] policy_list.append(policy) node_object = process_nodes() node_policy = process_policies() match_node = search_node(argument_node, node_object) match_policy = search_policy(policy_list, match_node, node_policy, node_object, auditcreeper) """ :param node_object: All node(s) in the database with all attributes. :type node_object: list :param node_template: All templates based on hardware_vendor and device type. :type node_template: list :param match_node: Nodes that matches the arguements passed in by user. :type match_node: list :param match_template: Return a list of 'match' and/or 'no match'. :type match_template: list """ ### THIS WILL PARSE OUT THE GENERATED CONFIGS FROM THE *.JINJA2 FILE TO A LIST ### POLICY_LIST_COPY TAKE A COPY OF THE CURRENT POLICY_LIST policy_list_original = policy_list[:] policy_list_copy = policy_list ### THE BELOW LENGTH OF MATCH_POLICY != 0 WILL TAKE CARE OF INVALID MATCH OF FIREWALL NODES ### AGAINST NONE ARGS.FILE ARGUEMENT if (auditcreeper and len(match_policy) != 0): policy_list = policy_list_copy[0] if (len(match_node) == 0): print("[!] [INVALID MATCHING NODE(S) AGAINST DATABASE]") print("") elif ((len(match_policy) == 0) or ('NO MATCH' in match_policy)): print( "[!] [INVALID FIREWALL NODE(S) ASSOCIATING WITH INVALID POLICY/POLICIES]" ) print("") else: node_create(match_node, node_object) policies(policy_list, node_policy, policy_list_copy, auditcreeper)
def ssh_connect(args): argument_node = args.name auditcreeper = False commands = initialize.configuration username = os.environ.get('USERNAME') """ :param argument_node: Argument accepted as regular expression. :type augument_node: str :param auditcreeper: When auditcreeper is active/non-active. :type auditcreeper: bool :param commands: Referenced to global variable commands which keeps track of all commands per node. :type commands: list :param username: Pulled from environment variable. :type ext: str """ node_object = process_nodes() match_node = search_node(argument_node, node_object) """ :param node_object: All node(s) in the database with all attributes. :type node_object: list :param match_node: Nodes that matches the arguements passed in by user. :type match_node: list """ try: if len(match_node) == 0: print('+ No matching nodes found in database.') print('') else: node_element(match_node, node_object) id = 1 ssh_id = 0 print('{} {: >27} {: >28} {: >26}'.format('id', 'name', 'address', 'platform')) for index in initialize.element: print( '{id: {align}{space}} {name: {align}{space}} {mgmt_ip4: {align}{space}} {platform_name: {align}{space}}' .format( id=id, name=node_object[index]['name'], mgmt_ip4=node_object[index]['mgmt_ip4'], platform_name=node_object[index]['hardware_vendor'], align='<', space=25)) id = id + 1 port = get_port(node_object, initialize.element, ssh_id) try: if (len(initialize.element) == 1): subprocess.call('ssh {}@{} -p {}'.format( username, node_object[initialize.element[ssh_id]]['mgmt_ip4'], port), shell=True) else: try: ssh_id = int(input('Enter ID to SSH to: ')) ssh_id = ssh_id - 1 if ssh_id + 1 < 1: print('IndexError: incorrect connection id') except KeyboardInterrupt as error: print('') print('Terminating...') else: port = get_port(node_object, initialize.element, ssh_id) subprocess.call('ssh {}@{} -p {}'.format( username, node_object[initialize.element[ssh_id]] ['mgmt_ip4'], port), shell=True) except IndexError: print('IndexError: incorrect connection id') except ValueError as error: print('ValueError: expected an integer')
def render_config(args): argument_node = args.node auditcreeper = False commands = initialize.configuration ext = '.jinja2' output = True with_remediation = False """ :param argument_node: Argument accepted as regular expression. :type augument_node: str :param auditcreeper: When auditcreeper is active/non-active. :type auditcreeper: bool :param commands: Referenced to global variable commands which keeps track of all commands per node. :type commands: list :param ext: File extention :type ext: str :param output: Flag to output to stdout. :type ext: bool :param with_remediation: Current function to remediate or not remediate. :type ext: bool """ if (args.file is None): template_list = [] auditcreeper = True else: template = args.file + ext template_list = [] template_list.append(template) node_object = process_nodes() node_template = process_templates() match_node = search_node(argument_node, node_object) match_template = search_template(template_list, match_node, node_template, node_object, auditcreeper) """ :param node_object: All node(s) in the database with all attributes. :type node_object: list :param node_template: All templates based on hardware_vendor and device type. :type node_template: list :param match_node: Nodes that matches the arguements passed in by user. :type match_node: list :param match_template: Return a list of 'match' and/or 'no match'. :type match_template: list """ if len(match_node) == 0: print('+ No matching node(s) found in database.') print() elif ('NO MATCH' in match_template): print('+ No matching template(s) found in database.') print() else: render(template_list, node_object, auditcreeper, output, with_remediation) return None
def node_list(args): argument_node = args.name auditcreeper = True element_position = 1 template_list = [] template_list_copy = template_list """ :param argument_node: Argument accepted as regular expression. :type augument_node: str :param auditcreeper: When auditcreeper is active/non-active. :type auditcreeper: bool :param element_position: Keeps track of the position. :type element_position: int :param template_list: Initializing list of templates :type template_list: list :param template_list_copy: Memory reference to template_list :type ext: list """ node_object = process_nodes() match_node = search_node(argument_node, node_object) node_template = process_templates() match_template = search_template(template_list, match_node, node_template, node_object, auditcreeper) """ :param node_object: All node(s) in the database with all attributes. :type node_object: list :param node_template: All templates based on hardware_vendor and device type. :type node_template: list :param match_node: Nodes that matches the arguements passed in by user. :type match_node: list :param match_template: Return a list of 'match' and/or 'no match'. :type match_template: list """ if len(match_node) == 0: print('+ No matching node(s) found in database.') print('') else: print('[') template_list = template_list_copy[0] for index in initialize.element: print(' {') if (args.attribute == 'protocols' or args.attribute == 'all'): print("\t\"bgp\": [") for peer in node_object[index]['bgp']: print("\t {") print("\t\t\"peer\": \"{}\"\n" \ "\t\t\"remote_as\": \"{}\"" \ .format(peer['peer'], peer['remote_as'] ) ) print("\t },") print(' ]') print("\t\"created_at\": \"{}\"\n" \ "\t\"created_by\": \"{}\"" \ .format(node_object[index]['created_at'],node_object[index]['created_by']) ) print("\t\"data\": {\n" \ "\t \"managed_configs\": {" \ ) for template in template_list: print("\t\t \"{}\"".format(template)) print('\t }') print(' }') print("\t\"domain_name\": \"{}\"\n" \ "\t\"hardware_vendor\": \"{}\"\n" \ "\t\"lifecycle_status\": \"{}\"\n" \ "\t\"location_name\": \"{}\"\n" \ "\t\"mgmt_con_ip4\": \"{}\"\n" \ "\t\"mgmt_ip4\": \"{}\"\n" \ "\t\"mgmt_oob_ip4\": \"{}\"\n" \ "\t\"mgmt_snmp_community4\": \"{}\"\n" \ "\t\"name\": \"{}\"\n" \ "\t\"opersys\": \"{}\"" \ .format(node_object[index]['domain_name'], node_object[index]['hardware_vendor'], node_object[index]['lifecycle_status'], node_object[index]['location_name'], node_object[index]['mgmt_con_ip4'], node_object[index]['mgmt_ip4'], node_object[index]['mgmt_oob_ip4'], node_object[index]['mgmt_snmp_community4'], node_object[index]['name'], node_object[index]['opersys'], ) ) if (args.attribute == 'protocols' or args.attribute == 'all'): print("\t\"ospf\": [") for peer in node_object[index]['ospf']: print("\t {") print("\t\t\"neighbor_id\": \"{}\"\n" \ "\t\t\"area\": \"{}\"\n" \ "\t\t\"priority: \"{}\"\n" \ "\t\t\"state: \"{}\"" \ .format(peer['neighbor_id'], peer['area'], peer['priority'], peer['state'] ) ) print("\t },") print(' ]') print("\t\"platform_name\": \"{}\"" \ .format(node_object[index]['platform_name'] ) ) if (args.attribute == 'ports' or args.attribute == 'all'): print("\t\"ports\": [") for interface in node_object[index]['ports']: print("\t {") print("\t\t\"access_vlan\": \"{}\"\n" \ "\t\t\"acl4_in\": \"{}\"\n" \ "\t\t\"acl4_out: \"{}\"\n" \ "\t\t\"admin_status: \"{}\"\n" \ "\t\t\"created_at: \"{}\"\n" \ "\t\t\"created_by: \"{}\"\n" \ "\t\t\"data: \"{}\"\n" \ "\t\t\"drain_status: \"{}\"\n" \ "\t\t\"farend_name: \"{}\"\n" \ "\t\t\"if_speed: \"{}\"\n" \ "\t\t\"ip4: \"{}\"\n" \ "\t\t\"management: \"{}\"\n" \ "\t\t\"mtu: \"{}\"\n" \ "\t\t\"name: \"{}\"\n" \ "\t\t\"node_name: \"{}\"\n" \ "\t\t\"portrole_name: \"{}\"\n" \ "\t\t\"type: \"{}\"\n" \ "\t\t\"updated_at: \"{}\"\n" \ "\t\t\"updated_by: \"{}\"\n" \ "\t\t\"wan_link: \"{}\"" \ .format(interface['access_vlan'], interface['acl4_in'], interface['acl4_out'], interface['admin_status'], interface['created_at'], interface['created_by'], interface['data'], interface['drain_status'], interface['farend_name'], interface['if_speed'], interface['ip4'], interface['management'], interface['mtu'], interface['name'], interface['node_name'], interface['portrole_name'], interface['type'], interface['updated_at'], interface['updated_by'], interface['wan_link'] ) ) print("\t },") print(' ]') print("\t\"role_name\": \"{}\"\n" \ "\t\"serial_num\": \"{}\"\n" \ "\t\"software_image\": \"{}\"\n" \ "\t\"software_version\": \"{}\"\n" \ "\t\"status\": \"{}\"\n" \ "\t\"type\": \"{}\"\n" \ "\t\"updated_at\": \"{}\"\n" \ "\t\"updated_by\": \"{}\"" \ .format(node_object[index]['role_name'], node_object[index]['serial_num'], node_object[index]['software_image'], node_object[index]['software_version'], node_object[index]['status'], node_object[index]['type'], node_object[index]['updated_at'], node_object[index]['updated_by'] ) ) template_list = get_updated_list(template_list_copy) if element_position == len(initialize.element): print(' }') else: print(' },') element_position = element_position + 1 print(']') return None
def auditdiff(args): argument_node = args.node auditcreeper = False commands = initialize.configuration ext = '.jinja2' output = True redirect = [] with_remediation = False """ :param argument_node: Argument accepted as regular expression. :type augument_node: str :param auditcreeper: When auditcreeper is active/non-active. :type auditcreeper: bool :param commands: Referenced to global variable commands which keeps track of all commands per node. :type commands: list :param ext: File extention :type ext: str :param output: Flag to output to stdout. :type ext: bool :param redirect: A list of which method superloop will access. This variable is sent to the multithread_engine. Each element is a redirect per node. :type alt_key_file: list :param with_remediation: Current function to remediate or not remediate. :type ext: bool """ redirect.append('exec_cmd') if args.file is None: template_list = [] auditcreeper = True else: template = args.file + ext template_list = [] template_list.append(template) node_object = process_nodes() node_template = process_templates() match_node = search_node(argument_node,node_object) match_template = search_template(template_list,match_node,node_template,node_object,auditcreeper) """ :param node_object: All node(s) in the database with all attributes. :type node_object: list :param node_template: All templates based on hardware_vendor and device type. :type node_template: list :param match_node: Nodes that matches the arguements passed in by user. :type match_node: list :param match_template: Return a list of 'match' and/or 'no match'. :type match_template: list """ if len(match_node) == 0: print('+ No matching nodes found in database.') print() elif 'NO MATCH' in match_template: print() else: node_create(match_node,node_object) mediator(template_list,node_object,auditcreeper,output,with_remediation) if(len(initialize.configuration) == 0): pass else: if(remediation): confirm(redirect,commands) return None