From 6baa5f84ba7428635ddd8b9262f1133cdb4652c5 Mon Sep 17 00:00:00 2001 From: Goutham Pratapa Date: Wed, 23 Aug 2017 17:47:33 +0530 Subject: [PATCH] Support for Project_domain_id and user_domain_id. Currently in Mistral-client There is support for only PROJECT_DOMAIN_NAME but in the latest release of OpenStack, there is an option PROJECT_DOMAIN_ID.This DOMAIN_ID option is evident in few cloud environments and not evident in other so it is better to give support for both DOMAIN_ID and DOMAIN_NAME. In Mistral Client though the option to use target_user_domain_name and target_project_domain_name are not used in the authentication. This commit is to use them. Added unit-testcases for the same and added few more for robustness. Closes-Bug: #1712545 Closes-Bug: #1712739 Change-Id: I64aa2ff3324ba770c1e3aabb6410cca91c793c15 --- mistralclient/auth/keystone.py | 14 ++- mistralclient/shell.py | 50 +++++++++- mistralclient/tests/unit/test_shell.py | 121 +++++++++++++++++++++++++ 3 files changed, 179 insertions(+), 6 deletions(-) diff --git a/mistralclient/auth/keystone.py b/mistralclient/auth/keystone.py index be105449..4e567b44 100644 --- a/mistralclient/auth/keystone.py +++ b/mistralclient/auth/keystone.py @@ -50,10 +50,11 @@ class KeystoneAuthHandler(mistral_auth.AuthHandler): project_id = req.get('project_id') region_name = req.get('region_name') user_domain_name = req.get('user_domain_name') + user_domain_id = req.get('user_domain_id') project_domain_name = req.get('project_domain_name') + project_domain_id = req.get('project_domain_id') cacert = req.get('cacert') insecure = req.get('insecure', False) - target_auth_url = req.get('target_auth_url') target_username = req.get('target_username') target_user_id = req.get('target_user_id') @@ -62,7 +63,9 @@ class KeystoneAuthHandler(mistral_auth.AuthHandler): target_project_name = req.get('target_project_name') target_project_id = req.get('target_project_id') target_user_domain_name = req.get('target_user_domain_name') + target_user_domain_id = req.get('target_user_domain_id') target_project_domain_name = req.get('target_project_domain_name') + target_project_domain_id = req.get('target_project_domain_id') target_cacert = req.get('target_cacert') target_insecure = req.get('target_insecure') @@ -87,6 +90,7 @@ class KeystoneAuthHandler(mistral_auth.AuthHandler): project_id=project_id, project_name=project_name, project_domain_name=project_domain_name, + project_domain_id=project_domain_id, cacert=cacert, insecure=insecure) elif api_key and (username or user_id): @@ -96,9 +100,11 @@ class KeystoneAuthHandler(mistral_auth.AuthHandler): user_id=user_id, password=api_key, user_domain_name=user_domain_name, + user_domain_id=user_domain_id, project_id=project_id, project_name=project_name, - project_domain_name=project_domain_name) + project_domain_name=project_domain_name, + project_domain_id=project_domain_id) else: # NOTE(jaosorior): We don't crash here cause it's needed for @@ -132,6 +138,7 @@ class KeystoneAuthHandler(mistral_auth.AuthHandler): project_id=target_project_id, project_name=target_project_name, project_domain_name=target_project_domain_name, + project_domain_id=target_project_domain_id, cacert=target_cacert, insecure=target_insecure) elif target_api_key and (target_username or target_user_id): @@ -141,10 +148,11 @@ class KeystoneAuthHandler(mistral_auth.AuthHandler): user_id=target_user_id, password=target_api_key, user_domain_name=target_user_domain_name, + user_domain_id=target_user_domain_id, project_id=target_project_id, project_name=target_project_name, project_domain_name=target_project_domain_name, - ) + project_domain_id=target_project_domain_id) else: raise RuntimeError("You must either provide a valid token or " "a password (target_api_key) and a user.") diff --git a/mistralclient/shell.py b/mistralclient/shell.py index d7a95095..399f92b1 100644 --- a/mistralclient/shell.py +++ b/mistralclient/shell.py @@ -313,8 +313,17 @@ class MistralShell(app.App): action='store', dest='project_domain_name', default=env('OS_PROJECT_DOMAIN_NAME'), - help='Authentication project domain name' - ' (Env: OS_PROJECT_DOMAIN_NAME)' + help='Authentication project domain name or ID' + ' (Env: OS_PROJECT_DOMAIN_NAME or OS_PROJECT_DOMAIN_NAME)' + ) + + parser.add_argument( + '--os-project-domain-id', + action='store', + dest='project_domain_id', + default=env('OS_PROJECT_DOMAIN_ID'), + help='Authentication project domain ID' + ' (Env: OS_PROJECT_DOMAIN_ID)' ) parser.add_argument( @@ -326,6 +335,15 @@ class MistralShell(app.App): ' (Env: OS_USER_DOMAIN_NAME)' ) + parser.add_argument( + '--os-user-domain-id', + action='store', + dest='user_domain_id', + default=env('OS_USER_DOMAIN_ID'), + help='Authentication user domain name' + ' (Env: OS_USER_DOMAIN_ID)' + ) + parser.add_argument( '--os-auth-url', action='store', @@ -483,6 +501,15 @@ class MistralShell(app.App): '(Env: OS_TARGET_USER_DOMAIN_NAME)' ) + parser.add_argument( + '--os-target-user-domain-id', + action='store', + dest='target_user_domain_id', + default=env('OS_TARGET_USER_DOMAIN_ID'), + help='User domain ID for target cloud' + '(Env: OS_TARGET_USER_DOMAIN_ID)' + ) + parser.add_argument( '--os-target-project-domain-name', action='store', @@ -492,6 +519,15 @@ class MistralShell(app.App): '(Env: OS_TARGET_PROJECT_DOMAIN_NAME)' ) + parser.add_argument( + '--os-target-project-domain-id', + action='store', + dest='target_project_domain_id', + default=env('OS_TARGET_PROJECT_DOMAIN_ID'), + help='Project domain ID for target cloud' + '(Env: OS_TARGET_PROJECT_DOMAIN_ID)' + ) + parser.add_argument( '--target_insecure', action='store_true', @@ -554,7 +590,15 @@ class MistralShell(app.App): 'cert': self.options.os_cert, 'key': self.options.os_key, 'user_domain_name': self.options.user_domain_name, - 'project_domain_name': self.options.project_domain_name + 'user_domain_id': self.options.user_domain_id, + 'project_domain_name': self.options.project_domain_name, + 'project_domain_id': self.options.project_domain_id, + 'target_project_domain_name': + self.options.target_project_domain_name, + 'target_project_domain_id': + self.options.target_project_domain_id, + 'target_user_domain_name': self.options.target_user_domain_name, + 'target_user_domain_id': self.options.target_user_domain_id } self.client = client.client( diff --git a/mistralclient/tests/unit/test_shell.py b/mistralclient/tests/unit/test_shell.py index 24e7a36d..d9397649 100644 --- a/mistralclient/tests/unit/test_shell.py +++ b/mistralclient/tests/unit/test_shell.py @@ -134,3 +134,124 @@ class TestShell(base.BaseShellTests): params = client_mock.call_args self.assertEqual('RegionOne', params[1]['region_name']) + + @mock.patch('mistralclient.api.client.client') + def test_tenant_id_and_tenant_name(self, client_mock): + self.shell( + '--os-tenant-id=123tenant --os-tenant-name=fake_tenant' + ' workbook-list') + + self.assertTrue(client_mock.called) + + params = client_mock.call_args + self.assertEqual('fake_tenant', params[1]['project_name']) + self.assertEqual('123tenant', params[1]['project_id']) + + @mock.patch('mistralclient.api.client.client') + def test_project_id_and_project_name(self, client_mock): + self.shell( + '--os-project-name=fake_tenant --os-project-id=123tenant' + ' workbook-list') + + self.assertTrue(client_mock.called) + + params = client_mock.call_args + + self.assertEqual('fake_tenant', params[1]['project_name']) + self.assertEqual('123tenant', params[1]['project_id']) + + @mock.patch('mistralclient.api.client.client') + def test_project_domain_name(self, client_mock): + self.shell('--os-project-domain-name=default workbook-list') + + self.assertTrue(client_mock.called) + + params = client_mock.call_args + + self.assertEqual('default', params[1]['project_domain_name']) + + @mock.patch('mistralclient.api.client.client') + def test_project_domain_id(self, client_mock): + self.shell('--os-project-domain-id=default workbook-list') + + self.assertTrue(client_mock.called) + + params = client_mock.call_args + + self.assertEqual('default', params[1]['project_domain_id']) + + @mock.patch('mistralclient.api.client.client') + def test_user_domain_name(self, client_mock): + self.shell('--os-user-domain-name=default workbook-list') + + self.assertTrue(client_mock.called) + + params = client_mock.call_args + self.assertEqual('default', params[1]['user_domain_name']) + + @mock.patch('mistralclient.api.client.client') + def test_user_domain_id(self, client_mock): + self.shell('--os-user-domain-id=default workbook-list') + + self.assertTrue(client_mock.called) + + params = client_mock.call_args + self.assertEqual('default', params[1]['user_domain_id']) + + @mock.patch('mistralclient.api.client.client') + def test_target_user_name_and_password(self, client_mock): + self.shell( + '--os-target-username=admin' + ' --os-target-password=secret_pass workbook-list') + self.assertTrue(client_mock.called) + + params = client_mock.call_args + self.assertEqual('admin', params[1]['target_username']) + self.assertEqual('secret_pass', params[1]['target_api_key']) + + @mock.patch('mistralclient.api.client.client') + def test_target_tenant_name_and_id(self, client_mock): + self.shell( + '--os-target-tenant-id=123fake' + ' --os-target-tenant-name=fake_target workbook-list') + self.assertTrue(client_mock.called) + + params = client_mock.call_args + self.assertEqual('123fake', params[1]['target_project_id']) + self.assertEqual('fake_target', params[1]['target_project_name']) + + @mock.patch('mistralclient.api.client.client') + def test_target_user_domain_id(self, client_mock): + self.shell('--os-target-user-domain-id=default workbook-list') + + self.assertTrue(client_mock.called) + + params = client_mock.call_args + self.assertEqual('default', params[1]['target_user_domain_id']) + + @mock.patch('mistralclient.api.client.client') + def test_target_user_domain_name(self, client_mock): + self.shell('--os-target-user-domain-name=default workbook-list') + + self.assertTrue(client_mock.called) + + params = client_mock.call_args + self.assertEqual('default', params[1]['target_user_domain_name']) + + @mock.patch('mistralclient.api.client.client') + def test_target_project_domain_id(self, client_mock): + self.shell('--os-target-project-domain-id=default workbook-list') + + self.assertTrue(client_mock.called) + + params = client_mock.call_args + self.assertEqual('default', params[1]['target_project_domain_id']) + + @mock.patch('mistralclient.api.client.client') + def test_target_project_domain_name(self, client_mock): + self.shell('--os-target-project-domain-name=default workbook-list') + + self.assertTrue(client_mock.called) + + params = client_mock.call_args + self.assertEqual('default', params[1]['target_project_domain_name'])