diff --git a/openstackclient/common/clientmanager.py b/openstackclient/common/clientmanager.py index edabf65e57..dce1972515 100644 --- a/openstackclient/common/clientmanager.py +++ b/openstackclient/common/clientmanager.py @@ -191,6 +191,26 @@ class ClientManager(object): self._auth_ref = self.auth.get_auth_ref(self.session) return self._auth_ref + def is_network_endpoint_enabled(self): + """Check if the network endpoint is enabled""" + # Trigger authentication necessary to determine if the network + # endpoint is enabled. + if self.auth_ref: + service_catalog = self.auth_ref.service_catalog + else: + service_catalog = None + # Assume that the network endpoint is enabled. + network_endpoint_enabled = True + if service_catalog: + if 'network' in service_catalog.get_endpoints(): + LOG.debug("Network endpoint in service catalog") + else: + LOG.debug("No network endpoint in service catalog") + network_endpoint_enabled = False + else: + LOG.debug("No service catalog, assuming network endpoint enabled") + return network_endpoint_enabled + def get_endpoint_for_service_type(self, service_type, region_name=None, interface='public'): """Return the endpoint URL for the service type.""" diff --git a/openstackclient/compute/v2/server.py b/openstackclient/compute/v2/server.py index be0ad8cb5a..7afd18f25b 100644 --- a/openstackclient/compute/v2/server.py +++ b/openstackclient/compute/v2/server.py @@ -257,10 +257,6 @@ class CreateServer(show.ShowOne): log = logging.getLogger(__name__ + '.CreateServer') - def _is_neutron_enabled(self): - service_catalog = self.app.client_manager.auth_ref.service_catalog - return 'network' in service_catalog.get_endpoints() - def get_parser(self, prog_name): parser = super(CreateServer, self).get_parser(prog_name) parser.add_argument( @@ -460,8 +456,6 @@ class CreateServer(show.ShowOne): block_device_mapping.update({dev_key: block_volume}) nics = [] - if parsed_args.nic: - neutron_enabled = self._is_neutron_enabled() for nic_str in parsed_args.nic: nic_info = {"net-id": "", "v4-fixed-ip": "", "v6-fixed-ip": "", "port-id": ""} @@ -471,7 +465,7 @@ class CreateServer(show.ShowOne): msg = _("either net-id or port-id should be specified " "but not both") raise exceptions.CommandError(msg) - if neutron_enabled: + if self.app.client_manager.is_network_endpoint_enabled(): network_client = self.app.client_manager.network if nic_info["net-id"]: net = network_client.find_network( @@ -489,7 +483,7 @@ class CreateServer(show.ShowOne): ).id if nic_info["port-id"]: msg = _("can't create server with port specified " - "since neutron not enabled") + "since network endpoint not enabled") raise exceptions.CommandError(msg) nics.append(nic_info) diff --git a/openstackclient/tests/common/test_clientmanager.py b/openstackclient/tests/common/test_clientmanager.py index 29cc59ed26..523f79a32a 100644 --- a/openstackclient/tests/common/test_clientmanager.py +++ b/openstackclient/tests/common/test_clientmanager.py @@ -77,6 +77,9 @@ class TestClientManager(utils.TestCase): self.requests = self.useFixture(fixture.Fixture()) # fake v2password token retrieval self.stub_auth(json=fakes.TEST_RESPONSE_DICT) + # fake token and token_endpoint retrieval + self.stub_auth(json=fakes.TEST_RESPONSE_DICT, + url='/'.join([fakes.AUTH_URL, 'v2.0/tokens'])) # fake v3password token retrieval self.stub_auth(json=fakes.TEST_RESPONSE_DICT_V3, url='/'.join([fakes.AUTH_URL, 'auth/tokens'])) @@ -99,6 +102,7 @@ class TestClientManager(utils.TestCase): verify=True ) client_manager.setup_auth() + client_manager.auth_ref self.assertEqual( fakes.AUTH_URL, @@ -114,6 +118,7 @@ class TestClientManager(utils.TestCase): ) self.assertFalse(client_manager._insecure) self.assertTrue(client_manager._verify) + self.assertTrue(client_manager.is_network_endpoint_enabled()) def test_client_manager_token(self): @@ -131,6 +136,7 @@ class TestClientManager(utils.TestCase): verify=True ) client_manager.setup_auth() + client_manager.auth_ref self.assertEqual( fakes.AUTH_URL, @@ -150,6 +156,7 @@ class TestClientManager(utils.TestCase): ) self.assertFalse(client_manager._insecure) self.assertTrue(client_manager._verify) + self.assertTrue(client_manager.is_network_endpoint_enabled()) def test_client_manager_password(self): @@ -166,6 +173,7 @@ class TestClientManager(utils.TestCase): verify=False, ) client_manager.setup_auth() + client_manager.auth_ref self.assertEqual( fakes.AUTH_URL, @@ -195,6 +203,28 @@ class TestClientManager(utils.TestCase): dir(SERVICE_CATALOG), dir(client_manager.auth_ref.service_catalog), ) + self.assertTrue(client_manager.is_network_endpoint_enabled()) + + def test_client_manager_network_endpoint_disabled(self): + + client_manager = clientmanager.ClientManager( + cli_options=FakeOptions( + auth=dict( + auth_url=fakes.AUTH_URL, + username=fakes.USERNAME, + password=fakes.PASSWORD, + project_name=fakes.PROJECT_NAME, + ), + auth_type='v3password', + ), + api_version={"identity": "3"}, + verify=False, + ) + client_manager.setup_auth() + client_manager.auth_ref + + # v3 fake doesn't have network endpoint. + self.assertFalse(client_manager.is_network_endpoint_enabled()) def stub_auth(self, json=None, url=None, verb=None, **kwargs): subject_token = fakes.AUTH_TOKEN @@ -229,10 +259,12 @@ class TestClientManager(utils.TestCase): verify='cafile', ) client_manager.setup_auth() + client_manager.auth_ref self.assertFalse(client_manager._insecure) self.assertTrue(client_manager._verify) self.assertEqual('cafile', client_manager._cacert) + self.assertTrue(client_manager.is_network_endpoint_enabled()) def _select_auth_plugin(self, auth_params, api_version, auth_plugin_name): auth_params['auth_type'] = auth_plugin_name @@ -243,6 +275,7 @@ class TestClientManager(utils.TestCase): verify=True ) client_manager.setup_auth() + client_manager.auth_ref self.assertEqual( auth_plugin_name, diff --git a/openstackclient/tests/fakes.py b/openstackclient/tests/fakes.py index 9f4dcc50b5..718dff694b 100644 --- a/openstackclient/tests/fakes.py +++ b/openstackclient/tests/fakes.py @@ -34,7 +34,15 @@ VERSION = "3" TEST_RESPONSE_DICT = fixture.V2Token(token_id=AUTH_TOKEN, user_name=USERNAME) _s = TEST_RESPONSE_DICT.add_service('identity', name='keystone') -_s.add_endpoint(AUTH_URL + '/v2.0') +_s.add_endpoint(AUTH_URL + ':5000/v2.0') +_s = TEST_RESPONSE_DICT.add_service('network', name='neutron') +_s.add_endpoint(AUTH_URL + ':9696') +_s = TEST_RESPONSE_DICT.add_service('compute', name='nova') +_s.add_endpoint(AUTH_URL + ':8774/v2') +_s = TEST_RESPONSE_DICT.add_service('image', name='glance') +_s.add_endpoint(AUTH_URL + ':9292') +_s = TEST_RESPONSE_DICT.add_service('object', name='swift') +_s.add_endpoint(AUTH_URL + ':8080/v1') TEST_RESPONSE_DICT_V3 = fixture.V3Token(user_name=USERNAME) TEST_RESPONSE_DICT_V3.set_project_scope() @@ -103,6 +111,7 @@ class FakeClientManager(object): self.session = None self.auth_ref = None self.auth_plugin_name = None + self.network_endpoint_enabled = True def get_configuration(self): return { @@ -115,6 +124,9 @@ class FakeClientManager(object): 'identity_api_version': VERSION, } + def is_network_endpoint_enabled(self): + return self.network_endpoint_enabled + class FakeModule(object): def __init__(self, name, version):