def get_ansible_inventory(): log = logger.getlogger() inventory_choice = None dynamic_inventory_path = get_dynamic_inventory_path() software_hosts_file_path = ( os.path.join(get_playbooks_path(), 'software_hosts')) heading1("Software hosts inventory setup\n") dynamic_inventory = None # If dynamic inventory contains clients prompt user to use it if (dynamic_inventory is not None and len(set(_get_hosts_list(dynamic_inventory)) - set(['deployer', 'localhost'])) > 0): print("Ansible Dynamic Inventory found:") print("--------------------------------") print(_get_groups_hosts_string(dynamic_inventory)) print("--------------------------------") validate_software_inventory(dynamic_inventory) if click.confirm('Do you want to use this inventory?'): print("Using Ansible Dynamic Inventory") inventory_choice = dynamic_inventory_path else: print("NOT using Ansible Dynamic Inventory") # If dynamic inventory has no hosts or user declines to use it if inventory_choice is None: while True: # Check if software inventory file exists if os.path.isfile(software_hosts_file_path): print("Software inventory file found at '{}':" .format(software_hosts_file_path)) # If no software inventory file exists create one using template else: rlinput("Press enter to create client node inventory") _create_new_software_inventory(software_hosts_file_path) # If still no software inventory file exists prompt user to # exit (else start over to create one). if not os.path.isfile(software_hosts_file_path): print("No inventory file found at '{}'" .format(software_hosts_file_path)) if click.confirm('Do you want to exit the program?'): sys.exit(1) else: continue # Menu items can modified to show validation results continue_msg = 'Continue with current inventory' edit_msg = 'Edit inventory file' exit_msg = 'Exit program' ssh_config_msg = 'Configure Client Nodes for SSH Key Access' menu_items = [] # Validate software inventory inv_count = len(_validate_inventory_count(software_hosts_file_path, 0)) print(f'Validating software inventory ({inv_count} nodes)...') if validate_software_inventory(software_hosts_file_path): print(bold("Validation passed!")) else: print(bold("Unable to complete validation")) continue_msg = ("Continue with inventory as-is - " "WARNING: Validation incomplete") menu_items.append(ssh_config_msg) # Prompt user menu_items += [continue_msg, edit_msg, exit_msg] choice, item = get_selection(menu_items) print(f'Choice: {choice} Item: {item}') if item == ssh_config_msg: configure_ssh_keys(software_hosts_file_path) elif item == continue_msg: print("Using '{}' as inventory" .format(software_hosts_file_path)) inventory_choice = software_hosts_file_path break elif item == edit_msg: click.edit(filename=software_hosts_file_path) elif item == exit_msg: sys.exit(1) if inventory_choice is None: log.error("Software inventory file is required to continue!") sys.exit(1) log.debug("User software inventory choice: {}".format(inventory_choice)) return inventory_choice
def configure_ssh_keys(software_hosts_file_path): """Configure SSH keys for Ansible software hosts Scan for SSH key pairs in home directory, and if called using 'sudo' also in "login" user's home directory. Allow user to create a new SSH key pair if 'default_ssh_key_name' doesn't already exist. If multiple choices are available user will be prompted to choose. Selected key pair is copied into "login" user's home '.ssh' directory if necessary. Selected key pair is then copied to all hosts listed in 'software_hosts' file via 'ssh-copy-id', and finally assigned to the 'ansible_ssh_private_key_file' var in the 'software_hosts' '[all:vars]' section. Args: software_hosts_file_path (str): Path to software inventory file """ log = logger.getlogger() default_ssh_key_name = "powerup" ssh_key_options = get_existing_ssh_key_pairs(no_root_keys=True) user_name, user_home_dir = get_user_and_home() if os.path.join(user_home_dir, ".ssh", default_ssh_key_name) not in ssh_key_options: ssh_key_options.insert(0, 'Create New "powerup" Key Pair') if len(ssh_key_options) == 1: item = ssh_key_options[0] elif len(ssh_key_options) > 1: print(bold("\nSelect an SSH key to use:")) choice, item = get_selection(ssh_key_options) if item == 'Create New "powerup" Key Pair': ssh_key = create_ssh_key_pair(default_ssh_key_name) else: ssh_key = item ssh_key = copy_ssh_key_pair_to_user_dir(ssh_key) add_software_hosts_global_var( software_hosts_file_path, "ansible_ssh_common_args='-o StrictHostKeyChecking=no'") hostvars = get_ansible_hostvars(software_hosts_file_path) run = True while run: global_user = None global_pass = None header_printed = False header_msg = bold('\nGlobal client SSH login credentials required') for host in _validate_inventory_count(software_hosts_file_path, 0): if global_user is None and 'ansible_user' not in hostvars[host]: print(header_msg) header_printed = True global_user = rlinput('username: '******'ansible_user={global_user}') if (global_pass is None and 'ansible_ssh_pass' not in hostvars[host]): if not header_printed: print(header_msg) global_pass = getpass('password: '******'Retry', 'Continue', 'Exit']) if choice == "1": pass elif choice == "2": run = False elif choice == "3": log.debug('User chooses to exit.') sys.exit('Exiting') else: print() log.info("SSH key successfully copied to all hosts\n") run = False add_software_hosts_global_var(software_hosts_file_path, f'ansible_ssh_private_key_file={ssh_key}')