Skip to content

Commit 0edab95

Browse files
Jenkinsopenstack-gerrit
authored andcommitted
Merge "Support client certificate/key"
2 parents 7767e5d + 3a8320a commit 0edab95

6 files changed

Lines changed: 80 additions & 0 deletions

File tree

doc/source/man/openstack.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,12 @@ OPTIONS
114114
:option:`--verify` | :option:`--insecure`
115115
Verify or ignore server certificate (default: verify)
116116

117+
:option:`--os-cert` <certificate-file>
118+
Client certificate bundle file
119+
120+
:option:`--os-key` <key-file>
121+
Client certificate key file
122+
117123
:option:`--os-identity-api-version` <identity-api-version>
118124
Identity API version (Default: 2.0)
119125

@@ -367,6 +373,12 @@ The following environment variables can be set to alter the behaviour of :progra
367373
:envvar:`OS_CACERT`
368374
CA certificate bundle file
369375

376+
:envvar:`OS_CERT`
377+
Client certificate bundle file
378+
379+
:envvar:`OS_KEY`
380+
Client certificate key file
381+
370382
:envvar:`OS_IDENTITY_API_VERSION`
371383
Identity API version (Default: 2.0)
372384

openstackclient/common/clientmanager.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,15 @@ def __init__(
110110
self._cacert = verify
111111
self._insecure = False
112112

113+
# Set up client certificate and key
114+
# NOTE(cbrandily): This converts client certificate/key to requests
115+
# cert argument: None (no client certificate), a path
116+
# to client certificate or a tuple with client
117+
# certificate/key paths.
118+
self._cert = self._cli_options.cert
119+
if self._cert and self._cli_options.key:
120+
self._cert = self._cert, self._cli_options.key
121+
113122
# Get logging from root logger
114123
root_logger = logging.getLogger('')
115124
LOG.setLevel(root_logger.getEffectiveLevel())
@@ -194,6 +203,7 @@ def setup_auth(self, required_scope=True):
194203
auth=self.auth,
195204
session=request_session,
196205
verify=self._verify,
206+
cert=self._cert,
197207
user_agent=USER_AGENT,
198208
)
199209

openstackclient/shell.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,18 @@ def build_option_parser(self, description, version):
189189
dest='cacert',
190190
default=utils.env('OS_CACERT'),
191191
help='CA certificate bundle file (Env: OS_CACERT)')
192+
parser.add_argument(
193+
'--os-cert',
194+
metavar='<certificate-file>',
195+
dest='cert',
196+
default=utils.env('OS_CERT'),
197+
help='Client certificate bundle file (Env: OS_CERT)')
198+
parser.add_argument(
199+
'--os-key',
200+
metavar='<key-file>',
201+
dest='key',
202+
default=utils.env('OS_KEY'),
203+
help='Client certificate key file (Env: OS_KEY)')
192204
verify_group = parser.add_mutually_exclusive_group()
193205
verify_group.add_argument(
194206
'--verify',

openstackclient/tests/common/test_clientmanager.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ def __init__(self, **kwargs):
5858
self.interface = None
5959
self.url = None
6060
self.auth = {}
61+
self.cert = None
62+
self.key = None
6163
self.default_domain = 'default'
6264
self.__dict__.update(kwargs)
6365

@@ -268,6 +270,21 @@ def test_client_manager_password_verify_ca(self):
268270
self.assertEqual('cafile', client_manager._cacert)
269271
self.assertTrue(client_manager.is_network_endpoint_enabled())
270272

273+
def test_client_manager_password_no_cert(self):
274+
client_manager = clientmanager.ClientManager(
275+
cli_options=FakeOptions())
276+
self.assertIsNone(client_manager._cert)
277+
278+
def test_client_manager_password_client_cert(self):
279+
client_manager = clientmanager.ClientManager(
280+
cli_options=FakeOptions(cert='cert'))
281+
self.assertEqual('cert', client_manager._cert)
282+
283+
def test_client_manager_password_client_cert_and_key(self):
284+
client_manager = clientmanager.ClientManager(
285+
cli_options=FakeOptions(cert='cert', key='key'))
286+
self.assertEqual(('cert', 'key'), client_manager._cert)
287+
271288
def _select_auth_plugin(self, auth_params, api_version, auth_plugin_name):
272289
auth_params['auth_type'] = auth_plugin_name
273290
auth_params['identity_api_version'] = api_version

openstackclient/tests/test_shell.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@
8080
'region_name': 'occ-cloud,krikkit,occ-env',
8181
'log_file': '/tmp/test_log_file',
8282
'log_level': 'debug',
83+
'cert': 'mycert',
84+
'key': 'mickey',
8385
}
8486
}
8587
}
@@ -562,6 +564,24 @@ def test_shell_args_ca_options(self):
562564
self.assertEqual('foo', _shell.options.cacert)
563565
self.assertFalse(_shell.verify)
564566

567+
def test_shell_args_cert_options(self):
568+
_shell = make_shell()
569+
570+
# Default
571+
fake_execute(_shell, "list user")
572+
self.assertEqual('', _shell.options.cert)
573+
self.assertEqual('', _shell.options.key)
574+
575+
# --os-cert
576+
fake_execute(_shell, "--os-cert mycert list user")
577+
self.assertEqual('mycert', _shell.options.cert)
578+
self.assertEqual('', _shell.options.key)
579+
580+
# --os-key
581+
fake_execute(_shell, "--os-key mickey list user")
582+
self.assertEqual('', _shell.options.cert)
583+
self.assertEqual('mickey', _shell.options.key)
584+
565585
def test_default_env(self):
566586
flag = ""
567587
kwargs = {
@@ -665,6 +685,9 @@ def test_shell_args_cloud_public(self, config_mock, public_mock):
665685
_shell.cloud.config['region_name'],
666686
)
667687

688+
self.assertEqual('mycert', _shell.cloud.config['cert'])
689+
self.assertEqual('mickey', _shell.cloud.config['key'])
690+
668691
@mock.patch("os_client_config.config.OpenStackConfig._load_vendor_file")
669692
@mock.patch("os_client_config.config.OpenStackConfig._load_config_file")
670693
def test_shell_args_precedence(self, config_mock, vendor_mock):
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
features:
3+
- Support client certificate/key. Client certificate/key can be provided
4+
using --os-cert/--os-key options, $OS_CERT/$OS_KEY environment
5+
variables or os-client-config config.
6+
[Bug `1565112 <https://bugs.launchpad.net/bugs/1565112>`_]

0 commit comments

Comments
 (0)