← Back to team overview

sts-sponsors team mailing list archive

[Merge] ~troyanov/maas:fix-pod-ws-handler into maas:master

 

Anton Troyanov has proposed merging ~troyanov/maas:fix-pod-ws-handler into maas:master.

Commit message:
fix(vault): vmhost use get/set power_parameters

Requested reviews:
  MAAS Lander (maas-lander)
  MAAS Maintainers (maas-maintainers)
Related bugs:
  Bug #1997599 in MAAS: "Losing LXD certificate "
  https://bugs.launchpad.net/maas/+bug/1997599

For more details, see:
https://code.launchpad.net/~troyanov/maas/+git/maas/+merge/433440
-- 
Your team MAAS Committers is subscribed to branch maas:master.
diff --git a/src/maasserver/forms/pods.py b/src/maasserver/forms/pods.py
index 27c2970..ed406fb 100644
--- a/src/maasserver/forms/pods.py
+++ b/src/maasserver/forms/pods.py
@@ -78,6 +78,7 @@ from provisioningserver.drivers.pod import (
     RequestedMachineBlockDevice,
     RequestedMachineInterface,
 )
+from provisioningserver.drivers.power.registry import sanitise_power_parameters
 from provisioningserver.enum import MACVLAN_MODE, MACVLAN_MODE_CHOICES
 from provisioningserver.utils.network import get_ifname_for_label
 from provisioningserver.utils.twisted import asynchronous
@@ -225,7 +226,7 @@ class PodForm(MAASModelForm):
             ].field_dict
             self.fields.update(self.param_fields)
             if not self.is_new:
-                for key, value in self.instance.power_parameters.items():
+                for key, value in self.instance.get_power_parameters().items():
                     if key not in self.data:
                         self.data[key] = value
             super()._clean_fields()
@@ -269,6 +270,10 @@ class PodForm(MAASModelForm):
             if param_name in self.cleaned_data
         }
 
+        sanitised_power_parameters, _ = sanitise_power_parameters(
+            power_type, power_parameters
+        )
+
         # When the Pod is new try to get a BMC of the same type and
         # parameters to convert the BMC to a new Pod. When the Pod is not
         # new the form will use the already existing pod instance to update
@@ -276,7 +281,8 @@ class PodForm(MAASModelForm):
         # a validation erorr will be raised from the model level.
         if self.is_new:
             bmc = BMC.objects.filter(
-                power_type=power_type, power_parameters=power_parameters
+                power_type=power_type,
+                power_parameters=sanitised_power_parameters,
             ).first()
             if bmc is not None:
                 if bmc.bmc_type == BMC_TYPE.BMC:
@@ -296,8 +302,9 @@ class PodForm(MAASModelForm):
         # update the object
         self.instance = super().save(commit=False)
         self.instance.power_type = power_type
-        self.instance.power_parameters = power_parameters
-
+        # save the object because we need ID from the database
+        self.instance.save()
+        self.instance.set_power_parameters(power_parameters)
         # update all members in a cluster if certificates are updated
         if not self.is_new and self.instance.cluster is not None:
             self.instance.cluster.update_certificate(
@@ -638,6 +645,7 @@ class ComposeMachineForm(forms.Form):
                     % (self.pod.name, over_commit_message)
                 )
 
+            power_parameters = self.pod.get_power_parameters()
             # Update the default storage pool.
             if self.pod.default_storage_pool is not None:
                 power_parameters[
@@ -646,7 +654,7 @@ class ComposeMachineForm(forms.Form):
 
             interfaces = get_known_host_interfaces(self.pod)
 
-            return client, interfaces
+            return client, interfaces, power_parameters
 
         def create_and_sync(result):
             requested_machine, result = result
@@ -666,24 +674,20 @@ class ComposeMachineForm(forms.Form):
             return created_machine
 
         @inlineCallbacks
-        def async_compose_machine(
-            result, power_type, power_paramaters, **kwargs
-        ):
-            client, result = result
+        def async_compose_machine(result, power_type, **kwargs):
+            client, interfaces, power_parameters = result
             requested_machine = yield deferToDatabase(
-                self.get_requested_machine, result
+                self.get_requested_machine, interfaces
             )
             result = yield compose_machine(
                 client,
                 power_type,
-                power_paramaters,
+                power_parameters,
                 requested_machine,
                 **kwargs,
             )
             return requested_machine, result
 
-        power_parameters = self.pod.power_parameters.copy()
-
         if isInIOThread():
             # Running under the twisted reactor, before the work from inside.
             d = deferToDatabase(transactional(self.pod.get_client_identifiers))
@@ -692,7 +696,6 @@ class ComposeMachineForm(forms.Form):
             d.addCallback(
                 async_compose_machine,
                 self.pod.power_type,
-                power_parameters,
                 pod_id=self.pod.id,
                 name=self.pod.name,
             )
@@ -723,9 +726,9 @@ class ComposeMachineForm(forms.Form):
                 )
                 return d
 
-            _, result = db_work(None)
+            _, interfaces, power_parameters = db_work(None)
             try:
-                requested_machine = self.get_requested_machine(result)
+                requested_machine = self.get_requested_machine(interfaces)
                 result = wrap_compose_machine(
                     self.pod.get_client_identifiers(),
                     self.pod.power_type,
diff --git a/src/maasserver/forms/tests/test_pods.py b/src/maasserver/forms/tests/test_pods.py
index beac59b..fbdeaef 100644
--- a/src/maasserver/forms/tests/test_pods.py
+++ b/src/maasserver/forms/tests/test_pods.py
@@ -272,8 +272,8 @@ class TestPodForm(MAASTransactionServerTestCase):
         self.assertTrue(form.is_valid(), form._errors)
         vmhost = form.save()
         cert = Certificate.from_pem(
-            vmhost.power_parameters["certificate"],
-            vmhost.power_parameters["key"],
+            vmhost.get_power_parameters()["certificate"],
+            vmhost.get_power_parameters()["key"],
         )
         self.assertEqual(cert.cn(), Config.objects.get_config("maas_name"))
 
@@ -288,8 +288,8 @@ class TestPodForm(MAASTransactionServerTestCase):
         self.assertTrue(form.is_valid(), form._errors)
         vmhost = form.save()
         cert = Certificate.from_pem(
-            vmhost.power_parameters["certificate"],
-            vmhost.power_parameters["key"],
+            vmhost.get_power_parameters()["certificate"],
+            vmhost.get_power_parameters()["key"],
         )
         self.assertEqual(
             cert.cn(), "lxd-server@" + Config.objects.get_config("maas_name")
@@ -310,7 +310,6 @@ class TestPodForm(MAASTransactionServerTestCase):
             power_type=pod_info["type"],
             power_parameters={
                 "power_address": pod_info["power_address"],
-                "power_pass": "",
             },
         )
         form = PodForm(data=pod_info, request=self.request)
@@ -432,11 +431,11 @@ class TestPodForm(MAASTransactionServerTestCase):
         updated_vmhosts = [vmhost for vmhost in result.hints.cluster.hosts()]
         for vmhost in updated_vmhosts:
             self.assertEqual(
-                vmhost.power_parameters["certificate"],
+                vmhost.get_power_parameters()["certificate"],
                 sample_cert.certificate_pem().strip(),
             )
             self.assertEqual(
-                vmhost.power_parameters["key"],
+                vmhost.get_power_parameters()["key"],
                 sample_cert.private_key_pem().strip(),
             )
 
diff --git a/src/maasserver/models/tests/test_vmcluster.py b/src/maasserver/models/tests/test_vmcluster.py
index 8c60656..edee8e3 100644
--- a/src/maasserver/models/tests/test_vmcluster.py
+++ b/src/maasserver/models/tests/test_vmcluster.py
@@ -531,8 +531,8 @@ class TestVMCluster(MAASServerTestCase):
 
         creds = [
             (
-                vmhost.power_parameters["certificate"],
-                vmhost.power_parameters["key"],
+                vmhost.get_power_parameters()["certificate"],
+                vmhost.get_power_parameters()["key"],
             )
             for vmhost in cluster.hosts()
         ]
diff --git a/src/maasserver/models/vmcluster.py b/src/maasserver/models/vmcluster.py
index 66bf485..b19b82a 100644
--- a/src/maasserver/models/vmcluster.py
+++ b/src/maasserver/models/vmcluster.py
@@ -237,10 +237,10 @@ class VMCluster(CleanSave, TimestampedModel):
         for vmhost in self.hosts():
             if skip is not None and vmhost.id == skip.id:
                 continue
-            power_parameters = vmhost.power_parameters.copy()
+            power_parameters = vmhost.get_power_parameters().copy()
             power_parameters["certificate"] = cert
             power_parameters["key"] = key
-            vmhost.power_parameters = power_parameters
+            vmhost.set_power_parameters(power_parameters)
             vmhost.save()
 
     @asynchronous
diff --git a/src/maasserver/tests/test_vmhost.py b/src/maasserver/tests/test_vmhost.py
index 808a471..d0c91bd 100644
--- a/src/maasserver/tests/test_vmhost.py
+++ b/src/maasserver/tests/test_vmhost.py
@@ -169,7 +169,7 @@ class TestDiscoverAndSyncVMHost(MAASServerTestCase):
         self.assertEqual(vmhost.cpu_speed, discovered_pod.cpu_speed)
         self.assertEqual(vmhost.zone, zone)
         self.assertEqual(vmhost.power_type, "virsh")
-        self.assertEqual(vmhost.power_parameters, power_parameters)
+        self.assertEqual(vmhost.get_power_parameters(), power_parameters)
         self.assertEqual(vmhost.ip_address.ip, pod_info["ip_address"])
         routable_racks = [
             relation.rack_controller
@@ -241,7 +241,7 @@ class TestDiscoverAndSyncVMHostAsync(MAASTransactionServerTestCase):
         self.assertEqual(vmhost.cpu_speed, discovered_pod.cpu_speed)
         self.assertEqual(vmhost.zone, zone)
         self.assertEqual(vmhost.power_type, "virsh")
-        self.assertEqual(vmhost.power_parameters, power_parameters)
+        self.assertEqual(vmhost.get_power_parameters(), power_parameters)
         self.assertEqual(vmhost.ip_address.ip, pod_info["ip_address"])
 
         def validate_rack_routes():
diff --git a/src/maasserver/websockets/handlers/pod.py b/src/maasserver/websockets/handlers/pod.py
index 66ccc4e..b32a080 100644
--- a/src/maasserver/websockets/handlers/pod.py
+++ b/src/maasserver/websockets/handlers/pod.py
@@ -119,7 +119,7 @@ class PodHandler(TimestampedModelHandler):
             }
         )
         if self.user.is_superuser:
-            data["power_parameters"] = obj.power_parameters
+            data["power_parameters"] = obj.get_power_parameters()
         if not for_list:
             if obj.host:
                 data["attached_vlans"] = list(
@@ -140,8 +140,8 @@ class PodHandler(TimestampedModelHandler):
                 data["boot_vlans"] = []
 
             # include certificate info if present
-            certificate = obj.power_parameters.get("certificate")
-            key = obj.power_parameters.get("key")
+            certificate = obj.get_power_parameters().get("certificate")
+            key = obj.get_power_parameters().get("key")
             if certificate and key:
                 cert = Certificate.from_pem(certificate, key)
                 data["certificate"] = dehydrate_certificate(cert)

Follow ups