def test_provision_cloud_init(setup_provider, provider, setup_ci_template, vm_name, smtp_test, request, provisioning): """Tests cloud init provisioning Metadata: test_flag: cloud_init, provision suite: infra_provisioning """ # generate_tests makes sure these have values template = provisioning.get('ci-image', None) or provisioning['image']['name'] host, datastore = map(provisioning.get, ('host', 'datastore')) mgmt_system = provider.get_mgmt_system() request.addfinalizer(lambda: cleanup_vm(vm_name, provider)) provisioning_data = { 'vm_name': vm_name, 'host_name': { 'name': [host] }, 'datastore_name': { 'name': [datastore] }, 'provision_type': 'Native Clone', 'custom_template': { 'name': [provisioning['ci-template']] }, } try: provisioning_data['vlan'] = provisioning['vlan'] except KeyError: # provisioning['vlan'] is required for rhevm provisioning if provider.type == 'rhevm': raise pytest.fail( 'rhevm requires a vlan value in provisioning info') do_vm_provisioning(template, provider, vm_name, provisioning_data, request, smtp_test, num_sec=900) connect_ip, tc = wait_for(mgmt_system.get_ip_address, [vm_name], num_sec=300, handle_exception=True) # Check that we can at least get the uptime via ssh this should only be possible # if the username and password have been set via the cloud-init script so # is a valid check sshclient = ssh.SSHClient(hostname=connect_ip, username=provisioning['ci-username'], password=provisioning['ci-pass']) wait_for(sshclient.uptime, num_sec=200, handle_exception=True)
def instance(request, local_setup_provider, provider, vm_name, vm_analysis_data, appliance): """ Fixture to provision instance on the provider """ vm = VM.factory(vm_name, provider, template_name=vm_analysis_data['image']) request.addfinalizer(lambda: cleanup_vm(vm_name, provider)) provision_data = vm_analysis_data.copy() del provision_data['image'] vm.create_on_provider(find_in_cfme=True, **provision_data) if provider.type == "openstack": vm.provider.mgmt.assign_floating_ip(vm.name, 'public') logger.info("VM %s provisioned, waiting for IP address to be assigned", vm_name) mgmt_system = provider.get_mgmt_system() @pytest.wait_for(timeout="20m", delay=5) def get_ip_address(): logger.info("Power state for {} vm: {}, is_vm_stopped: {}".format( vm_name, mgmt_system.vm_status(vm_name), mgmt_system.is_vm_stopped(vm_name))) if mgmt_system.is_vm_stopped(vm_name): mgmt_system.start_vm(vm_name) ip = mgmt_system.current_ip_address(vm_name) logger.info("Fetched IP for %s: %s", vm_name, ip) return ip is not None connect_ip = mgmt_system.get_ip_address(vm_name) assert connect_ip is not None # Check that we can at least get the uptime via ssh this should only be possible # if the username and password have been set via the cloud-init script so # is a valid check if vm_analysis_data['fs-type'] not in ['ntfs', 'fat32']: logger.info("Waiting for %s to be available via SSH", connect_ip) ssh_client = ssh.SSHClient(hostname=connect_ip, username=vm_analysis_data['username'], password=vm_analysis_data['password'], port=22) wait_for(ssh_client.uptime, num_sec=3600, handle_exception=True) vm.ssh = ssh_client vm.system_type = detect_system_type(vm) logger.info("Detected system type: %s", vm.system_type) vm.image = vm_analysis_data['image'] vm.connect_ip = connect_ip # TODO: This is completely wrong and needs to be fixed # CFME relationship is suppose to be set to the appliance, which is required # to be placed within the same datastore that the VM resides # # Also, if rhev and iscsi, it need direct_lun if provider.type == 'rhevm': logger.info("Setting a relationship between VM and appliance") from cfme.infrastructure.virtual_machines import Vm cfme_rel = Vm.CfmeRelationship(vm) server_name = appliance.server_name() cfme_rel.set_relationship(str(server_name), configuration.server_id()) return vm
def test_provision_cloud_init(request, setup_provider, provider, provisioning, setup_ci_template, vm_name): """ Tests provisioning from a template with cloud_init Metadata: test_flag: cloud_init, provision """ image = provisioning.get('ci-image', None) or provisioning['image']['name'] note = ( 'Testing provisioning from image {} to vm {} on provider {}'.format( image, vm_name, provider.key)) logger.info(note) mgmt_system = provider.mgmt instance = Instance.factory(vm_name, provider, image) request.addfinalizer(instance.delete_from_provider) inst_args = { 'email': '*****@*****.**', 'first_name': 'Image', 'last_name': 'Provisioner', 'notes': note, 'instance_type': provisioning['instance_type'], 'availability_zone': provisioning['availability_zone'], 'security_groups': [provisioning['security_group']], 'guest_keypair': provisioning['guest_keypair'], 'custom_template': { 'name': [provisioning['ci-template']] }, } if provider.type == "openstack": floating_ip = mgmt_system.get_first_floating_ip() inst_args['cloud_network'] = provisioning['cloud_network'] inst_args['public_ip_address'] = floating_ip logger.info('Instance args: {}'.format(inst_args)) instance.create(**inst_args) connect_ip, tc = wait_for(mgmt_system.get_ip_address, [vm_name], num_sec=300, handle_exception=True) # Check that we can at least get the uptime via ssh this should only be possible # if the username and password have been set via the cloud-init script so # is a valid check with ssh.SSHClient(hostname=connect_ip, username=provisioning['ci-username'], password=provisioning['ci-pass']) as ssh_client: wait_for(ssh_client.uptime, num_sec=200, handle_exception=True)
def test_webmks_vm_console(request, appliance, provider, vm_obj, configure_vmware_console_for_test): """Test the VMware WebMKS console support for a particular provider. The supported providers are: VMware vSphere6 and vSphere6.5 For a given provider, and a given VM, the console will be opened, and then: - The console's status will be checked. - A command that creates a file will be sent through the console. - Using ssh we will check that the command worked (i.e. that the file was created.) """ console_vm_username = credentials[provider.data.templates.get( 'console_template')['creds']].get('username') console_vm_password = credentials[provider.data.templates.get( 'console_template')['creds']].get('password') vm_obj.open_console(console='VM Console', invokes_alert=True) assert vm_obj.vm_console, 'VMConsole object should be created' vm_console = vm_obj.vm_console request.addfinalizer(vm_console.close_console_window) request.addfinalizer(appliance.server.logout) # Get the login screen image, and make sure it is a jpeg file: screen = vm_console.get_screen(180) assert imghdr.what('', screen) == 'jpeg' with ssh.SSHClient(hostname=vm_obj.ip_address, username=console_vm_username, password=console_vm_password) as vm_ssh_client: assert vm_console.wait_for_text(text_to_find="login:"******"VM Console didn't prompt for Login" result_before_login = vm_ssh_client.run_command("who --count", ensure_user=True) # Enter Username: vm_console.send_keys(console_vm_username) assert vm_console.wait_for_text(text_to_find="Password", timeout=200),\ "VM Console didn't prompt for Password" # Enter Password: vm_console.send_keys("{}\n".format(console_vm_password)) result_after_login = vm_ssh_client.run_command("who --count", ensure_user=True) # Number of users before login would be 0 and after login would be 180 # If below assertion would fail result_after_login is also 0, denoting login failed assert ( result_before_login.output.split('=')[-1].strip() < result_after_login.output.split('=')[-1].strip()), "Login Failed" # This regex can find if there is a word 'login','password','incorrect' present in # text, irrespective of its case regex_for_login_password = re.compile( r'\blogin\b | \bpassword\b| \bincorrect\b', flags=re.I | re.X) def _validate_login(): """ Try to read what is on present on the last line in console. If it is word 'login', enter username, if 'password' enter password, in order to make the login successful """ if vm_console.find_text_on_screen(text_to_find='login', current_line=True): vm_console.send_keys(console_vm_username) if vm_console.find_text_on_screen(text_to_find='Password', current_line=True): vm_console.send_keys("{}\n".format(console_vm_password)) # if the login attempt failed for some reason (happens with RHOS-cirros), # last line of the console will contain one of the following words: # [login, password, incorrect] # if so, regex_for_login_password will find it and result will not be [] # .split('\n')[-1] splits the console text on '\n' & picks last item of resulting list result = regex_for_login_password.findall( vm_console.get_screen_text().split('\n')[-1]) return result == [] # if _validate_login() returns True, it means we did not find any of words # [login, password, incorrect] on last line of console text, which implies login success wait_for(func=_validate_login, timeout=300, delay=5) logger.info("Wait to get the '$' prompt") vm_console.wait_for_text(text_to_find=provider.data.templates.get( 'console_template')['prompt_text'], timeout=200) with ssh.SSHClient(hostname=vm_obj.ip_address, username=console_vm_username, password=console_vm_password) as vm_ssh_client: # create file on system vm_console.send_keys("touch blather\n") wait_for(func=lambda: vm_ssh_client.run_command("ls blather", ensure_user=True) == 0, delay=1, num_sec=10) # if file was created in previous steps it will be removed here # we will get instance of SSHResult # Sometimes Openstack drops characters from word 'blather' hence try to remove # file using partial file name. Known issue, being worked on. command_result = vm_ssh_client.run_command("rm blather", ensure_user=True) assert command_result
def test_html5_vm_console(appliance, provider, configure_websocket, vm_obj, configure_vmware_console_for_test): """ Test the HTML5 console support for a particular provider. The supported providers are: VMware Openstack RHV For a given provider, and a given VM, the console will be opened, and then: - The console's status will be checked. - A command that creates a file will be sent through the console. - Using ssh we will check that the command worked (i.e. that the file was created. """ console_vm_username = credentials[provider.data.templates.get('console_template') ['creds']].get('username') console_vm_password = credentials[provider.data.templates.get('console_template') ['creds']].get('password') vm_obj.open_console(console='VM Console') assert vm_obj.vm_console, 'VMConsole object should be created' vm_console = vm_obj.vm_console try: # If the banner/connection-status element exists we can get # the connection status text and if the console is healthy, it should connect. assert vm_console.wait_for_connect(180), "VM Console did not reach 'connected' state" # Get the login screen image, and make sure it is a jpeg file: screen = vm_console.get_screen() assert imghdr.what('', screen) == 'jpeg' assert vm_console.wait_for_text(text_to_find="login:"******"VM Console" " didn't prompt for Login") # Enter Username: vm_console.send_keys(console_vm_username) assert vm_console.wait_for_text(text_to_find="Password", timeout=200), ("VM Console" " didn't prompt for Password") # Enter Password: vm_console.send_keys("{}\n".format(console_vm_password)) time.sleep(5) # wait for login to complete # This regex can find if there is a word 'login','password','incorrect' present in # text, irrespective of its case regex_for_login_password = re.compile(r'\blogin\b | \bpassword\b| \bincorrect\b', flags=re.I | re.X) def _validate_login(): """ Try to read what is on present on the last line in console. If it is word 'login', enter username, if 'password' enter password, in order to make the login successful """ if vm_console.find_text_on_screen(text_to_find='login', current_line=True): vm_console.send_keys(console_vm_username) if vm_console.find_text_on_screen(text_to_find='Password', current_line=True): vm_console.send_keys("{}\n".format(console_vm_password)) # if the login attempt failed for some reason (happens with RHOS-cirros), # last line of the console will contain one of the following words: # [login, password, incorrect] # if so, regex_for_login_password will find it and result will not be [] # .split('\n')[-1] splits the console text on '\n' & picks last item of resulting list result = regex_for_login_password.findall(vm_console.get_screen_text().split('\n')[-1]) return result == [] # if _validate_login() returns True, it means we did not find any of words # [login, password, incorrect] on last line of console text, which implies login success wait_for(func=_validate_login, timeout=300, delay=5) logger.info("Wait to get the '$' prompt") if provider.one_of(VMwareProvider): vm_console.wait_for_text(text_to_find=provider.data.templates.get('console_template') ['prompt_text'], timeout=200) else: time.sleep(15) # create file on system vm_console.send_keys("touch blather") # Test pressing ctrl-alt-delete...we should be able to get a new login prompt: vm_console.send_ctrl_alt_delete() vm_console.wait_for_text(text_to_find="login:"******"login:"******"VM Console" " didn't prompt for Login") if not provider.one_of(OpenStackProvider): assert vm_console.send_fullscreen(), ("VM Console Toggle Full Screen button does" " not work") with ssh.SSHClient(hostname=vm_obj.ip_address, username=console_vm_username, password=console_vm_password) as ssh_client: # if file was created in previous steps it will be removed here # we will get instance of SSHResult # Sometimes Openstack drops characters from word 'blather' hence try to remove # file using partial file name. Known issue, being worked on. command_result = ssh_client.run_command("rm blather", ensure_user=True) assert command_result finally: vm_console.close_console_window() # Logout is required because when running the Test back 2 back against RHV and VMware # Providers, following issue would arise: # If test for RHV is just finished, code would proceed to adding VMware Provider and once it # is added, then it will navigate to Infrastructure -> Virtual Machines Page, it will see # "Page Does not Exists" Error, because the browser will try to go to the # VM details page of RHV VM which is already deleted # at the End of test for RHV Provider Console and test would fail. # Logging out would get rid of this issue. appliance.server.logout()
def instance(request, local_setup_provider, provider, vm_name, vm_analysis_data): """ Fixture to provision instance on the provider """ template = vm_analysis_data.get('image', None) host_name, datastore_name = map(vm_analysis_data.get, ('host', 'datastore')) mgmt_system = provider.get_mgmt_system() provisioning_data = { 'vm_name': vm_name, 'host_name': { 'name': [host_name] }, 'datastore_name': { 'name': [datastore_name] }, } try: provisioning_data['vlan'] = vm_analysis_data['vlan'] except KeyError: # provisioning['vlan'] is required for rhevm provisioning if provider.type == 'rhevm': raise pytest.fail( 'rhevm requires a vlan value in provisioning info') vm = VM.factory(vm_name, provider) connect_ip = None if provider.type == "openstack": image = vm_analysis_data['image'] vm = VM.factory(vm_name, provider, image) request.addfinalizer(vm.delete_from_provider) connect_ip = mgmt_system.get_first_floating_ip() provider.refresh_provider_relationships(method='ui') inst_args = { 'email': '*****@*****.**', 'first_name': 'Image', 'last_name': 'Provisioner', 'template_name': image, 'notes': ('Testing provisioning from image {} to vm {} on provider {}'. format(image, vm_name, provider.key)), 'instance_type': vm_analysis_data['instance_type'], 'availability_zone': vm_analysis_data['availability_zone'], 'security_groups': [vm_analysis_data['security_group']], 'cloud_network': vm_analysis_data['cloud_network'], 'public_ip_address': connect_ip, } vm.create(**inst_args) else: request.addfinalizer(lambda: cleanup_vm(vm_name, provider)) do_vm_provisioning(template, provider, vm_name, provisioning_data, request, None, num_sec=6000) logger.info("VM %s provisioned, waiting for IP address to be assigned", vm_name) @pytest.wait_for(timeout="20m", delay=5) def get_ip_address(): logger.info("Power state for {} vm: {}, is_vm_stopped: {}".format( vm_name, mgmt_system.vm_status(vm_name), mgmt_system.is_vm_stopped(vm_name))) if mgmt_system.is_vm_stopped(vm_name): mgmt_system.start_vm(vm_name) ip = mgmt_system.current_ip_address(vm_name) logger.info("Fetched IP for %s: %s", vm_name, ip) return ip is not None connect_ip = mgmt_system.get_ip_address(vm_name) assert connect_ip is not None # Check that we can at least get the uptime via ssh this should only be possible # if the username and password have been set via the cloud-init script so # is a valid check if vm_analysis_data['fs-type'] not in ['ntfs', 'fat32']: logger.info("Waiting for %s to be available via SSH", connect_ip) ssh_client = ssh.SSHClient(hostname=connect_ip, username=vm_analysis_data['username'], password=vm_analysis_data['password'], port=22) wait_for(ssh_client.uptime, num_sec=3600, handle_exception=False) vm.ssh = ssh_client vm.system_type = detect_system_type(vm) logger.info("Detected system type: %s", vm.system_type) vm.image = vm_analysis_data['image'] vm.connect_ip = connect_ip if provider.type == 'rhevm': logger.info("Setting a relationship between VM and appliance") from cfme.infrastructure.virtual_machines import Vm cfme_rel = Vm.CfmeRelationship(vm) cfme_rel.set_relationship(str(configuration.server_name()), configuration.server_id()) return vm