def test_version_discovery(self, mocker): _shell = shell.OpenStackCinderShell() sess = session.Session() os_auth_url = "https://wrongdiscoveryresponse.discovery.com:35357/v2.0" self.register_keystone_auth_fixture(mocker, os_auth_url) self.assertRaises(DiscoveryFailure, _shell._discover_auth_versions, sess, auth_url=os_auth_url) os_auth_url = "https://DiscoveryNotSupported.discovery.com:35357/v2.0" self.register_keystone_auth_fixture(mocker, os_auth_url) v2_url, v3_url = _shell._discover_auth_versions(sess, auth_url=os_auth_url) self.assertEqual(os_auth_url, v2_url, "Expected v2 url") self.assertIsNone(v3_url, "Expected no v3 url") os_auth_url = "https://DiscoveryNotSupported.discovery.com:35357/v3.0" self.register_keystone_auth_fixture(mocker, os_auth_url) v2_url, v3_url = _shell._discover_auth_versions(sess, auth_url=os_auth_url) self.assertEqual(os_auth_url, v3_url, "Expected v3 url") self.assertIsNone(v2_url, "Expected no v2 url")
def setUp(self): """Run before each test.""" super(ShellTest, self).setUp() for var in self.FAKE_ENV: self.useFixture( fixtures.EnvironmentVariable(var, self.FAKE_ENV[var])) self.shell = shell.OpenStackCinderShell() # HACK(bcwaldon): replace this when we start using stubs self.old_get_client_class = client.get_client_class client.get_client_class = lambda *_: fakes.FakeClient self.requests = self.useFixture(requests_mock_fixture.Fixture()) self.requests.register_uri( 'GET', keystone_client.BASE_URL, text=keystone_client.keystone_request_callback) token = keystone_client_fixture.V2Token() s = token.add_service('volume', 'cinder') s.add_endpoint(public='http://127.0.0.1:8776') self.requests.post(keystone_client.BASE_URL + 'v2.0/tokens', json=token) self.requests.get('http://127.0.0.1:8776', json=fixture_base.generate_version_output())
def test_auth_type_env(self): self.make_env(exclude='OS_PASSWORD', include={'OS_AUTH_SYSTEM': 'non existent auth', 'OS_AUTH_TYPE': 'noauth'}) _shell = shell.OpenStackCinderShell() args, __ = _shell.get_base_parser().parse_known_args([]) self.assertEqual('noauth', args.os_auth_type)
def test_session_client_debug_logger(self, mock_session): _shell = shell.OpenStackCinderShell() # This "fails" but instantiates the client. self.assertRaises(exceptions.CommandError, _shell.main, ['--debug', 'list']) # In case of SessionClient when --debug switch is specified # 'keystoneauth' logger should be initialized. self.assertEqual('keystoneauth', _shell.cs.client.logger.name)
def test_http_client_with_cert(self, mock_session): _shell = shell.OpenStackCinderShell() # We crash the command after Session instantiation because this test # focuses only on arguments provided to Session.__init__ args = '--os-cert', 'minnie', 'list' self.assertRaises(RuntimeError, _shell.main, args) mock_session.assert_called_once_with(cert='minnie', verify=mock.ANY)
def test_password_auth_type(self, mock_authenticate, mock_get_session): self.make_env(include={'OS_AUTH_TYPE': 'password'}) _shell = shell.OpenStackCinderShell() # We crash the command after Client instantiation because this test # focuses only keystoneauth1 indentity cli opts parsing. self.assertRaises(RuntimeError, _shell.main, ['list']) self.assertIsInstance(_shell.cs.client.session.auth, ks_password)
def test_http_client_insecure(self, mock_authenticate, mock_session): self.make_env(include={'CINDERCLIENT_INSECURE': True}) _shell = shell.OpenStackCinderShell() # This "fails" but instantiates the client. self.assertRaises(exceptions.CommandError, _shell.main, ['list']) self.assertEqual(False, _shell.cs.client.verify_cert)
def list_volumes_on_service(self, count, mocker): os_auth_url = "http://multiple.service.names/v2.0" mocker.register_uri('POST', os_auth_url + "/tokens", text=keystone_client.keystone_request_callback) mocker.register_uri('GET', "http://cinder%i.api.com/v2/volumes/detail" % count, text='{"volumes": []}') self.make_env(include={'OS_AUTH_URL': os_auth_url, 'CINDER_SERVICE_NAME': 'cinder%i' % count}) _shell = shell.OpenStackCinderShell() _shell.main(['list'])
def test_noauth_plugin(self, mocker): os_auth_url = "http://example.com/v2" mocker.register_uri('GET', "%s/admin/volumes/detail" % os_auth_url, text='{"volumes": []}') _shell = shell.OpenStackCinderShell() args = ['--os-endpoint', os_auth_url, '--os-auth-type', 'noauth', '--os-user-id', 'admin', '--os-project-id', 'admin', 'list'] _shell.main(args) self.assertIsInstance(_shell.cs.client.session.auth, noauth.CinderNoAuthPlugin)
def test_noauth_plugin(self): _shell = shell.OpenStackCinderShell() args = [ '--os-endpoint', 'http://example.com/v2', '--os-auth-type', 'noauth', '--os-user-id', 'admin', '--os-project-id', 'admin', 'list' ] # This "fails" but instantiates the client with session self.assertRaises(exceptions.NotFound, _shell.main, args) self.assertIsInstance(_shell.cs.client.session.auth, noauth.CinderNoAuthPlugin)
def setUp(self): """Run before each test.""" super(ShellTest, self).setUp() for var in self.FAKE_ENV: self.useFixture( fixtures.EnvironmentVariable(var, self.FAKE_ENV[var])) self.shell = shell.OpenStackCinderShell() #HACK(bcwaldon): replace this when we start using stubs self.old_get_client_class = client.get_client_class client.get_client_class = lambda *_: fakes.FakeClient
def test_password_prompted(self, mock_getpass, mock_stdin, mock_discover, mock_token, mock_password): self.make_env(exclude='OS_PASSWORD') _shell = shell.OpenStackCinderShell() self.assertRaises(ks_exc.ConnectFailure, _shell.main, ['list']) mock_getpass.assert_called_with('OS Password: '******'password' # equal to mock_getpass.return_value. mock_password.assert_called_with( self.FAKE_ENV['OS_AUTH_URL'], password=mock_getpass.return_value, tenant_id='', tenant_name=self.FAKE_ENV['OS_TENANT_NAME'], username=self.FAKE_ENV['OS_USERNAME'])
def shell(self, argstr): orig = sys.stdout try: sys.stdout = moves.StringIO() _shell = shell.OpenStackCinderShell() _shell.main(argstr.split()) except SystemExit: exc_type, exc_value, exc_traceback = sys.exc_info() self.assertEqual(0, exc_value.code) finally: out = sys.stdout.getvalue() sys.stdout.close() sys.stdout = orig return out
def setUp(self): """Run before each test.""" super(ShellTest, self).setUp() for var in self.FAKE_ENV: self.useFixture(fixtures.EnvironmentVariable(var, self.FAKE_ENV[var])) self.shell = shell.OpenStackCinderShell() self.requests = self.useFixture(requests_mock_fixture.Fixture()) self.requests.register_uri( 'GET', keystone_client.BASE_URL, text=keystone_client.keystone_request_callback) self.cs = mock.Mock()
def setUp(self): """Run before each test.""" self.old_environment = os.environ.copy() os.environ = { 'CINDER_USERNAME': '******', 'CINDER_PASSWORD': '******', 'CINDER_PROJECT_ID': 'project_id', 'OS_COMPUTE_API_VERSION': '1.1', 'CINDER_URL': 'http://no.where', } self.shell = shell.OpenStackCinderShell() #HACK(bcwaldon): replace this when we start using stubs self.old_get_client_class = client.get_client_class client.get_client_class = lambda *_: fakes.FakeClient
def setUp(self): """Run before each test.""" super(ShellTest, self).setUp() for var in self.FAKE_ENV: self.useFixture(fixtures.EnvironmentVariable(var, self.FAKE_ENV[var])) self.shell = shell.OpenStackCinderShell() # HACK(bcwaldon): replace this when we start using stubs self.old_client_class = client.Client client.Client = fakes.FakeClient self.requests = self.useFixture(requests_mock_fixture.Fixture()) self.requests.register_uri( 'GET', keystone_client.BASE_URL, text=keystone_client.keystone_request_callback)
def test_auth_system_not_keystone(self, mock_iter_entry_points, mock_request): """Test that we can authenticate using the auth plugin system.""" non_keystone_auth_url = "http://non-keystone-url.com/v2.0" class MockEntrypoint(pkg_resources.EntryPoint): def load(self): return FakePlugin class FakePlugin(auth_plugin.BaseAuthPlugin): def authenticate(self, cls, auth_url): cls._authenticate(auth_url, {"fake": "me"}) def get_auth_url(self): return non_keystone_auth_url mock_iter_entry_points.side_effect = lambda _t: [ MockEntrypoint("fake", "fake", ["FakePlugin"]) ] mock_request.side_effect = mock_http_request() # Tell the shell we wish to use our 'fake' auth instead of keystone # and the auth plugin will provide the auth url self.make_env(exclude="OS_AUTH_URL", include={'OS_AUTH_SYSTEM': 'fake'}) # This should fail as we have not setup a mock response for 'list', # however auth should have been called _shell = shell.OpenStackCinderShell() self.assertRaises(KeyError, _shell.main, ['list']) headers = requested_headers(_shell.cs) token_url = _shell.cs.client.auth_url + "/tokens" self.assertEqual(non_keystone_auth_url + "/tokens", token_url) mock_request.assert_any_call("POST", token_url, headers=headers, data='{"fake": "me"}', allow_redirects=True, **self.TEST_REQUEST_BASE)
def test_version_discovery(self): _shell = shell.OpenStackCinderShell() os_auth_url = "https://WrongDiscoveryResponse.discovery.com:35357/v2.0" self.register_keystone_auth_fixture(os_auth_url) self.assertRaises(DiscoveryFailure, _shell._discover_auth_versions, None, auth_url=os_auth_url) os_auth_url = "https://DiscoveryNotSupported.discovery.com:35357/v2.0" self.register_keystone_auth_fixture(os_auth_url) v2_url, v3_url = _shell._discover_auth_versions(None, auth_url=os_auth_url) self.assertEqual(v2_url, os_auth_url, "Expected v2 url") self.assertEqual(v3_url, None, "Expected no v3 url") os_auth_url = "https://DiscoveryNotSupported.discovery.com:35357/v3.0" self.register_keystone_auth_fixture(os_auth_url) v2_url, v3_url = _shell._discover_auth_versions(None, auth_url=os_auth_url) self.assertEqual(v3_url, os_auth_url, "Expected v3 url") self.assertEqual(v2_url, None, "Expected no v2 url")
def run(self): """Load and document the current config options.""" cindershell = shell.OpenStackCinderShell() parser = cindershell.get_base_parser() api_version = api_versions.APIVersion(api_versions.MAX_VERSION) LOG.info('Generating CLI docs %s', api_version) cindershell.get_subcommand_parser(api_version, False, []) result = sm.ViewList() source = '<{}>'.format(__name__) result.append('.. _cinder_command_usage:', source) result.append('', source) result.append('cinder usage', source) result.append('------------', source) result.append('', source) result.append('.. code-block:: console', source) result.append('', source) result.append('', source) usage = self._get_usage_lines(parser.format_usage(), '<subcommand> ...') for line in usage: result.append(' {}'.format(line), source) result.append('', source) result.append('.. _cinder_command_options:', source) result.append('', source) result.append('Optional Arguments', source) result.append('~~~~~~~~~~~~~~~~~~', source) result.append('', source) # This accesses a private variable from argparse. That's a little # risky, but since this is just for the docs and not "production" code, # and since this variable hasn't changed in years, it's a calculated # risk to make this documentation generation easier. But if something # suddenly breaks, check here first. actions = sorted(parser._actions, key=lambda x: x.option_strings[0]) for action in actions: if action.help == '==SUPPRESS==': continue opts = ', '.join(action.option_strings) result.append('``{}``'.format(opts), source) result.append(' {}'.format(action.help), source) result.append('', source) result.append('', source) result.append('.. _cinder_commands:', source) result.append('', source) result.append('Commands', source) result.append('~~~~~~~~', source) result.append('', source) for cmd in cindershell.subcommands: if 'completion' in cmd: continue result.append('``{}``'.format(cmd), source) subcmd = cindershell.subcommands[cmd] description = self._format_description_lines(subcmd.description) result.append(' {}'.format(description[0]), source) result.append('', source) result.append('', source) result.append('.. _cinder_command_details:', source) result.append('', source) result.append('Command Details', source) result.append('---------------', source) result.append('', source) for cmd in cindershell.subcommands: if 'completion' in cmd: continue subcmd = cindershell.subcommands[cmd] result.append('.. _cinder{}:'.format(cmd), source) result.append('', source) result.append(subcmd.prog, source) result.append('~' * len(subcmd.prog), source) result.append('', source) result.append('.. code-block:: console', source) result.append('', source) usage = self._get_usage_lines(subcmd.format_usage()) for line in usage: result.append(' {}'.format(line), source) result.append('', source) description = self._format_description_lines(subcmd.description) result.append(description[0], source) result.append('', source) if len(subcmd._actions) == 0: continue positional = [] optional = [] for action in subcmd._actions: if len(action.option_strings): if (action.option_strings[0] != '-h' and action.help != '==SUPPRESS=='): optional.append(action) else: positional.append(action) if positional: result.append('**Positional arguments:**', source) result.append('', source) for action in positional: result.append('``{}``'.format(action.metavar), source) result.append(' {}'.format(action.help), source) result.append('', source) if optional: result.append('**Optional arguments:**', source) result.append('', source) for action in optional: result.append( '``{} {}``'.format(', '.join(action.option_strings), action.metavar), source) result.append(' {}'.format(action.help), source) result.append('', source) node = nodes.section() node.document = self.state.document nested_parse_with_titles(self.state, result, node) return node.children
def test_password_prompted(self, mock_getpass, mock_stdin, mock_discover, mock_token): self.make_env(exclude='OS_PASSWORD') _shell = shell.OpenStackCinderShell() self.assertRaises(ks_exc.ConnectionRefused, _shell.main, ['list']) mock_getpass.assert_called_with('OS Password: ')
def test_duplicate_filters(self): _shell = shell.OpenStackCinderShell() self.assertRaises(exceptions.CommandError, _shell.main, ['list', '--name', 'abc', '--filters', 'name=xyz'])
def test_default_auth_env(self): _shell = shell.OpenStackCinderShell() args, __ = _shell.get_base_parser().parse_known_args([]) self.assertEqual('', args.os_auth_type)