def setup_external_auth_ipa(**data): """Sets up the appliance for an external authentication with IPA. Keywords: get_groups: Get User Groups from External Authentication (httpd). ipaserver: IPA server address. iparealm: Realm. credentials: Key of the credential in credentials.yaml """ ssh = SSHClient() ensure_browser_open() login_admin() if data["ipaserver"] not in get_ntp_servers(): set_ntp_servers(data["ipaserver"]) sleep(120) auth = ExternalAuthSetting(get_groups=data.pop("get_groups", False)) auth.setup() logout() creds = credentials.get(data.pop("credentials"), {}) data.update(**creds) rc, out = ssh.run_command( "appliance_console_cli --ipaserver {ipaserver} --iparealm {iparealm} " "--ipaprincipal {principal} --ipapassword {password}".format(**data)) assert rc == 0, out assert "failed" not in out.lower( ), "External auth setup failed:\n{}".format(out) login_admin()
def step(self): # Can be either blank or logged in del self.view # In order to unbind the browser quit() ensure_browser_open(self.obj.appliance.server.address()) if not self.view.is_displayed: raise Exception('Could not open the login screen')
def setup_external_auth_ipa(**data): """Sets up the appliance for an external authentication with IPA. Keywords: get_groups: Get User Groups from External Authentication (httpd). ipaserver: IPA server address. iparealm: Realm. credentials: Key of the credential in credentials.yaml """ ssh = SSHClient() ensure_browser_open() login_admin() if data["ipaserver"] not in get_ntp_servers(): set_ntp_servers(data["ipaserver"]) sleep(120) auth = ExternalAuthSetting(get_groups=data.pop("get_groups", False)) auth.setup() logout() creds = credentials.get(data.pop("credentials"), {}) data.update(**creds) rc, out = ssh.run_command( "appliance_console_cli --ipaserver {ipaserver} --iparealm {iparealm} " "--ipaprincipal {principal} --ipapassword {password}".format(**data) ) assert rc == 0, out assert "failed" not in out.lower(), "External auth setup failed:\n{}".format(out) login_admin()
def setup_external_auth_openldap(**data): """Sets up the appliance for an external authentication with OpenLdap. Keywords: get_groups: Get User Groups from External Authentication (httpd). ipaserver: IPA server address. iparealm: Realm. credentials: Key of the credential in credentials.yaml """ connect_kwargs = { 'username': credentials['host_default']['username'], 'password': credentials['host_default']['password'], 'hostname': data['ipaddress'], } appliance_obj = appliance.IPAppliance() appliance_name = 'cfmeappliance{}'.format(fauxfactory.gen_alpha(7).lower()) appliance_address = appliance_obj.address appliance_fqdn = '{}.{}'.format(appliance_name, data['domain_name']) ldapserver_ssh = SSHClient(**connect_kwargs) # updating the /etc/hosts is a workaround due to the # https://bugzilla.redhat.com/show_bug.cgi?id=1360928 command = 'echo "{}\t{}" >> /etc/hosts'.format(appliance_address, appliance_fqdn) ldapserver_ssh.run_command(command) ldapserver_ssh.get_file(remote_file=data['cert_filepath'], local_path=conf_path.strpath) ldapserver_ssh.close() ensure_browser_open() login_admin() auth = ExternalAuthSetting(get_groups=data.pop("get_groups", True)) auth.setup() appliance_obj.configure_appliance_for_openldap_ext_auth(appliance_fqdn) logout()
def setup_external_auth_openldap(**data): """Sets up the appliance for an external authentication with OpenLdap. Keywords: get_groups: Get User Groups from External Authentication (httpd). ipaserver: IPA server address. iparealm: Realm. credentials: Key of the credential in credentials.yaml """ connect_kwargs = { 'username': credentials['host_default']['username'], 'password': credentials['host_default']['password'], 'hostname': data['ipaddress'], } appliance_obj = appliance.IPAppliance() appliance_name = 'cfmeappliance{}'.format(fauxfactory.gen_alpha(7).lower()) appliance_address = appliance_obj.address appliance_fqdn = '{}.{}'.format(appliance_name, data['domain_name']) with SSHClient(**connect_kwargs) as ldapserver_ssh: # updating the /etc/hosts is a workaround due to the # https://bugzilla.redhat.com/show_bug.cgi?id=1360928 command = 'echo "{}\t{}" >> /etc/hosts'.format(appliance_address, appliance_fqdn) ldapserver_ssh.run_command(command) ldapserver_ssh.get_file(remote_file=data['cert_filepath'], local_path=conf_path.strpath) ensure_browser_open() login_admin() auth = ExternalAuthSetting(get_groups=data.pop("get_groups", True)) auth.setup() appliance_obj.configure_appliance_for_openldap_ext_auth(appliance_fqdn) logout()
def needs_firefox(): """ Fixture which skips the test if not run under firefox. I recommend putting it in the first place. """ browser.ensure_browser_open() if browser.browser().name != "firefox": pytest.skip(msg="This test needs firefox to run")
def force_navigate(page_name, _tries=0, *args, **kwargs): """force_navigate(page_name) Given a page name, attempt to navigate to that page no matter what breaks. Args: page_name: Name a page from the current :py:data:`ui_navigate.nav_tree` tree to navigate to. """ if _tries >= 3: # Need at least three tries: # 1: login_admin handles an alert or closes the browser due any error # 2: If login_admin handles an alert, go_to can still encounter an unexpected error # 3: Everything should work. If not, NavigationError. raise exceptions.NavigationError(page_name) _tries += 1 logger.debug('force_navigate to %s, try %d' % (page_name, _tries)) # circular import prevention: cfme.login uses functions in this module from cfme import login # Import the top-level nav menus for convenience from cfme.web_ui import menu # NOQA # browser fixture should do this, but it's needed for subsequent calls ensure_browser_open() # Clear any running "spinnies" try: browser().execute_script('miqSparkleOff();') except: # miqSparkleOff undefined, so it's definitely off. pass try: # What we'd like to happen... login.login_admin() logger.info('Navigating to %s' % page_name) ui_navigate.go_to(page_name, *args, **kwargs) except (KeyboardInterrupt, ValueError): # KeyboardInterrupt: Don't block this while navigating # ValueError: ui_navigate.go_to can't handle this page, give up raise except UnexpectedAlertPresentException: if _tries == 1: # There was an alert, accept it and try again handle_alert(wait=0) else: # There was still an alert when we tried again, shoot the browser in the head logger.debug("Unxpected alert on try %d, recycling browser" % _tries) browser().quit() force_navigate(page_name, _tries, *args, **kwargs) except Exception as ex: # Anything else happened, nuke the browser and try again. logger.info('Caught %s during navigation, trying again.' % type(ex).__name__) logger.debug(format_exc()) browser().quit() force_navigate(page_name, _tries, *args, **kwargs)
def standup_perf_ui(ui_worker_pid, soft_assert): logger.info('Opening /var/www/miq/vmdb/log/production.log for tail') prod_tail = SSHTail('/var/www/miq/vmdb/log/production.log') prod_tail.set_initial_file_end() ensure_browser_open() pages = analyze_page_stat(perf_click(ui_worker_pid, prod_tail, False, login_admin), soft_assert) return pages, prod_tail
def disable_external_auth_ipa(): """Unconfigure external auth.""" ssh = SSHClient() ensure_browser_open() login_admin() auth = DatabaseAuthSetting() auth.update() rc, out = ssh.run_command("appliance_console_cli --uninstall-ipa") assert rc == 0, out
def disable_external_auth_ipa(): """Unconfigure external auth.""" with SSHClient() as ssh_client: ensure_browser_open() login_admin() auth = DatabaseAuthSetting() auth.update() assert ssh_client.run_command("appliance_console_cli --uninstall-ipa") appliance.IPAppliance().wait_for_web_ui() logout()
def check_logged_out(): if browser.browser() is not None: browser.quit() browser.ensure_browser_open() login.logout() yield if browser.browser() is not None: browser.quit() browser.ensure_browser_open() login.logout()
def disable_external_auth_ipa(): """Unconfigure external auth.""" ssh = SSHClient() ensure_browser_open() login_admin() auth = DatabaseAuthSetting() auth.update() assert ssh.run_command("appliance_console_cli --uninstall-ipa") appliance.IPAppliance().wait_for_web_ui() logout()
def disable_external_auth_ipa(): """Unconfigure external auth.""" current_appliance = get_or_create_current_appliance() with current_appliance.ssh_client as ssh: ensure_browser_open() appliance.current_appliance.server.login_admin() auth = DatabaseAuthSetting() auth.update() assert ssh.run_command("appliance_console_cli --uninstall-ipa") current_appliance.wait_for_web_ui() appliance.current_appliance.server.logout()
def test_basic_metrics(provider): """ Basic Metrics availability test This test checks that the Metrics service is up Opens the hawkular status page and checks if it's up """ hostname = 'https://' + conf.cfme_data.get('management_systems', {})[provider.key]\ .get('hostname', []) + '/hawkular/metrics' ensure_browser_open() sel.get(hostname) element = sel.ByText('STARTED') assert element
def login(user, submit_method=_js_auth_fn): """ Login to CFME with the given username and password. Optionally, submit_method can be press_enter_after_password to use the enter key to login, rather than clicking the button. Args: user: The username to fill in the username field. password: The password to fill in the password field. submit_method: A function to call after the username and password have been input. Raises: RuntimeError: If the login fails, ie. if a flash message appears """ if not user: username = conf.credentials['default']['username'] password = conf.credentials['default']['password'] cred = Credential(principal=username, secret=password) user = User(credential=cred) if not logged_in() or user.credential.principal is not current_username(): if logged_in(): logout() # workaround for strange bug where we are logged out # as soon as we click something on the dashboard sel.sleep(1.0) logger.debug('Logging in as user %s', user.credential.principal) try: fill(form, {'username': user.credential.principal, 'password': user.credential.secret}) except sel.InvalidElementStateException as e: logger.warning("Got an error. Details follow.") msg = str(e).lower() if "element is read-only" in msg: logger.warning("Got a read-only login form, will reload the browser.") # Reload browser quit() ensure_browser_open() sel.sleep(1.0) sel.wait_for_ajax() # And try filling the form again fill(form, {'username': user.credential.principal, 'password': user.credential.secret}) else: logger.warning("Unknown error, reraising.") logger.exception(e) raise with sel.ajax_timeout(90): submit_method() flash.assert_no_errors() user.full_name = _full_name() store.user = user
def logged_in(browser): """ Logs into the system as admin and then returns the browser object. Args: browser: Current browser object. Yields: Browser object """ ensure_browser_open() login_admin() yield browser()
def login(user, submit_method=_js_auth_fn): """ Login to CFME with the given username and password. Optionally, submit_method can be press_enter_after_password to use the enter key to login, rather than clicking the button. Args: user: The username to fill in the username field. password: The password to fill in the password field. submit_method: A function to call after the username and password have been input. Raises: RuntimeError: If the login fails, ie. if a flash message appears """ if not user: username = conf.credentials['default']['username'] password = conf.credentials['default']['password'] cred = Credential(principal=username, secret=password) user = User(credential=cred) if not logged_in() or user.credential.principal is not current_username(): if logged_in(): logout() # workaround for strange bug where we are logged out # as soon as we click something on the dashboard sel.sleep(1.0) logger.debug('Logging in as user %s' % user.credential.principal) try: fill(form, {'username': user.credential.principal, 'password': user.credential.secret}) except sel.InvalidElementStateException as e: logger.warning("Got an error. Details follow.") msg = str(e).lower() if "element is read-only" in msg: logger.warning("Got a read-only login form, will reload the browser.") # Reload browser quit() ensure_browser_open() sel.sleep(1.0) sel.wait_for_ajax() # And try filling the form again fill(form, {'username': user.credential.principal, 'password': user.credential.secret}) else: logger.warning("Unknown error, reraising.") logger.exception(e) raise with sel.ajax_timeout(90): submit_method() flash.assert_no_errors() user.full_name = _full_name() store.user = user
def step(self): # Can be either blank or logged in from utils.browser import ensure_browser_open logged_in_view = self.create_view(BaseLoggedInPage) if logged_in_view.logged_in: logged_in_view.logout() if not self.view.is_displayed: # Something is wrong del self.view # In order to unbind the browser quit() ensure_browser_open() if not self.view.is_displayed: raise Exception('Could not open the login screen')
def really_logout(): """A convenience function logging out This function simply ensures that we are logged out and that a new browser is loaded ready for use. """ try: current_appliance.server.logout() except AttributeError: try: browser().quit() except AttributeError: ensure_browser_open()
def step(self): # Can be either blank or logged in from utils import browser logged_in_view = self.create_view(BaseLoggedInPage) if logged_in_view.logged_in: logged_in_view.logout() if not self.view.is_displayed: # Something is wrong del self.view # In order to unbind the browser browser.quit() browser.ensure_browser_open(self.obj.appliance.server.address()) if not self.view.is_displayed: raise Exception('Could not open the login screen')
def _on_detail_page(self): """ Returns ``True`` if on the providers detail page, ``False`` if not.""" if not self.string_name: # No point in doing that since it is probably being called from badly configured class # And since it is badly configured, let's notify the user. logger.warning( 'Hey, _on_details_page called from {} class which does not have string_name set' .format(type(self).__name__)) return False ensure_browser_open() collection = '{} Providers'.format(self.string_name) title = '{} (Summary)'.format(self.name) return breadcrumbs_names() == [collection, title] and summary_title() == title
def really_logout(): """A convenience function logging out This function simply ensures that we are logged out and that a new browser is loaded ready for use. """ try: logout() except AttributeError: try: browser().quit() except AttributeError: ensure_browser_open()
def _on_detail_page(self): """ Returns ``True`` if on the providers detail page, ``False`` if not.""" if not self.string_name: # No point in doing that since it is probably being called from badly configured class # And since it is badly configured, let's notify the user. logger.warning( 'Hey, _on_details_page called from {} class which does not have string_name set' .format(type(self).__name__)) return False ensure_browser_open() collection = '{} Providers'.format(self.string_name) title = '{} (Summary)'.format(self.name) return breadcrumbs_names() == [collection, title ] and summary_title() == title
def setup_external_auth_ipa(**data): """Sets up the appliance for an external authentication with IPA. Keywords: get_groups: Get User Groups from External Authentication (httpd). ipaserver: IPA server address. iparealm: Realm. credentials: Key of the credential in credentials.yaml """ connect_kwargs = { 'username': credentials['host_default']['username'], 'password': credentials['host_default']['password'], 'hostname': data['ipaserver'], } current_appliance = get_or_create_current_appliance() appliance_name = 'cfmeappliance{}'.format(fauxfactory.gen_alpha(7).lower()) appliance_address = current_appliance.address appliance_fqdn = '{}.{}'.format(appliance_name, data['iparealm'].lower()) with SSHClient(**connect_kwargs) as ipaserver_ssh: ipaserver_ssh.run_command('cp /etc/hosts /etc/hosts_bak') ipaserver_ssh.run_command( "sed -i -r '/^{}/d' /etc/hosts".format(appliance_address)) command = 'echo "{}\t{}" >> /etc/hosts'.format(appliance_address, appliance_fqdn) ipaserver_ssh.run_command(command) with current_appliance.ssh_client as ssh: result = ssh.run_command( 'appliance_console_cli --host {}'.format(appliance_fqdn)).success if not current_appliance.is_pod: assert result else: # appliance_console_cli fails when calls hostnamectl --host. it seems docker issue # raise BZ ? assert str(ssh.run_command('hostname')).rstrip() == appliance_fqdn ensure_browser_open() appliance.current_appliance.server.login_admin() if data["ipaserver"] not in get_ntp_servers(): set_ntp_servers(data["ipaserver"]) sleep(120) auth = ExternalAuthSetting(get_groups=data.pop("get_groups", False)) auth.setup() creds = credentials.get(data.pop("credentials"), {}) data.update(**creds) assert ssh.run_command( "appliance_console_cli --ipaserver {ipaserver} --iparealm {iparealm} " "--ipaprincipal {principal} --ipapassword {password}".format( **data)) appliance.current_appliance.server.login_admin()
def setup_external_auth_ipa(**data): """Sets up the appliance for an external authentication with IPA. Keywords: get_groups: Get User Groups from External Authentication (httpd). ipaserver: IPA server address. iparealm: Realm. credentials: Key of the credential in credentials.yaml """ connect_kwargs = { 'username': credentials['host_default']['username'], 'password': credentials['host_default']['password'], 'hostname': data['ipaserver'], } current_appliance = get_or_create_current_appliance() appliance_name = 'cfmeappliance{}'.format(fauxfactory.gen_alpha(7).lower()) appliance_address = current_appliance.address appliance_fqdn = '{}.{}'.format(appliance_name, data['iparealm'].lower()) with SSHClient(**connect_kwargs) as ipaserver_ssh: ipaserver_ssh.run_command('cp /etc/hosts /etc/hosts_bak') ipaserver_ssh.run_command("sed -i -r '/^{}/d' /etc/hosts".format(appliance_address)) command = 'echo "{}\t{}" >> /etc/hosts'.format(appliance_address, appliance_fqdn) ipaserver_ssh.run_command(command) with current_appliance.ssh_client as ssh: result = ssh.run_command('appliance_console_cli --host {}'.format(appliance_fqdn)).success if not current_appliance.is_pod: assert result else: # appliance_console_cli fails when calls hostnamectl --host. it seems docker issue # raise BZ ? assert str(ssh.run_command('hostname')).rstrip() == appliance_fqdn ensure_browser_open() appliance.current_appliance.server.login_admin() if data["ipaserver"] not in get_ntp_servers(): set_ntp_servers(data["ipaserver"]) sleep(120) auth = ExternalAuthSetting(get_groups=data.pop("get_groups", False)) auth.setup() creds = credentials.get(data.pop("credentials"), {}) data.update(**creds) assert ssh.run_command( "appliance_console_cli --ipaserver {ipaserver} --iparealm {iparealm} " "--ipaprincipal {principal} --ipapassword {password}".format(**data) ) appliance.current_appliance.server.login_admin()
def setup_external_auth_ipa(**data): """Sets up the appliance for an external authentication with IPA. Keywords: get_groups: Get User Groups from External Authentication (httpd). ipaserver: IPA server address. iparealm: Realm. credentials: Key of the credential in credentials.yaml """ connect_kwargs = { 'username': credentials['host_default']['username'], 'password': credentials['host_default']['password'], 'hostname': data['ipaserver'], } import fauxfactory appliance_name = 'cfmeappliance'.format(fauxfactory.gen_alpha(7).lower()) appliance_address = appliance.IPAppliance().address appliance_fqdn = '{}.{}'.format(appliance_name, data['iparealm'].lower()) ipaserver_ssh = SSHClient(**connect_kwargs) # updating the /etc/hosts is a workaround due to the # https://bugzilla.redhat.com/show_bug.cgi?id=1360928 command = 'echo "{}\t{}" >> /etc/hosts'.format(appliance_address, appliance_fqdn) ipaserver_ssh.run_command(command) ipaserver_ssh.close() ssh = SSHClient() rc, out = ssh.run_command('appliance_console_cli --host {}'.format(appliance_fqdn)) assert rc == 0, out ssh.run_command('echo "127.0.0.1\t{}" > /etc/hosts'.format(appliance_fqdn)) ensure_browser_open() login_admin() if data["ipaserver"] not in get_ntp_servers(): set_ntp_servers(data["ipaserver"]) sleep(120) auth = ExternalAuthSetting(get_groups=data.pop("get_groups", False)) auth.setup() logout() creds = credentials.get(data.pop("credentials"), {}) data.update(**creds) rc, out = ssh.run_command( "appliance_console_cli --ipaserver {ipaserver} --iparealm {iparealm} " "--ipaprincipal {principal} --ipapassword {password}".format(**data) ) assert rc == 0, out assert "failed" not in out.lower(), "External auth setup failed:\n{}".format(out) login_admin()
def local_setup_provider(request, setup_provider_modscope, provider, vm_analysis_data): if provider.type == 'rhevm' and version.current_version() < "5.5": # See https://bugzilla.redhat.com/show_bug.cgi?id=1300030 pytest.skip("SSA is not supported on RHEVM for appliances earlier than 5.5 and upstream") if GH("ManageIQ/manageiq:6506").blocks: pytest.skip("Upstream provisioning is blocked by" + "https://github.com/ManageIQ/manageiq/issues/6506") if provider.type == 'virtualcenter': store.current_appliance.install_vddk(reboot=True, wait_for_web_ui_after_reboot=True) ensure_browser_open() set_host_credentials(request, provider, vm_analysis_data) # Make sure all roles are set roles = configuration.get_server_roles(db=False) roles["automate"] = True roles["smartproxy"] = True roles["smartstate"] = True configuration.set_server_roles(**roles)
def wait_until(f, msg="Webdriver wait timed out", timeout=120.0): """This used to be a wrapper around WebDriverWait from selenium. Now it is just compatibility layer using :py:func:`utils.wait.wait_for` """ return wait_for(lambda: f(ensure_browser_open()), num_sec=timeout, message=msg, delay=0.5)
def setup_external_auth_ipa(**data): """Sets up the appliance for an external authentication with IPA. Keywords: get_groups: Get User Groups from External Authentication (httpd). ipaserver: IPA server address. iparealm: Realm. credentials: Key of the credential in credentials.yaml """ connect_kwargs = { 'username': credentials['host_default']['username'], 'password': credentials['host_default']['password'], 'hostname': data['ipaserver'], } appliance_name = 'cfmeappliance{}'.format(fauxfactory.gen_alpha(7).lower()) appliance_address = appliance.IPAppliance().address appliance_fqdn = '{}.{}'.format(appliance_name, data['iparealm'].lower()) ipaserver_ssh = SSHClient(**connect_kwargs) ipaserver_ssh.run_command('cp /etc/hosts /etc/hosts_bak') ipaserver_ssh.run_command( "sed -i -r '/^{}/d' /etc/hosts".format(appliance_address)) command = 'echo "{}\t{}" >> /etc/hosts'.format(appliance_address, appliance_fqdn) ipaserver_ssh.run_command(command) ipaserver_ssh.close() ssh = SSHClient() assert ssh.run_command( 'appliance_console_cli --host {}'.format(appliance_fqdn)) ensure_browser_open() login_admin() if data["ipaserver"] not in get_ntp_servers(): set_ntp_servers(data["ipaserver"]) sleep(120) auth = ExternalAuthSetting(get_groups=data.pop("get_groups", False)) auth.setup() creds = credentials.get(data.pop("credentials"), {}) data.update(**creds) assert ssh.run_command( "appliance_console_cli --ipaserver {ipaserver} --iparealm {iparealm} " "--ipaprincipal {principal} --ipapassword {password}".format(**data)) login_admin()
def setup_external_auth_ipa(**data): """Sets up the appliance for an external authentication with IPA. Keywords: get_groups: Get User Groups from External Authentication (httpd). ipaserver: IPA server address. iparealm: Realm. credentials: Key of the credential in credentials.yaml """ connect_kwargs = { 'username': credentials['host_default']['username'], 'password': credentials['host_default']['password'], 'hostname': data['ipaserver'], } appliance_name = 'cfmeappliance{}'.format(fauxfactory.gen_alpha(7).lower()) appliance_address = appliance.IPAppliance().address appliance_fqdn = '{}.{}'.format(appliance_name, data['iparealm'].lower()) ipaserver_ssh = SSHClient(**connect_kwargs) ipaserver_ssh.run_command('cp /etc/hosts /etc/hosts_bak') ipaserver_ssh.run_command("sed -i -r '/^{}/d' /etc/hosts".format(appliance_address)) command = 'echo "{}\t{}" >> /etc/hosts'.format(appliance_address, appliance_fqdn) ipaserver_ssh.run_command(command) ipaserver_ssh.close() ssh = SSHClient() assert ssh.run_command('appliance_console_cli --host {}'.format(appliance_fqdn)) ensure_browser_open() login_admin() if data["ipaserver"] not in get_ntp_servers(): set_ntp_servers(data["ipaserver"]) sleep(120) auth = ExternalAuthSetting(get_groups=data.pop("get_groups", False)) auth.setup() creds = credentials.get(data.pop("credentials"), {}) data.update(**creds) assert ssh.run_command( "appliance_console_cli --ipaserver {ipaserver} --iparealm {iparealm} " "--ipaprincipal {principal} --ipapassword {password}".format(**data) ) login_admin()
def local_setup_provider(request, setup_provider_modscope, provider, vm_analysis_data): if provider.type == 'rhevm' and version.current_version() < "5.5": # See https://bugzilla.redhat.com/show_bug.cgi?id=1300030 pytest.skip( "SSA is not supported on RHEVM for appliances earlier than 5.5 and upstream" ) if GH("ManageIQ/manageiq:6506").blocks: pytest.skip("Upstream provisioning is blocked by" + "https://github.com/ManageIQ/manageiq/issues/6506") if provider.type == 'virtualcenter': store.current_appliance.install_vddk(reboot=True, wait_for_web_ui_after_reboot=True) ensure_browser_open() set_host_credentials(request, provider, vm_analysis_data) # Make sure all roles are set roles = configuration.get_server_roles(db=False) roles["automate"] = True roles["smartproxy"] = True roles["smartstate"] = True configuration.set_server_roles(**roles)
def logged_in(browser): """ Logs into the system as admin and then returns the browser object. Args: browser: Current browser object. Yields: Browser object """ ensure_browser_open() try: login_admin() except pytest.sel.WebDriverException as e: # If we find a web driver exception, we can recycle the browser as long # as it is a jquery error as we know about those if "jquery" not in str(e).lower(): raise recycle() except pytest.sel.NoSuchElementException as e: # We have also seen instances where the page gets stuck on something other # than the login page, and gobbles tests, this is an attempt to fix that recycle() yield browser()
def _t(t, root=None): """Assume tuple is a 2-item tuple like (By.ID, 'myid'). Handles the case when root= locator resolves to multiple elements. In that case all of them are processed and all results are put in the same list.""" result = [] for root_element in (elements(root) if root is not None else [ensure_browser_open()]): # 20140920 - dajo - hack to get around selenium e is null bs count = 0 while count < 8: count += 1 try: result += root_element.find_elements(*t) break except Exception as e: logger.info('Exception detected: %s', str(e)) sleep(0.25) if count == 8: result += root_element.find_elements(*t) # Monkey patch them for elem in result: elem._source_locator = (t, root) return result
def force_navigate(page_name, _tries=0, *args, **kwargs): """force_navigate(page_name) Given a page name, attempt to navigate to that page no matter what breaks. Args: page_name: Name a page from the current :py:data:`ui_navigate.nav_tree` tree to navigate to. """ if _tries > 2: # Need at least three tries: # 1: login_admin handles an alert or CannotContinueWithNavigation appears. # 2: Everything should work. If not, NavigationError. raise exceptions.NavigationError(page_name) _tries += 1 logger.debug('force_navigate to %s, try %d' % (page_name, _tries)) # circular import prevention: cfme.login uses functions in this module from cfme import login # Import the top-level nav menus for convenience from cfme.web_ui import menu # browser fixture should do this, but it's needed for subsequent calls ensure_browser_open() # Clear any running "spinnies" try: execute_script('miqSparkleOff();') except: # miqSparkleOff undefined, so it's definitely off. pass # Set this to True in the handlers below to trigger a browser restart recycle = False # remember the current user, if any current_user = login.current_user() try: # What we'd like to happen... if not current_user: # default to admin user login.login_admin() else: # we recycled and want to log back in login.login(current_user.username, current_user.password) logger.info('Navigating to %s' % page_name) menu.nav.go_to(page_name, *args, **kwargs) except (KeyboardInterrupt, ValueError): # KeyboardInterrupt: Don't block this while navigating # ValueError: ui_navigate.go_to can't handle this page, give up raise except UnexpectedAlertPresentException: if _tries == 1: # There was an alert, accept it and try again handle_alert(wait=0) force_navigate(page_name, _tries, *args, **kwargs) else: # There was still an alert when we tried again, shoot the browser in the head logger.debug('Unxpected alert, recycling browser') recycle = True except (ErrorInResponseException, InvalidSwitchToTargetException): # Unable to switch to the browser at all, need to recycle logger.info('Invalid browser state, recycling browser') recycle = True except exceptions.CannotContinueWithNavigation as e: # The some of the navigation steps cannot succeed logger.info('Cannot continue with navigation due to: %s; Recycling browser' % str(e)) recycle = True except (NoSuchElementException, InvalidElementStateException, WebDriverException): from cfme.web_ui import cfme_exception as cfme_exc # To prevent circular imports # If the page is blocked, then recycle... if is_displayed("//div[@id='blocker_div']"): logger.warning("Page was blocked with blocker div, recycling.") recycle = True elif cfme_exc.is_cfme_exception(): logger.exception("CFME Exception before force_navigate started!: `{}`".format( cfme_exc.cfme_exception_text() )) recycle = True elif is_displayed("//body/div[@class='dialog' and ./h1 and ./p]"): # Rails exception detection logger.exception("Rails exception before force_navigate started!: {}:{} at {}".format( text("//body/div[@class='dialog']/h1").encode("utf-8"), text("//body/div[@class='dialog']/p").encode("utf-8"), current_url() )) recycle = True elif elements("//ul[@id='maintab']/li[@class='inactive']") and not\ elements("//ul[@id='maintab']/li[@class='active']/ul/li"): # If upstream and is the bottom part of menu is not displayed logger.exception("Detected glitch from BZ#1112574. HEADSHOT!") recycle = True else: logger.error("Could not determine the reason for failing the navigation. Reraising.") raise if recycle: browser().quit() # login.current_user() will be retained for next login logger.debug('browser killed on try %d' % _tries) # If given a "start" nav destination, it won't be valid after quitting the browser kwargs.pop("start", None) force_navigate(page_name, _tries, *args, **kwargs)
def logged_in(): ensure_browser_open() with sel.ajax_timeout(90): sel.wait_for_ajax() # This is called almost everywhere, protects from spinner return sel.is_displayed(dashboard.page.user_dropdown)
def force_navigate(page_name, _tries=0, *args, **kwargs): """force_navigate(page_name) Given a page name, attempt to navigate to that page no matter what breaks. Args: page_name: Name a page from the current :py:data:`ui_navigate.nav_tree` tree to navigate to. """ if _tries > 2: # Need at least three tries: # 1: login_admin handles an alert or CannotContinueWithNavigation appears. # 2: Everything should work. If not, NavigationError. raise exceptions.NavigationError(page_name) if "context" in kwargs: if not isinstance(kwargs["context"], ContextWrapper) and isinstance( kwargs["context"], dict): kwargs["context"] = ContextWrapper(kwargs["context"]) _tries += 1 logger.debug('force_navigate to %s, try %d' % (page_name, _tries)) # circular import prevention: cfme.login uses functions in this module from cfme import login # Import the top-level nav menus for convenience from cfme.web_ui import menu # browser fixture should do this, but it's needed for subsequent calls ensure_browser_open() # Clear any running "spinnies" try: execute_script('miqSparkleOff();') except: # Diaper OK (mfalesni) # miqSparkleOff undefined, so it's definitely off. pass # Set this to True in the handlers below to trigger a browser restart recycle = False # remember the current user, if any current_user = login.current_user() # Check if the page is blocked with blocker_div. If yes, let's headshot the browser right here if ( is_displayed("//div[@id='blocker_div' or @id='notification']", _no_deeper=True) or is_displayed(".modal-backdrop.fade.in", _no_deeper=True)): logger.warning("Page was blocked with blocker div on start of navigation, recycling.") quit() kwargs.pop("start", None) force_navigate("dashboard") # Start fresh # Check if modal window is displayed if (is_displayed( "//div[contains(@class, 'modal-dialog') and contains(@class, 'modal-lg')]", _no_deeper=True)): logger.warning("Modal window was open; closing the window") click("//button[contains(@class, 'close') and contains(@data-dismiss, 'modal')]") # Check if jQuery present try: execute_script("jQuery") except Exception as e: if "jQuery" not in str(e): logger.error("Checked for jQuery but got something different.") logger.exception(e) # Restart some workers logger.warning("Restarting UI and VimBroker workers!") with store.current_appliance.ssh_client as ssh: # Blow off the Vim brokers and UI workers ssh.run_rails_command("\"(MiqVimBrokerWorker.all + MiqUiWorker.all).each &:kill\"") logger.info("Waiting for web UI to come back alive.") sleep(10) # Give it some rest store.current_appliance.wait_for_web_ui() quit() ensure_browser_open() kwargs.pop("start", None) force_navigate("dashboard") # And start fresh # Same with rails errors rails_e = get_rails_error() if rails_e is not None: logger.warning("Page was blocked by rails error, renavigating.") logger.error(rails_e) logger.debug('Top CPU consumers:') logger.debug(store.current_appliance.ssh_client.run_command( 'top -c -b -n1 -M | head -30').output) logger.debug('Top Memory consumers:') logger.debug(store.current_appliance.ssh_client.run_command( 'top -c -b -n1 -M -a | head -30').output) logger.debug('Managed Providers:') logger.debug(store.current_appliance.managed_providers) quit() # Refresh the session, forget loaded summaries, ... kwargs.pop("start", None) ensure_browser_open() menu.nav.go_to("dashboard") # If there is a rails error past this point, something is really awful def _login_func(): if not current_user: # default to admin user login.login_admin() else: # we recycled and want to log back in login.login(current_user.username, current_user.password) try: try: # What we'd like to happen... _login_func() except WebDriverException as e: if "jquery" not in str(e).lower(): raise # Something unknown happened logger.info("Seems we got a non-CFME page (blank or screwed up) so killing the browser") quit() ensure_browser_open() # And try it again _login_func() # If this failed, no help with that :/ logger.info('Navigating to %s' % page_name) menu.nav.go_to(page_name, *args, **kwargs) except (KeyboardInterrupt, ValueError): # KeyboardInterrupt: Don't block this while navigating # ValueError: ui_navigate.go_to can't handle this page, give up raise except UnexpectedAlertPresentException: if _tries == 1: # There was an alert, accept it and try again handle_alert(wait=0) force_navigate(page_name, _tries, *args, **kwargs) else: # There was still an alert when we tried again, shoot the browser in the head logger.debug('Unxpected alert, recycling browser') recycle = True except (ErrorInResponseException, InvalidSwitchToTargetException): # Unable to switch to the browser at all, need to recycle logger.info('Invalid browser state, recycling browser') recycle = True except exceptions.CFMEExceptionOccured as e: # We hit a Rails exception logger.info('CFME Exception occured') logger.exception(e) recycle = True except exceptions.CannotContinueWithNavigation as e: # The some of the navigation steps cannot succeed logger.info('Cannot continue with navigation due to: %s; Recycling browser' % str(e)) recycle = True except (NoSuchElementException, InvalidElementStateException, WebDriverException) as e: from cfme.web_ui import cfme_exception as cfme_exc # To prevent circular imports # First check - if jquery is not found, there can be also another reason why this happened # so do not put the next branches in elif if isinstance(e, WebDriverException) and "jQuery" in str(e): # UI failed in some way, try recycling the browser logger.exception( "UI failed in some way, jQuery not found, (probably) recycling the browser.") recycle = True # If the page is blocked, then recycle... if ( is_displayed("//div[@id='blocker_div' or @id='notification']", _no_deeper=True) or is_displayed(".modal-backdrop.fade.in", _no_deeper=True)): logger.warning("Page was blocked with blocker div, recycling.") recycle = True elif cfme_exc.is_cfme_exception(): logger.exception("CFME Exception before force_navigate started!: `{}`".format( cfme_exc.cfme_exception_text() )) recycle = True elif is_displayed("//body[./h1 and ./p and ./hr and ./address]", _no_deeper=True): # 503 and similar sort of errors title = text("//body/h1") body = text("//body/p") logger.exception("Application error '{}': {}".format(title, body)) sleep(5) # Give it a little bit of rest recycle = True elif is_displayed("//body/div[@class='dialog' and ./h1 and ./p]", _no_deeper=True): # Rails exception detection logger.exception("Rails exception before force_navigate started!: {}:{} at {}".format( text("//body/div[@class='dialog']/h1").encode("utf-8"), text("//body/div[@class='dialog']/p").encode("utf-8"), current_url() )) recycle = True elif elements("//ul[@id='maintab']/li[@class='inactive']") and not\ elements("//ul[@id='maintab']/li[@class='active']/ul/li"): # If upstream and is the bottom part of menu is not displayed logger.exception("Detected glitch from BZ#1112574. HEADSHOT!") recycle = True else: logger.error("Could not determine the reason for failing the navigation. " + " Reraising. Exception: %s" % str(e)) logger.debug(store.current_appliance.ssh_client.run_command( 'service evmserverd status').output) raise if recycle: browser().quit() # login.current_user() will be retained for next login logger.debug('browser killed on try %d' % _tries) # If given a "start" nav destination, it won't be valid after quitting the browser kwargs.pop("start", None) force_navigate(page_name, _tries, *args, **kwargs)
def load_utilization_page(self, refresh=True): ensure_browser_open() self._object.load_details(refresh=refresh) mon_btn("Utilization")
def _on_detail_page(self): """ Returns ``True`` if on the providers detail page, ``False`` if not.""" ensure_browser_open() return sel.is_displayed( '//div[@class="dhtmlxInfoBarLabel-2"][contains(., "%s (Summary)")]' % self.name)
def force_navigate(page_name, _tries=0, *args, **kwargs): """force_navigate(page_name) Given a page name, attempt to navigate to that page no matter what breaks. Args: page_name: Name a page from the current :py:data:`ui_navigate.nav_tree` tree to navigate to. """ if _tries > 2: # Need at least three tries: # 1: login_admin handles an alert or CannotContinueWithNavigation appears. # 2: Everything should work. If not, NavigationError. raise exceptions.NavigationError(page_name) _tries += 1 logger.debug('force_navigate to %s, try %d' % (page_name, _tries)) # circular import prevention: cfme.login uses functions in this module from cfme import login # Import the top-level nav menus for convenience from cfme.web_ui import menu # browser fixture should do this, but it's needed for subsequent calls ensure_browser_open() # Clear any running "spinnies" try: execute_script('miqSparkleOff();') except: # miqSparkleOff undefined, so it's definitely off. pass # Set this to True in the handlers below to trigger a browser restart recycle = False # remember the current user, if any current_user = login.current_user() try: # What we'd like to happen... if not current_user: # default to admin user login.login_admin() else: # we recycled and want to log back in login.login(current_user.username, current_user.password) logger.info('Navigating to %s' % page_name) menu.nav.go_to(page_name, *args, **kwargs) except (KeyboardInterrupt, ValueError): # KeyboardInterrupt: Don't block this while navigating # ValueError: ui_navigate.go_to can't handle this page, give up raise except UnexpectedAlertPresentException: if _tries == 1: # There was an alert, accept it and try again handle_alert(wait=0) force_navigate(page_name, _tries, *args, **kwargs) else: # There was still an alert when we tried again, shoot the browser in the head logger.debug('Unxpected alert, recycling browser') recycle = True except (ErrorInResponseException, InvalidSwitchToTargetException): # Unable to switch to the browser at all, need to recycle logger.info('Invalid browser state, recycling browser') recycle = True except exceptions.CannotContinueWithNavigation as e: # The some of the navigation steps cannot succeed logger.info( 'Cannot continue with navigation due to: %s; Recycling browser' % str(e)) recycle = True except (NoSuchElementException, InvalidElementStateException, WebDriverException): from cfme.web_ui import cfme_exception as cfme_exc # To prevent circular imports # If the page is blocked, then recycle... if is_displayed("//div[@id='blocker_div']"): logger.warning("Page was blocked with blocker div, recycling.") recycle = True elif cfme_exc.is_cfme_exception(): logger.exception( "CFME Exception before force_navigate started!: `{}`".format( cfme_exc.cfme_exception_text())) recycle = True elif is_displayed("//body/div[@class='dialog' and ./h1 and ./p]"): # Rails exception detection logger.exception( "Rails exception before force_navigate started!: {}:{} at {}". format( text("//body/div[@class='dialog']/h1").encode("utf-8"), text("//body/div[@class='dialog']/p").encode("utf-8"), current_url())) recycle = True elif elements("//ul[@id='maintab']/li[@class='inactive']") and not\ elements("//ul[@id='maintab']/li[@class='active']/ul/li"): # If upstream and is the bottom part of menu is not displayed logger.exception("Detected glitch from BZ#1112574. HEADSHOT!") recycle = True else: logger.error( "Could not determine the reason for failing the navigation. Reraising." ) raise if recycle: browser().quit( ) # login.current_user() will be retained for next login logger.debug('browser killed on try %d' % _tries) # If given a "start" nav destination, it won't be valid after quitting the browser kwargs.pop("start", None) force_navigate(page_name, _tries, *args, **kwargs)
def recycle(): quit() ensure_browser_open() login_admin()
def refresh(self): ensure_browser_open() sel.click( "//*[contains(@class, 'container_topology')]//button[contains(., 'Refresh')]" ) self._reload()
def reload(self): ensure_browser_open() self._object.load_topology_page() self._reload()
def prerequisite(self): from utils.browser import ensure_browser_open ensure_browser_open()
def force_navigate(page_name, _tries=0, *args, **kwargs): """force_navigate(page_name) Given a page name, attempt to navigate to that page no matter what breaks. Args: page_name: Name a page from the current :py:data:`ui_navigate.nav_tree` tree to navigate to. """ if _tries > 2: # Need at least three tries: # 1: login_admin handles an alert or CannotContinueWithNavigation appears. # 2: Everything should work. If not, NavigationError. raise exceptions.NavigationError(page_name) if "context" in kwargs: if not isinstance(kwargs["context"], ContextWrapper) and isinstance( kwargs["context"], dict): kwargs["context"] = ContextWrapper(kwargs["context"]) _tries += 1 logger.debug('force_navigate to %s, try %d' % (page_name, _tries)) # circular import prevention: cfme.login uses functions in this module from cfme import login # Import the top-level nav menus for convenience from cfme.web_ui import menu # browser fixture should do this, but it's needed for subsequent calls ensure_browser_open() # Clear any running "spinnies" try: execute_script('miqSparkleOff();') except: # Diaper OK (mfalesni) # miqSparkleOff undefined, so it's definitely off. pass # Set this to True in the handlers below to trigger a browser restart recycle = False # remember the current user, if any current_user = login.current_user() # Check if the page is blocked with blocker_div. If yes, let's headshot the browser right here if ( is_displayed("//div[@id='blocker_div' or @id='notification']", _no_deeper=True) or is_displayed(".modal-backdrop.fade.in", _no_deeper=True)): logger.warning("Page was blocked with blocker div on start of navigation, recycling.") quit() kwargs.pop("start", None) force_navigate("dashboard") # Start fresh # Check if jQuery present try: execute_script("jQuery") except Exception as e: if "jQuery" not in str(e): logger.error("Checked for jQuery but got something different.") logger.exception(e) # Restart some workers logger.warning("Restarting UI and VimBroker workers!") with store.current_appliance.ssh_client() as ssh: # Blow off the Vim brokers and UI workers ssh.run_rails_command("\"(MiqVimBrokerWorker.all + MiqUiWorker.all).each &:kill\"") logger.info("Waiting for web UI to come back alive.") sleep(10) # Give it some rest store.current_appliance.wait_for_web_ui() quit() ensure_browser_open() kwargs.pop("start", None) force_navigate("dashboard") # And start fresh # Same with rails errors rails_e = get_rails_error() if rails_e is not None: logger.warning("Page was blocked by rails error, renavigating.") logger.error(rails_e) logger.debug('Top CPU consumers:') logger.debug(store.current_appliance.ssh_client().run_command( 'top -c -b -n1 -M | head -30').output) logger.debug('Top Memory consumers:') logger.debug(store.current_appliance.ssh_client().run_command( 'top -c -b -n1 -M -a | head -30').output) logger.debug('Managed Providers:') logger.debug(store.current_appliance.managed_providers) quit() # Refresh the session, forget loaded summaries, ... kwargs.pop("start", None) ensure_browser_open() menu.nav.go_to("dashboard") # If there is a rails error past this point, something is really awful def _login_func(): if not current_user: # default to admin user login.login_admin() else: # we recycled and want to log back in login.login(current_user.username, current_user.password) try: try: # What we'd like to happen... _login_func() except WebDriverException as e: if "jquery" not in str(e).lower(): raise # Something unknown happened logger.info("Seems we got a non-CFME page (blank or screwed up) so killing the browser") quit() ensure_browser_open() # And try it again _login_func() # If this failed, no help with that :/ logger.info('Navigating to %s' % page_name) menu.nav.go_to(page_name, *args, **kwargs) except (KeyboardInterrupt, ValueError): # KeyboardInterrupt: Don't block this while navigating # ValueError: ui_navigate.go_to can't handle this page, give up raise except UnexpectedAlertPresentException: if _tries == 1: # There was an alert, accept it and try again handle_alert(wait=0) force_navigate(page_name, _tries, *args, **kwargs) else: # There was still an alert when we tried again, shoot the browser in the head logger.debug('Unxpected alert, recycling browser') recycle = True except (ErrorInResponseException, InvalidSwitchToTargetException): # Unable to switch to the browser at all, need to recycle logger.info('Invalid browser state, recycling browser') recycle = True except exceptions.CFMEExceptionOccured as e: # We hit a Rails exception logger.info('CFME Exception occured') logger.exception(e) recycle = True except exceptions.CannotContinueWithNavigation as e: # The some of the navigation steps cannot succeed logger.info('Cannot continue with navigation due to: %s; Recycling browser' % str(e)) recycle = True except (NoSuchElementException, InvalidElementStateException, WebDriverException) as e: from cfme.web_ui import cfme_exception as cfme_exc # To prevent circular imports # First check - if jquery is not found, there can be also another reason why this happened # so do not put the next branches in elif if isinstance(e, WebDriverException) and "jQuery" in str(e): # UI failed in some way, try recycling the browser logger.exception( "UI failed in some way, jQuery not found, (probably) recycling the browser.") recycle = True # If the page is blocked, then recycle... if ( is_displayed("//div[@id='blocker_div' or @id='notification']", _no_deeper=True) or is_displayed(".modal-backdrop.fade.in", _no_deeper=True)): logger.warning("Page was blocked with blocker div, recycling.") recycle = True elif cfme_exc.is_cfme_exception(): logger.exception("CFME Exception before force_navigate started!: `{}`".format( cfme_exc.cfme_exception_text() )) recycle = True elif is_displayed("//body[./h1 and ./p and ./hr and ./address]", _no_deeper=True): # 503 and similar sort of errors title = text("//body/h1") body = text("//body/p") logger.exception("Application error '{}': {}".format(title, body)) sleep(5) # Give it a little bit of rest recycle = True elif is_displayed("//body/div[@class='dialog' and ./h1 and ./p]", _no_deeper=True): # Rails exception detection logger.exception("Rails exception before force_navigate started!: {}:{} at {}".format( text("//body/div[@class='dialog']/h1").encode("utf-8"), text("//body/div[@class='dialog']/p").encode("utf-8"), current_url() )) recycle = True elif elements("//ul[@id='maintab']/li[@class='inactive']") and not\ elements("//ul[@id='maintab']/li[@class='active']/ul/li"): # If upstream and is the bottom part of menu is not displayed logger.exception("Detected glitch from BZ#1112574. HEADSHOT!") recycle = True else: logger.error("Could not determine the reason for failing the navigation. " + " Reraising. Exception: %s" % str(e)) logger.debug(store.current_appliance.ssh_client().run_command( 'service evmserverd status').output) raise if recycle: browser().quit() # login.current_user() will be retained for next login logger.debug('browser killed on try %d' % _tries) # If given a "start" nav destination, it won't be valid after quitting the browser kwargs.pop("start", None) force_navigate(page_name, _tries, *args, **kwargs)
def logged_in(): ensure_browser_open() with sel.ajax_timeout(90): sel.wait_for_ajax( ) # This is called almost everywhere, protects from spinner return sel.is_displayed(dashboard.page.user_dropdown)
def _on_detail_page(self): """ Returns ``True`` if on the providers detail page, ``False`` if not.""" ensure_browser_open() return sel.is_displayed('//div//h1[contains(., "{} (Summary)")]'.format(self.name))
def prerequisite(self): from utils.browser import ensure_browser_open ensure_browser_open(self.obj.appliance.server.address())