Use keystone v3 and get a project scoped token
Change to use the keystone v3 client. Rename os-tenant-id to os-project id and os-tenant-name to os-project-name to match keystone v3 Validate token is a project scoped token if the token is fetched using user and password and not passed in Allow the user to specify os-domain-name or os-domain-id if needed to resolve os-project-name Change-Id: I19fe2d9af5f0f862303066bb235826373e6d605f
This commit is contained in:
parent
aa1c054dc5
commit
6a83c8d8a2
|
@ -23,7 +23,7 @@ import argparse
|
|||
import logging
|
||||
import sys
|
||||
|
||||
from keystoneclient.v2_0 import client as ksclient
|
||||
from keystoneclient.v3 import client as ksclient
|
||||
|
||||
import monascaclient
|
||||
from monascaclient import client as monasca_client
|
||||
|
@ -115,18 +115,32 @@ class MonascaShell(object):
|
|||
parser.add_argument('--os_password',
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
parser.add_argument('--os-tenant-id',
|
||||
default=utils.env('OS_TENANT_ID'),
|
||||
help='Defaults to env[OS_TENANT_ID].')
|
||||
parser.add_argument('--os-project-id',
|
||||
default=utils.env('OS_PROJECT_ID'),
|
||||
help='Defaults to env[OS_PROJECT_ID].')
|
||||
|
||||
parser.add_argument('--os_tenant_id',
|
||||
parser.add_argument('--os_project_id',
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
parser.add_argument('--os-tenant-name',
|
||||
default=utils.env('OS_TENANT_NAME'),
|
||||
help='Defaults to env[OS_TENANT_NAME].')
|
||||
parser.add_argument('--os-project-name',
|
||||
default=utils.env('OS_PROJECT_NAME'),
|
||||
help='Defaults to env[OS_PROJECT_NAME].')
|
||||
|
||||
parser.add_argument('--os_tenant_name',
|
||||
parser.add_argument('--os_project_name',
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
parser.add_argument('--os-domain-id',
|
||||
default=utils.env('OS_DOMAIN_ID'),
|
||||
help='Defaults to env[OS_DOMAIN_ID].')
|
||||
|
||||
parser.add_argument('--os_domain_id',
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
parser.add_argument('--os-domain-name',
|
||||
default=utils.env('OS_DOMAIN_NAME'),
|
||||
help='Defaults to env[OS_DOMAIN_NAME].')
|
||||
|
||||
parser.add_argument('--os_domain_name',
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
parser.add_argument('--os-auth-url',
|
||||
|
@ -236,18 +250,24 @@ class MonascaShell(object):
|
|||
|
||||
:param username: name of user
|
||||
:param password: user's password
|
||||
:param tenant_id: unique identifier of tenant
|
||||
:param tenant_name: name of tenant
|
||||
:param project_id: unique identifier of project
|
||||
:param project_name: name of project
|
||||
:param domain_name: name of domain project is in
|
||||
:param domain_id: id of domain project is in
|
||||
:param auth_url: endpoint to authenticate against
|
||||
:param token: token to use instead of username/password
|
||||
"""
|
||||
kc_args = {'auth_url': kwargs.get('auth_url'),
|
||||
'insecure': kwargs.get('insecure')}
|
||||
|
||||
if kwargs.get('tenant_id'):
|
||||
kc_args['tenant_id'] = kwargs.get('tenant_id')
|
||||
else:
|
||||
kc_args['tenant_name'] = kwargs.get('tenant_name')
|
||||
if kwargs.get('project_id'):
|
||||
kc_args['project_id'] = kwargs.get('project_id')
|
||||
elif kwargs.get('project_name'):
|
||||
kc_args['project_name'] = kwargs.get('project_name')
|
||||
if kwargs.get('domain_name'):
|
||||
kc_args['project_domain_name'] = kwargs.get('domain_name')
|
||||
if kwargs.get('domain_id'):
|
||||
kc_args['project_domain_id'] = kwargs.get('domain_id')
|
||||
|
||||
if kwargs.get('token'):
|
||||
kc_args['token'] = kwargs.get('token')
|
||||
|
@ -257,6 +277,24 @@ class MonascaShell(object):
|
|||
|
||||
return ksclient.Client(**kc_args)
|
||||
|
||||
def _get_token(self, _ksclient):
|
||||
"""Validate token is project scoped and return it if it is
|
||||
|
||||
project_id and auth_token were fetched when keystone client was created
|
||||
|
||||
:param _ksclient: keystone client
|
||||
"""
|
||||
if _ksclient.project_id:
|
||||
return _ksclient.auth_token
|
||||
raise exc.CommandError("User does not have a default project. "
|
||||
"You must provide a project id using "
|
||||
"--os-project-id or via env[OS_PROJECT_ID], "
|
||||
"or you must provide a project name using "
|
||||
"--os-project-name or via env[OS_PROJECT_NAME] "
|
||||
"and a domain using --os-domain-name, via "
|
||||
"env[OS_DOMAIN_NAME], using --os-domain-id or "
|
||||
"via env[OS_DOMAIN_ID]")
|
||||
|
||||
def _get_endpoint(self, client, **kwargs):
|
||||
"""Get an endpoint using the provided keystone client."""
|
||||
if kwargs.get('region_name'):
|
||||
|
@ -327,14 +365,6 @@ class MonascaShell(object):
|
|||
" via either --monasca-api-url or"
|
||||
" env[MONASCA_API_URL]")
|
||||
else:
|
||||
# Tenant name or ID is needed to make keystoneclient retrieve a
|
||||
# service catalog, it's not required if os_no_client_auth is
|
||||
# specified, neither is the auth URL
|
||||
if not (args.os_tenant_id or args.os_tenant_name):
|
||||
raise exc.CommandError("You must provide a tenant_id via"
|
||||
" either --os-tenant-id or via"
|
||||
" env[OS_TENANT_ID]")
|
||||
|
||||
if not args.os_auth_url:
|
||||
raise exc.CommandError("You must provide an auth url via"
|
||||
" either --os-auth-url or via"
|
||||
|
@ -344,11 +374,13 @@ class MonascaShell(object):
|
|||
'username': args.os_username,
|
||||
'password': args.os_password,
|
||||
'token': args.os_auth_token,
|
||||
'tenant_id': args.os_tenant_id,
|
||||
'tenant_name': args.os_tenant_name,
|
||||
'auth_url': args.os_auth_url,
|
||||
'service_type': args.os_service_type,
|
||||
'endpoint_type': args.os_endpoint_type,
|
||||
'project_id': args.os_project_id,
|
||||
'project_name': args.os_project_name,
|
||||
'domain_id': args.os_domain_id,
|
||||
'domain_name': args.os_domain_name,
|
||||
'insecure': args.insecure
|
||||
}
|
||||
|
||||
|
@ -356,7 +388,10 @@ class MonascaShell(object):
|
|||
|
||||
if not args.os_no_client_auth:
|
||||
_ksclient = self._get_ksclient(**kwargs)
|
||||
token = args.os_auth_token or _ksclient.auth_token
|
||||
if args.os_auth_token:
|
||||
token = args.os_auth_token
|
||||
else:
|
||||
token = self._get_token(_ksclient)
|
||||
|
||||
kwargs = {
|
||||
'token': token,
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from keystoneclient.v2_0 import client as ksclient
|
||||
from keystoneclient.v3 import client as ksclient
|
||||
|
||||
from monascaclient.openstack.common import jsonutils
|
||||
|
||||
|
@ -23,14 +23,14 @@ def script_keystone_client(token=None):
|
|||
ksclient.Client(auth_url='http://no.where',
|
||||
insecure=False,
|
||||
tenant_id='tenant_id',
|
||||
token=token).AndReturn(FakeKeystone(token))
|
||||
token=token).AndReturn(FakeKeystone(token, None))
|
||||
else:
|
||||
ksclient.Client(auth_url='http://no.where',
|
||||
insecure=False,
|
||||
password='password',
|
||||
tenant_name='tenant_name',
|
||||
project_name='project_name',
|
||||
username='username').AndReturn(FakeKeystone(
|
||||
'abcd1234'))
|
||||
'abcd1234', 'test'))
|
||||
|
||||
|
||||
def fake_headers():
|
||||
|
@ -49,8 +49,9 @@ class FakeServiceCatalog():
|
|||
class FakeKeystone():
|
||||
service_catalog = FakeServiceCatalog()
|
||||
|
||||
def __init__(self, auth_token):
|
||||
def __init__(self, auth_token, project_id):
|
||||
self.auth_token = auth_token
|
||||
self.project_id = project_id
|
||||
|
||||
|
||||
class FakeRaw():
|
||||
|
|
|
@ -17,7 +17,7 @@ import re
|
|||
import sys
|
||||
|
||||
import fixtures
|
||||
from keystoneclient.v2_0 import client as ksclient
|
||||
from keystoneclient.v3 import client as ksclient
|
||||
from mox3 import mox
|
||||
import six
|
||||
import testtools
|
||||
|
@ -31,9 +31,10 @@ from monascaclient.tests import fakes
|
|||
class TestCase(testtools.TestCase):
|
||||
|
||||
def set_fake_env(self, fake_env):
|
||||
client_env = ('OS_USERNAME', 'OS_PASSWORD', 'OS_TENANT_ID',
|
||||
'OS_TENANT_NAME', 'OS_AUTH_URL', 'OS_REGION_NAME',
|
||||
client_env = ('OS_USERNAME', 'OS_PASSWORD', 'OS_PROJECT_ID',
|
||||
'OS_PROJECT_NAME', 'OS_AUTH_URL', 'OS_REGION_NAME',
|
||||
'OS_AUTH_TOKEN', 'OS_NO_CLIENT_AUTH', 'OS_SERVICE_TYPE',
|
||||
'OS_DOMAIN_NAME', 'OS_DOMAIN_ID',
|
||||
'OS_ENDPOINT_TYPE', 'MONASCA_API_URL')
|
||||
|
||||
for key in client_env:
|
||||
|
@ -152,7 +153,7 @@ class ShellTestMonascaCommands(ShellBase):
|
|||
fake_env = {
|
||||
'OS_USERNAME': 'username',
|
||||
'OS_PASSWORD': 'password',
|
||||
'OS_TENANT_NAME': 'tenant_name',
|
||||
'OS_PROJECT_NAME': 'project_name',
|
||||
'OS_AUTH_URL': 'http://no.where',
|
||||
}
|
||||
self.set_fake_env(fake_env)
|
||||
|
|
Loading…
Reference in New Issue