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:
Vishvananda Ishaya 2013-01-31 11:51:29 -08:00
parent 1e1d95d559
commit 1e4a778bf8
8 changed files with 87 additions and 14 deletions

View File

@ -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

View File

@ -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):

View File

@ -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

View File

@ -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))

View File

@ -35,6 +35,9 @@ def mock_http_request(resp=None):
"token": {
"expires": "12345",
"id": "FAKE_ID",
"tenant": {
"id": "FAKE_TENANT_ID",
}
},
"serviceCatalog": [
{

View File

@ -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'],

View File

@ -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": [
{

View File

@ -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 \