def get_dummy_ssh(self, retry=False): ssh = SSH("", "", "") ssh.test_connectivity = Mock(return_value=True) ssh.execute = Mock(return_value=("10", "", 0)) ssh.sftp_put_files = Mock(return_value=True) ssh.sftp_mkdir = Mock(return_value=True) ssh.sftp_put_dir = Mock(return_value=True) ssh.sftp_put = Mock(return_value=True) return ssh
def wait_ssh_access(vm, delay=10, max_wait=None, quiet=False): """ Test the SSH access to the VM return: init, new or pk_file or None if it fails """ if not max_wait: max_wait = CtxtAgent.SSH_WAIT_TIMEOUT wait = 0 success = False res = None last_tested_private = False while wait < max_wait: if 'ctxt_ip' in vm: vm_ip = vm['ctxt_ip'] elif 'private_ip' in vm and not last_tested_private: # First test the private one vm_ip = vm['private_ip'] last_tested_private = True else: vm_ip = vm['ip'] last_tested_private = False if not quiet: CtxtAgent.logger.debug("Testing SSH access to VM: %s:%s" % (vm_ip, vm['remote_port'])) wait += delay try: ssh_client = SSH(vm_ip, vm['user'], vm['passwd'], vm['private_key'], vm['remote_port']) success = ssh_client.test_connectivity(delay) res = 'init' except AuthenticationException: try_ansible_key = True if 'new_passwd' in vm: try_ansible_key = False # If the process of changing credentials has finished in the # VM, we must use the new ones if not quiet: CtxtAgent.logger.debug( "Error connecting with SSH with initial credentials with: " + vm_ip + ". Try to use new ones.") try: ssh_client = SSH(vm_ip, vm['user'], vm['new_passwd'], vm['private_key'], vm['remote_port']) success = ssh_client.test_connectivity() res = "new" except AuthenticationException: try_ansible_key = True except: if not quiet: CtxtAgent.logger.exception( "Error connecting with SSH with: " + vm_ip) success = False if try_ansible_key: # In some very special cases the last two cases fail, so check # if the ansible key works if not quiet: CtxtAgent.logger.debug( "Error connecting with SSH with initial credentials with: " + vm_ip + ". Try to ansible_key.") try: ssh_client = SSH(vm_ip, vm['user'], None, CtxtAgent.PK_FILE, vm['remote_port']) success = ssh_client.test_connectivity() res = 'pk_file' except: if not quiet: CtxtAgent.logger.exception( "Error connecting with SSH with: " + vm_ip) success = False except: if not quiet: CtxtAgent.logger.exception( "Error connecting with SSH with: " + vm_ip) success = False if success: vm['ctxt_ip'] = vm_ip return res else: time.sleep(delay) return None
def contextualize_vm(general_conf_data, vm_conf_data): vault_pass = None if 'VAULT_PASS' in os.environ: vault_pass = os.environ['VAULT_PASS'] res_data = {} CtxtAgent.logger.info('Generate and copy the ssh key') # If the file exists, do not create it again if not os.path.isfile(CtxtAgent.PK_FILE): out = CtxtAgent.run_command('ssh-keygen -t rsa -C ' + getpass.getuser() + ' -q -N "" -f ' + CtxtAgent.PK_FILE) CtxtAgent.logger.debug(out) # Check that we can SSH access the node ctxt_vm = None for vm in general_conf_data['vms']: if vm['id'] == vm_conf_data['id']: ctxt_vm = vm if not ctxt_vm: CtxtAgent.logger.error("No VM to Contextualize!") res_data['OK'] = False return res_data for task in vm_conf_data['tasks']: task_ok = False num_retries = 0 while not task_ok and num_retries < CtxtAgent.PLAYBOOK_RETRIES: num_retries += 1 CtxtAgent.logger.info('Launch task: ' + task) if ctxt_vm['os'] == "windows": # playbook = general_conf_data['conf_dir'] + "/" + task + "_task_all_win.yml" playbook = general_conf_data[ 'conf_dir'] + "/" + task + "_task.yml" else: playbook = general_conf_data[ 'conf_dir'] + "/" + task + "_task_all.yml" inventory_file = general_conf_data['conf_dir'] + "/hosts" ansible_thread = None if task == "basic": # This is always the fist step, so put the SSH test, the # requiretty removal and change password here for vm in general_conf_data['vms']: if vm['os'] == "windows": CtxtAgent.logger.info( "Waiting WinRM access to VM: " + vm['ip']) ssh_res = CtxtAgent.wait_winrm_access(vm) else: CtxtAgent.logger.info( "Waiting SSH access to VM: " + vm['ip']) ssh_res = CtxtAgent.wait_ssh_access(vm) # the IP has changed public for private and we are the # master VM if 'ctxt_ip' in vm and vm['ctxt_ip'] != vm[ 'ip'] and ctxt_vm['master']: # update the ansible inventory CtxtAgent.logger.info( "Changing the IP %s for %s in config files." % (vm['ctxt_ip'], vm['ip'])) CtxtAgent.replace_vm_ip(vm) if vm['id'] == vm_conf_data['id']: cred_used = ssh_res if not ssh_res: CtxtAgent.logger.error( "Error Waiting access to VM: " + vm['ip']) res_data['SSH_WAIT'] = False res_data['OK'] = False return res_data else: res_data['SSH_WAIT'] = True CtxtAgent.logger.info("Remote access to VM: " + vm['ip'] + " Open!") # The basic task uses the credentials of VM stored in ctxt_vm pk_file = None if cred_used == "pk_file": pk_file = CtxtAgent.PK_FILE # First remove requiretty in the node if ctxt_vm['os'] != "windows": success = CtxtAgent.removeRequiretty(ctxt_vm, pk_file) if success: CtxtAgent.logger.info( "Requiretty successfully removed") else: CtxtAgent.logger.error("Error removing Requiretty") # Check if we must chage user credentials # Do not change it on the master. It must be changed only by # the ConfManager change_creds = False if not ctxt_vm['master']: change_creds = CtxtAgent.changeVMCredentials( ctxt_vm, pk_file) res_data['CHANGE_CREDS'] = change_creds if ctxt_vm['os'] != "windows": # this step is not needed in windows systems ansible_thread = CtxtAgent.LaunchAnsiblePlaybook( CtxtAgent.logger, vm_conf_data['remote_dir'], playbook, ctxt_vm, 2, inventory_file, pk_file, CtxtAgent.INTERNAL_PLAYBOOK_RETRIES, change_creds, vault_pass) else: # In some strange cases the pk_file disappears. So test it and # remake basic recipe if ctxt_vm['os'] != "windows": success = False try: ssh_client = SSH(ctxt_vm['ip'], ctxt_vm['user'], None, CtxtAgent.PK_FILE, ctxt_vm['remote_port']) success = ssh_client.test_connectivity() except: success = False if not success: CtxtAgent.logger.warn( "Error connecting with SSH using the ansible key with: " + ctxt_vm['ip'] + ". Call the basic playbook again.") basic_playbook = general_conf_data[ 'conf_dir'] + "/basic_task_all.yml" output_basic = StringIO() ansible_thread = CtxtAgent.LaunchAnsiblePlaybook( output_basic, vm_conf_data['remote_dir'], basic_playbook, ctxt_vm, 2, inventory_file, None, CtxtAgent.INTERNAL_PLAYBOOK_RETRIES, True, vault_pass) (task_ok, _) = CtxtAgent.wait_thread(ansible_thread) # in the other tasks pk_file can be used ansible_thread = CtxtAgent.LaunchAnsiblePlaybook( CtxtAgent.logger, vm_conf_data['remote_dir'], playbook, ctxt_vm, 2, inventory_file, CtxtAgent.PK_FILE, CtxtAgent.INTERNAL_PLAYBOOK_RETRIES, vm_conf_data['changed_pass'], vault_pass) if ansible_thread: (task_ok, _) = CtxtAgent.wait_thread(ansible_thread) else: task_ok = True if not task_ok: CtxtAgent.logger.warn( "ERROR executing task %s: (%s/%s)" % (task, num_retries, CtxtAgent.PLAYBOOK_RETRIES)) else: CtxtAgent.logger.info('Task %s finished successfully' % task) res_data[task] = task_ok if not task_ok: res_data['OK'] = False return res_data res_data['OK'] = True CtxtAgent.logger.info('Process finished') return res_data