← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~jtv/maas/nodegroup-update-lease-api into lp:maas

 

Jeroen T. Vermeulen has proposed merging lp:~jtv/maas/nodegroup-update-lease-api into lp:maas with lp:~jtv/maas/nodegroups-api as a prerequisite.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~jtv/maas/nodegroup-update-lease-api/+merge/114565

This was discussed for pre-imp with Raphaël.  It builds on a previous, still unreviewed branch that created a very minimal NodeGroups API.  The new POST method I introduce here allows a node group worker to register its current DHCP leases with the server.

There remains work to be done: we need proper worker authentication so that regular users can't call this API method (it does require /some/ authentication of course) and we still need to pass the news on to the master worker so that it can update the corresponding DNS zone file.


Jeroen
-- 
https://code.launchpad.net/~jtv/maas/nodegroup-update-lease-api/+merge/114565
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~jtv/maas/nodegroup-update-lease-api into lp:maas.
=== modified file 'src/maasserver/api.py'
--- src/maasserver/api.py	2012-07-04 14:51:08 +0000
+++ src/maasserver/api.py	2012-07-12 06:02:19 +0000
@@ -61,6 +61,7 @@
     "AccountHandler",
     "AnonNodesHandler",
     "FilesHandler",
+    "NodeGroupsHandler",
     "NodeHandler",
     "NodesHandler",
     "NodeMacHandler",
@@ -116,9 +117,11 @@
     )
 from maasserver.models import (
     Config,
+    DHCPLease,
     FileStorage,
     MACAddress,
     Node,
+    NodeGroup,
     )
 from piston.doc import generate_doc
 from piston.handler import (
@@ -833,6 +836,38 @@
 
 
 @api_operations
+class NodeGroupsHandler(BaseHandler):
+    """Node-groups API."""
+
+    allowed_methods = ('GET', 'POST')
+
+    def read(self, request, nodegroup=None):
+        """Index of node groups."""
+        if nodegroup is None:
+            # Request is for the NodeGroups index.
+            return HttpResponse(
+                [nodegroup.name for nodegroup in NodeGroup.objects.all()])
+
+    @classmethod
+    def resource_uri(cls, nodegroup=None):
+        if nodegroup is None:
+            nodegroup = 'name'
+        return ('nodegroups_handler', (nodegroup, ))
+
+    @api_exported('POST')
+    def update_leases(self, request, nodegroup):
+        nodegroup = get_object_or_404(NodeGroup, name=nodegroup)
+
+        leases = request.data.get('leases', None)
+        if leases is None:
+            raise MAASAPIBadRequest("No leases given.")
+
+        DHCPLease.objects.update_leases(nodegroup, json.loads(leases))
+
+        return HttpResponse("Leases updated.", status=httplib.OK)
+
+
+@api_operations
 class AccountHandler(BaseHandler):
     """Manage the current logged-in user."""
     allowed_methods = ('POST',)

=== modified file 'src/maasserver/tests/test_api.py'
--- src/maasserver/tests/test_api.py	2012-07-12 06:02:19 +0000
+++ src/maasserver/tests/test_api.py	2012-07-12 06:02:19 +0000
@@ -51,6 +51,7 @@
 from maasserver.exceptions import Unauthorized
 from maasserver.models import (
     Config,
+    DHCPLease,
     MACAddress,
     Node,
     )
@@ -2277,6 +2278,10 @@
 
 class TestNodeGroupsAPI(APITestCase):
 
+    def get_nodegroup_uri(self, nodegroup):
+        """Compose the API URI for `nodegroup`."""
+        return self.get_uri('nodegroups/%s/' % nodegroup.name)
+
     def test_nodegroups_index_lists_nodegroups(self):
         # The nodegroups index lists node groups for the MAAS.
         nodegroup = factory.make_node_group()
@@ -2284,6 +2289,38 @@
         self.assertEqual(httplib.OK, response.status_code)
         self.assertIn(nodegroup.name, json.loads(response.content))
 
+    def test_update_leases_processes_empty_leases_dict(self):
+        nodegroup = factory.make_node_group()
+        factory.make_dhcp_lease(nodegroup=nodegroup)
+        response = self.client.post(
+            self.get_nodegroup_uri(nodegroup),
+            {
+                'op': 'update_leases',
+                'leases': json.dumps({}),
+            })
+        self.assertEqual(
+            (httplib.OK, "Leases updated."),
+            (response.status_code, response.content))
+        self.assertItemsEqual(
+            [], DHCPLease.objects.filter(nodegroup=nodegroup))
+
+    def test_update_leases_stores_leases(self):
+        nodegroup = factory.make_node_group()
+        ip = factory.getRandomIPAddress()
+        mac = factory.getRandomMACAddress()
+        response = self.client.post(
+            self.get_nodegroup_uri(nodegroup),
+            {
+                'op': 'update_leases',
+                'leases': json.dumps({ip: mac}),
+            })
+        self.assertEqual(
+            (httplib.OK, "Leases updated."),
+            (response.status_code, response.content))
+        self.assertEqual([ip], [
+            lease.ip
+            for lease in DHCPLease.objects.filter(nodegroup=nodegroup)])
+
 
 class TestAnonNodeGroupsAPI(AnonAPITestCase):
 

=== modified file 'src/maasserver/urls_api.py'
--- src/maasserver/urls_api.py	2012-07-04 13:07:31 +0000
+++ src/maasserver/urls_api.py	2012-07-12 06:02:19 +0000
@@ -22,6 +22,7 @@
     api_doc,
     FilesHandler,
     MAASHandler,
+    NodeGroupsHandler,
     NodeHandler,
     NodeMacHandler,
     NodeMacsHandler,
@@ -39,6 +40,8 @@
 node_mac_handler = RestrictedResource(NodeMacHandler, authentication=api_auth)
 node_macs_handler = RestrictedResource(
     NodeMacsHandler, authentication=api_auth)
+nodegroups_handler = RestrictedResource(
+    NodeGroupsHandler, authentication=api_auth)
 
 
 # Admin handlers.
@@ -65,6 +68,9 @@
         r'nodes/(?P<system_id>[\w\-]+)/$', node_handler,
         name='node_handler'),
     url(r'nodes/$', nodes_handler, name='nodes_handler'),
+    url(
+        r'nodegroups/(?P<nodegroup>[^/]+)?/*$',
+        nodegroups_handler, name='nodegroups_handler'),
     url(r'files/$', files_handler, name='files_handler'),
     url(r'account/$', account_handler, name='account_handler'),
 )


Follow ups