Store tenant_id from keystone and use for quotas
Some calls in nova require a tenant_id when it could be interpreted from the current authentication data, so save the tenant id and use it in the quotas command if tenant_id is not specified. Change-Id: I89647cfe9da73bc474ef80a61a5678db42a5571c
This commit is contained in:
parent
1e1d95d559
commit
1e4a778bf8
@ -251,6 +251,7 @@ class HTTPClient(object):
|
||||
service_catalog.ServiceCatalog(body)
|
||||
if extract_token:
|
||||
self.auth_token = self.service_catalog.get_token()
|
||||
self.tenant_id = self.service_catalog.get_tenant_id()
|
||||
|
||||
management_url = self.service_catalog.url_for(
|
||||
attr='region',
|
||||
@ -356,7 +357,9 @@ class HTTPClient(object):
|
||||
|
||||
# Store the token/mgmt url in the keyring for later requests.
|
||||
if self.keyring_saver and self.os_cache and not self.keyring_saved:
|
||||
self.keyring_saver.save(self.auth_token, self.management_url)
|
||||
self.keyring_saver.save(self.auth_token,
|
||||
self.management_url,
|
||||
self.tenant_id)
|
||||
# Don't save it again
|
||||
self.keyring_saved = True
|
||||
|
||||
|
@ -28,6 +28,9 @@ class ServiceCatalog(object):
|
||||
def get_token(self):
|
||||
return self.catalog['access']['token']['id']
|
||||
|
||||
def get_tenant_id(self):
|
||||
return self.catalog['access']['token']['tenant']['id']
|
||||
|
||||
def url_for(self, attr=None, filter_value=None,
|
||||
service_type=None, endpoint_type='publicURL',
|
||||
service_name=None, volume_service_name=None):
|
||||
|
@ -114,16 +114,18 @@ class SecretsHelper(object):
|
||||
pass
|
||||
return pw
|
||||
|
||||
def save(self, auth_token, management_url):
|
||||
def save(self, auth_token, management_url, tenant_id):
|
||||
if not HAS_KEYRING or not self.args.os_cache:
|
||||
return
|
||||
if (auth_token == self.auth_token and
|
||||
management_url == self.management_url):
|
||||
# Nothing changed....
|
||||
return
|
||||
if not all([management_url, auth_token]):
|
||||
if not all([management_url, auth_token, tenant_id]):
|
||||
raise ValueError("Unable to save empty management url/auth token")
|
||||
value = "|".join([str(auth_token), str(management_url)])
|
||||
value = "|".join([str(auth_token),
|
||||
str(management_url),
|
||||
str(tenant_id)])
|
||||
keyring.set_password("novaclient_auth", self._make_key(), value)
|
||||
|
||||
@property
|
||||
@ -143,7 +145,7 @@ class SecretsHelper(object):
|
||||
try:
|
||||
block = keyring.get_password('novaclient_auth', self._make_key())
|
||||
if block:
|
||||
_token, management_url = block.split('|', 1)
|
||||
_token, management_url, _tenant_id = block.split('|', 2)
|
||||
except ValueError:
|
||||
pass
|
||||
return management_url
|
||||
@ -160,11 +162,24 @@ class SecretsHelper(object):
|
||||
try:
|
||||
block = keyring.get_password('novaclient_auth', self._make_key())
|
||||
if block:
|
||||
token, _management_url = block.split('|', 1)
|
||||
token, _management_url, _tenant_id = block.split('|', 2)
|
||||
except ValueError:
|
||||
pass
|
||||
return token
|
||||
|
||||
@property
|
||||
def tenant_id(self):
|
||||
if not HAS_KEYRING:
|
||||
return None
|
||||
tenant_id = None
|
||||
try:
|
||||
block = keyring.get_password('novaclient_auth', self._make_key())
|
||||
if block:
|
||||
_token, _management_url, tenant_id = block.split('|', 2)
|
||||
except ValueError:
|
||||
pass
|
||||
return tenant_id
|
||||
|
||||
|
||||
class NovaClientArgumentParser(argparse.ArgumentParser):
|
||||
|
||||
@ -609,9 +624,11 @@ class OpenStackComputeShell(object):
|
||||
if not utils.isunauthenticated(args.func):
|
||||
helper = SecretsHelper(args, self.cs.client)
|
||||
use_pw = True
|
||||
auth_token, management_url = (helper.auth_token,
|
||||
helper.management_url)
|
||||
if auth_token and management_url:
|
||||
tenant_id, auth_token, management_url = (helper.tenant_id,
|
||||
helper.auth_token,
|
||||
helper.management_url)
|
||||
if tenant_id and auth_token and management_url:
|
||||
self.cs.client.tenant_id = tenant_id
|
||||
self.cs.client.auth_token = auth_token
|
||||
self.cs.client.management_url = management_url
|
||||
# Try to auth with the given info, if it fails
|
||||
|
@ -2597,7 +2597,7 @@ def do_quota_show(cs, args):
|
||||
"""List the quotas for a tenant."""
|
||||
|
||||
if not args.tenant:
|
||||
raise exceptions.CommandError("you need to specify a Tenant ID ")
|
||||
_quota_show(cs.quotas.get(cs.client.tenant_id))
|
||||
else:
|
||||
_quota_show(cs.quotas.get(args.tenant))
|
||||
|
||||
@ -2610,7 +2610,7 @@ def do_quota_defaults(cs, args):
|
||||
"""List the default quotas for a tenant."""
|
||||
|
||||
if not args.tenant:
|
||||
_quota_show(cs.quotas.defaults(cs.project_id))
|
||||
_quota_show(cs.quotas.defaults(cs.client.tenant_id))
|
||||
else:
|
||||
_quota_show(cs.quotas.defaults(args.tenant))
|
||||
|
||||
|
@ -35,6 +35,9 @@ def mock_http_request(resp=None):
|
||||
"token": {
|
||||
"expires": "12345",
|
||||
"id": "FAKE_ID",
|
||||
"tenant": {
|
||||
"id": "FAKE_TENANT_ID",
|
||||
}
|
||||
},
|
||||
"serviceCatalog": [
|
||||
{
|
||||
|
@ -37,6 +37,7 @@ class FakeHTTPClient(base_client.HTTPClient):
|
||||
self.username = 'username'
|
||||
self.password = 'password'
|
||||
self.auth_url = 'auth_url'
|
||||
self.tenant_id = 'tenant_id'
|
||||
self.callstack = []
|
||||
|
||||
def _cs_request(self, url, method, **kwargs):
|
||||
@ -863,6 +864,23 @@ class FakeHTTPClient(base_client.HTTPClient):
|
||||
'security_groups': 1,
|
||||
'security_group_rules': 1}})
|
||||
|
||||
def get_os_quota_sets_tenant_id(self, **kw):
|
||||
return (200, {}, {'quota_set': {
|
||||
'tenant_id': 'test',
|
||||
'metadata_items': [],
|
||||
'injected_file_content_bytes': 1,
|
||||
'injected_file_path_bytes': 1,
|
||||
'volumes': 1,
|
||||
'gigabytes': 1,
|
||||
'ram': 1,
|
||||
'floating_ips': 1,
|
||||
'instances': 1,
|
||||
'injected_files': 1,
|
||||
'cores': 1,
|
||||
'keypairs': 1,
|
||||
'security_groups': 1,
|
||||
'security_group_rules': 1}})
|
||||
|
||||
def get_os_quota_sets_97f4c221bff44578b0300df4ef119353(self, **kw):
|
||||
return (200, {}, {'quota_set': {
|
||||
'tenant_id': '97f4c221bff44578b0300df4ef119353',
|
||||
@ -931,6 +949,23 @@ class FakeHTTPClient(base_client.HTTPClient):
|
||||
'security_groups': 1,
|
||||
'security_group_rules': 1}})
|
||||
|
||||
def get_os_quota_sets_tenant_id_defaults(self):
|
||||
return (200, {}, {'quota_set': {
|
||||
'tenant_id': 'test',
|
||||
'metadata_items': [],
|
||||
'injected_file_content_bytes': 1,
|
||||
'injected_file_path_bytes': 1,
|
||||
'volumes': 1,
|
||||
'gigabytes': 1,
|
||||
'ram': 1,
|
||||
'floating_ips': 1,
|
||||
'instances': 1,
|
||||
'injected_files': 1,
|
||||
'cores': 1,
|
||||
'keypairs': 1,
|
||||
'security_groups': 1,
|
||||
'security_group_rules': 1}})
|
||||
|
||||
def put_os_quota_sets_97f4c221bff44578b0300df4ef119353(self, body, **kw):
|
||||
assert body.keys() == ['quota_set']
|
||||
fakes.assert_has_keys(body['quota_set'],
|
||||
|
@ -18,6 +18,9 @@ class AuthenticateAgainstKeystoneTests(utils.TestCase):
|
||||
"token": {
|
||||
"expires": "12345",
|
||||
"id": "FAKE_ID",
|
||||
"tenant": {
|
||||
"id": "FAKE_TENANT_ID",
|
||||
}
|
||||
},
|
||||
"serviceCatalog": [
|
||||
{
|
||||
@ -101,6 +104,9 @@ class AuthenticateAgainstKeystoneTests(utils.TestCase):
|
||||
"token": {
|
||||
"expires": "12345",
|
||||
"id": "FAKE_ID",
|
||||
"tenant": {
|
||||
"id": "FAKE_TENANT_ID",
|
||||
}
|
||||
},
|
||||
"serviceCatalog": [
|
||||
{
|
||||
@ -186,6 +192,9 @@ class AuthenticateAgainstKeystoneTests(utils.TestCase):
|
||||
"token": {
|
||||
"expires": "12345",
|
||||
"id": "FAKE_ID",
|
||||
"tenant": {
|
||||
"id": "FAKE_TENANT_ID",
|
||||
}
|
||||
},
|
||||
"serviceCatalog": [
|
||||
{
|
||||
|
@ -707,14 +707,17 @@ class ShellTest(utils.TestCase):
|
||||
self.assert_called('GET', '/os-quota-sets/test')
|
||||
|
||||
def test_quota_show_no_tenant(self):
|
||||
self.assertRaises(exceptions.CommandError,
|
||||
self.run_command,
|
||||
'quota-show')
|
||||
self.run_command('quota-show')
|
||||
self.assert_called('GET', '/os-quota-sets/tenant_id')
|
||||
|
||||
def test_quota_defaults(self):
|
||||
self.run_command('quota-defaults --tenant test')
|
||||
self.assert_called('GET', '/os-quota-sets/test/defaults')
|
||||
|
||||
def test_quota_defaults_no_nenant(self):
|
||||
self.run_command('quota-defaults')
|
||||
self.assert_called('GET', '/os-quota-sets/tenant_id/defaults')
|
||||
|
||||
def test_quota_update(self):
|
||||
self.run_command(
|
||||
'quota-update 97f4c221bff44578b0300df4ef119353 \
|
||||
|
Loading…
x
Reference in New Issue
Block a user