Modify v1 client
This commit is contained in:
parent
1d3450c8cf
commit
06d6a356f6
2
.gitignore
vendored
2
.gitignore
vendored
@ -2,6 +2,8 @@
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
|
||||
*.sw?
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
|
@ -41,7 +41,7 @@ from bileanclient import shell as openstack_shell
|
||||
from bileanclient.tests.unit import utils as testutils
|
||||
|
||||
|
||||
DEFAULT_IMAGE_URL = 'http://127.0.0.1:8770/'
|
||||
DEFAULT_BILEAN_URL = 'http://127.0.0.1:5000/'
|
||||
DEFAULT_USERNAME = 'username'
|
||||
DEFAULT_PASSWORD = 'password'
|
||||
DEFAULT_TENANT_ID = 'tenant_id'
|
||||
@ -51,33 +51,33 @@ DEFAULT_USER_DOMAIN_NAME = 'user_domain_name'
|
||||
DEFAULT_UNVERSIONED_AUTH_URL = 'http://127.0.0.1:5000/'
|
||||
DEFAULT_V2_AUTH_URL = '%sv2.0' % DEFAULT_UNVERSIONED_AUTH_URL
|
||||
DEFAULT_V3_AUTH_URL = '%sv3' % DEFAULT_UNVERSIONED_AUTH_URL
|
||||
DEFAULT_AUTH_TOKEN = ' 3bcc3d3a03f44e3d8377f9247b0ad155'
|
||||
TEST_SERVICE_URL = 'http://127.0.0.1:8770/'
|
||||
DEFAULT_AUTH_TOKEN = 'ba5501a434914768824374764adb8014'
|
||||
TEST_SERVICE_URL = 'http://127.0.0.1:5000/'
|
||||
|
||||
FAKE_V2_ENV = {'OS_USERNAME': DEFAULT_USERNAME,
|
||||
'OS_PASSWORD': DEFAULT_PASSWORD,
|
||||
'OS_TENANT_NAME': DEFAULT_TENANT_NAME,
|
||||
'OS_AUTH_URL': DEFAULT_V2_AUTH_URL,
|
||||
'OS_IMAGE_URL': DEFAULT_IMAGE_URL}
|
||||
'OS_IMAGE_URL': DEFAULT_BILEAN_URL}
|
||||
|
||||
FAKE_V3_ENV = {'OS_USERNAME': DEFAULT_USERNAME,
|
||||
'OS_PASSWORD': DEFAULT_PASSWORD,
|
||||
'OS_PROJECT_ID': DEFAULT_PROJECT_ID,
|
||||
'OS_USER_DOMAIN_NAME': DEFAULT_USER_DOMAIN_NAME,
|
||||
'OS_AUTH_URL': DEFAULT_V3_AUTH_URL,
|
||||
'OS_IMAGE_URL': DEFAULT_IMAGE_URL}
|
||||
'OS_IMAGE_URL': DEFAULT_BILEAN_URL}
|
||||
|
||||
TOKEN_ID = uuid.uuid4().hex
|
||||
|
||||
V2_TOKEN = ks_fixture.V2Token(token_id=TOKEN_ID)
|
||||
V2_TOKEN.set_scope()
|
||||
_s = V2_TOKEN.add_service('billing', name='bilean')
|
||||
_s.add_endpoint(DEFAULT_IMAGE_URL)
|
||||
_s.add_endpoint(DEFAULT_BILEAN_URL)
|
||||
|
||||
V3_TOKEN = ks_fixture.V3Token()
|
||||
V3_TOKEN.set_project_scope()
|
||||
_s = V3_TOKEN.add_service('billing', name='bilean')
|
||||
_s.add_standard_endpoints(public=DEFAULT_IMAGE_URL)
|
||||
_s.add_standard_endpoints(public=DEFAULT_BILEAN_URL)
|
||||
|
||||
|
||||
class ShellTest(testutils.TestCase):
|
||||
@ -99,7 +99,7 @@ class ShellTest(testutils.TestCase):
|
||||
self.requests = self.useFixture(rm_fixture.Fixture())
|
||||
|
||||
json_list = ks_fixture.DiscoveryList(DEFAULT_UNVERSIONED_AUTH_URL)
|
||||
self.requests.get(DEFAULT_IMAGE_URL, json=json_list, status_code=300)
|
||||
self.requests.get(DEFAULT_BILEAN_URL, json=json_list, status_code=300)
|
||||
|
||||
json_v2 = {'version': ks_fixture.V2Discovery(DEFAULT_V2_AUTH_URL)}
|
||||
self.requests.get(DEFAULT_V2_AUTH_URL, json=json_v2)
|
||||
@ -217,30 +217,35 @@ class ShellTest(testutils.TestCase):
|
||||
formatter_class=openstack_shell.HelpFormatter,)
|
||||
self.assertEqual(str(expected), str(actual_parser))
|
||||
|
||||
# @mock.patch.object(openstack_shell.BileanShell,
|
||||
# '_get_keystone_session')
|
||||
# @mock.patch.object(openstack_shell.BileanShell,
|
||||
# '_get_keystone_auth')
|
||||
# def test_cert_and_key_args_interchangeable(self,
|
||||
# mock_keystone_session,
|
||||
# mock_keystone_auth):
|
||||
# # make sure --os-cert and --os-key are passed correctly
|
||||
# args = ('--bilean-api-version 1 '
|
||||
# '--os-cert mycert '
|
||||
# '--os-key mykey user-list')
|
||||
# shell(args)
|
||||
# assert mock_keystone_session.called
|
||||
# args, kwargs = mock_keystone_session.call_args
|
||||
#
|
||||
# self.assertEqual('mycert', kwargs['cert'])
|
||||
# self.assertEqual('mykey', kwargs['key'])
|
||||
#
|
||||
@mock.patch.object(openstack_shell.BileanShell,
|
||||
'_get_versioned_client')
|
||||
def test_cert_and_key_args_interchangeable(self,
|
||||
mock_versioned_client):
|
||||
# make sure --os-cert and --os-key are passed correctly
|
||||
args = ('--os-cert mycert '
|
||||
'--os-key mykey user-list')
|
||||
shell(args)
|
||||
assert mock_versioned_client.called
|
||||
((api_version, args), kwargs) = mock_versioned_client.call_args
|
||||
self.assertEqual('mycert', args.os_cert)
|
||||
self.assertEqual('mykey', args.os_key)
|
||||
|
||||
# make sure we get the same thing with --cert-file and --key-file
|
||||
args = ('--cert-file mycertfile '
|
||||
'--key-file mykeyfile user-list')
|
||||
bilean_shell = openstack_shell.BileanShell()
|
||||
bilean_shell.main(args.split())
|
||||
assert mock_versioned_client.called
|
||||
((api_version, args), kwargs) = mock_versioned_client.call_args
|
||||
self.assertEqual('mycertfile', args.os_cert)
|
||||
self.assertEqual('mykeyfile', args.os_key)
|
||||
|
||||
@mock.patch('bileanclient.v1.client.Client')
|
||||
def test_no_auth_with_token_and_bilean_url(self, mock_client):
|
||||
# test no authentication is required if both token and endpoint url
|
||||
# are specified
|
||||
args = ('--os-bilean-api-version 1 --os-auth-token mytoken'
|
||||
' --os-bilean-url http://host:1234/v1 user-list')
|
||||
args = ('--os-auth-token mytoken '
|
||||
'--os-bilean-url http://host:1234/v1 user-list')
|
||||
bilean_shell = openstack_shell.BileanShell()
|
||||
bilean_shell.main(args.split())
|
||||
assert mock_client.called
|
||||
@ -248,389 +253,245 @@ class ShellTest(testutils.TestCase):
|
||||
self.assertEqual('mytoken', kwargs['token'])
|
||||
self.assertEqual('http://host:1234', args[0])
|
||||
|
||||
# @mock.patch('bileanclient.v1.client.Client')
|
||||
# def test_no_auth_with_token_and_image_url_with_v1(self, v1_client):
|
||||
# # test no authentication is required if both token and endpoint url
|
||||
# # are specified
|
||||
# args = ('--os-image-api-version 1 --os-auth-token mytoken'
|
||||
# ' --os-image-url https://image:1234/v1 image-list')
|
||||
# bilean_shell = openstack_shell.OpenStackImagesShell()
|
||||
# bilean_shell.main(args.split())
|
||||
# assert v1_client.called
|
||||
# (args, kwargs) = v1_client.call_args
|
||||
# self.assertEqual('mytoken', kwargs['token'])
|
||||
# self.assertEqual('https://image:1234', args[0])
|
||||
#
|
||||
# @mock.patch('bileanclient.v2.client.Client')
|
||||
# def test_no_auth_with_token_and_image_url_with_v2(self, v2_client):
|
||||
# # test no authentication is required if both token and endpoint url
|
||||
# # are specified
|
||||
# args = ('--os-image-api-version 2 --os-auth-token mytoken '
|
||||
# '--os-image-url https://image:1234 image-list')
|
||||
# bilean_shell = openstack_shell.OpenStackImagesShell()
|
||||
# bilean_shell.main(args.split())
|
||||
# self.assertTrue(v2_client.called)
|
||||
# (args, kwargs) = v2_client.call_args
|
||||
# self.assertEqual('mytoken', kwargs['token'])
|
||||
# self.assertEqual('https://image:1234', args[0])
|
||||
#
|
||||
# def _assert_auth_plugin_args(self):
|
||||
# # make sure our auth plugin is invoked with the correct args
|
||||
# self.assertFalse(self.v3_auth.called)
|
||||
#
|
||||
# body = json.loads(self.v2_auth.last_request.body)
|
||||
#
|
||||
# self.assertEqual(self.auth_env['OS_TENANT_NAME'],
|
||||
# body['auth']['tenantName'])
|
||||
# self.assertEqual(self.auth_env['OS_USERNAME'],
|
||||
# body['auth']['passwordCredentials']['username'])
|
||||
# self.assertEqual(self.auth_env['OS_PASSWORD'],
|
||||
# body['auth']['passwordCredentials']['password'])
|
||||
#
|
||||
# @mock.patch.object(openstack_shell.OpenStackImagesShell, '_cache_schemas',
|
||||
# return_value=False)
|
||||
# @mock.patch('bileanclient.v2.client.Client')
|
||||
# def test_auth_plugin_invocation_without_version(self,
|
||||
# v2_client,
|
||||
# cache_schemas):
|
||||
#
|
||||
# cli2 = mock.MagicMock()
|
||||
# v2_client.return_value = cli2
|
||||
# cli2.http_client.get.return_value = (None, {'versions':
|
||||
# [{'id': 'v2'}]})
|
||||
#
|
||||
# args = 'image-list'
|
||||
# bilean_shell = openstack_shell.OpenStackImagesShell()
|
||||
# bilean_shell.main(args.split())
|
||||
# # NOTE(flaper87): this currently calls auth twice since it'll
|
||||
# # authenticate to get the version list *and* to execute the command.
|
||||
# # This is not the ideal behavior and it should be fixed in a follow
|
||||
# # up patch.
|
||||
#
|
||||
# @mock.patch('bileanclient.v1.client.Client')
|
||||
# def test_auth_plugin_invocation_with_v1(self, v1_client):
|
||||
# args = '--os-image-api-version 1 image-list'
|
||||
# bilean_shell = openstack_shell.OpenStackImagesShell()
|
||||
# bilean_shell.main(args.split())
|
||||
# self.assertEqual(0, self.v2_auth.call_count)
|
||||
#
|
||||
# @mock.patch('bileanclient.v2.client.Client')
|
||||
# def test_auth_plugin_invocation_with_v2(self,
|
||||
# v2_client):
|
||||
# args = '--os-image-api-version 2 image-list'
|
||||
# bilean_shell = openstack_shell.OpenStackImagesShell()
|
||||
# bilean_shell.main(args.split())
|
||||
# self.assertEqual(0, self.v2_auth.call_count)
|
||||
#
|
||||
# @mock.patch('bileanclient.v1.client.Client')
|
||||
# def test_auth_plugin_invocation_with_unversioned_auth_url_with_v1(
|
||||
# self, v1_client):
|
||||
# args = ('--os-image-api-version 1 --os-auth-url %s image-list' %
|
||||
# DEFAULT_UNVERSIONED_AUTH_URL)
|
||||
# bilean_shell = openstack_shell.OpenStackImagesShell()
|
||||
# bilean_shell.main(args.split())
|
||||
#
|
||||
# @mock.patch('bileanclient.v2.client.Client')
|
||||
# @mock.patch.object(openstack_shell.OpenStackImagesShell, '_cache_schemas',
|
||||
# return_value=False)
|
||||
# def test_auth_plugin_invocation_with_unversioned_auth_url_with_v2(
|
||||
# self, v2_client, cache_schemas):
|
||||
# args = ('--os-auth-url %s --os-image-api-version 2 '
|
||||
# 'image-list') % DEFAULT_UNVERSIONED_AUTH_URL
|
||||
# bilean_shell = openstack_shell.OpenStackImagesShell()
|
||||
# bilean_shell.main(args.split())
|
||||
#
|
||||
# @mock.patch('bileanclient.Client')
|
||||
# def test_endpoint_token_no_auth_req(self, mock_client):
|
||||
#
|
||||
# def verify_input(version=None, endpoint=None, *args, **kwargs):
|
||||
# self.assertIn('token', kwargs)
|
||||
# self.assertEqual(TOKEN_ID, kwargs['token'])
|
||||
# self.assertEqual(DEFAULT_IMAGE_URL, endpoint)
|
||||
# return mock.MagicMock()
|
||||
#
|
||||
# mock_client.side_effect = verify_input
|
||||
# bilean_shell = openstack_shell.OpenStackImagesShell()
|
||||
# args = ['--os-image-api-version', '2',
|
||||
# '--os-auth-token', TOKEN_ID,
|
||||
# '--os-image-url', DEFAULT_IMAGE_URL,
|
||||
# 'image-list']
|
||||
#
|
||||
# bilean_shell.main(args)
|
||||
# self.assertEqual(1, mock_client.call_count)
|
||||
#
|
||||
# @mock.patch('bileanclient.v2.client.Client')
|
||||
# def test_password_prompted_with_v2(self, v2_client):
|
||||
# self.requests.post(self.token_url, exc=requests.ConnectionError)
|
||||
#
|
||||
# cli2 = mock.MagicMock()
|
||||
# v2_client.return_value = cli2
|
||||
# cli2.http_client.get.return_value = (None, {'versions': []})
|
||||
# bilean_shell = openstack_shell.OpenStackImagesShell()
|
||||
# os.environ['OS_PASSWORD'] = 'password'
|
||||
# self.assertRaises(exc.CommunicationError,
|
||||
# bilean_shell.main, ['image-list'])
|
||||
#
|
||||
# @mock.patch('sys.stdin', side_effect=mock.MagicMock)
|
||||
# @mock.patch('getpass.getpass', side_effect=EOFError)
|
||||
# @mock.patch('bileanclient.v2.client.Client')
|
||||
# def test_password_prompted_ctrlD_with_v2(self, v2_client,
|
||||
# mock_getpass, mock_stdin):
|
||||
# cli2 = mock.MagicMock()
|
||||
# v2_client.return_value = cli2
|
||||
# cli2.http_client.get.return_value = (None, {'versions': []})
|
||||
#
|
||||
# bilean_shell = openstack_shell.OpenStackImagesShell()
|
||||
# self.make_env(exclude='OS_PASSWORD')
|
||||
# # We should get Command Error because we mock Ctl-D.
|
||||
# self.assertRaises(exc.CommandError, bilean_shell.main, ['image-list'])
|
||||
# # Make sure we are actually prompted.
|
||||
# mock_getpass.assert_called_with('OS Password: ')
|
||||
#
|
||||
# @mock.patch(
|
||||
# 'bileanclient.shell.OpenStackImagesShell._get_keystone_session')
|
||||
# @mock.patch.object(openstack_shell.OpenStackImagesShell, '_cache_schemas',
|
||||
# return_value=False)
|
||||
# def test_no_auth_with_proj_name(self, cache_schemas, session):
|
||||
# with mock.patch('bileanclient.v2.client.Client'):
|
||||
# args = ('--os-project-name myname '
|
||||
# '--os-project-domain-name mydomain '
|
||||
# '--os-project-domain-id myid '
|
||||
# '--os-image-api-version 2 image-list')
|
||||
# bilean_shell = openstack_shell.OpenStackImagesShell()
|
||||
# bilean_shell.main(args.split())
|
||||
# ((args), kwargs) = session.call_args
|
||||
# self.assertEqual('myname', kwargs['project_name'])
|
||||
# self.assertEqual('mydomain', kwargs['project_domain_name'])
|
||||
# self.assertEqual('myid', kwargs['project_domain_id'])
|
||||
#
|
||||
# @mock.patch.object(openstack_shell.OpenStackImagesShell, 'main')
|
||||
# def test_shell_keyboard_interrupt(self, mock_bilean_shell):
|
||||
# # Ensure that exit code is 130 for KeyboardInterrupt
|
||||
# try:
|
||||
# mock_bilean_shell.side_effect = KeyboardInterrupt()
|
||||
# openstack_shell.main()
|
||||
# except SystemExit as ex:
|
||||
# self.assertEqual(130, ex.code)
|
||||
#
|
||||
# @mock.patch('bileanclient.common.utils.exit', side_effect=utils.exit)
|
||||
# def test_shell_illegal_version(self, mock_exit):
|
||||
# # Only int versions are allowed on cli
|
||||
# shell = openstack_shell.OpenStackImagesShell()
|
||||
# argstr = '--os-image-api-version 1.1 image-list'
|
||||
# try:
|
||||
# shell.main(argstr.split())
|
||||
# except SystemExit as ex:
|
||||
# self.assertEqual(1, ex.code)
|
||||
# msg = ("Invalid API version parameter. "
|
||||
# "Supported values are %s" % openstack_shell.SUPPORTED_VERSIONS)
|
||||
# mock_exit.assert_called_with(msg=msg)
|
||||
#
|
||||
# @mock.patch('bileanclient.common.utils.exit', side_effect=utils.exit)
|
||||
# def test_shell_unsupported_version(self, mock_exit):
|
||||
# # Test an integer version which is not supported (-1)
|
||||
# shell = openstack_shell.OpenStackImagesShell()
|
||||
# argstr = '--os-image-api-version -1 image-list'
|
||||
# try:
|
||||
# shell.main(argstr.split())
|
||||
# except SystemExit as ex:
|
||||
# self.assertEqual(1, ex.code)
|
||||
# msg = ("Invalid API version parameter. "
|
||||
# "Supported values are %s" % openstack_shell.SUPPORTED_VERSIONS)
|
||||
# mock_exit.assert_called_with(msg=msg)
|
||||
#
|
||||
# @mock.patch.object(openstack_shell.OpenStackImagesShell,
|
||||
# 'get_subcommand_parser')
|
||||
# def test_shell_import_error_with_mesage(self, mock_parser):
|
||||
# msg = 'Unable to import module xxx'
|
||||
# mock_parser.side_effect = ImportError('%s' % msg)
|
||||
# shell = openstack_shell.OpenStackImagesShell()
|
||||
# argstr = '--os-image-api-version 2 image-list'
|
||||
# try:
|
||||
# shell.main(argstr.split())
|
||||
# self.fail('No import error returned')
|
||||
# except ImportError as e:
|
||||
# self.assertEqual(msg, str(e))
|
||||
#
|
||||
# @mock.patch.object(openstack_shell.OpenStackImagesShell,
|
||||
# 'get_subcommand_parser')
|
||||
# def test_shell_import_error_default_message(self, mock_parser):
|
||||
# mock_parser.side_effect = ImportError
|
||||
# shell = openstack_shell.OpenStackImagesShell()
|
||||
# argstr = '--os-image-api-version 2 image-list'
|
||||
# try:
|
||||
# shell.main(argstr.split())
|
||||
# self.fail('No import error returned')
|
||||
# except ImportError as e:
|
||||
# msg = 'Unable to import module. Re-run with --debug for more info.'
|
||||
# self.assertEqual(msg, str(e))
|
||||
#
|
||||
# @mock.patch('bileanclient.v2.client.Client')
|
||||
# @mock.patch('bileanclient.v1.images.ImageManager.list')
|
||||
# def test_shell_v1_fallback_from_v2(self, v1_imgs, v2_client):
|
||||
# self.make_env()
|
||||
# cli2 = mock.MagicMock()
|
||||
# v2_client.return_value = cli2
|
||||
# cli2.http_client.get.return_value = (None, {'versions': []})
|
||||
# args = 'image-list'
|
||||
# bilean_shell = openstack_shell.OpenStackImagesShell()
|
||||
# bilean_shell.main(args.split())
|
||||
# self.assertFalse(cli2.schemas.get.called)
|
||||
# self.assertTrue(v1_imgs.called)
|
||||
#
|
||||
# @mock.patch.object(openstack_shell.OpenStackImagesShell,
|
||||
# '_cache_schemas')
|
||||
# @mock.patch('bileanclient.v2.client.Client')
|
||||
# def test_shell_no_fallback_from_v2(self, v2_client, cache_schemas):
|
||||
# self.make_env()
|
||||
# cli2 = mock.MagicMock()
|
||||
# v2_client.return_value = cli2
|
||||
# cli2.http_client.get.return_value = (None,
|
||||
# {'versions': [{'id': 'v2'}]})
|
||||
# cache_schemas.return_value = False
|
||||
# args = 'image-list'
|
||||
# bilean_shell = openstack_shell.OpenStackImagesShell()
|
||||
# bilean_shell.main(args.split())
|
||||
# self.assertTrue(cli2.images.list.called)
|
||||
#
|
||||
# @mock.patch('bileanclient.v1.client.Client')
|
||||
# def test_auth_plugin_invocation_without_username_with_v1(self, v1_client):
|
||||
# self.make_env(exclude='OS_USERNAME')
|
||||
# args = '--os-image-api-version 2 image-list'
|
||||
# bilean_shell = openstack_shell.OpenStackImagesShell()
|
||||
# self.assertRaises(exc.CommandError, bilean_shell.main, args.split())
|
||||
#
|
||||
# @mock.patch('bileanclient.v2.client.Client')
|
||||
# def test_auth_plugin_invocation_without_username_with_v2(self, v2_client):
|
||||
# self.make_env(exclude='OS_USERNAME')
|
||||
# args = '--os-image-api-version 2 image-list'
|
||||
# bilean_shell = openstack_shell.OpenStackImagesShell()
|
||||
# self.assertRaises(exc.CommandError, bilean_shell.main, args.split())
|
||||
#
|
||||
# @mock.patch('bileanclient.v1.client.Client')
|
||||
# def test_auth_plugin_invocation_without_auth_url_with_v1(self, v1_client):
|
||||
# self.make_env(exclude='OS_AUTH_URL')
|
||||
# args = '--os-image-api-version 1 image-list'
|
||||
# bilean_shell = openstack_shell.OpenStackImagesShell()
|
||||
# self.assertRaises(exc.CommandError, bilean_shell.main, args.split())
|
||||
#
|
||||
# @mock.patch('bileanclient.v2.client.Client')
|
||||
# def test_auth_plugin_invocation_without_auth_url_with_v2(self, v2_client):
|
||||
# self.make_env(exclude='OS_AUTH_URL')
|
||||
# args = '--os-image-api-version 2 image-list'
|
||||
# bilean_shell = openstack_shell.OpenStackImagesShell()
|
||||
# self.assertRaises(exc.CommandError, bilean_shell.main, args.split())
|
||||
#
|
||||
# @mock.patch('bileanclient.v1.client.Client')
|
||||
# def test_auth_plugin_invocation_without_tenant_with_v1(self, v1_client):
|
||||
# if 'OS_TENANT_NAME' in os.environ:
|
||||
# self.make_env(exclude='OS_TENANT_NAME')
|
||||
# if 'OS_PROJECT_ID' in os.environ:
|
||||
# self.make_env(exclude='OS_PROJECT_ID')
|
||||
# args = '--os-image-api-version 1 image-list'
|
||||
# bilean_shell = openstack_shell.OpenStackImagesShell()
|
||||
# self.assertRaises(exc.CommandError, bilean_shell.main, args.split())
|
||||
#
|
||||
# @mock.patch('bileanclient.v2.client.Client')
|
||||
# @mock.patch.object(openstack_shell.OpenStackImagesShell, '_cache_schemas',
|
||||
# return_value=False)
|
||||
# def test_auth_plugin_invocation_without_tenant_with_v2(self, v2_client,
|
||||
# cache_schemas):
|
||||
# if 'OS_TENANT_NAME' in os.environ:
|
||||
# self.make_env(exclude='OS_TENANT_NAME')
|
||||
# if 'OS_PROJECT_ID' in os.environ:
|
||||
# self.make_env(exclude='OS_PROJECT_ID')
|
||||
# args = '--os-image-api-version 2 image-list'
|
||||
# bilean_shell = openstack_shell.OpenStackImagesShell()
|
||||
# self.assertRaises(exc.CommandError, bilean_shell.main, args.split())
|
||||
#
|
||||
# @mock.patch('sys.argv', ['bilean'])
|
||||
# @mock.patch('sys.stdout', six.StringIO())
|
||||
# @mock.patch('sys.stderr', six.StringIO())
|
||||
# def test_main_noargs(self):
|
||||
# # Ensure that main works with no command-line arguments
|
||||
# try:
|
||||
# openstack_shell.main()
|
||||
# except SystemExit:
|
||||
# self.fail('Unexpected SystemExit')
|
||||
#
|
||||
# # We expect the normal v2 usage as a result
|
||||
# expected = ['Command-line interface to the OpenStack Images API',
|
||||
# 'image-list',
|
||||
# 'image-deactivate',
|
||||
# 'location-add']
|
||||
# for output in expected:
|
||||
# self.assertIn(output,
|
||||
# sys.stdout.getvalue())
|
||||
#
|
||||
# @mock.patch('bileanclient.v2.client.Client')
|
||||
# @mock.patch('bileanclient.v1.shell.do_image_list')
|
||||
# @mock.patch('bileanclient.shell.logging.basicConfig')
|
||||
# def test_setup_debug(self, conf, func, v2_client):
|
||||
# cli2 = mock.MagicMock()
|
||||
# v2_client.return_value = cli2
|
||||
# cli2.http_client.get.return_value = (None, {'versions': []})
|
||||
# args = '--debug image-list'
|
||||
# bilean_shell = openstack_shell.OpenStackImagesShell()
|
||||
# bilean_shell.main(args.split())
|
||||
# bilean_logger = logging.getLogger('bileanclient')
|
||||
# self.assertEqual(bilean_logger.getEffectiveLevel(), logging.DEBUG)
|
||||
# conf.assert_called_with(level=logging.DEBUG)
|
||||
#
|
||||
#
|
||||
#class ShellTestWithKeystoneV3Auth(ShellTest):
|
||||
# # auth environment to use
|
||||
# auth_env = FAKE_V3_ENV.copy()
|
||||
# token_url = DEFAULT_V3_AUTH_URL + '/auth/tokens'
|
||||
#
|
||||
# def _assert_auth_plugin_args(self):
|
||||
# self.assertFalse(self.v2_auth.called)
|
||||
#
|
||||
# body = json.loads(self.v3_auth.last_request.body)
|
||||
# user = body['auth']['identity']['password']['user']
|
||||
#
|
||||
# self.assertEqual(self.auth_env['OS_USERNAME'], user['name'])
|
||||
# self.assertEqual(self.auth_env['OS_PASSWORD'], user['password'])
|
||||
# self.assertEqual(self.auth_env['OS_USER_DOMAIN_NAME'],
|
||||
# user['domain']['name'])
|
||||
# self.assertEqual(self.auth_env['OS_PROJECT_ID'],
|
||||
# body['auth']['scope']['project']['id'])
|
||||
#
|
||||
# @mock.patch('bileanclient.v1.client.Client')
|
||||
# def test_auth_plugin_invocation_with_v1(self, v1_client):
|
||||
# args = '--os-image-api-version 1 image-list'
|
||||
# bilean_shell = openstack_shell.OpenStackImagesShell()
|
||||
# bilean_shell.main(args.split())
|
||||
# self.assertEqual(0, self.v3_auth.call_count)
|
||||
#
|
||||
# @mock.patch('bileanclient.v2.client.Client')
|
||||
# def test_auth_plugin_invocation_with_v2(self, v2_client):
|
||||
# args = '--os-image-api-version 2 image-list'
|
||||
# bilean_shell = openstack_shell.OpenStackImagesShell()
|
||||
# bilean_shell.main(args.split())
|
||||
# self.assertEqual(0, self.v3_auth.call_count)
|
||||
#
|
||||
# @mock.patch('keystoneclient.discover.Discover',
|
||||
# side_effect=ks_exc.ClientException())
|
||||
# def test_api_discovery_failed_with_unversioned_auth_url(self,
|
||||
# discover):
|
||||
# args = ('--os-image-api-version 2 --os-auth-url %s image-list'
|
||||
# % DEFAULT_UNVERSIONED_AUTH_URL)
|
||||
# bilean_shell = openstack_shell.OpenStackImagesShell()
|
||||
# self.assertRaises(exc.CommandError, bilean_shell.main, args.split())
|
||||
#
|
||||
# def test_bash_completion(self):
|
||||
# stdout, stderr = self.shell('--os-image-api-version 2 bash_completion')
|
||||
# # just check we have some output
|
||||
# required = [
|
||||
# '--status',
|
||||
# 'image-create',
|
||||
# 'help',
|
||||
# '--size']
|
||||
# for r in required:
|
||||
# self.assertIn(r, stdout.split())
|
||||
# avoided = [
|
||||
# 'bash_completion',
|
||||
# 'bash-completion']
|
||||
# for r in avoided:
|
||||
# self.assertNotIn(r, stdout.split())
|
||||
def _assert_auth_plugin_args(self):
|
||||
# make sure our auth plugin is invoked with the correct args
|
||||
self.assertFalse(self.v3_auth.called)
|
||||
|
||||
body = json.loads(self.v2_auth.last_request.body)
|
||||
|
||||
self.assertEqual(self.auth_env['OS_TENANT_NAME'],
|
||||
body['auth']['tenantName'])
|
||||
self.assertEqual(self.auth_env['OS_USERNAME'],
|
||||
body['auth']['passwordCredentials']['username'])
|
||||
self.assertEqual(self.auth_env['OS_PASSWORD'],
|
||||
body['auth']['passwordCredentials']['password'])
|
||||
|
||||
@mock.patch('bileanclient.v1.client.Client')
|
||||
def test_auth_plugin_invocation(self, v1_client):
|
||||
args = 'user-list'
|
||||
bilean_shell = openstack_shell.BileanShell()
|
||||
bilean_shell.main(args.split())
|
||||
self.assertEqual(0, self.v2_auth.call_count)
|
||||
|
||||
@mock.patch('bileanclient.v1.client.Client')
|
||||
def test_auth_plugin_invocation_with_unversioned_auth_url(
|
||||
self, v1_client):
|
||||
args = ('--os-auth-url %s user-list' % DEFAULT_UNVERSIONED_AUTH_URL)
|
||||
bilean_shell = openstack_shell.BileanShell()
|
||||
bilean_shell.main(args.split())
|
||||
|
||||
@mock.patch('bileanclient.Client')
|
||||
def test_endpoint_token_no_auth_req(self, mock_client):
|
||||
|
||||
def verify_input(version=None, endpoint=None, *args, **kwargs):
|
||||
self.assertIn('token', kwargs)
|
||||
self.assertEqual(TOKEN_ID, kwargs['token'])
|
||||
self.assertEqual(DEFAULT_BILEAN_URL, endpoint)
|
||||
return mock.MagicMock()
|
||||
|
||||
mock_client.side_effect = verify_input
|
||||
bilean_shell = openstack_shell.BileanShell()
|
||||
args = ['--os-auth-token', TOKEN_ID,
|
||||
'--os-bilean-url', DEFAULT_BILEAN_URL,
|
||||
'user-list']
|
||||
|
||||
bilean_shell.main(args)
|
||||
self.assertEqual(1, mock_client.call_count)
|
||||
|
||||
@mock.patch('sys.stdin', side_effect=mock.MagicMock)
|
||||
@mock.patch('getpass.getpass', side_effect=EOFError)
|
||||
@mock.patch('bileanclient.v1.client.Client')
|
||||
def test_password_prompted_ctrlD(self, v1_client,
|
||||
mock_getpass, mock_stdin):
|
||||
cli = mock.MagicMock()
|
||||
v1_client.return_value = cli
|
||||
cli.http_client.get.return_value = (None, {'versions': []})
|
||||
|
||||
bilean_shell = openstack_shell.BileanShell()
|
||||
self.make_env(exclude='OS_PASSWORD')
|
||||
# We should get Command Error because we mock Ctl-D.
|
||||
self.assertRaises(exc.CommandError, bilean_shell.main, ['user-list'])
|
||||
# Make sure we are actually prompted.
|
||||
mock_getpass.assert_called_with('OS Password: ')
|
||||
|
||||
@mock.patch(
|
||||
'bileanclient.shell.BileanShell._get_keystone_session')
|
||||
def test_no_auth_with_proj_name(self, session):
|
||||
with mock.patch('bileanclient.v1.client.Client'):
|
||||
args = ('--os-project-name myname '
|
||||
'--os-project-domain-name mydomain '
|
||||
'--os-project-domain-id myid user-list')
|
||||
bilean_shell = openstack_shell.BileanShell()
|
||||
bilean_shell.main(args.split())
|
||||
((args), kwargs) = session.call_args
|
||||
self.assertEqual('myname', kwargs['project_name'])
|
||||
self.assertEqual('mydomain', kwargs['project_domain_name'])
|
||||
self.assertEqual('myid', kwargs['project_domain_id'])
|
||||
|
||||
@mock.patch.object(openstack_shell.BileanShell, 'main')
|
||||
def test_shell_keyboard_interrupt(self, mock_bilean_shell):
|
||||
# Ensure that exit code is 130 for KeyboardInterrupt
|
||||
try:
|
||||
mock_bilean_shell.side_effect = KeyboardInterrupt()
|
||||
openstack_shell.main()
|
||||
except SystemExit as ex:
|
||||
self.assertEqual(130, ex.code)
|
||||
|
||||
@mock.patch('bileanclient.common.utils.exit', side_effect=utils.exit)
|
||||
def test_shell_illegal_version(self, mock_exit):
|
||||
# Only int versions are allowed on cli
|
||||
shell = openstack_shell.BileanShell()
|
||||
argstr = '--os-bilean-api-version 1.1 user-list'
|
||||
try:
|
||||
shell.main(argstr.split())
|
||||
except SystemExit as ex:
|
||||
self.assertEqual(1, ex.code)
|
||||
msg = ("Invalid API version parameter. "
|
||||
"Supported values are %s" % openstack_shell.SUPPORTED_VERSIONS)
|
||||
mock_exit.assert_called_with(msg=msg)
|
||||
|
||||
@mock.patch('bileanclient.common.utils.exit', side_effect=utils.exit)
|
||||
def test_shell_unsupported_version(self, mock_exit):
|
||||
# Test an integer version which is not supported (-1)
|
||||
shell = openstack_shell.BileanShell()
|
||||
argstr = '--os-bilean-api-version -1 user-list'
|
||||
try:
|
||||
shell.main(argstr.split())
|
||||
except SystemExit as ex:
|
||||
self.assertEqual(1, ex.code)
|
||||
msg = ("Invalid API version parameter. "
|
||||
"Supported values are %s" % openstack_shell.SUPPORTED_VERSIONS)
|
||||
mock_exit.assert_called_with(msg=msg)
|
||||
|
||||
@mock.patch.object(openstack_shell.BileanShell,
|
||||
'get_subcommand_parser')
|
||||
def test_shell_import_error_with_mesage(self, mock_parser):
|
||||
msg = 'Unable to import module xxx'
|
||||
mock_parser.side_effect = ImportError('%s' % msg)
|
||||
shell = openstack_shell.BileanShell()
|
||||
argstr = '--os-bilean-api-version 1 user-list'
|
||||
try:
|
||||
shell.main(argstr.split())
|
||||
self.fail('No import error returned')
|
||||
except ImportError as e:
|
||||
self.assertEqual(msg, str(e))
|
||||
|
||||
@mock.patch.object(openstack_shell.BileanShell,
|
||||
'get_subcommand_parser')
|
||||
def test_shell_import_error_default_message(self, mock_parser):
|
||||
mock_parser.side_effect = ImportError
|
||||
shell = openstack_shell.BileanShell()
|
||||
argstr = '--os-bilean-api-version 1 user-list'
|
||||
try:
|
||||
shell.main(argstr.split())
|
||||
self.fail('No import error returned')
|
||||
except ImportError as e:
|
||||
msg = 'Unable to import module. Re-run with --debug for more info.'
|
||||
self.assertEqual(msg, str(e))
|
||||
|
||||
@mock.patch('bileanclient.v1.client.Client')
|
||||
def test_auth_plugin_invocation_without_username(self, v1_client):
|
||||
self.make_env(exclude='OS_USERNAME')
|
||||
args = '--os-bilean-api-version 1 user-list'
|
||||
bilean_shell = openstack_shell.BileanShell()
|
||||
self.assertRaises(exc.CommandError, bilean_shell.main, args.split())
|
||||
|
||||
@mock.patch('bileanclient.v1.client.Client')
|
||||
def test_auth_plugin_invocation_without_auth_url(self, v1_client):
|
||||
self.make_env(exclude='OS_AUTH_URL')
|
||||
args = '--os-bilean-api-version 1 user-list'
|
||||
bilean_shell = openstack_shell.BileanShell()
|
||||
self.assertRaises(exc.CommandError, bilean_shell.main, args.split())
|
||||
|
||||
@mock.patch('bileanclient.v1.client.Client')
|
||||
def test_auth_plugin_invocation_without_tenant(self, v1_client):
|
||||
if 'OS_TENANT_NAME' in os.environ:
|
||||
self.make_env(exclude='OS_TENANT_NAME')
|
||||
if 'OS_PROJECT_ID' in os.environ:
|
||||
self.make_env(exclude='OS_PROJECT_ID')
|
||||
args = '--os-bilean-api-version 1 user-list'
|
||||
bilean_shell = openstack_shell.BileanShell()
|
||||
self.assertRaises(exc.CommandError, bilean_shell.main, args.split())
|
||||
|
||||
@mock.patch('sys.argv', ['bilean'])
|
||||
@mock.patch('sys.stdout', six.StringIO())
|
||||
@mock.patch('sys.stderr', six.StringIO())
|
||||
def test_main_noargs(self):
|
||||
# Ensure that main works with no command-line arguments
|
||||
try:
|
||||
openstack_shell.main()
|
||||
except SystemExit:
|
||||
self.fail('Unexpected SystemExit')
|
||||
|
||||
# We expect the normal usage as a result
|
||||
expected = ['Command-line interface to the OpenStack Bilean API',
|
||||
'user-list',
|
||||
'rule-list']
|
||||
for output in expected:
|
||||
self.assertIn(output,
|
||||
sys.stdout.getvalue())
|
||||
|
||||
@mock.patch('bileanclient.v1.client.Client')
|
||||
@mock.patch('bileanclient.v1.shell.do_user_list')
|
||||
@mock.patch('bileanclient.shell.logging.basicConfig')
|
||||
def test_setup_debug(self, conf, func, v1_client):
|
||||
cli = mock.MagicMock()
|
||||
v1_client.return_value = cli
|
||||
cli.http_client.get.return_value = (None, {'versions': []})
|
||||
args = '--debug user-list'
|
||||
bilean_shell = openstack_shell.BileanShell()
|
||||
bilean_shell.main(args.split())
|
||||
bilean_logger = logging.getLogger('bileanclient')
|
||||
self.assertEqual(bilean_logger.getEffectiveLevel(), logging.DEBUG)
|
||||
conf.assert_called_with(level=logging.DEBUG)
|
||||
|
||||
|
||||
class ShellTestWithKeystoneV3Auth(ShellTest):
|
||||
# auth environment to use
|
||||
auth_env = FAKE_V3_ENV.copy()
|
||||
token_url = DEFAULT_V3_AUTH_URL + '/auth/tokens'
|
||||
|
||||
def _assert_auth_plugin_args(self):
|
||||
self.assertFalse(self.v2_auth.called)
|
||||
|
||||
body = json.loads(self.v3_auth.last_request.body)
|
||||
user = body['auth']['identity']['password']['user']
|
||||
|
||||
self.assertEqual(self.auth_env['OS_USERNAME'], user['name'])
|
||||
self.assertEqual(self.auth_env['OS_PASSWORD'], user['password'])
|
||||
self.assertEqual(self.auth_env['OS_USER_DOMAIN_NAME'],
|
||||
user['domain']['name'])
|
||||
self.assertEqual(self.auth_env['OS_PROJECT_ID'],
|
||||
body['auth']['scope']['project']['id'])
|
||||
|
||||
@mock.patch('bileanclient.v1.client.Client')
|
||||
def test_auth_plugin_invocation(self, v1_client):
|
||||
args = '--os-bilean-api-version 1 user-list'
|
||||
bilean_shell = openstack_shell.BileanShell()
|
||||
bilean_shell.main(args.split())
|
||||
self.assertEqual(0, self.v3_auth.call_count)
|
||||
|
||||
@mock.patch('keystoneclient.discover.Discover',
|
||||
side_effect=ks_exc.ClientException())
|
||||
def test_api_discovery_failed_with_unversioned_auth_url(self,
|
||||
discover):
|
||||
args = ('--os-bilean-api-version 1 --os-auth-url %s user-list'
|
||||
% DEFAULT_UNVERSIONED_AUTH_URL)
|
||||
bilean_shell = openstack_shell.BileanShell()
|
||||
self.assertRaises(exc.CommandError, bilean_shell.main, args.split())
|
||||
|
||||
def test_bash_completion(self):
|
||||
stdout, stderr = self.shell('--os-bilean-api-version 1 bash_completion')
|
||||
# just check we have some output
|
||||
required = [
|
||||
'--value',
|
||||
'rule-create',
|
||||
'help',
|
||||
'--limit']
|
||||
for r in required:
|
||||
self.assertIn(r, stdout.split())
|
||||
avoided = [
|
||||
'bash_completion',
|
||||
'bash-completion']
|
||||
for r in avoided:
|
||||
self.assertNotIn(r, stdout.split())
|
||||
|
@ -28,6 +28,16 @@ class Policy(base.Resource):
|
||||
class PolicyManager(base.BaseManager):
|
||||
resource_class = Policy
|
||||
|
||||
def _list(self, url, response_key, obj_class=None, body=None):
|
||||
resp, body = self.client.get(url)
|
||||
|
||||
if obj_class is None:
|
||||
obj_class = self.resource_class
|
||||
|
||||
data = body[response_key]
|
||||
return ([obj_class(self, res, loaded=True) for res in data if res],
|
||||
resp)
|
||||
|
||||
def list(self, **kwargs):
|
||||
"""Retrieve a list of policies.
|
||||
|
||||
@ -37,7 +47,7 @@ class PolicyManager(base.BaseManager):
|
||||
'''Paginate policies, even if more than API limit.'''
|
||||
current_limit = int(params.get('limit') or 0)
|
||||
url = '/policies?%s' % parse.urlencode(params, True)
|
||||
policies = self._list(url, 'policies')
|
||||
policies, resq = self._list(url, 'policies')
|
||||
for policy in policies:
|
||||
yield policy
|
||||
|
||||
@ -61,18 +71,22 @@ class PolicyManager(base.BaseManager):
|
||||
return paginate(params)
|
||||
|
||||
def create(self, **kwargs):
|
||||
"""Create a policy."""
|
||||
return self._post('/policies', json=kwargs, response_key='policy')
|
||||
"""Create a new policy."""
|
||||
resq, body = self.client.post(url, data=kwargs)
|
||||
return self.resource_class(self, body.get('policy'), loaded=True)
|
||||
|
||||
def get(self, policy_id):
|
||||
"""Get a specific policy."""
|
||||
return self._get('/policies/%s' % policy_id, 'policy')
|
||||
url = '/policies/%s' % parse.quote(str(policy_id))
|
||||
resq, body = self.client.get(url)
|
||||
return self.resource_class(self, body.get('policy'), loaded=True)
|
||||
|
||||
def action(self, policy_id, **kwargs):
|
||||
"""Perform specified action on a policy."""
|
||||
url = '/policies/%s/action' % policy_id
|
||||
return self._post(url, json=kwargs, response_key='policy')
|
||||
url = '/policies/%s/action' % parse.quote(str(policy_id))
|
||||
resq, body = self.client.post(url, data=kwargs)
|
||||
return self.resource_class(self, body.get('policy'), loaded=True)
|
||||
|
||||
def delete(self, policy_id):
|
||||
"""Delete a specific policy."""
|
||||
return self._delete('/policies/%s' % policy_id)
|
||||
return self._delete('/policies/%s' % parse.quote(str(policy_id)))
|
||||
|
@ -28,6 +28,16 @@ class BileanResource(base.Resource):
|
||||
class ResourceManager(base.BaseManager):
|
||||
resource_class = BileanResource
|
||||
|
||||
def _list(self, url, response_key, obj_class=None, body=None):
|
||||
resp, body = self.client.get(url)
|
||||
|
||||
if obj_class is None:
|
||||
obj_class = self.resource_class
|
||||
|
||||
data = body[response_key]
|
||||
return ([obj_class(self, res, loaded=True) for res in data if res],
|
||||
resp)
|
||||
|
||||
def list(self, **kwargs):
|
||||
"""Retrieve a list of resources.
|
||||
|
||||
@ -37,7 +47,7 @@ class ResourceManager(base.BaseManager):
|
||||
'''Paginate resources, even if more than API limit.'''
|
||||
current_limit = int(params.get('limit') or 0)
|
||||
url = '/resources?%s' % parse.urlencode(params, True)
|
||||
resources = self._list(url, 'resources')
|
||||
resources, resp = self._list(url, 'resources')
|
||||
for resource in resources:
|
||||
yield resource
|
||||
|
||||
@ -65,4 +75,6 @@ class ResourceManager(base.BaseManager):
|
||||
|
||||
:param resource_id: ID of the resource
|
||||
"""
|
||||
return self._get('/resources/%s' % resource_id, 'resource')
|
||||
url = '/resources/%s' % parse.quote(str(resource_id))
|
||||
resp, body = self.client.get(url)
|
||||
return self.resource_class(self, body.get('resource'), loaded=True)
|
||||
|
@ -28,6 +28,16 @@ class Rule(base.Resource):
|
||||
class RuleManager(base.BaseManager):
|
||||
resource_class = Rule
|
||||
|
||||
def _list(self, url, response_key, obj_class=None, body=None):
|
||||
resp, body = self.client.get(url)
|
||||
|
||||
if obj_class is None:
|
||||
obj_class = self.resource_class
|
||||
|
||||
data = body[response_key]
|
||||
return ([obj_class(self, res, loaded=True) for res in data if res],
|
||||
resp)
|
||||
|
||||
def list(self, **kwargs):
|
||||
"""Retrieve a list of rules.
|
||||
|
||||
@ -37,7 +47,7 @@ class RuleManager(base.BaseManager):
|
||||
'''Paginate rules, even if more than API limit.'''
|
||||
current_limit = int(params.get('limit') or 0)
|
||||
url = '/rules?%s' % parse.urlencode(params, True)
|
||||
rules = self._list(url, 'rules')
|
||||
rules, resp = self._list(url, 'rules')
|
||||
for rule in rules:
|
||||
yield rule
|
||||
|
||||
@ -49,6 +59,7 @@ class RuleManager(base.BaseManager):
|
||||
for rule in paginate(params):
|
||||
yield rule
|
||||
|
||||
return_request_id = kwargs.get('return_req_id', None)
|
||||
params = {}
|
||||
if 'filters' in kwargs:
|
||||
filters = kwargs.pop('filters')
|
||||
@ -61,13 +72,25 @@ class RuleManager(base.BaseManager):
|
||||
return paginate(params)
|
||||
|
||||
def create(self, **kwargs):
|
||||
"""Create a rule."""
|
||||
return self._post('/rules', json=kwargs, response_key='rule')
|
||||
"""Create a rule by given data."""
|
||||
url = '/rules'
|
||||
resp, body = self.client.post(url, data=kwargs)
|
||||
rule = body.get('rule')
|
||||
return self.resource_class(self, rule, loaded=True)
|
||||
|
||||
def get(self, rule_id):
|
||||
"""Get a specific rule."""
|
||||
return self._get('/rules/%s' % rule_id, 'rule')
|
||||
"""Get a specific rule.
|
||||
|
||||
:param rule_id: Id of the rule to get
|
||||
"""
|
||||
url = '/rules/%s' % parse.quote(str(rule_id))
|
||||
resp, body = self.client.get(url)
|
||||
data = body.get('rule')
|
||||
return self.resource_class(self, data, loaded=True)
|
||||
|
||||
def delete(self, rule_id):
|
||||
"""Delete a specific rule."""
|
||||
return self._delete('/rules/%s' % rule_id)
|
||||
"""Delete a specific rule.
|
||||
|
||||
:param rule_id: Id of the rule to delete
|
||||
"""
|
||||
return self._delete('/rules/%s' % parse.quote(str(rule_id)))
|
||||
|
@ -19,6 +19,8 @@ from six.moves.urllib import parse
|
||||
|
||||
from bileanclient.openstack.common.apiclient import base
|
||||
|
||||
OS_REQ_ID_HDR = 'x-openstack-request-id'
|
||||
|
||||
|
||||
class User(base.Resource):
|
||||
def __repr__(self):
|
||||
@ -72,7 +74,7 @@ class UserManager(base.BaseManager):
|
||||
if value:
|
||||
params[key] = value
|
||||
|
||||
return paginate(params)
|
||||
return paginate(params, return_request_id)
|
||||
|
||||
def get(self, user_id, return_request_id=None):
|
||||
"""Get the details for a specific user.
|
||||
|
Loading…
x
Reference in New Issue
Block a user