Support client certificate/key
This change enables to specify a client certificate/key with: * usual CLI options (--os-cert/--os-key) * usual environment variables ($OS_CERT/$OS_KEY) * os-client-config Change-Id: Ibeaaa5897ae37b37c1e91f3e47076e4e8e4a8ded Closes-Bug: #1565112
This commit is contained in:
parent
a1a470693e
commit
3a8320a1d7
@ -114,6 +114,12 @@ OPTIONS
|
|||||||
:option:`--verify` | :option:`--insecure`
|
:option:`--verify` | :option:`--insecure`
|
||||||
Verify or ignore server certificate (default: verify)
|
Verify or ignore server certificate (default: verify)
|
||||||
|
|
||||||
|
:option:`--os-cert` <certificate-file>
|
||||||
|
Client certificate bundle file
|
||||||
|
|
||||||
|
:option:`--os-key` <key-file>
|
||||||
|
Client certificate key file
|
||||||
|
|
||||||
:option:`--os-identity-api-version` <identity-api-version>
|
:option:`--os-identity-api-version` <identity-api-version>
|
||||||
Identity API version (Default: 2.0)
|
Identity API version (Default: 2.0)
|
||||||
|
|
||||||
@ -367,6 +373,12 @@ The following environment variables can be set to alter the behaviour of :progra
|
|||||||
:envvar:`OS_CACERT`
|
:envvar:`OS_CACERT`
|
||||||
CA certificate bundle file
|
CA certificate bundle file
|
||||||
|
|
||||||
|
:envvar:`OS_CERT`
|
||||||
|
Client certificate bundle file
|
||||||
|
|
||||||
|
:envvar:`OS_KEY`
|
||||||
|
Client certificate key file
|
||||||
|
|
||||||
:envvar:`OS_IDENTITY_API_VERSION`
|
:envvar:`OS_IDENTITY_API_VERSION`
|
||||||
Identity API version (Default: 2.0)
|
Identity API version (Default: 2.0)
|
||||||
|
|
||||||
|
@ -110,6 +110,15 @@ class ClientManager(object):
|
|||||||
self._cacert = verify
|
self._cacert = verify
|
||||||
self._insecure = False
|
self._insecure = False
|
||||||
|
|
||||||
|
# Set up client certificate and key
|
||||||
|
# NOTE(cbrandily): This converts client certificate/key to requests
|
||||||
|
# cert argument: None (no client certificate), a path
|
||||||
|
# to client certificate or a tuple with client
|
||||||
|
# certificate/key paths.
|
||||||
|
self._cert = self._cli_options.cert
|
||||||
|
if self._cert and self._cli_options.key:
|
||||||
|
self._cert = self._cert, self._cli_options.key
|
||||||
|
|
||||||
# Get logging from root logger
|
# Get logging from root logger
|
||||||
root_logger = logging.getLogger('')
|
root_logger = logging.getLogger('')
|
||||||
LOG.setLevel(root_logger.getEffectiveLevel())
|
LOG.setLevel(root_logger.getEffectiveLevel())
|
||||||
@ -194,6 +203,7 @@ class ClientManager(object):
|
|||||||
auth=self.auth,
|
auth=self.auth,
|
||||||
session=request_session,
|
session=request_session,
|
||||||
verify=self._verify,
|
verify=self._verify,
|
||||||
|
cert=self._cert,
|
||||||
user_agent=USER_AGENT,
|
user_agent=USER_AGENT,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -189,6 +189,18 @@ class OpenStackShell(app.App):
|
|||||||
dest='cacert',
|
dest='cacert',
|
||||||
default=utils.env('OS_CACERT'),
|
default=utils.env('OS_CACERT'),
|
||||||
help='CA certificate bundle file (Env: OS_CACERT)')
|
help='CA certificate bundle file (Env: OS_CACERT)')
|
||||||
|
parser.add_argument(
|
||||||
|
'--os-cert',
|
||||||
|
metavar='<certificate-file>',
|
||||||
|
dest='cert',
|
||||||
|
default=utils.env('OS_CERT'),
|
||||||
|
help='Client certificate bundle file (Env: OS_CERT)')
|
||||||
|
parser.add_argument(
|
||||||
|
'--os-key',
|
||||||
|
metavar='<key-file>',
|
||||||
|
dest='key',
|
||||||
|
default=utils.env('OS_KEY'),
|
||||||
|
help='Client certificate key file (Env: OS_KEY)')
|
||||||
verify_group = parser.add_mutually_exclusive_group()
|
verify_group = parser.add_mutually_exclusive_group()
|
||||||
verify_group.add_argument(
|
verify_group.add_argument(
|
||||||
'--verify',
|
'--verify',
|
||||||
|
@ -58,6 +58,8 @@ class FakeOptions(object):
|
|||||||
self.interface = None
|
self.interface = None
|
||||||
self.url = None
|
self.url = None
|
||||||
self.auth = {}
|
self.auth = {}
|
||||||
|
self.cert = None
|
||||||
|
self.key = None
|
||||||
self.default_domain = 'default'
|
self.default_domain = 'default'
|
||||||
self.__dict__.update(kwargs)
|
self.__dict__.update(kwargs)
|
||||||
|
|
||||||
@ -268,6 +270,21 @@ class TestClientManager(utils.TestCase):
|
|||||||
self.assertEqual('cafile', client_manager._cacert)
|
self.assertEqual('cafile', client_manager._cacert)
|
||||||
self.assertTrue(client_manager.is_network_endpoint_enabled())
|
self.assertTrue(client_manager.is_network_endpoint_enabled())
|
||||||
|
|
||||||
|
def test_client_manager_password_no_cert(self):
|
||||||
|
client_manager = clientmanager.ClientManager(
|
||||||
|
cli_options=FakeOptions())
|
||||||
|
self.assertIsNone(client_manager._cert)
|
||||||
|
|
||||||
|
def test_client_manager_password_client_cert(self):
|
||||||
|
client_manager = clientmanager.ClientManager(
|
||||||
|
cli_options=FakeOptions(cert='cert'))
|
||||||
|
self.assertEqual('cert', client_manager._cert)
|
||||||
|
|
||||||
|
def test_client_manager_password_client_cert_and_key(self):
|
||||||
|
client_manager = clientmanager.ClientManager(
|
||||||
|
cli_options=FakeOptions(cert='cert', key='key'))
|
||||||
|
self.assertEqual(('cert', 'key'), client_manager._cert)
|
||||||
|
|
||||||
def _select_auth_plugin(self, auth_params, api_version, auth_plugin_name):
|
def _select_auth_plugin(self, auth_params, api_version, auth_plugin_name):
|
||||||
auth_params['auth_type'] = auth_plugin_name
|
auth_params['auth_type'] = auth_plugin_name
|
||||||
auth_params['identity_api_version'] = api_version
|
auth_params['identity_api_version'] = api_version
|
||||||
|
@ -79,6 +79,8 @@ CLOUD_2 = {
|
|||||||
'region_name': 'occ-cloud,krikkit,occ-env',
|
'region_name': 'occ-cloud,krikkit,occ-env',
|
||||||
'log_file': '/tmp/test_log_file',
|
'log_file': '/tmp/test_log_file',
|
||||||
'log_level': 'debug',
|
'log_level': 'debug',
|
||||||
|
'cert': 'mycert',
|
||||||
|
'key': 'mickey',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -567,6 +569,24 @@ class TestShellCli(TestShell):
|
|||||||
self.assertEqual('foo', _shell.options.cacert)
|
self.assertEqual('foo', _shell.options.cacert)
|
||||||
self.assertFalse(_shell.verify)
|
self.assertFalse(_shell.verify)
|
||||||
|
|
||||||
|
def test_shell_args_cert_options(self):
|
||||||
|
_shell = make_shell()
|
||||||
|
|
||||||
|
# Default
|
||||||
|
fake_execute(_shell, "list user")
|
||||||
|
self.assertEqual('', _shell.options.cert)
|
||||||
|
self.assertEqual('', _shell.options.key)
|
||||||
|
|
||||||
|
# --os-cert
|
||||||
|
fake_execute(_shell, "--os-cert mycert list user")
|
||||||
|
self.assertEqual('mycert', _shell.options.cert)
|
||||||
|
self.assertEqual('', _shell.options.key)
|
||||||
|
|
||||||
|
# --os-key
|
||||||
|
fake_execute(_shell, "--os-key mickey list user")
|
||||||
|
self.assertEqual('', _shell.options.cert)
|
||||||
|
self.assertEqual('mickey', _shell.options.key)
|
||||||
|
|
||||||
def test_default_env(self):
|
def test_default_env(self):
|
||||||
flag = ""
|
flag = ""
|
||||||
kwargs = {
|
kwargs = {
|
||||||
@ -670,6 +690,9 @@ class TestShellCli(TestShell):
|
|||||||
_shell.cloud.config['region_name'],
|
_shell.cloud.config['region_name'],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.assertEqual('mycert', _shell.cloud.config['cert'])
|
||||||
|
self.assertEqual('mickey', _shell.cloud.config['key'])
|
||||||
|
|
||||||
@mock.patch("os_client_config.config.OpenStackConfig._load_vendor_file")
|
@mock.patch("os_client_config.config.OpenStackConfig._load_vendor_file")
|
||||||
@mock.patch("os_client_config.config.OpenStackConfig._load_config_file")
|
@mock.patch("os_client_config.config.OpenStackConfig._load_config_file")
|
||||||
def test_shell_args_precedence(self, config_mock, vendor_mock):
|
def test_shell_args_precedence(self, config_mock, vendor_mock):
|
||||||
|
6
releasenotes/notes/bug_1565112-e0cea9bfbcab954f.yaml
Normal file
6
releasenotes/notes/bug_1565112-e0cea9bfbcab954f.yaml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- Support client certificate/key. Client certificate/key can be provided
|
||||||
|
using --os-cert/--os-key options, $OS_CERT/$OS_KEY environment
|
||||||
|
variables or os-client-config config.
|
||||||
|
[Bug `1565112 <https://bugs.launchpad.net/bugs/1565112>`_]
|
Loading…
Reference in New Issue
Block a user