diff options
Diffstat (limited to 'ceilometerclient/client.py')
-rw-r--r-- | ceilometerclient/client.py | 203 |
1 files changed, 156 insertions, 47 deletions
diff --git a/ceilometerclient/client.py b/ceilometerclient/client.py index 7bfe1a6..b66e547 100644 --- a/ceilometerclient/client.py +++ b/ceilometerclient/client.py @@ -10,38 +10,133 @@ # License for the specific language governing permissions and limitations # under the License. -from keystoneclient.v2_0 import client as ksclient +from keystoneclient.auth.identity import v2 as v2_auth +from keystoneclient.auth.identity import v3 as v3_auth +from keystoneclient import discover +from keystoneclient import session import six from ceilometerclient.common import utils - - -def _get_ksclient(**kwargs): - """Get an endpoint and auth token from Keystone. - - :param kwargs: keyword args containing credentials: - * username: name of user - * password: user's password - * auth_url: endpoint to authenticate against - * cacert: path of CA TLS certificate - * insecure: allow insecure SSL (no cert verification) - * tenant_{name|id}: name or ID of tenant - """ - return ksclient.Client(username=kwargs.get('username'), - password=kwargs.get('password'), - tenant_id=kwargs.get('tenant_id'), - tenant_name=kwargs.get('tenant_name'), - auth_url=kwargs.get('auth_url'), - region_name=kwargs.get('region_name'), - cacert=kwargs.get('cacert'), - insecure=kwargs.get('insecure')) - - -def _get_endpoint(client, **kwargs): - """Get an endpoint using the provided keystone client.""" - return client.service_catalog.url_for( - service_type=kwargs.get('service_type') or 'metering', - endpoint_type=kwargs.get('endpoint_type') or 'publicURL') +from ceilometerclient import exc + + +def _get_keystone_session(**kwargs): + # TODO(fabgia): the heavy lifting here should be really done by Keystone. + # Unfortunately Keystone does not support a richer method to perform + # discovery and return a single viable URL. A bug against Keystone has + # been filed: https://bugs.launchpad.net/pyhton-keystoneclient/+bug/1330677 + + # first create a Keystone session + cacert = kwargs.pop('cacert', None) + cert = kwargs.pop('cert', None) + key = kwargs.pop('key', None) + insecure = kwargs.pop('insecure', False) + auth_url = kwargs.pop('auth_url', None) + project_id = kwargs.pop('project_id', None) + project_name = kwargs.pop('project_name', None) + + if insecure: + verify = False + else: + verify = cacert or True + + if cert and key: + # passing cert and key together is deprecated in favour of the + # requests lib form of having the cert and key as a tuple + cert = (cert, key) + + # create the keystone client session + ks_session = session.Session(verify=verify, cert=cert) + + try: + # discover the supported keystone versions using the auth endpoint url + ks_discover = discover.Discover(session=ks_session, auth_url=auth_url) + # Determine which authentication plugin to use. + v2_auth_url = ks_discover.url_for('2.0') + v3_auth_url = ks_discover.url_for('3.0') + except Exception: + raise exc.CommandError('Unable to determine the Keystone version ' + 'to authenticate with using the given ' + 'auth_url: %s' % auth_url) + + username = kwargs.pop('username', None) + user_id = kwargs.pop('user_id', None) + user_domain_name = kwargs.pop('user_domain_name', None) + user_domain_id = kwargs.pop('user_domain_id', None) + project_domain_name = kwargs.pop('project_domain_name', None) + project_domain_id = kwargs.pop('project_domain_id', None) + auth = None + + if v3_auth_url and v2_auth_url: + # the auth_url does not have the versions specified + # e.g. http://no.where:5000 + # Keystone will return both v2 and v3 as viable options + # but we need to decide based on the arguments passed + # what version is callable + if (user_domain_name or user_domain_id or project_domain_name or + project_domain_id): + # domain is supported only in v3 + auth = v3_auth.Password( + v3_auth_url, + username=username, + user_id=user_id, + user_domain_name=user_domain_name, + user_domain_id=user_domain_id, + project_domain_name=project_domain_name, + project_domain_id=project_domain_id, + **kwargs) + else: + # no domain, then use v2 + auth = v2_auth.Password( + v2_auth_url, + username, + kwargs.pop('password', None), + tenant_id=project_id, + tenant_name=project_name) + elif v3_auth_url: + # the auth_url as v3 specified + # e.g. http://no.where:5000/v3 + # Keystone will return only v3 as viable option + auth = v3_auth.Password( + v3_auth_url, + username=username, + user_id=user_id, + user_domain_name=user_domain_name, + user_domain_id=user_domain_id, + project_domain_name=project_domain_name, + project_domain_id=project_domain_id, + **kwargs) + elif v2_auth_url: + # the auth_url as v2 specified + # e.g. http://no.where:5000/v2.0 + # Keystone will return only v2 as viable option + auth = v2_auth.Password( + v2_auth_url, + username, + kwargs.pop('password', None), + tenant_id=project_id, + tenant_name=project_name) + else: + raise exc.CommandError('Unable to determine the Keystone version ' + 'to authenticate with using the given ' + 'auth_url.') + + ks_session.auth = auth + return ks_session + + +def _get_endpoint(ks_session, **kwargs): + """Get an endpoint using the provided keystone session.""" + + # set service specific endpoint types + endpoint_type = kwargs.get('endpoint_type') or 'publicURL' + service_type = kwargs.get('service_type') or 'metering' + + endpoint = ks_session.get_endpoint(service_type=service_type, + endpoint_type=endpoint_type, + region_name=kwargs.get('region_name')) + + return endpoint def get_client(api_version, **kwargs): @@ -55,10 +150,19 @@ def get_client(api_version, **kwargs): or: * os_username: name of user * os_password: user's password + * os_user_id: user's id + * os_user_domain_id: the domain id of the user + * os_user_domain_name: the domain name of the user + * os_project_id: the user project id + * os_tenant_id: V2 alternative to os_project_id + * os_project_name: the user project name + * os_tenant_name: V2 alternative to os_project_name + * os_project_domain_name: domain name for the user project + * os_project_domain_id: domain id for the user project * os_auth_url: endpoint to authenticate against - * os_cacert: path of CA TLS certificate + * os_cert|os_cacert: path of CA TLS certificate + * os_key: SSL private key * insecure: allow insecure SSL (no cert verification) - * os_tenant_{name|id}: name or ID of tenant """ token = kwargs.get('os_auth_token') if token and not six.callable(token): @@ -66,36 +170,41 @@ def get_client(api_version, **kwargs): if token and kwargs.get('ceilometer_url'): endpoint = kwargs.get('ceilometer_url') - elif (kwargs.get('os_username') and - kwargs.get('os_password') and - kwargs.get('os_auth_url') and - (kwargs.get('os_tenant_id') or kwargs.get('os_tenant_name'))): - + else: + project_id = kwargs.get('os_project_id') or kwargs.get('os_tenant_id') + project_name = (kwargs.get('os_project_name') or + kwargs.get('os_tenant_name')) ks_kwargs = { 'username': kwargs.get('os_username'), 'password': kwargs.get('os_password'), - 'tenant_id': kwargs.get('os_tenant_id'), - 'tenant_name': kwargs.get('os_tenant_name'), + 'user_id': kwargs.get('os_user_id'), + 'user_domain_id': kwargs.get('os_user_domain_id'), + 'user_domain_name': kwargs.get('os_user_domain_name'), + 'project_id': project_id, + 'project_name': project_name, + 'project_domain_name': kwargs.get('os_project_domain_name'), + 'project_domain_id': kwargs.get('os_project_domain_id'), 'auth_url': kwargs.get('os_auth_url'), - 'region_name': kwargs.get('os_region_name'), - 'service_type': kwargs.get('os_service_type'), - 'endpoint_type': kwargs.get('os_endpoint_type'), 'cacert': kwargs.get('os_cacert'), - 'insecure': kwargs.get('insecure'), + 'cert': kwargs.get('os_cert'), + 'key': kwargs.get('os_key'), + 'insecure': kwargs.get('insecure') } - _ksclient = _get_ksclient(**ks_kwargs) - token = token or (lambda: _ksclient.auth_token) + + # retrieve session + ks_session = _get_keystone_session(**ks_kwargs) + token = token or (lambda: ks_session.get_token()) endpoint = kwargs.get('ceilometer_url') or \ - _get_endpoint(_ksclient, **ks_kwargs) + _get_endpoint(ks_session, **ks_kwargs) cli_kwargs = { 'token': token, 'insecure': kwargs.get('insecure'), 'timeout': kwargs.get('timeout'), 'cacert': kwargs.get('os_cacert'), - 'cert_file': kwargs.get('cert_file'), - 'key_file': kwargs.get('key_file'), + 'cert_file': kwargs.get('os_cert'), + 'key_file': kwargs.get('os_key') } return Client(api_version, endpoint, **cli_kwargs) |