def test_load_versioned_actions(self): parser = novaclient.shell.NovaClientArgumentParser() subparsers = parser.add_subparsers(metavar='<subcommand>') shell = novaclient.shell.OpenStackComputeShell() shell.subcommands = {} shell._find_actions(subparsers, fake_actions_module, api_versions.APIVersion("2.15"), False) self.assertIn('fake-action', shell.subcommands.keys()) self.assertEqual( 1, shell.subcommands['fake-action'].get_default('func')()) shell.subcommands = {} shell._find_actions(subparsers, fake_actions_module, api_versions.APIVersion("2.25"), False) self.assertIn('fake-action', shell.subcommands.keys()) self.assertEqual( 2, shell.subcommands['fake-action'].get_default('func')()) self.assertIn('fake-action2', shell.subcommands.keys()) self.assertEqual( 3, shell.subcommands['fake-action2'].get_default('func')())
def test_usage_list_paginated(self): usages = self.usages.list() novaclient = self.stub_novaclient() novaclient.versions = self.mox.CreateMockAnything() novaclient.versions.get_current().AndReturn( api_versions.APIVersion('2.40')) novaclient.api_version = api_versions.APIVersion('2.40') novaclient.usage = self.mox.CreateMockAnything() novaclient.usage.list('start', 'end', True).AndReturn(usages) novaclient.usage.list( 'start', 'end', True, marker=u'063cf7f3-ded1-4297-bc4c-31eae876cc93', ).AndReturn({}) self.mox.ReplayAll() ret_val = api.nova.usage_list(self.request, 'start', 'end') for usage in ret_val: self.assertIsInstance(usage, api.nova.NovaUsage)
def test_load_versioned_actions_with_args_and_help(self, mock_add_arg): parser = novaclient.shell.NovaClientArgumentParser(add_help=False) subparsers = parser.add_subparsers(metavar='<subcommand>') shell = novaclient.shell.OpenStackComputeShell() shell.subcommands = {} shell._find_actions(subparsers, fake_actions_module, api_versions.APIVersion("2.4"), True) mock_add_arg.assert_has_calls([ mock.call('-h', '--help', action='help', help='==SUPPRESS=='), mock.call('--bar', help=" (Supported by API versions '2.3' - '2.4')") ])
def test_load_versioned_actions_with_args(self, mock_add_arg): parser = novaclient.shell.NovaClientArgumentParser(add_help=False) subparsers = parser.add_subparsers(metavar='<subcommand>') shell = novaclient.shell.OpenStackComputeShell() shell.subcommands = {} shell._find_actions(subparsers, fake_actions_module, api_versions.APIVersion("2.1"), False) self.assertIn('fake-action2', shell.subcommands.keys()) mock_add_arg.assert_has_calls([ mock.call('-h', '--help', action='help', help='==SUPPRESS=='), mock.call('--foo') ])
def take_action(self, parsed_args): compute_client = self.app.client_manager.compute identity_client = self.app.client_manager.identity if parsed_args.project and parsed_args.public: msg = _("--project is only allowed with --private") raise exceptions.CommandError(msg) if parsed_args.description: if compute_client.api_version < api_versions.APIVersion("2.55"): msg = _("--os-compute-api-version 2.55 or later is required") raise exceptions.CommandError(msg) args = (parsed_args.name, parsed_args.ram, parsed_args.vcpus, parsed_args.disk, parsed_args.id, parsed_args.ephemeral, parsed_args.swap, parsed_args.rxtx_factor, parsed_args.public, parsed_args.description) flavor = compute_client.flavors.create(*args) if parsed_args.project: try: project_id = identity_common.find_project( identity_client, parsed_args.project, parsed_args.project_domain, ).id compute_client.flavor_access.add_tenant_access( flavor.id, project_id) except Exception as e: msg = _("Failed to add project %(project)s access to " "flavor: %(e)s") LOG.error(msg, {'project': parsed_args.project, 'e': e}) if parsed_args.property: try: flavor.set_keys(parsed_args.property) except Exception as e: LOG.error(_("Failed to set flavor property: %s"), e) flavor_info = flavor._info.copy() flavor_info['properties'] = flavor.get_keys() display_columns, columns = _get_flavor_columns(flavor_info) data = utils.get_dict_properties(flavor_info, columns, formatters=_formatters, mixed_case_fields=[ 'OS-FLV-DISABLED:disabled', 'OS-FLV-EXT-DATA:ephemeral' ]) return (display_columns, data)
def take_action(self, parsed_args): compute_client = self.app.client_manager.compute #WRS:extension compute_client.api_version = api_versions.APIVersion("2.53") group = utils.find_resource(compute_client.server_groups, parsed_args.server_group) info = {} info.update(group._info) columns = _get_columns(info) data = utils.get_dict_properties(info, columns, formatters=_formatters) return columns, data
def test_arguments_property_is_copied(self, mock_name): @nutils.arg("argument_1") @api_versions.wraps("2.666", "2.777") @nutils.arg("argument_2") def some_func(): pass versioned_method = api_versions.get_substitutions( mock_name.return_value, api_versions.APIVersion("2.700"))[0] self.assertEqual(some_func.arguments, versioned_method.func.arguments) self.assertIn((("argument_1", ), {}), versioned_method.func.arguments) self.assertIn((("argument_2", ), {}), versioned_method.func.arguments)
def _get_nova_api_version(context): client = novaclient.Client(REQUIRED_NOVA_API_VERSION, session=context.session, service_type=CONF.nova_service_type) required = nova_api_versions.APIVersion(REQUIRED_NOVA_API_MICROVERSION) current = client.versions.get_current() if not current: logger.warning( _LW('Could not check Nova API version because no version ' 'was found in Nova version list for url %(url)s of service ' 'type "%(service_type)s". ' 'Use v%(required_api_version)s Nova API.'), {'url': client.client.get_endpoint(), 'service_type': CONF.nova_service_type, 'required_api_version': REQUIRED_NOVA_API_MICROVERSION}) return REQUIRED_NOVA_API_MICROVERSION if current.id != REQUIRED_NOVA_API_VERSION_ID: logger.warning( _LW('Specified "%s" Nova service type does not support v2.1 API. ' 'A lot of useful EC2 compliant instance properties ' 'will be unavailable.'), CONF.nova_service_type) return LEGACY_NOVA_API_VERSION if (nova_api_versions.APIVersion(current.version) < required): logger.warning( _LW('Nova support v%(nova_api_version)s, ' 'but v%(required_api_version)s is required. ' 'A lot of useful EC2 compliant instance properties ' 'will be unavailable.'), {'nova_api_version': current.version, 'required_api_version': REQUIRED_NOVA_API_MICROVERSION}) return current.version logger.info(_LI('Provided Nova API version is v%(nova_api_version)s, ' 'used one is v%(required_api_version)s'), {'nova_api_version': current.version, 'required_api_version': ( REQUIRED_NOVA_API_MICROVERSION)}) return REQUIRED_NOVA_API_MICROVERSION
def stub_novaclient(self): if not hasattr(self, "novaclient"): self.mox.StubOutWithMock(nova_client, 'Client') # mock the api_version since MockObject.__init__ ignores it. # The preferred version in the api.nova code is 2 but that's # equivalent to 2.1 now and is the base version that's backward # compatible to 2.0 anyway. api_version = nova_api_versions.APIVersion('2.1') nova_client.Client.api_version = api_version nova_client.Client.projectid = 'fake_project' nova_client.Client.tenant_id = 'fake_tenant' self.novaclient = self.mox.CreateMock(nova_client.Client) return self.novaclient
def test_usage_get(self): novaclient = self.stub_novaclient() novaclient.versions = self.mox.CreateMockAnything() novaclient.versions.get_current().AndReturn( api_versions.APIVersion('2.1')) novaclient.usage = self.mox.CreateMockAnything() novaclient.usage.get(self.tenant.id, 'start', 'end').AndReturn(self.usages.first()) self.mox.ReplayAll() ret_val = api.nova.usage_get(self.request, self.tenant.id, 'start', 'end') self.assertIsInstance(ret_val, api.nova.NovaUsage)
def take_action(self, parsed_args): compute_client = self.app.client_manager.compute identity_client = self.app.client_manager.identity flavor = _find_flavor(compute_client, parsed_args.flavor) result = 0 key_list = [] if parsed_args.no_property: try: for key in flavor.get_keys().keys(): key_list.append(key) flavor.unset_keys(key_list) except Exception as e: LOG.error(_("Failed to clear flavor property: %s"), e) result += 1 if parsed_args.property: try: flavor.set_keys(parsed_args.property) except Exception as e: LOG.error(_("Failed to set flavor property: %s"), e) result += 1 if parsed_args.project: try: if flavor.is_public: msg = _("Cannot set access for a public flavor") raise exceptions.CommandError(msg) else: project_id = identity_common.find_project( identity_client, parsed_args.project, parsed_args.project_domain, ).id compute_client.flavor_access.add_tenant_access( flavor.id, project_id) except Exception as e: LOG.error(_("Failed to set flavor access to project: %s"), e) result += 1 if result > 0: raise exceptions.CommandError( _("Command Failed: One or more of" " the operations failed")) if parsed_args.description: if compute_client.api_version < api_versions.APIVersion("2.55"): msg = _("--os-compute-api-version 2.55 or later is required") raise exceptions.CommandError(msg) compute_client.flavors.update(flavor=parsed_args.flavor, description=parsed_args.description)
def test_usage_list(self): usages = self.usages.list() novaclient = self.stub_novaclient() novaclient.versions = self.mox.CreateMockAnything() novaclient.versions.get_current().AndReturn( api_versions.APIVersion('2.1')) novaclient.usage = self.mox.CreateMockAnything() novaclient.usage.list('start', 'end', True).AndReturn(usages) self.mox.ReplayAll() ret_val = api.nova.usage_list(self.request, 'start', 'end') for usage in ret_val: self.assertIsInstance(usage, api.nova.NovaUsage)
def test_adapter_properties(self): # sample of properties, there are many more user_agent = uuidutils.generate_uuid(dashed=False) endpoint_override = uuidutils.generate_uuid(dashed=False) s = session.Session() c = client.Client(session=s, api_version=api_versions.APIVersion("2.0"), user_agent=user_agent, endpoint_override=endpoint_override, direct_use=False) self.assertEqual(user_agent, c.client.user_agent) self.assertEqual(endpoint_override, c.client.endpoint_override)
def test_microversions_max_version(self, mock_client): headers = self._make_headers(self.max_version) url = '/v2.1/' + self.tenant_id + '/servers/detail' mock_client.return_value = FakeNovaClient() self.app.get(url, headers=headers) mock_client.assert_called_with(api_version=api_versions.APIVersion( self.max_version.split()[1]), auth_token=None, auth_url='auth_url', direct_use=False, project_id=None, timeout=60, username=None, api_key=None)
def novaclient(context, timeout=None): """Returns a Nova client @param timeout: Number of seconds to wait for an answer before raising a Timeout exception (None to disable) """ nova_catalog_info = CONF.nova_catalog_admin_info service_type, service_name, endpoint_type = nova_catalog_info.split(':') context = ctx.RequestContext( CONF.os_privileged_user_name, None, auth_token=CONF.os_privileged_user_password, project_name=CONF.os_privileged_user_tenant, service_catalog=context.service_catalog, global_request_id=context.global_id) # User needs to authenticate to Keystone before querying Nova, so we set # auth_url to the identity service endpoint url = CONF.os_privileged_user_auth_url LOG.debug('Creating a Nova client using "%s" user', CONF.os_privileged_user_name) # Now that we have the correct auth_url, username, password and # project_name, let's build a Keystone session. loader = keystoneauth1.loading.get_plugin_loader( CONF.keystone_authtoken.auth_type) auth = loader.load_from_options( auth_url=url, username=context.user_id, password=context.auth_token, project_name=context.project_name, user_domain_name=CONF.os_user_domain_name, project_domain_name=CONF.os_project_domain_name) keystone_session = keystoneauth1.session.Session(auth=auth) client_obj = nova_client.Client( api_versions.APIVersion(NOVA_API_VERSION), session=keystone_session, insecure=CONF.nova_api_insecure, timeout=timeout, global_request_id=context.global_id, region_name=CONF.os_region_name, endpoint_type=endpoint_type, service_type=service_type, service_name=service_name, cacert=CONF.nova_ca_certificates_file, extensions=nova_extensions) return client_obj
def usage_get(request, tenant_id, start, end): client = upgrade_api(request, novaclient(request), '2.40') usage = client.usage.get(tenant_id, start, end) if client.api_version >= api_versions.APIVersion('2.40'): # If the number of instances used to calculate the usage is greater # than max_limit, the usage will be split across multiple requests # and the responses will need to be merged back together. marker = _get_usage_marker(usage) while marker: next_usage = client.usage.get(tenant_id, start, end, marker=marker) marker = _get_usage_marker(next_usage) if marker: _merge_usage(usage, next_usage) return NovaUsage(usage)
def test_load_versioned_actions_with_help_on_latest(self): parser = novaclient.shell.NovaClientArgumentParser() subparsers = parser.add_subparsers(metavar='<subcommand>') shell = novaclient.shell.OpenStackComputeShell() shell.subcommands = {} shell._find_actions(subparsers, fake_actions_module, api_versions.APIVersion("2.latest"), True) self.assertIn('another-fake-action', shell.subcommands.keys()) expected_desc = (" (Supported by API versions '%(start)s' - " "'%(end)s')%(hint)s") % { 'start': '2.0', 'end': '2.latest', 'hint': novaclient.shell.HINT_HELP_MSG} self.assertEqual(expected_desc, shell.subcommands['another-fake-action'].description)
def take_action(self, parsed_args): compute_client = self.app.client_manager.compute info = {} if parsed_args.policy in ('soft-affinity', 'soft-anti-affinity'): if compute_client.api_version < api_versions.APIVersion('2.15'): msg = _( '--os-compute-api-version 2.15 or greater is required to ' 'support the %s policy') raise exceptions.CommandError(msg % parsed_args.policy) policy_arg = {'policies': [parsed_args.policy]} if compute_client.api_version >= api_versions.APIVersion("2.64"): policy_arg = {'policy': parsed_args.policy} server_group = compute_client.server_groups.create( name=parsed_args.name, **policy_arg) info.update(server_group._info) columns = _get_columns(info) data = utils.get_dict_properties(info, columns, formatters=_formatters) return columns, data
def test_v2_get_endpoint_without_project_id(self): # create a fake client such that get_endpoint() # doesn't return uuid in url endpoint_type = 'v2' expected_endpoint = 'http://nova-api:8774/v2/' cs_2 = fakes.FakeClient(api_versions.APIVersion("2.0"), endpoint_type=endpoint_type) result = cs_2.versions.get_current() self.assert_request_id(result, fakes.FAKE_REQUEST_ID_LIST) self.assertEqual(result.manager.api.client.endpoint_type, endpoint_type, "Check v2 endpoint_type was set") # check that the full request works as expected cs_2.assert_called('GET', expected_endpoint)
def test_microversions_both_version(self, mock_client): headers = self._make_headers(self.vaild_version, 'both') url = '/v2.1/' + self.tenant_id + '/servers/detail' mock_client.return_value = FakeNovaClient() self.app.get(url, headers=headers, expect_errors=True) # The new format microversion priority to leagecy mock_client.assert_called_with(api_version=api_versions.APIVersion( self.vaild_version.split()[1]), auth_token=None, auth_url='auth_url', direct_use=False, project_id=None, timeout=60, username=None, api_key=None)
def test_hypervisor_list_with_marker(self): self.app.client_manager.compute.api_version = \ api_versions.APIVersion('2.33') arglist = [ '--marker', 'test_hyp', ] verifylist = [ ('marker', 'test_hyp'), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.cmd.take_action(parsed_args) self.hypervisors_mock.list.assert_called_with(marker='test_hyp')
def test_load_versioned_actions_with_help(self): parser = novaclient.shell.NovaClientArgumentParser() subparsers = parser.add_subparsers(metavar='<subcommand>') shell = novaclient.shell.OpenStackComputeShell() shell.subcommands = {} shell._find_actions(subparsers, fake_actions_module, api_versions.APIVersion("2.10000"), True) self.assertIn('fake-action', shell.subcommands.keys()) expected_desc = ("(Supported by API versions '%(start)s' - " "'%(end)s')") % { 'start': '2.10', 'end': '2.30' } self.assertIn(expected_desc, shell.subcommands['fake-action'].description)
def test_microversions_min_version(self, mock_client): headers = self._make_headers(self.min_version, 'leagecy') url = '/v2.1/' + self.tenant_id + '/servers/detail' mock_client.return_value = FakeNovaClient() self.app.get(url, headers=headers) mock_client.assert_called_with(api_version=api_versions.APIVersion( self.min_version), auth_token=None, auth_url='auth_url', direct_use=False, project_name=None, endpoint_override='endpoint_url', project_domain_name=None, timeout=60, username=None)
def take_action(self, parsed_args): compute_client = self.app.client_manager.compute info = {} policy_arg = {'policies': [parsed_args.policy]} if compute_client.api_version >= api_versions.APIVersion("2.64"): policy_arg = {'policy': parsed_args.policy} server_group = compute_client.server_groups.create( name=parsed_args.name, **policy_arg) info.update(server_group._info) columns = _get_columns(info) data = utils.get_dict_properties(info, columns, formatters=_formatters) return columns, data
def novaclient(context, privileged_user=False, timeout=None, api_version=None): """Returns a Nova client @param privileged_user: If True, use the account from configuration (requires 'auth_type' and the other usual Keystone authentication options to be set in the [nova] section) @param timeout: Number of seconds to wait for an answer before raising a Timeout exception (None to disable) @param api_version: api version of nova """ if privileged_user and CONF[NOVA_GROUP].auth_type: LOG.debug('Creating Keystone auth plugin from conf') n_auth = ks_loading.load_auth_from_conf_options(CONF, NOVA_GROUP) else: if CONF[NOVA_GROUP].token_auth_url: url = CONF[NOVA_GROUP].token_auth_url else: url = _get_identity_endpoint_from_sc(context) LOG.debug('Creating Keystone token plugin using URL: %s', url) n_auth = identity.Token(auth_url=url, token=context.auth_token, project_name=context.project_name, project_domain_id=context.project_domain_id) if CONF.auth_strategy == 'keystone': n_auth = service_auth.get_auth_plugin(context, auth=n_auth) keystone_session = ks_loading.load_session_from_conf_options( CONF, NOVA_GROUP, auth=n_auth) c = nova_client.Client( api_versions.APIVersion(api_version or NOVA_API_VERSION), session=keystone_session, insecure=CONF[NOVA_GROUP].insecure, timeout=timeout, region_name=CONF[NOVA_GROUP].region_name, endpoint_type=CONF[NOVA_GROUP].interface, cacert=CONF[NOVA_GROUP].cafile, global_request_id=context.global_id, extensions=nova_extensions) return c
def test_server_volume_list_with_delete_on_attachment(self): self.app.client_manager.compute.api_version = \ api_versions.APIVersion('2.79') arglist = [ self.server.id, ] verifylist = [ ('server', self.server.id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.assertEqual( ( 'ID', 'Device', 'Server ID', 'Volume ID', 'Tag', 'Delete On Termination?', ), columns, ) self.assertEqual( ( ( self.volume_attachments[0].id, self.volume_attachments[0].device, self.volume_attachments[0].serverId, self.volume_attachments[0].volumeId, self.volume_attachments[0].tag, self.volume_attachments[0].delete_on_termination, ), ( self.volume_attachments[1].id, self.volume_attachments[1].device, self.volume_attachments[1].serverId, self.volume_attachments[1].volumeId, self.volume_attachments[1].tag, self.volume_attachments[1].delete_on_termination, ), ), tuple(data), ) self.servers_volumes_mock.get_server_volumes.assert_called_once_with( self.server.id)
def novaclient(context, privileged_user=False, timeout=None): """Returns a Nova client @param privileged_user: If True, use the account from configuration (requires 'auth_type' and the other usual Keystone authentication options to be set in the [nova] section) @param timeout: Number of seconds to wait for an answer before raising a Timeout exception (None to disable) """ if privileged_user and CONF[NOVA_GROUP].auth_type: n_auth = ks_loading.load_auth_from_conf_options(CONF, NOVA_GROUP) else: if CONF[NOVA_GROUP].token_auth_url: url = CONF[NOVA_GROUP].token_auth_url else: # Search for the identity endpoint in the service catalog # if nova.token_auth_url is not configured matching_endpoints = [] for service in context.service_catalog: if service.get('type') != 'identity': continue for endpoint in service['endpoints']: if (not CONF[NOVA_GROUP].region_name or endpoint.get('region') == CONF[NOVA_GROUP].region_name): matching_endpoints.append(endpoint) if not matching_endpoints: raise nova_exceptions.EndpointNotFound() url = matching_endpoints[0].get(CONF[NOVA_GROUP].interface + 'URL') n_auth = identity.Token(auth_url=url, token=context.auth_token, project_name=context.project_name, project_domain_id=context.project_domain) keystone_session = ks_loading.load_session_from_conf_options(CONF, NOVA_GROUP, auth=n_auth) c = nova_client.Client(api_versions.APIVersion(NOVA_API_VERSION), session=keystone_session, insecure=CONF[NOVA_GROUP].insecure, timeout=timeout, region_name=CONF[NOVA_GROUP].region_name, endpoint_type=CONF[NOVA_GROUP].interface, cacert=CONF[NOVA_GROUP].cafile, extensions=nova_extensions) return c
def take_action(self, parsed_args): compute_client = self.app.client_manager.compute info = {} #WRS:extension meta = _extract_metadata(parsed_args) compute_client.api_version = api_versions.APIVersion("2.53") server_group = compute_client.server_groups.create( name=parsed_args.name, metadata=meta, policies=[parsed_args.policy]) info.update(server_group._info) columns = _get_columns(info) data = utils.get_dict_properties(info, columns, formatters=_formatters) return columns, data
def test_keypair_delete_with_user_pre_v210(self, sm_mock): self.app.client_manager.compute.api_version = \ api_versions.APIVersion('2.9') arglist = ['--user', identity_fakes.user_name, self.keypairs[0].name] verifylist = [ ('user', identity_fakes.user_name), ('name', [self.keypairs[0].name]), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) ex = self.assertRaises(exceptions.CommandError, self.cmd.take_action, parsed_args) self.assertIn('--os-compute-api-version 2.10 or greater is required', str(ex))
def test_version_matches(self): v1 = api_versions.APIVersion("2.0") v2 = api_versions.APIVersion("2.5") v3 = api_versions.APIVersion("2.45") v4 = api_versions.APIVersion("3.3") v5 = api_versions.APIVersion("3.23") v6 = api_versions.APIVersion("2.0") v7 = api_versions.APIVersion("3.3") v8 = api_versions.APIVersion("4.0") v_null = api_versions.APIVersion() self.assertTrue(v2.matches(v1, v3)) self.assertTrue(v2.matches(v1, v_null)) self.assertTrue(v1.matches(v6, v2)) self.assertTrue(v4.matches(v2, v7)) self.assertTrue(v4.matches(v_null, v7)) self.assertTrue(v4.matches(v_null, v8)) self.assertFalse(v1.matches(v2, v3)) self.assertFalse(v5.matches(v2, v4)) self.assertFalse(v2.matches(v3, v1)) self.assertRaises(ValueError, v_null.matches, v1, v3)