diff --git a/designateclient/shell.py b/designateclient/shell.py index 9e25a35..c07933f 100644 --- a/designateclient/shell.py +++ b/designateclient/shell.py @@ -20,9 +20,8 @@ import traceback from cliff.app import App from cliff.commandmanager import CommandManager -from keystoneclient.auth.identity import generic -from keystoneclient import session as ks_session +from designateclient import utils from designateclient.version import version_info as version @@ -155,6 +154,11 @@ class DesignateShell(App): help=("Defaults to env[OS_DNS_SERVICE_TYPE], or " "'dns'")) + parser.add_argument('--os-cacert', + default=env('OS_CACERT'), + help=('CA certificate bundle file. Defaults to ' + 'env[OS_CACERT]')) + parser.add_argument('--insecure', action='store_true', help="Explicitly allow 'insecure' SSL requests") @@ -206,37 +210,25 @@ class DesignateShell(App): def initialize_app(self, argv): super(DesignateShell, self).initialize_app(argv) - self.session = self.get_session() - - def get_session(self): - session = ks_session.Session() - - auth_args = { - 'auth_url': self.options.os_auth_url, - 'domain_id': self.options.os_domain_id, - 'domain_name': self.options.os_domain_name, - 'project_id': self.options.os_project_id, - 'project_name': self.options.os_project_name, - 'project_domain_name': self.options.os_project_domain_name, - 'project_domain_id': self.options.os_project_domain_id, - 'tenant_id': self.options.os_tenant_id, - 'tenant_name': self.options.os_tenant_name, - } - - if self.options.os_token: - auth_args['token'] = self.options.os_token - session.auth = generic.Token(**auth_args) - else: - password_args = { - 'username': self.options.os_username, - 'user_id': self.options.os_user_id, - 'user_domain_id': self.options.os_user_domain_id, - 'user_domain_name': self.options.os_user_domain_name, - 'password': self.options.os_password - } - auth_args.update(password_args) - session.auth = generic.Password(**auth_args) - return session + self.session = utils.get_session( + auth_url=self.options.os_auth_url, + endpoint=self.options.os_endpoint, + domain_id=self.options.os_domain_id, + domain_name=self.options.os_domain_name, + project_id=self.options.os_project_id or self.options.os_tenant_id, + project_name=(self.options.os_project_name or + self.options.os_tenant_name), + project_domain_name=self.options.os_project_domain_name, + project_domain_id=self.options.os_project_domain_id, + username=self.options.os_username, + user_id=self.options.os_user_id, + password=self.options.os_password, + user_domain_id=self.options.os_user_domain_id, + user_domain_name=self.options.os_user_domain_name, + token=self.options.os_token, + insecure=self.options.insecure, + cacert=self.options.os_cacert, + ) def run(self, argv): try: diff --git a/designateclient/utils.py b/designateclient/utils.py index 33de29e..576b76e 100644 --- a/designateclient/utils.py +++ b/designateclient/utils.py @@ -18,6 +18,9 @@ import json import os +from keystoneclient.auth.identity import generic +from keystoneclient.auth import token_endpoint +from keystoneclient import session as ks_session import pkg_resources from designateclient import exceptions @@ -92,3 +95,48 @@ def get_columns(data): map(lambda item: map(_seen, item.keys()), data) return list(columns) + + +def get_session(auth_url, endpoint, domain_id, domain_name, project_id, + project_name, project_domain_name, project_domain_id, username, + user_id, password, user_domain_id, user_domain_name, token, + insecure, cacert): + session = ks_session.Session() + + # Build + Attach Authentication Plugin + auth_args = { + 'auth_url': auth_url, + 'domain_id': domain_id, + 'domain_name': domain_name, + 'project_id': project_id, + 'project_name': project_name, + 'project_domain_name': project_domain_name, + 'project_domain_id': project_domain_id, + } + + if token and endpoint: + session.auth = token_endpoint.Token(endpoint, token) + + elif token: + auth_args.update({ + 'token': token + }) + session.auth = generic.Token(**auth_args) + + else: + auth_args.update({ + 'username': username, + 'user_id': user_id, + 'password': password, + 'user_domain_id': user_domain_id, + 'user_domain_name': user_domain_name, + }) + session.auth = generic.Password(**auth_args) + + # SSL/TLS Server Cert Verification + if insecure is True: + session.verify = False + else: + session.verify = cacert + + return session diff --git a/designateclient/v1/__init__.py b/designateclient/v1/__init__.py index aab6772..127ea13 100644 --- a/designateclient/v1/__init__.py +++ b/designateclient/v1/__init__.py @@ -14,12 +14,10 @@ # License for the specific language governing permissions and limitations # under the License. from keystoneclient import adapter -from keystoneclient.auth.identity import generic -from keystoneclient.auth import token_endpoint -from keystoneclient import session as ks_session from stevedore import extension from designateclient import exceptions +from designateclient import utils from designateclient import version @@ -33,51 +31,39 @@ class Client(object): project_id=None, project_domain_name=None, project_domain_id=None, auth_url=None, token=None, endpoint_type='publicURL', region_name=None, - service_type='dns', insecure=False, verify=None, session=None, - auth=None): + service_type='dns', insecure=False, session=None, + cacert=None): """ :param endpoint: Endpoint URL :param token: A token instead of username / password :param insecure: Allow "insecure" HTTPS requests """ - # Backwards compat to preserve the functionality of insecure. - if verify is None and insecure: - verify = False - else: - verify = True + + if endpoint: + endpoint = endpoint.rstrip('/') + if not endpoint.endswith('v1'): + endpoint = "%s/v1" % endpoint # Compatibility code to mimic the old behaviour of the client if session is None: - session = ks_session.Session(verify=verify) - - auth_args = { - 'auth_url': auth_url, - 'domain_id': domain_id, - 'domain_name': domain_name, - 'project_id': project_id, - 'project_name': project_name, - 'project_domain_name': project_domain_name, - 'project_domain_id': project_domain_id, - 'tenant_id': tenant_id, - 'tenant_name': tenant_name, - } - - if token: - # To mimic typical v1 behaviour I copied this - endpoint = endpoint.rstrip('/') - if not endpoint.endswith('v1'): - endpoint = "%s/v1" % endpoint - session.auth = token_endpoint.Token(endpoint, token) - else: - password_args = { - 'username': username, - 'user_id': user_id, - 'user_domain_id': user_domain_id, - 'user_domain_name': user_domain_name, - 'password': password - } - auth_args.update(password_args) - session.auth = generic.Password(**auth_args) + session = utils.get_session( + auth_url=auth_url, + endpoint=endpoint, + domain_id=domain_id, + domain_name=domain_name, + project_id=project_id or tenant_id, + project_name=project_name or tenant_name, + project_domain_name=project_domain_name, + project_domain_id=project_domain_id, + username=username, + user_id=user_id, + password=password, + user_domain_id=user_domain_id, + user_domain_name=user_domain_name, + token=token, + insecure=insecure, + cacert=cacert, + ) # Since we have to behave nicely like a legacy client/bindings we use # an adapter around the session to not modify it's state. @@ -85,7 +71,7 @@ class Client(object): self.session = adapter.Adapter( session, - auth=auth, + auth=session.auth, endpoint_override=endpoint, region_name=region_name, service_type=service_type,