diff --git a/openstackclient/common/clientmanager.py b/openstackclient/common/clientmanager.py index 24b09beb..85f544e4 100644 --- a/openstackclient/common/clientmanager.py +++ b/openstackclient/common/clientmanager.py @@ -50,7 +50,7 @@ class ClientManager(object): def __init__(self, token=None, url=None, auth_url=None, project_name=None, project_id=None, username=None, password=None, - region_name=None, api_version=None): + region_name=None, verify=True, api_version=None): self._token = token self._url = url self._auth_url = auth_url @@ -62,6 +62,16 @@ class ClientManager(object): self._api_version = api_version self._service_catalog = None + # verify is the Requests-compatible form + self._verify = verify + # also store in the form used by the legacy client libs + self._cacert = None + if verify is True or verify is False: + self._insecure = not verify + else: + self._cacert = verify + self._insecure = True + self.auth_ref = None if not self._url: diff --git a/openstackclient/common/restapi.py b/openstackclient/common/restapi.py index 4cea5a06..a45c8426 100644 --- a/openstackclient/common/restapi.py +++ b/openstackclient/common/restapi.py @@ -53,6 +53,7 @@ class RESTApi(object): os_auth=None, user_agent=USER_AGENT, debug=None, + verify=True, **kwargs ): self.set_auth(os_auth) diff --git a/openstackclient/compute/client.py b/openstackclient/compute/client.py index 9bd40a4f..4d3b1b71 100644 --- a/openstackclient/compute/client.py +++ b/openstackclient/compute/client.py @@ -38,8 +38,8 @@ def make_client(instance): api_key=instance._password, project_id=instance._project_name, auth_url=instance._auth_url, - # FIXME(dhellmann): add constructor argument for this - insecure=False, + cacert=instance._cacert, + insecure=instance._insecure, region_name=instance._region_name, # FIXME(dhellmann): get endpoint_type from option? endpoint_type='publicURL', diff --git a/openstackclient/identity/client.py b/openstackclient/identity/client.py index 8c9437ba..4814bc3e 100644 --- a/openstackclient/identity/client.py +++ b/openstackclient/identity/client.py @@ -47,7 +47,10 @@ def make_client(instance): tenant_name=instance._project_name, tenant_id=instance._project_id, auth_url=instance._auth_url, - region_name=instance._region_name) + region_name=instance._region_name, + cacert=instance._cacert, + insecure=instance._insecure, + ) instance.auth_ref = client.auth_ref return client diff --git a/openstackclient/image/client.py b/openstackclient/image/client.py index 70bef1c8..d56ca3b2 100644 --- a/openstackclient/image/client.py +++ b/openstackclient/image/client.py @@ -40,7 +40,12 @@ def make_client(instance): if not instance._url: instance._url = instance.get_endpoint_for_service_type(API_NAME) - return image_client(instance._url, token=instance._token) + return image_client( + instance._url, + token=instance._token, + cacert=instance._cacert, + insecure=instance._insecure, + ) # NOTE(dtroyer): glanceclient.v1.image.ImageManager() doesn't have a find() diff --git a/openstackclient/shell.py b/openstackclient/shell.py index 67977907..d0905fd9 100644 --- a/openstackclient/shell.py +++ b/openstackclient/shell.py @@ -79,6 +79,9 @@ class OpenStackShell(app.App): # password flow auth self.auth_client = None + # Assume TLS host certificate verification is enabled + self.verify = True + # NOTE(dtroyer): This hack changes the help action that Cliff # automatically adds to the parser so we can defer # its execution until after the api-versioned commands @@ -158,6 +161,22 @@ class OpenStackShell(app.App): metavar='', default=env('OS_REGION_NAME'), help='Authentication region name (Env: OS_REGION_NAME)') + parser.add_argument( + '--os-cacert', + metavar='', + default=env('OS_CACERT'), + help='CA certificate bundle file (Env: OS_CACERT)') + verify_group = parser.add_mutually_exclusive_group() + verify_group.add_argument( + '--verify', + action='store_true', + help='Verify server certificate (default)', + ) + verify_group.add_argument( + '--insecure', + action='store_true', + help='Disable server certificate verification', + ) parser.add_argument( '--os-default-domain', metavar='', @@ -299,7 +318,9 @@ class OpenStackShell(app.App): username=self.options.os_username, password=self.options.os_password, region_name=self.options.os_region_name, - api_version=self.api_version) + verify=self.verify, + api_version=self.api_version, + ) return def init_keyring_backend(self): @@ -387,7 +408,11 @@ class OpenStackShell(app.App): self.DeferredHelpAction(self.parser, self.parser, None, None) # Set up common client session - self.restapi = restapi.RESTApi() + if self.options.os_cacert: + self.verify = self.options.os_cacert + else: + self.verify = not self.options.insecure + self.restapi = restapi.RESTApi(verify=self.verify) def prepare_to_run_command(self, cmd): """Set up auth and API versions""" diff --git a/openstackclient/volume/client.py b/openstackclient/volume/client.py index 92f3b14a..626b23f1 100644 --- a/openstackclient/volume/client.py +++ b/openstackclient/volume/client.py @@ -40,6 +40,8 @@ def make_client(instance): api_key=instance._password, project_id=instance._project_name, auth_url=instance._auth_url, + cacert=instance._cacert, + insecure=instance._insecure, ) return client