diff --git a/esi_leap/api/controllers/v1/node.py b/esi_leap/api/controllers/v1/node.py index 1dd3e67b..fab221de 100644 --- a/esi_leap/api/controllers/v1/node.py +++ b/esi_leap/api/controllers/v1/node.py @@ -64,15 +64,31 @@ def __init__(self, **kwargs): class NodesController(rest.RestController): - @wsme_pecan.wsexpose(NodeCollection) - def get_all(self): + @wsme_pecan.wsexpose(NodeCollection, wtypes.text, + wtypes.text, wtypes.text) + def get_all(self, resource_class=None, owner=None, + lessee=None): context = pecan.request.context + if owner is not None: + owner = keystone.get_project_uuid_from_ident(owner) + if lessee is not None: + lessee = keystone.get_project_uuid_from_ident(lessee) + + filter_args = { + 'resource_class': resource_class, + 'owner': owner, + 'lessee': lessee + } + nodes = None project_list = None with concurrent.futures.ThreadPoolExecutor() as executor: - f1 = executor.submit(ironic.get_node_list, context) + filter_args = { + k: v for k, v in filter_args.items() if v is not None + } + f1 = executor.submit(ironic.get_node_list, context, **filter_args) f2 = executor.submit(keystone.get_project_list) nodes = f1.result() project_list = f2.result() diff --git a/esi_leap/common/ironic.py b/esi_leap/common/ironic.py index 57109f40..89f026b2 100644 --- a/esi_leap/common/ironic.py +++ b/esi_leap/common/ironic.py @@ -43,8 +43,9 @@ def get_ironic_client(context=None): return cli -def get_node_list(context=None): - return get_ironic_client(context).node.list(detail=True) +def get_node_list(context=None, **filter_args): + client = get_ironic_client(context) + return client.node.list(detail=True, **filter_args) def get_node(node_uuid, node_list=None): diff --git a/esi_leap/tests/api/controllers/v1/test_node.py b/esi_leap/tests/api/controllers/v1/test_node.py index 2596b172..51c035b2 100644 --- a/esi_leap/tests/api/controllers/v1/test_node.py +++ b/esi_leap/tests/api/controllers/v1/test_node.py @@ -64,3 +64,59 @@ def test_get_all(self, mock_gpl, mock_lga, mock_oga, mock_gnl): self.assertEqual(data['nodes'][0]['lessee'], 'fake-project') self.assertEqual(data['nodes'][0]['properties'], { 'cpu': '40'}) + + @mock.patch('esi_leap.common.ironic.get_node_list') + @mock.patch('esi_leap.common.keystone.get_project_list') + def test_get_all_resource_class_filter(self, mock_gpl, mock_gnl): + fake_node = FakeIronicNode() + fake_project = FakeProject() + mock_gnl.return_value = [fake_node] + mock_gpl.return_value = [fake_project] + + data = self.get_json('/nodes?resource_class=baremetal') + + mock_gnl.assert_called_once_with( + self.context, resource_class='baremetal') + mock_gpl.assert_called_once() + + self.assertEqual(data['nodes'][0]['resource_class'], 'baremetal') + + @mock.patch('esi_leap.common.ironic.get_node_list') + @mock.patch('esi_leap.common.keystone.get_project_list') + @mock.patch('esi_leap.common.keystone.get_project_uuid_from_ident') + def test_get_all_owner_filter( + self, mock_get_project_uuid, mock_gpl, mock_gnl): + + fake_node = FakeIronicNode() + fake_project = FakeProject() + mock_gnl.return_value = [fake_node] + mock_gpl.return_value = [fake_project] + + mock_get_project_uuid.return_value = fake_project.id + + data = self.get_json('/nodes?owner=fake-project') + + mock_gnl.assert_called_once_with(self.context, owner=fake_project.id) + mock_get_project_uuid.assert_called_once_with('fake-project') + + self.assertEqual(data['nodes'][0]['owner'], fake_project.name) + + @mock.patch('esi_leap.common.ironic.get_node_list') + @mock.patch('esi_leap.common.keystone.get_project_list') + @mock.patch('esi_leap.common.keystone.get_project_uuid_from_ident') + def test_get_all_lesse_filter( + self, mock_get_project_uuid, mock_gpl, mock_gnl): + + fake_node = FakeIronicNode() + fake_project = FakeProject() + mock_gnl.return_value = [fake_node] + mock_gpl.return_value = [fake_project] + + mock_get_project_uuid.return_value = fake_project.id + + data = self.get_json('/nodes?lessee=fake-project') + + mock_gnl.assert_called_once_with(self.context, lessee=fake_project.id) + mock_get_project_uuid.assert_called_once_with('fake-project') + + self.assertEqual(data['nodes'][0]['lessee'], 'fake-project')