def test_0020_config_invalid_value_types(self): # tests for when config file has incorrect value types invalid_values_config1 = yaml_to_dict(ACTIVE_CONFIG_FILEPATH) invalid_values_config1['vcd'] = True invalid_values_config1['vcs'] = 'a' invalid_values_config2 = yaml_to_dict(ACTIVE_CONFIG_FILEPATH) invalid_values_config2['vcd']['username'] = True invalid_values_config2['vcd']['api_version'] = 123 invalid_values_config2['vcd']['port'] = 'a' invalid_values_config3 = yaml_to_dict(ACTIVE_CONFIG_FILEPATH) invalid_values_config3['vcs'][0]['username'] = True invalid_values_config3['vcs'][0]['password'] = 123 invalid_values_config3['vcs'][0]['verify'] = 'a' invalid_values_config4 = yaml_to_dict(ACTIVE_CONFIG_FILEPATH) invalid_values_config4['broker']['templates'][0]['cpu'] = 'a' invalid_values_config4['broker']['templates'][0]['name'] = 123 configs = [ invalid_values_config1, invalid_values_config2, invalid_values_config3, invalid_values_config4 ] for config_dict in configs: dict_to_yaml_file(config_dict, ACTIVE_CONFIG_FILEPATH) try: get_validated_config(ACTIVE_CONFIG_FILEPATH) print(f"{ACTIVE_CONFIG_FILEPATH} passed validation when " f"it should not have") assert False except ValueError: pass
def test_0010_config_invalid_keys(config): """Test that config files with invalid/extra keys don't pass validation.""" bad_key_config1 = testutils.yaml_to_dict(env.ACTIVE_CONFIG_FILEPATH) del bad_key_config1['amqp'] bad_key_config1['extra_section'] = True bad_key_config2 = testutils.yaml_to_dict(env.ACTIVE_CONFIG_FILEPATH) del bad_key_config2['vcs'][0]['username'] bad_key_config2['vcs'][0]['extra_property'] = 'a' bad_key_config3 = testutils.yaml_to_dict(env.ACTIVE_CONFIG_FILEPATH) del bad_key_config3['broker']['templates'][0]['mem'] del bad_key_config3['broker']['templates'][0]['name'] bad_key_config3['broker']['templates'][0]['extra_property'] = 0 configs = [ bad_key_config1, bad_key_config2, bad_key_config3 ] for config in configs: testutils.dict_to_yaml_file(config, env.ACTIVE_CONFIG_FILEPATH) try: get_validated_config(env.ACTIVE_CONFIG_FILEPATH) assert False, f"{env.ACTIVE_CONFIG_FILEPATH} passed validation " \ f"when it should not have" except KeyError: pass
def test_0050_config_invalid_value_types(config): """Test that configs with invalid value types don't pass validation.""" bad_values_config1 = testutils.yaml_to_dict(env.ACTIVE_CONFIG_FILEPATH) bad_values_config1['vcd'] = True bad_values_config1['vcs'] = 'a' bad_values_config2 = testutils.yaml_to_dict(env.ACTIVE_CONFIG_FILEPATH) bad_values_config2['vcd']['username'] = True bad_values_config2['vcd']['api_version'] = 123 bad_values_config2['vcd']['port'] = 'a' bad_values_config3 = testutils.yaml_to_dict(env.ACTIVE_CONFIG_FILEPATH) bad_values_config3['vcs'][0]['username'] = True bad_values_config3['vcs'][0]['password'] = 123 bad_values_config3['vcs'][0]['verify'] = 'a' bad_values_config4 = testutils.yaml_to_dict(env.ACTIVE_CONFIG_FILEPATH) bad_values_config4['broker']['remote_template_cookbook_url'] = 1 configs = [ bad_values_config1, bad_values_config2, bad_values_config3, bad_values_config4 ] for config in configs: testutils.dict_to_yaml_file(config, env.ACTIVE_CONFIG_FILEPATH) try: get_validated_config(env.ACTIVE_CONFIG_FILEPATH, skip_config_decryption=True) assert False, f"{env.ACTIVE_CONFIG_FILEPATH} passed validation " \ f"when it should not have" except TypeError: pass
def test_0010_config_invalid_keys(self): """Tests that config file with invalid/extra keys or invalid value types do not pass config validation. """ # 3 tests for when config file has missing or extra keys invalid_keys_config1 = yaml_to_dict(ACTIVE_CONFIG_FILEPATH) del invalid_keys_config1['amqp'] invalid_keys_config1['extra_section'] = True invalid_keys_config2 = yaml_to_dict(ACTIVE_CONFIG_FILEPATH) del invalid_keys_config2['vcs'][0]['username'] invalid_keys_config2['vcs'][0]['extra_property'] = 'a' invalid_keys_config3 = yaml_to_dict(ACTIVE_CONFIG_FILEPATH) del invalid_keys_config3['broker']['templates'][0]['mem'] del invalid_keys_config3['broker']['templates'][0]['name'] invalid_keys_config3['broker']['templates'][0]['extra_property'] = 0 configs = [ invalid_keys_config1, invalid_keys_config2, invalid_keys_config3 ] for config_dict in configs: dict_to_yaml_file(config_dict, ACTIVE_CONFIG_FILEPATH) try: get_validated_config(ACTIVE_CONFIG_FILEPATH) print(f"{ACTIVE_CONFIG_FILEPATH} passed validation when " f"it should not have") assert False except KeyError: pass
def test_0040_config_missing_keys(config): """Test that config files with missing keys don't pass validation.""" bad_key_config1 = testutils.yaml_to_dict(env.ACTIVE_CONFIG_FILEPATH) del bad_key_config1['mqtt'] bad_key_config2 = testutils.yaml_to_dict(env.ACTIVE_CONFIG_FILEPATH) del bad_key_config2['vcs'][0]['username'] configs = [ bad_key_config1, bad_key_config2 ] for config in configs: testutils.dict_to_yaml_file(config, env.ACTIVE_CONFIG_FILEPATH) PYTEST_LOGGER.debug(f"Validating config: {config}") try: get_validated_config(env.ACTIVE_CONFIG_FILEPATH, skip_config_decryption=True) PYTEST_LOGGER.debug("Validation succeeded when it " "should not have") assert False, f"{env.ACTIVE_CONFIG_FILEPATH} passed validation " \ f"when it should not have" except KeyError as e: PYTEST_LOGGER.debug("Validation failed as expected due " f"to invalid keys: {e}")
def ovdc_disable_test_case(request): test_case: OVDC_DISABLE_TEST_PARAM = request.param # login user config = testutils.yaml_to_dict(env.BASE_CONFIG_FILEPATH) user = test_case.user pwd = test_case.password org_name = test_case.org_name if test_case.user == env.SYS_ADMIN_NAME: user = config['vcd']['username'] pwd = config['vcd']['password'] org_name = 'system' cmd = f"login {config['vcd']['host']} {org_name} " \ f"{user} -iwp {pwd} " \ f"-V {env.VCD_API_VERSION_TO_USE}" env.CLI_RUNNER.invoke(vcd, cmd.split(), catch_exceptions=False) PYTEST_LOGGER.debug(f"Logged in as {test_case.user}") if test_case.enable_before_test: # disable ovdc before test cmd = f"cse ovdc enable --native --org {test_case.org_name} {test_case.ovdc_name}" # noqa: E501 env.CLI_RUNNER.invoke(vcd, cmd.split(), catch_exceptions=True) yield test_case # logout env.CLI_RUNNER.invoke(vcd, ['logout']) PYTEST_LOGGER.debug(f"Logged out as {test_case.user}")
def vcd_cluster_admin(): """Fixture to ensure that we are logged in to vcd-cli as cluster admin. Usage: add the parameter 'vcd_cluster_admin' to the test function. User will have the credentials specified in 'system_test_framework/environment.py' Do not use this fixture with the other vcd_role fixtures, as only one user can be logged in at a time. """ config = testutils.yaml_to_dict(env.BASE_CONFIG_FILEPATH) cmd = f"login {config['vcd']['host']} {env.TEST_ORG} " \ f"{env.CLUSTER_ADMIN_NAME} -iwp {env.CLUSTER_ADMIN_PASSWORD} " \ f"-V {env.VCD_API_VERSION_TO_USE}" result = env.CLI_RUNNER.invoke(vcd, cmd.split(), catch_exceptions=False) assert result.exit_code == 0, \ testutils.format_command_info('vcd', cmd, result.exit_code, result.output) # ovdc context may be nondeterministic when there's multiple ovdcs cmd = f"vdc use {env.TEST_VDC}" result = env.CLI_RUNNER.invoke(vcd, cmd.split(), catch_exceptions=False) assert result.exit_code == 0,\ testutils.format_command_info('vcd', cmd, result.exit_code, result.output) PYTEST_LOGGER.debug(f"Logged in as {env.CLUSTER_ADMIN_NAME}") yield result = env.CLI_RUNNER.invoke(vcd, ['logout']) PYTEST_LOGGER.debug(f"Logged out as {env.CLUSTER_ADMIN_NAME}")
def setUp(self): """Runs before each test method. Tasks: - Create a new active config and file from base config file. - Reset VCD AMQP settings. - Unregister CSE from VCD. - Blank out customization scripts. """ self._config = yaml_to_dict(BASE_CONFIG_FILEPATH) dict_to_yaml_file(self._config, ACTIVE_CONFIG_FILEPATH) os.chmod(ACTIVE_CONFIG_FILEPATH, 0o600) configure_vcd_amqp(self._client, self._default_amqp_settings['AmqpExchange'], self._default_amqp_settings['AmqpHost'], self._default_amqp_settings['AmqpPort'], self._default_amqp_settings['AmqpPrefix'], self._default_amqp_settings['AmqpSslAcceptAll'], self._default_amqp_settings['AmqpUseSSL'], self._default_amqp_settings['AmqpVHost'], self._amqp_username, self._amqp_password, quiet=True) try: self._api_extension.delete_extension(CSE_NAME, CSE_NAMESPACE) except MissingRecordException: pass restore_customizaton_scripts()
def init_environment(config_filepath=BASE_CONFIG_FILEPATH): """Set up module variables according to config dict. :param str config_filepath: """ global AMQP_USERNAME, AMQP_PASSWORD, CLIENT, ORG_HREF, VDC_HREF, \ CATALOG_NAME, DEV_MODE config = testutils.yaml_to_dict(config_filepath) CLIENT = Client(config['vcd']['host'], api_version=config['vcd']['api_version'], verify_ssl_certs=config['vcd']['verify']) credentials = BasicLoginCredentials(config['vcd']['username'], utils.SYSTEM_ORG_NAME, config['vcd']['password']) CLIENT.set_credentials(credentials) org = utils.get_org(CLIENT, org_name=config['broker']['org']) vdc = utils.get_vdc(CLIENT, config['broker']['vdc'], org=org) ORG_HREF = org.href VDC_HREF = vdc.href CATALOG_NAME = config['broker']['catalog'] AMQP_USERNAME = config['amqp']['username'] AMQP_PASSWORD = config['amqp']['password'] try: DEV_MODE = config['test']['developer_mode'] except KeyError: pass
def init_environment(config_filepath=BASE_CONFIG_FILEPATH): """Set up module variables according to config dict. :param str config_filepath: """ global AMQP_USERNAME, AMQP_PASSWORD, CLIENT, ORG_HREF, VDC_HREF, \ CATALOG_NAME, TEARDOWN_INSTALLATION, TEARDOWN_CLUSTERS, \ TEMPLATE_DEFINITIONS, TEST_ALL_TEMPLATES, SYS_ADMIN_LOGIN_CMD, \ ORG_ADMIN_LOGIN_CMD, VAPP_AUTHOR_LOGIN_CMD, USER_LOGIN_CMD_MAP config = testutils.yaml_to_dict(config_filepath) rtm = RemoteTemplateManager( config['broker']['remote_template_cookbook_url']) template_cookbook = rtm.get_remote_template_cookbook() TEMPLATE_DEFINITIONS = template_cookbook['templates'] rtm.download_all_template_scripts(force_overwrite=True) CLIENT = Client(config['vcd']['host'], api_version=config['vcd']['api_version'], verify_ssl_certs=config['vcd']['verify']) credentials = BasicLoginCredentials(config['vcd']['username'], SYSTEM_ORG_NAME, config['vcd']['password']) CLIENT.set_credentials(credentials) org = pyvcloud_utils.get_org(CLIENT, org_name=config['broker']['org']) vdc = pyvcloud_utils.get_vdc(CLIENT, vdc_name=config['broker']['vdc'], org=org) ORG_HREF = org.href VDC_HREF = vdc.href CATALOG_NAME = config['broker']['catalog'] AMQP_USERNAME = config['amqp']['username'] AMQP_PASSWORD = config['amqp']['password'] SYS_ADMIN_LOGIN_CMD = f"login {config['vcd']['host']} system " \ f"{config['vcd']['username']} " \ f"-iwp {config['vcd']['password']} " \ f"-V {config['vcd']['api_version']}" ORG_ADMIN_LOGIN_CMD = f"login {config['vcd']['host']} " \ f"{config['broker']['org']}" \ f" {ORG_ADMIN_NAME} -iwp {ORG_ADMIN_PASSWORD} " \ f"-V {config['vcd']['api_version']}" VAPP_AUTHOR_LOGIN_CMD = f"login {config['vcd']['host']} " \ f"{config['broker']['org']} " \ f"{VAPP_AUTHOR_NAME} -iwp {VAPP_AUTHOR_PASSWORD}" \ f" -V {config['vcd']['api_version']}" USER_LOGIN_CMD_MAP = { 'sys_admin': SYS_ADMIN_LOGIN_CMD, 'org_admin': ORG_ADMIN_LOGIN_CMD, 'vapp_author': VAPP_AUTHOR_LOGIN_CMD } test_config = config.get('test') if test_config is not None: TEARDOWN_INSTALLATION = test_config.get('teardown_installation', True) TEARDOWN_CLUSTERS = test_config.get('teardown_clusters', True) TEST_ALL_TEMPLATES = test_config.get('test_all_templates', False)
def vcd_sys_admin(): """Fixture to ensure that we are logged in to vcd-cli as sys admin. Usage: add the parameter 'vcd_sys_admin' to the test function. User will have the credentials specified in 'system_tests/base_config.yaml' Do not use this fixture with the other vcd_role fixtures, as only one user can be logged in at a time. """ config = testutils.yaml_to_dict(env.BASE_CONFIG_FILEPATH) cmd = f"login {config['vcd']['host']} system " \ f"{config['vcd']['username']} -iwp {config['vcd']['password']} " \ f"-V {config['vcd']['api_version']}" result = env.CLI_RUNNER.invoke(vcd, cmd.split(), catch_exceptions=False) assert result.exit_code == 0,\ testutils.format_command_info('vcd', cmd, result.exit_code, result.output) cmd = f"org use {config['broker']['org']}" result = env.CLI_RUNNER.invoke(vcd, cmd.split(), catch_exceptions=False) assert result.exit_code == 0,\ testutils.format_command_info('vcd', cmd, result.exit_code, result.output) # ovdc context may be nondeterministic when there's multiple ovdcs cmd = f"vdc use {config['broker']['vdc']}" result = env.CLI_RUNNER.invoke(vcd, cmd.split(), catch_exceptions=False) assert result.exit_code == 0,\ testutils.format_command_info('vcd', cmd, result.exit_code, result.output) yield result = env.CLI_RUNNER.invoke(vcd, ['logout'])
def vcd_vapp_author(): """Fixture to ensure that we are logged in to vcd-cli as vapp author. Usage: add the parameter 'vcd_vapp_author' to the test function. User will have the credentials specified in 'system_test_framework/environment.py' Do not use this fixture with the other vcd_role fixtures, as only one user can be logged in at a time. """ config = testutils.yaml_to_dict(env.BASE_CONFIG_FILEPATH) cmd = f"login {config['vcd']['host']} {config['broker']['org']} " \ f"{env.VAPP_AUTHOR_NAME} -iwp {env.VAPP_AUTHOR_PASSWORD}" result = env.CLI_RUNNER.invoke(vcd, cmd.split(), catch_exceptions=False) assert result.exit_code == 0,\ testutils.format_command_info('vcd', cmd, result.exit_code, result.output) # ovdc context may be nondeterministic when there's multiple ovdcs cmd = f"vdc use {config['broker']['vdc']}" result = env.CLI_RUNNER.invoke(vcd, cmd.split(), catch_exceptions=False) assert result.exit_code == 0,\ testutils.format_command_info('vcd', cmd, result.exit_code, result.output) yield result = env.CLI_RUNNER.invoke(vcd, ['logout']) assert result.exit_code == 0,\ testutils.format_command_info('vcd', cmd, result.exit_code, result.output)
def vcd_org_admin(): """Fixture to ensure that we are logged in to vcd-cli as org admin. Usage: add the parameter 'vcd_org_admin' to the test function. vCD instance must have an org admin user in the specified org with username and password identical to those described in config['vcd']. Do not use this fixture with 'vcd_org_admin' fixture, as a user cannot be logged in as both sys admin and org admin. """ config = testutils.yaml_to_dict(env.BASE_CONFIG_FILEPATH) result = env.CLI_RUNNER.invoke(vcd, ['login', config['vcd']['host'], config['broker']['org'], config['vcd']['username'], '-iwp', config['vcd']['password']], catch_exceptions=False) assert result.exit_code == 0 yield result = env.CLI_RUNNER.invoke(vcd, ['logout']) assert result.exit_code == 0
def delete_installation_entities(): """Fixture to ensure that CSE entities do not exist in vCD. This fixture executes automatically for this module's setup and teardown. Setup tasks: - Delete source ova files, vapp templates, temp vapps, catalogs - Unregister CSE from vCD Teardown tasks (only if config key 'teardown_installation'=True): - Delete source ova files, vapp templates, temp vapps, catalogs - Unregister CSE from vCD """ config = testutils.yaml_to_dict(env.BASE_CONFIG_FILEPATH) for template in config['broker']['templates']: env.delete_catalog_item(template['source_ova_name']) env.delete_catalog_item(template['catalog_item']) env.delete_vapp(template['temp_vapp']) env.delete_catalog() env.unregister_cse() yield if env.TEARDOWN_INSTALLATION: for template in config['broker']['templates']: env.delete_catalog_item(template['source_ova_name']) env.delete_catalog_item(template['catalog_item']) env.delete_vapp(template['temp_vapp']) env.delete_catalog() env.unregister_cse()
def init_environment(config_filepath=BASE_CONFIG_FILEPATH): """Set up module variables according to config dict. :param str config_filepath: """ global AMQP_USERNAME, AMQP_PASSWORD, CLIENT, ORG_HREF, VDC_HREF, \ CATALOG_NAME, TEARDOWN_INSTALLATION, TEARDOWN_CLUSTERS, \ TEST_ALL_TEMPLATES config = testutils.yaml_to_dict(config_filepath) CLIENT = Client(config['vcd']['host'], api_version=config['vcd']['api_version'], verify_ssl_certs=config['vcd']['verify']) credentials = BasicLoginCredentials(config['vcd']['username'], utils.SYSTEM_ORG_NAME, config['vcd']['password']) CLIENT.set_credentials(credentials) org = utils.get_org(CLIENT, org_name=config['broker']['org']) vdc = utils.get_vdc(CLIENT, config['broker']['vdc'], org=org) ORG_HREF = org.href VDC_HREF = vdc.href CATALOG_NAME = config['broker']['catalog'] AMQP_USERNAME = config['amqp']['username'] AMQP_PASSWORD = config['amqp']['password'] test_config = config.get('test') if test_config is not None: TEARDOWN_INSTALLATION = test_config.get('teardown_installation', True) TEARDOWN_CLUSTERS = test_config.get('teardown_clusters', True) TEST_ALL_TEMPLATES = test_config.get('test_all_templates', False)
def setUpClass(cls): """Runs once for this class, before all test methods. Tasks: - Initialize client, config, and other attributes. - Restore VCD AMQP settings to defaults. - Delete any pre-existing CSE entities. """ cls._config = yaml_to_dict(BASE_CONFIG_FILEPATH) cls._client = Client(cls._config['vcd']['host'], api_version=cls._config['vcd']['api_version'], verify_ssl_certs=cls._config['vcd']['verify']) credentials = BasicLoginCredentials(cls._config['vcd']['username'], SYSTEM_ORG_NAME, cls._config['vcd']['password']) cls._client.set_credentials(credentials) assert cls._client is not None cls._org = get_org(cls._client, org_name=cls._config['broker']['org']) assert cls._org is not None cls._vdc = get_vdc(cls._client, cls._config['broker']['vdc'], org=cls._org) assert cls._vdc is not None cls._api_extension = APIExtension(cls._client) assert cls._api_extension is not None cls._amqp_service = AmqpService(cls._client) assert cls._amqp_service is not None cls._runner = CliRunner() assert cls._runner is not None cls._ssh_key_filepath = f"{Path.home() / '.ssh' / 'id_rsa.pub'}" configure_vcd_amqp(cls._client, 'vcdext', cls._config['amqp']['host'], cls._config['amqp']['port'], 'vcd', cls._config['amqp']['ssl_accept_all'], cls._config['amqp']['ssl'], '/', cls._config['amqp']['username'], cls._config['amqp']['password'], quiet=True) cls._default_amqp_settings = to_dict(cls._amqp_service.get_settings()) assert cls._default_amqp_settings is not None cls._amqp_username = cls._config['amqp']['username'] assert cls._amqp_username is not None cls._amqp_password = cls._config['amqp']['password'] assert cls._amqp_password is not None CSEServerInstallationTest.delete_cse_entities()
def test_0040_config_missing_keys(config): """Test that config files with missing keys don't pass validation.""" bad_key_config1 = testutils.yaml_to_dict(env.ACTIVE_CONFIG_FILEPATH) del bad_key_config1['amqp'] bad_key_config2 = testutils.yaml_to_dict(env.ACTIVE_CONFIG_FILEPATH) del bad_key_config2['vcs'][0]['username'] configs = [bad_key_config1, bad_key_config2] for config in configs: testutils.dict_to_yaml_file(config, env.ACTIVE_CONFIG_FILEPATH) try: get_validated_config(env.ACTIVE_CONFIG_FILEPATH) assert False, f"{env.ACTIVE_CONFIG_FILEPATH} passed validation " \ f"when it should not have" except KeyError: pass
def cse_server(): """Fixture to ensure that CSE is installed and running before client tests. This fixture executes automatically for this module's setup and teardown. Setup tasks: - If templates do not exist, install CSE using `--upgrade` - Run `cse install` to ensure that CSE is registered and AMQP exchange exists. - Run CSE server as a subprocess Teardown tasks: - Stop CSE server """ config = testutils.yaml_to_dict(env.BASE_CONFIG_FILEPATH) install_cmd = ['install', '--config', env.ACTIVE_CONFIG_FILEPATH, '--ssh-key', env.SSH_KEY_FILEPATH] for template in config['broker']['templates']: if not env.catalog_item_exists(template['catalog_item']): install_cmd.append('--update') break env.setup_active_config() result = env.CLI_RUNNER.invoke(cli, install_cmd, input='y', catch_exceptions=False) assert result.exit_code == 0 # start cse server as subprocess cmd = f"cse run -c {env.ACTIVE_CONFIG_FILEPATH}" p = subprocess.Popen(cmd.split(), stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT) time.sleep(env.WAIT_INTERVAL) # server takes a little time to set up # enable kubernetes functionality on our ovdc # by default, an ovdc cannot deploy kubernetes clusters # TODO() this should be removed once this behavior is changed cmd = f"login {config['vcd']['host']} {utils.SYSTEM_ORG_NAME} " \ f"{config['vcd']['username']} -iwp {config['vcd']['password']}" result = env.CLI_RUNNER.invoke(vcd, cmd.split(), catch_exceptions=False) assert result.exit_code == 0 cmd = f"org use {config['broker']['org']}" result = env.CLI_RUNNER.invoke(vcd, cmd.split(), catch_exceptions=False) assert result.exit_code == 0 cmd = f"cse ovdc enablek8s {config['broker']['vdc']} -c vcd" result = env.CLI_RUNNER.invoke(vcd, cmd.split(), catch_exceptions=False) assert result.exit_code == 0 result = env.CLI_RUNNER.invoke(vcd, 'logout', catch_exceptions=False) yield # terminate cse server subprocess try: p.terminate() except OSError: pass
def create_user(username, password, role): config = testutils.yaml_to_dict(BASE_CONFIG_FILEPATH) cmd = f"login {config['vcd']['host']} {SYSTEM_ORG_NAME} " \ f"{config['vcd']['username']} -iwp {config['vcd']['password']} " \ f"-V {config['vcd']['api_version']}" result = CLI_RUNNER.invoke(vcd, cmd.split(), catch_exceptions=False) assert result.exit_code == 0 cmd = f"org use {config['broker']['org']}" result = CLI_RUNNER.invoke(vcd, cmd.split(), catch_exceptions=False) assert result.exit_code == 0 # cannot use cmd.split() here because the role name # "Organization Administrator" gets split into 2 arguments result = CLI_RUNNER.invoke( vcd, ['user', 'create', username, password, role, '--enabled'], catch_exceptions=False)
def setup_active_config(): """Set up the active config file from BASE_CONFIG_FILEPATH. 'test' section is removed if it exists in base config, active config is created at ACTIVE_CONFIG_FILEPATH. :returns: config dict without 'test' key :rtype: dict """ config = testutils.yaml_to_dict(BASE_CONFIG_FILEPATH) if 'test' in config: del config['test'] testutils.dict_to_yaml_file(config, ACTIVE_CONFIG_FILEPATH) os.chmod(ACTIVE_CONFIG_FILEPATH, 0o600) return config
def vcd_sys_admin(): """Fixture to ensure that we are logged in to vcd-cli as sys admin. Usage: add the parameter 'vcd_sys_admin' to the test function. Do not use both `vcd_sys_admin` and `vcd_org_admin` fixtures in the same function. """ config = testutils.yaml_to_dict(env.BASE_CONFIG_FILEPATH) result = env.CLI_RUNNER.invoke(vcd, [ 'login', config['vcd']['host'], utils.SYSTEM_ORG_NAME, config['vcd']['username'], '-iwp', config['vcd']['password'] ], catch_exceptions=False) assert result.exit_code == 0 yield result = env.CLI_RUNNER.invoke(vcd, ['logout']) assert result.exit_code == 0
def system_toggle_test_case(request): param: SYSTEM_TOGGLE_TEST_PARAM = request.param # login as sysadmin config = testutils.yaml_to_dict(env.BASE_CONFIG_FILEPATH) user = param.user user = config['vcd']['username'] pwd = config['vcd']['password'] org_name = 'system' cmd = f"login {config['vcd']['host']} {org_name} " \ f"{user} -iwp {pwd} " \ f"-V {env.VCD_API_VERSION_TO_USE}" result = env.CLI_RUNNER.invoke(vcd, cmd.split(), catch_exceptions=False) PYTEST_LOGGER.debug(f"Executing command: {cmd}") PYTEST_LOGGER.debug(f"Exit code: {result.exit_code}") PYTEST_LOGGER.debug(f"Output: {result.output}") PYTEST_LOGGER.debug(f"Logged in as {user}") cleanup_cluster_artifacts() # create apply specification spec_params = { 'worker_count': param.worker_count, 'nfs_count': param.nfs_count, 'rollback': param.rollback, 'template_name': param.template_name, 'template_revision': param.template_revision, 'network': param.ovdc_network, 'sizing_class': param.sizing_class, 'storage_profile': param.storage_profile, 'cluster_name': param.cluster_name } create_apply_spec(spec_params) yield param cleanup_cluster_artifacts() # logout env.CLI_RUNNER.invoke(vcd, ['logout']) PYTEST_LOGGER.debug(f"Logged out as {user}")
def cse_server(): """Fixture to ensure that CSE is installed before client tests. This function will execute once for this module. Setup tasks: - If templates do not exist, install CSE using `--upgrade` - If CSE is not registered properly, install CSE normally """ config = testutils.yaml_to_dict(env.BASE_CONFIG_FILEPATH) install_cmd = [ 'install', '--config', env.ACTIVE_CONFIG_FILEPATH, '--ssh-key', env.SSH_KEY_FILEPATH ] installation_exists = True for template in config['broker']['templates']: if not env.catalog_item_exists(template['catalog_item']): installation_exists = False install_cmd.append('--update') break env.setup_active_config() if not installation_exists \ or not env.is_cse_registration_valid(config['amqp']['routing_key'], config['amqp']['exchange']): result = env.CLI_RUNNER.invoke(cli, install_cmd, input='y', catch_exceptions=False) assert result.exit_code == 0 # start cse server as subprocess cmd = f"cse run -c {env.ACTIVE_CONFIG_FILEPATH}" p = subprocess.Popen(cmd.split(), stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT) time.sleep(10) yield # terminate cse server subprocess p.terminate()
def create_user(username, password, role, logger=NULL_LOGGER): config = testutils.yaml_to_dict(BASE_CONFIG_FILEPATH) cmd = f"login {config['vcd']['host']} " \ f"{shared_constants.SYSTEM_ORG_NAME} " \ f"{config['vcd']['username']} -iwp {config['vcd']['password']} " \ f"-V {VCD_API_VERSION_TO_USE}" result = CLI_RUNNER.invoke(vcd, cmd.split(), catch_exceptions=False) assert result.exit_code == 0 cmd = f"org use {TEST_ORG}" result = CLI_RUNNER.invoke(vcd, cmd.split(), catch_exceptions=False) assert result.exit_code == 0 # cannot use cmd.split() here because the role name # "Organization Administrator" gets split into 2 arguments CLI_RUNNER.invoke( vcd, ['user', 'create', username, password, role, '--enabled'], catch_exceptions=False) # no assert here because if the user exists, the exit code will be 2 logger.debug(f"Successfully created user {username}")
def ovdc_enable_test_case(request): test_case: OVDC_ENABLE_TEST_PARAM = request.param # login user config = testutils.yaml_to_dict(env.BASE_CONFIG_FILEPATH) pwd = test_case.password user = test_case.user org_name = test_case.org_name if test_case.user == env.SYS_ADMIN_NAME: user = config['vcd']['username'] pwd = config['vcd']['password'] org_name = 'system' cmd = f"login {config['vcd']['host']} {org_name} " \ f"{user} -iwp {pwd} " \ f"-V {env.VCD_API_VERSION_TO_USE}" result = env.CLI_RUNNER.invoke(vcd, cmd.split(), catch_exceptions=False) PYTEST_LOGGER.debug(f"Executing command: {cmd}") PYTEST_LOGGER.debug(f"Exit code: {result.exit_code}") PYTEST_LOGGER.debug(f"Output: {result.output}") PYTEST_LOGGER.debug(f"Logged in as {test_case.user}") assert result.exit_code == 0, \ testutils.format_command_info('vcd', cmd, result.exit_code, result.output) if test_case.disable_before_test: # disable ovdc before test cmd = f"cse ovdc disable --native --org {test_case.org_name} {test_case.ovdc_name} --force" # noqa: E501 env.CLI_RUNNER.invoke(vcd, cmd.split(), catch_exceptions=True) yield test_case # disable ovdc after test cmd = f"cse ovdc disable --native --org {test_case.org_name} {test_case.ovdc_name} --force" # noqa: E501 env.CLI_RUNNER.invoke(vcd, cmd.split(), catch_exceptions=True) # logout env.CLI_RUNNER.invoke(vcd, ['logout']) PYTEST_LOGGER.debug(f"Logged out as {test_case.user}")
def create_user(username, password, role): config = testutils.yaml_to_dict(BASE_CONFIG_FILEPATH) cmd = f"login {config['vcd']['host']} {SYSTEM_ORG_NAME} " \ f"{config['vcd']['username']} -iwp {config['vcd']['password']}" result = CLI_RUNNER.invoke(vcd, cmd.split(), catch_exceptions=False) assert result.exit_code == 0 cmd = f"org use {config['broker']['org']}" result = CLI_RUNNER.invoke(vcd, cmd.split(), catch_exceptions=False) assert result.exit_code == 0 # cannot use cmd.split() here because the role name # "Organization Administrator" gets split into 2 arguments result = CLI_RUNNER.invoke( vcd, ['user', 'create', username, password, role, '--enabled'], catch_exceptions=False) # no assert here because if the user exists, the exit code will be 2 # user can already exist but be disabled cmd = f"user update {username} --enable" result = CLI_RUNNER.invoke(vcd, cmd.split(), catch_exceptions=False) assert result.exit_code == 0,\ testutils.format_command_info('vcd', cmd, result.exit_code, result.output)
def delete_installation_entities(): """Fixture to ensure that CSE entities do not exist in vCD. This fixture executes automatically for test module setup and teardown If 'developer_mode_aware' is enabled, then the teardown deletion will not occur. """ config = testutils.yaml_to_dict(env.BASE_CONFIG_FILEPATH) for template in config['broker']['templates']: env.delete_catalog_item(template['source_ova_name']) env.delete_catalog_item(template['catalog_item']) env.delete_vapp(template['temp_vapp']) env.delete_catalog() env.unregister_cse() yield if not env.DEV_MODE: for template in config['broker']['templates']: env.delete_catalog_item(template['source_ova_name']) env.delete_catalog_item(template['catalog_item']) env.delete_vapp(template['temp_vapp']) env.delete_catalog() env.unregister_cse()
def init_environment(config_filepath=BASE_CONFIG_FILEPATH): """Set up module variables according to config dict. :param str config_filepath: """ global AMQP_USERNAME, AMQP_PASSWORD, CLIENT, ORG_HREF, VDC_HREF, \ CATALOG_NAME, TEARDOWN_INSTALLATION, TEARDOWN_CLUSTERS, \ TEMPLATE_DEFINITIONS, TEST_ALL_TEMPLATES, SYS_ADMIN_LOGIN_CMD, \ ORG_ADMIN_LOGIN_CMD, K8_AUTHOR_LOGIN_CMD, USERNAME_TO_LOGIN_CMD, \ USERNAME_TO_CLUSTER_NAME, TEST_ORG_HREF, TEST_VDC_HREF, \ VCD_API_VERSION_TO_USE, TEMPLATE_COOKBOOK_VERSION config = testutils.yaml_to_dict(config_filepath) rtm = \ RemoteTemplateManager(config['broker']['remote_template_cookbook_url'], legacy_mode=config['service']['legacy_mode']) template_cookbook = rtm.get_filtered_remote_template_cookbook() TEMPLATE_COOKBOOK_VERSION = rtm.cookbook_version TEMPLATE_DEFINITIONS = template_cookbook['templates'] rtm.download_all_template_scripts(force_overwrite=True) CLIENT = Client(config['vcd']['host'], api_version=config['vcd']['api_version'], verify_ssl_certs=config['vcd']['verify']) credentials = BasicLoginCredentials(config['vcd']['username'], shared_constants.SYSTEM_ORG_NAME, config['vcd']['password']) CLIENT.set_credentials(credentials) VCD_API_VERSION_TO_USE = config['vcd']['api_version'] CATALOG_NAME = config['broker']['catalog'] AMQP_USERNAME = config['amqp']['username'] AMQP_PASSWORD = config['amqp']['password'] SYS_ADMIN_LOGIN_CMD = f"login {config['vcd']['host']} system " \ f"{config['vcd']['username']} " \ f"-iwp {config['vcd']['password']} " \ f"-V {VCD_API_VERSION_TO_USE}" ORG_ADMIN_LOGIN_CMD = f"login {config['vcd']['host']} " \ f"{TEST_ORG}" \ f" {ORG_ADMIN_NAME} -iwp {ORG_ADMIN_PASSWORD} " \ f"-V {VCD_API_VERSION_TO_USE}" K8_AUTHOR_LOGIN_CMD = f"login {config['vcd']['host']} " \ f"{TEST_ORG} " \ f"{K8_AUTHOR_NAME} -iwp {K8_AUTHOR_PASSWORD}" \ f" -V {VCD_API_VERSION_TO_USE}" USERNAME_TO_LOGIN_CMD = { 'sys_admin': SYS_ADMIN_LOGIN_CMD, 'org_admin': ORG_ADMIN_LOGIN_CMD, 'k8_author': K8_AUTHOR_LOGIN_CMD } USERNAME_TO_CLUSTER_NAME = { 'sys_admin': SYS_ADMIN_TEST_CLUSTER_NAME, 'org_admin': ORG_ADMIN_TEST_CLUSTER_NAME, 'k8_author': K8_AUTHOR_TEST_CLUSTER_NAME } # hrefs for Org and VDC that hosts the catalog org = pyvcloud_utils.get_org(CLIENT, org_name=config['broker']['org']) vdc = pyvcloud_utils.get_vdc(CLIENT, vdc_name=config['broker']['vdc'], org=org) ORG_HREF = org.href VDC_HREF = vdc.href # hrefs for Org and VDC that tests cluster operations test_org = pyvcloud_utils.get_org(CLIENT, org_name=TEST_ORG) test_vdc = pyvcloud_utils.get_vdc(CLIENT, vdc_name=TEST_VDC, org=test_org) TEST_ORG_HREF = test_org.href TEST_VDC_HREF = test_vdc.href create_k8_author_role(config['vcd'])
def init_rde_environment(config_filepath=BASE_CONFIG_FILEPATH, logger=NULL_LOGGER): # noqa: E501 """Set up module variables according to config dict. :param str config_filepath: :param logging.Logger logger: """ global CLIENT, ORG_HREF, VDC_HREF, \ CATALOG_NAME, TEARDOWN_INSTALLATION, TEARDOWN_CLUSTERS, \ TEST_ALL_TEMPLATES, SYS_ADMIN_LOGIN_CMD, \ CLUSTER_ADMIN_LOGIN_CMD, CLUSTER_AUTHOR_LOGIN_CMD, \ USERNAME_TO_LOGIN_CMD, USERNAME_TO_CLUSTER_NAME, TEST_ORG_HREF, \ TEST_VDC_HREF, VCD_API_VERSION_TO_USE, VCD_SITE logger.debug("Setting RDE environement") config = testutils.yaml_to_dict(config_filepath) logger.debug(f"Config file used: {config}") sysadmin_client = Client(config['vcd']['host'], verify_ssl_certs=config['vcd']['verify']) sysadmin_client.set_credentials( BasicLoginCredentials(config['vcd']['username'], shared_constants.SYSTEM_ORG_NAME, config['vcd']['password'])) vcd_supported_api_versions = \ set(sysadmin_client.get_supported_versions_list()) cse_supported_api_versions = set( shared_constants.SUPPORTED_VCD_API_VERSIONS) # noqa: E501 common_supported_api_versions = \ list(cse_supported_api_versions.intersection(vcd_supported_api_versions)) # noqa: E501 common_supported_api_versions.sort() max_api_version = get_max_api_version(common_supported_api_versions) CLIENT = Client(config['vcd']['host'], api_version=max_api_version, verify_ssl_certs=config['vcd']['verify']) credentials = BasicLoginCredentials(config['vcd']['username'], shared_constants.SYSTEM_ORG_NAME, config['vcd']['password']) CLIENT.set_credentials(credentials) VCD_API_VERSION_TO_USE = max_api_version logger.debug(f"Using VCD api version: {VCD_API_VERSION_TO_USE}") CATALOG_NAME = config['broker']['catalog'] VCD_SITE = f"https://{config['vcd']['host']}" SYS_ADMIN_LOGIN_CMD = f"login {config['vcd']['host']} system " \ f"{config['vcd']['username']} " \ f"-iwp {config['vcd']['password']} " \ f"-V {VCD_API_VERSION_TO_USE}" CLUSTER_ADMIN_LOGIN_CMD = f"login {config['vcd']['host']} " \ f"{TEST_ORG}" \ f" {CLUSTER_ADMIN_NAME} " \ f"-iwp {CLUSTER_ADMIN_PASSWORD} " \ f"-V {VCD_API_VERSION_TO_USE}" CLUSTER_AUTHOR_LOGIN_CMD = f"login {config['vcd']['host']} " \ f"{TEST_ORG}" \ f" {CLUSTER_AUTHOR_NAME} " \ f"-iwp {CLUSTER_AUTHOR_PASSWORD} " \ f"-V {VCD_API_VERSION_TO_USE}" USERNAME_TO_LOGIN_CMD = { SYS_ADMIN_NAME: SYS_ADMIN_LOGIN_CMD, CLUSTER_ADMIN_NAME: CLUSTER_ADMIN_LOGIN_CMD, CLUSTER_AUTHOR_NAME: CLUSTER_AUTHOR_LOGIN_CMD } # hrefs for Org and VDC that hosts the catalog org = pyvcloud_utils.get_org(CLIENT, org_name=config['broker']['org']) vdc = pyvcloud_utils.get_vdc(CLIENT, vdc_name=config['broker']['vdc'], org=org) ORG_HREF = org.href VDC_HREF = vdc.href logger.debug(f"Using template org {org.get_name()} with href {ORG_HREF}") logger.debug(f"Using template vdc {vdc.name} with href {VDC_HREF}") # hrefs for Org and VDC that tests cluster operations test_org = pyvcloud_utils.get_org(CLIENT, org_name=TEST_ORG) test_vdc = pyvcloud_utils.get_vdc(CLIENT, vdc_name=TEST_VDC, org=test_org) TEST_ORG_HREF = test_org.href TEST_VDC_HREF = test_vdc.href logger.debug(f"Using test org {test_org.get_name()} " f"with href {TEST_ORG_HREF}") logger.debug(f"Using test vdc {test_vdc.name} with href {TEST_VDC_HREF}") if SHOULD_INSTALL_PREREQUISITES: create_cluster_admin_role(config['vcd'], logger=logger) create_cluster_author_role(config['vcd'], logger=logger) # create and publish sizing class sc1 to TEST_VDC cpm = ComputePolicyManager(sysadmin_client=sysadmin_client, log_wire=True) created_policy = None try: created_policy = cpm.add_vdc_compute_policy( SIZING_CLASS_NAME, description=SIZING_CLASS_DESCRIPTION, cpu_count=2, memory_mb=2048) except HTTPError as err: if 'already exists' in err.response.text: logger.debug( f"Compute policy {SIZING_CLASS_NAME} already exists" ) # noqa: E501 created_policy = cpm.get_vdc_compute_policy(SIZING_CLASS_NAME) else: logger.error( f"Request to create sizing policy {SIZING_CLASS_NAME} failed." ) # noqa: E501 raise try: cpm.add_compute_policy_to_vdc( pyvcloud_utils.extract_id( test_vdc.get_resource_admin().get('id')), # noqa: E501 created_policy['id']) except Exception as err: logger.error( f"Error publishing sizing policy {SIZING_CLASS_NAME} to vdc {TEST_VDC}: {err}" ) # noqa: E501 create_cluster_admin_role(config['vcd'], logger=logger) create_cluster_author_role(config['vcd'], logger=logger)
template_def['name'], int(template_def['revision'])): # noqa: E501 specified_templates_def.append(template_def) break TEMPLATE_DEFINITIONS = specified_templates_def SHOULD_INSTALL_PREREQUISITES = \ test_config.get('should_install_prerequisites', True) IS_CSE_SERVER_RUNNING = test_config.get('is_cse_server_running', False) TEST_CLUSTER_UPGRADES = \ test_config.get('test_cluster_upgrades', False) if TEST_CLUSTER_UPGRADES: _populate_template_upgrade_paths(config, logger=NULL_LOGGER) _init_test_vars(testutils.yaml_to_dict(BASE_CONFIG_FILEPATH)) def init_rde_environment(config_filepath=BASE_CONFIG_FILEPATH, logger=NULL_LOGGER): # noqa: E501 """Set up module variables according to config dict. :param str config_filepath: :param logging.Logger logger: """ global CLIENT, ORG_HREF, VDC_HREF, \ CATALOG_NAME, TEARDOWN_INSTALLATION, TEARDOWN_CLUSTERS, \ TEST_ALL_TEMPLATES, SYS_ADMIN_LOGIN_CMD, \ CLUSTER_ADMIN_LOGIN_CMD, CLUSTER_AUTHOR_LOGIN_CMD, \ USERNAME_TO_LOGIN_CMD, USERNAME_TO_CLUSTER_NAME, TEST_ORG_HREF, \ TEST_VDC_HREF, VCD_API_VERSION_TO_USE, VCD_SITE