From 731cfab0e28fb0e1090708fd0244d13d376c3018 Mon Sep 17 00:00:00 2001 From: David Shrewsbury Date: Tue, 5 May 2015 15:49:28 -0400 Subject: [PATCH] Update server API for get/list/search interface Support the new search interface, and transform the server objects to Bunch objects. Change-Id: Ic8ea3e79863e11b4a00f104557966c81e2f06388 --- shade/__init__.py | 30 ++++++++++++++++---------- shade/meta.py | 2 +- shade/tests/unit/test_delete_server.py | 8 +++---- shade/tests/unit/test_meta.py | 22 +++++++++++++------ shade/tests/unit/test_shade.py | 20 +++++++++++++++++ 5 files changed, 59 insertions(+), 23 deletions(-) diff --git a/shade/__init__.py b/shade/__init__.py index 6c3d19bee..532cf7271 100644 --- a/shade/__init__.py +++ b/shade/__init__.py @@ -729,9 +729,6 @@ class OpenStackCloud(object): except OpenStackCloudException: return False - def list_servers(self): - return self.manager.submitTask(_tasks.ServerList()) - def list_server_dicts(self): return [self.get_openstack_vars(server) for server in self.list_servers()] @@ -869,6 +866,10 @@ class OpenStackCloud(object): groups = self.list_security_groups() return self._filter_list(groups, name_or_id, filters) + def search_servers(self, name_or_id=None, filters=None): + servers = self.list_servers() + return self._filter_list(servers, name_or_id, filters) + def list_networks(self): return self.manager.submitTask(_tasks.NetworkList())['networks'] @@ -905,6 +906,16 @@ class OpenStackCloud(object): self.manager.submitTask(_tasks.SecurityGroupList()) ) + def list_servers(self): + try: + return meta.obj_list_to_dict( + self.manager.submitTask(_tasks.ServerList()) + ) + except Exception as e: + self.log.debug("server list failed: %s" % e, exc_info=True) + raise OpenStackCloudException( + "Error fetching server list: %s" % e) + def get_network(self, name_or_id, filters=None): return self._get_entity(self.search_networks, name_or_id, filters) @@ -924,6 +935,9 @@ class OpenStackCloud(object): return self._get_entity(self.search_security_groups, name_or_id, filters) + def get_server(self, name_or_id, filters=None): + return self._get_entity(self.search_servers, name_or_id, filters) + # TODO(Shrews): This will eventually need to support tenant ID and # provider networks, which are admin-level params. def create_network(self, name, shared=False, admin_state_up=True): @@ -1537,12 +1551,6 @@ class OpenStackCloud(object): def get_server_public_ip(self, server): return meta.get_server_public_ip(server) - def get_server(self, name_or_id): - for server in self.list_servers(): - if name_or_id in (server.name, server.id): - return server - return None - def get_server_dict(self, name_or_id): server = self.get_server(name_or_id) if not server: @@ -1733,7 +1741,7 @@ class OpenStackCloud(object): def delete_server(self, name, wait=False, timeout=180): server = self.get_server(name) if server: - self.manager.submitTask(_tasks.ServerDelete(server=server)) + self.manager.submitTask(_tasks.ServerDelete(server=server.id)) else: return if not wait: @@ -1743,7 +1751,7 @@ class OpenStackCloud(object): "Timed out waiting for server to get deleted."): try: server = self.manager.submitTask( - _tasks.ServerGet(server=server)) + _tasks.ServerGet(server=server.id)) if not server: return except nova_exceptions.NotFound: diff --git a/shade/meta.py b/shade/meta.py index c794df6e4..6f5718b74 100644 --- a/shade/meta.py +++ b/shade/meta.py @@ -95,7 +95,7 @@ def get_groups_from_server(cloud, server, server_vars): def get_hostvars_from_server(cloud, server, mounts=None): - server_vars = obj_to_dict(server) + server_vars = server server_vars.pop('links', None) # Fist, add an IP address diff --git a/shade/tests/unit/test_delete_server.py b/shade/tests/unit/test_delete_server.py index 6259d507d..1e8157722 100644 --- a/shade/tests/unit/test_delete_server.py +++ b/shade/tests/unit/test_delete_server.py @@ -42,7 +42,7 @@ class TestDeleteServer(base.TestCase): server.name = 'daffy' nova_mock.servers.list.return_value = [server] self.cloud.delete_server('daffy', wait=False) - nova_mock.servers.delete.assert_called_with(server=server) + nova_mock.servers.delete.assert_called_with(server=server.id) @mock.patch('shade.OpenStackCloud.nova_client') def test_delete_server_already_gone(self, nova_mock): @@ -70,15 +70,15 @@ class TestDeleteServer(base.TestCase): def _delete_wily(*args, **kwargs): self.assertIn('server', kwargs) - self.assertEqual('9999', kwargs['server'].id) + self.assertEqual('9999', kwargs['server']) nova_mock.servers.list.return_value = [] def _raise_notfound(*args, **kwargs): self.assertIn('server', kwargs) - self.assertEqual('9999', kwargs['server'].id) + self.assertEqual('9999', kwargs['server']) raise nova_exc.NotFound(code='404') nova_mock.servers.get.side_effect = _raise_notfound nova_mock.servers.delete.side_effect = _delete_wily self.cloud.delete_server('wily', wait=True) - nova_mock.servers.delete.assert_called_with(server=server) + nova_mock.servers.delete.assert_called_with(server=server.id) diff --git a/shade/tests/unit/test_meta.py b/shade/tests/unit/test_meta.py index a36d9929f..da3076892 100644 --- a/shade/tests/unit/test_meta.py +++ b/shade/tests/unit/test_meta.py @@ -106,7 +106,8 @@ class TestMeta(testtools.TestCase): self.assertEqual(new_list[1]['value'], 1) def test_basic_hostvars(self): - hostvars = meta.get_hostvars_from_server(FakeCloud(), FakeServer()) + hostvars = meta.get_hostvars_from_server( + FakeCloud(), meta.obj_to_dict(FakeServer())) self.assertNotIn('links', hostvars) self.assertEqual(PRIVATE_V4, hostvars['private_v4']) self.assertEqual(PUBLIC_V4, hostvars['public_v4']) @@ -126,19 +127,22 @@ class TestMeta(testtools.TestCase): def test_private_interface_ip(self): cloud = FakeCloud() cloud.private = True - hostvars = meta.get_hostvars_from_server(cloud, FakeServer()) + hostvars = meta.get_hostvars_from_server( + cloud, meta.obj_to_dict(FakeServer())) self.assertEqual(PRIVATE_V4, hostvars['interface_ip']) def test_image_string(self): server = FakeServer() server.image = 'fake-image-id' - hostvars = meta.get_hostvars_from_server(FakeCloud(), server) + hostvars = meta.get_hostvars_from_server( + FakeCloud(), meta.obj_to_dict(server)) self.assertEquals('fake-image-id', hostvars['image']['id']) def test_az(self): server = FakeServer() server.__dict__['OS-EXT-AZ:availability_zone'] = 'az1' - hostvars = meta.get_hostvars_from_server(FakeCloud(), server) + hostvars = meta.get_hostvars_from_server( + FakeCloud(), meta.obj_to_dict(server)) self.assertEquals('az1', hostvars['az']) def test_has_volume(self): @@ -150,7 +154,8 @@ class TestMeta(testtools.TestCase): mock_volume.attachments = [{'device': '/dev/sda0'}] mock_volume_dict = meta.obj_to_dict(mock_volume) mock_cloud.get_volumes.return_value = [mock_volume_dict] - hostvars = meta.get_hostvars_from_server(mock_cloud, FakeServer()) + hostvars = meta.get_hostvars_from_server( + mock_cloud, meta.obj_to_dict(FakeServer())) self.assertEquals('volume1', hostvars['volumes'][0]['id']) self.assertEquals('/dev/sda0', hostvars['volumes'][0]['device']) @@ -160,7 +165,8 @@ class TestMeta(testtools.TestCase): def side_effect(*args): raise exc.OpenStackCloudException("No Volumes") mock_cloud.get_volumes.side_effect = side_effect - hostvars = meta.get_hostvars_from_server(mock_cloud, FakeServer()) + hostvars = meta.get_hostvars_from_server( + mock_cloud, meta.obj_to_dict(FakeServer())) self.assertEquals([], hostvars['volumes']) def test_unknown_volume_exception(self): @@ -174,7 +180,9 @@ class TestMeta(testtools.TestCase): mock_cloud.get_volumes.side_effect = side_effect self.assertRaises( FakeException, - meta.get_hostvars_from_server, mock_cloud, FakeServer()) + meta.get_hostvars_from_server, + mock_cloud, + meta.obj_to_dict(FakeServer())) def test_obj_to_dict(self): cloud = FakeCloud() diff --git a/shade/tests/unit/test_shade.py b/shade/tests/unit/test_shade.py index 268e38de7..0109d071b 100644 --- a/shade/tests/unit/test_shade.py +++ b/shade/tests/unit/test_shade.py @@ -72,6 +72,26 @@ class TestShade(base.TestCase): }}) self.assertEquals([el2, el3], ret) + @mock.patch.object(shade.OpenStackCloud, 'search_servers') + def test_get_server(self, mock_search): + server1 = dict(id='123', name='mickey') + mock_search.return_value = [server1] + r = self.cloud.get_server('mickey') + self.assertIsNotNone(r) + self.assertDictEqual(server1, r) + + @mock.patch.object(shade.OpenStackCloud, 'search_servers') + def test_get_server_not_found(self, mock_search): + mock_search.return_value = [] + r = self.cloud.get_server('doesNotExist') + self.assertIsNone(r) + + @mock.patch.object(shade.OpenStackCloud, 'nova_client') + def test_list_servers_exception(self, mock_client): + mock_client.servers.list.side_effect = Exception() + self.assertRaises(exc.OpenStackCloudException, + self.cloud.list_servers) + @mock.patch.object(shade.OpenStackCloud, 'search_subnets') def test_get_subnet(self, mock_search): subnet = dict(id='123', name='mickey')