← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~jtv/maas/refresh-worker-secrets into lp:maas

 

Jeroen T. Vermeulen has proposed merging lp:~jtv/maas/refresh-worker-secrets into lp:maas.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~jtv/maas/refresh-worker-secrets/+merge/119156

I must admit I haven't properly pre-imped this branch per se, but it's the logical continuation of work I discussed with Julian and that showed up in most or all of my branches in the past few days.

We have a mechanism to send a node-group worker its API credentials, OMAPI key etc. through a single “refresh” task.  We may want to expose that through an anonymous API, so that a booting worker can ask the server to send over its credentials and other knowledge over the trusted rabbit channel; or we may opt to run it periodically so that a worker needs to know absolutely nothing except how to connect to rabbit, and gets all other information it needs over that connection.

The mechanism still needs more work, e.g. multi-processing capability (it's currently written to deal only with threads) and a simple way to reset its knowledge between tests.  It may also need a new name (it's currently called refresh_secrets but already it's grown beyond that).  But the basic mechanism seems usable and useful.

Anyway.  In this branch you see how the server can gather up all the information a node-group worker needs, and send it over, in one convenient function call.  We can decide later how & when we issue that call.


Jeroen
-- 
https://code.launchpad.net/~jtv/maas/refresh-worker-secrets/+merge/119156
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~jtv/maas/refresh-worker-secrets into lp:maas.
=== added file 'src/maasserver/refresh_worker.py'
--- src/maasserver/refresh_worker.py	1970-01-01 00:00:00 +0000
+++ src/maasserver/refresh_worker.py	2012-08-10 16:00:31 +0000
@@ -0,0 +1,45 @@
+# Copyright 2012 Canonical Ltd.  This software is licensed under the
+# GNU Affero General Public License version 3 (see the file LICENSE).
+
+"""Refresh node-group worker's knowledge."""
+
+from __future__ import (
+    absolute_import,
+    print_function,
+    unicode_literals,
+    )
+
+__metaclass__ = type
+__all__ = [
+    'refresh_worker',
+    ]
+
+from provisioningserver.tasks import refresh_secrets
+
+
+def refresh_worker(nodegroup):
+    """Send worker for `nodegroup` a refresh message with credentials etc.
+
+    This is how we tell the worker its MAAS API credentials, the name of
+    the node group it manages, and so on.  The function gathers all the
+    usual information (although we can always extend the mechanism with
+    more specific knowledge that we may choose not to include here) and
+    issues a task to the node-group worker that causes it to absorb the
+    given information items.
+    """
+
+    items = {
+        'nodegroup_name': nodegroup.name,
+    }
+
+    if nodegroup.dhcp_key is not None and len(nodegroup.dhcp_key) > 0:
+        items['omapi_shared_key'] = nodegroup.dhcp_key
+
+    items['api_credentials'] = ':'.join([
+        nodegroup.api_token.consumer.key,
+        nodegroup.api_token.key,
+        nodegroup.api_token.secret,
+        ])
+
+    # TODO: Route this to the right worker, once we have multiple.
+    refresh_secrets.delay(**items)

=== added file 'src/maasserver/tests/test_refresh_worker.py'
--- src/maasserver/tests/test_refresh_worker.py	1970-01-01 00:00:00 +0000
+++ src/maasserver/tests/test_refresh_worker.py	2012-08-10 16:00:31 +0000
@@ -0,0 +1,77 @@
+# Copyright 2012 Canonical Ltd.  This software is licensed under the
+# GNU Affero General Public License version 3 (see the file LICENSE).
+
+"""Tests for the code that refreshes a node-group worker's information."""
+
+from __future__ import (
+    absolute_import,
+    print_function,
+    unicode_literals,
+    )
+
+__metaclass__ = type
+__all__ = []
+
+from maasserver.refresh_worker import refresh_worker
+from maasserver.testing.factory import factory
+from maasserver.testing.testcase import TestCase
+from maastesting.fakemethod import FakeMethod
+from provisioningserver import tasks
+
+
+class TestRefreshWorker(TestCase):
+
+    def patch_refresh_functions(self):
+        """Replace the worker refresh functions with a test double.
+
+        The test double, which is returned for convenience, contains the
+        same keys as the original, but each maps to a `FakeMethod`.
+
+        To verify a refresh task's effect, all that a test needs to do
+        is inspect the calls on these fakes.  If the test mis-spells an
+        item's name, or tries to inspect a nonexistent item, it will
+        fail to find a test double for that item.
+        """
+        playground_refresh_functions = {
+            item: FakeMethod()
+            for item in tasks.refresh_functions}
+        self.patch(tasks, 'refresh_functions', playground_refresh_functions)
+        return playground_refresh_functions
+
+    def test_refreshes_api_credentials(self):
+        refresh_functions = self.patch_refresh_functions()
+        nodegroup = factory.make_node_group()
+        refresh_worker(nodegroup)
+        creds_string = ':'.join([
+            nodegroup.api_token.consumer.key,
+            nodegroup.api_token.key,
+            nodegroup.api_token.secret,
+            ])
+        self.assertEqual(
+            [(creds_string, )],
+            refresh_functions['api_credentials'].extract_args())
+
+    def test_refreshes_omapi_shared_key(self):
+        refresh_functions = self.patch_refresh_functions()
+        dhcp_key = factory.getRandomString()
+        nodegroup = factory.make_node_group(dhcp_key=dhcp_key)
+        refresh_worker(nodegroup)
+        self.assertEqual(
+            [(dhcp_key, )],
+            refresh_functions['omapi_shared_key'].extract_args())
+
+    def test_omits_omapi_shared_key_if_not_set(self):
+        refresh_functions = self.patch_refresh_functions()
+        nodegroup = factory.make_node_group()
+        refresh_worker(nodegroup)
+        self.assertEqual(
+            [],
+            refresh_functions['omapi_shared_key'].extract_args())
+
+    def test_refreshes_nodegroup_name(self):
+        refresh_functions = self.patch_refresh_functions()
+        nodegroup = factory.make_node_group()
+        refresh_worker(nodegroup)
+        self.assertEqual(
+            [(nodegroup.name, )],
+            refresh_functions['nodegroup_name'].extract_args())