← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~jameinel/maas/get-nodes-for-group into lp:maas

 

John A Meinel has proposed merging lp:~jameinel/maas/get-nodes-for-group into lp:maas.

Commit message:
Add nodegroups/UUID/?op=list_nodes to get the system_ids for all nodes that are part of the group.
The permissions for this is restricted to the worker for the nodegroup, so it shouldn't be visible to users.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~jameinel/maas/get-nodes-for-group/+merge/127484

This exposes a '/nodegroups/UUID/?op=list_nodes' that returns the list of system_ids for a given nodegroup.

The use case for this is the new Tag changes to allow the nodegroups to process the tag definitions themselves. We will spawn a 'start processing' request, which will then need to come back and determine what nodes need to be updated for this group.

This is the first step along that path.
-- 
https://code.launchpad.net/~jameinel/maas/get-nodes-for-group/+merge/127484
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~jameinel/maas/get-nodes-for-group into lp:maas.
=== modified file 'src/maasserver/api.py'
--- src/maasserver/api.py	2012-10-02 10:12:12 +0000
+++ src/maasserver/api.py	2012-10-02 13:17:21 +0000
@@ -1128,6 +1128,14 @@
                 {ip: leases[ip] for ip in new_leases if ip in leases})
         return HttpResponse("Leases updated.", status=httplib.OK)
 
+    @operation(idempotent=True)
+    def list_nodes(self, request, uuid):
+        """Get the list of node ids that are part of this group."""
+        nodegroup = get_object_or_404(NodeGroup, uuid=uuid)
+        check_nodegroup_access(request, nodegroup)
+        return [node.system_id
+                for node in Node.objects.filter(nodegroup=nodegroup)]
+
 
 DISPLAYED_NODEGROUP_FIELDS = (
     'ip', 'management', 'interface', 'subnet_mask',

=== modified file 'src/maasserver/tests/test_api.py'
--- src/maasserver/tests/test_api.py	2012-10-02 10:12:12 +0000
+++ src/maasserver/tests/test_api.py	2012-10-02 13:17:21 +0000
@@ -1666,6 +1666,17 @@
         self.assertItemsEqual(
             required_node_ids, extract_system_ids(parsed_result))
 
+    def test_GET_list_with_nodegroup(self):
+        group_a = factory.make_nodegroup()
+        group_b = factory.make_nodegroup()
+        node_in_a = factory.make_node(nodegroup=group_a)
+        node_in_b = factory.make_node(nodegroup=group_b)
+
+        response = self.client.get(self.get_uri('nodes/'), {
+            'op': 'list',
+            'id': required_node_ids,
+        })
+
     def test_POST_acquire_returns_available_node(self):
         # The "acquire" operation returns an available node.
         available_status = NODE_STATUS.READY
@@ -3437,6 +3448,36 @@
             httplib.FORBIDDEN, response.status_code,
             explain_unexpected_response(httplib.FORBIDDEN, response))
 
+    def test_nodegroup_list_nodes_requires_authentication(self):
+        nodegroup = factory.make_node_group()
+        response = self.client.get(
+            reverse('nodegroup_handler', args=[nodegroup.uuid]),
+            {'op': 'list_nodes'})
+        self.assertEqual(httplib.UNAUTHORIZED, response.status_code)
+
+    def test_nodegroup_list_nodes_does_not_work_for_normal_user(self):
+        nodegroup = factory.make_node_group()
+        log_in_as_normal_user(self.client)
+        response = self.client.get(
+            reverse('nodegroup_handler', args=[nodegroup.uuid]),
+            {'op': 'list_nodes'})
+        self.assertEqual(
+            httplib.FORBIDDEN, response.status_code,
+            explain_unexpected_response(httplib.FORBIDDEN, response))
+
+    def test_nodegroup_list_works_for_nodegroup_worker(self):
+        nodegroup = factory.make_node_group()
+        node = factory.make_node(nodegroup=nodegroup)
+        client = make_worker_client(nodegroup)
+        response = client.get(
+            reverse('nodegroup_handler', args=[nodegroup.uuid]),
+            {'op': 'list_nodes'})
+        self.assertEqual(
+            httplib.OK, response.status_code,
+            explain_unexpected_response(httplib.OK, response))
+        parsed_result = json.loads(response.content)
+        self.assertItemsEqual([node.system_id], parsed_result)
+
 
 class TestBootImagesAPI(APITestCase):