Merge lp:~rvb/maas/backport-fixes into lp:maas/1.2

Proposed by Raphaël Badin
Status: Merged
Approved by: Raphaël Badin
Approved revision: no longer in the source branch.
Merged at revision: 1375
Proposed branch: lp:~rvb/maas/backport-fixes
Merge into: lp:maas/1.2
Diff against target: 307 lines (+116/-29)
6 files modified
src/maasserver/api.py (+29/-3)
src/maasserver/models/node.py (+2/-0)
src/maasserver/testing/factory.py (+19/-0)
src/maasserver/tests/test_api.py (+46/-0)
src/maasserver/tests/test_forms.py (+7/-26)
src/maasserver/tests/test_node.py (+13/-0)
To merge this branch: bzr merge lp:~rvb/maas/backport-fixes
Reviewer Review Type Date Requested Status
Raphaël Badin (community) Approve
Review via email: mp+160809@code.launchpad.net

Commit message

Backport revisions 1468 and 1469.

To post a comment you must log in.
Revision history for this message
Raphaël Badin (rvb) wrote :

Simple backport, self-approving.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/maasserver/api.py'
--- src/maasserver/api.py 2013-03-12 16:28:26 +0000
+++ src/maasserver/api.py 2013-04-25 07:58:26 +0000
@@ -65,6 +65,7 @@
65 "FilesHandler",65 "FilesHandler",
66 "get_oauth_token",66 "get_oauth_token",
67 "MaasHandler",67 "MaasHandler",
68 "NodeGroupHandler",
68 "NodeGroupsHandler",69 "NodeGroupsHandler",
69 "NodeGroupInterfaceHandler",70 "NodeGroupInterfaceHandler",
70 "NodeGroupInterfacesHandler",71 "NodeGroupInterfacesHandler",
@@ -149,6 +150,7 @@
149from maasserver.forms import (150from maasserver.forms import (
150 get_node_create_form,151 get_node_create_form,
151 get_node_edit_form,152 get_node_edit_form,
153 NodeGroupEdit,
152 NodeGroupInterfaceForm,154 NodeGroupInterfaceForm,
153 NodeGroupWithInterfacesForm,155 NodeGroupWithInterfacesForm,
154 TagForm,156 TagForm,
@@ -457,6 +459,9 @@
457 )459 )
458460
459461
462METHOD_RESERVED_ADMIN = "That method is reserved for admin users."
463
464
460def store_node_power_parameters(node, request):465def store_node_power_parameters(node, request):
461 """Store power parameters in request.466 """Store power parameters in request.
462467
@@ -1363,7 +1368,7 @@
1363 nodegroup.accept()1368 nodegroup.accept()
1364 return HttpResponse("Nodegroup(s) accepted.", status=httplib.OK)1369 return HttpResponse("Nodegroup(s) accepted.", status=httplib.OK)
1365 else:1370 else:
1366 raise PermissionDenied("That method is reserved to admin users.")1371 raise PermissionDenied(METHOD_RESERVED_ADMIN)
13671372
1368 @operation(idempotent=False)1373 @operation(idempotent=False)
1369 def reject(self, request):1374 def reject(self, request):
@@ -1381,7 +1386,7 @@
1381 nodegroup.reject()1386 nodegroup.reject()
1382 return HttpResponse("Nodegroup(s) rejected.", status=httplib.OK)1387 return HttpResponse("Nodegroup(s) rejected.", status=httplib.OK)
1383 else:1388 else:
1384 raise PermissionDenied("That method is reserved to admin users.")1389 raise PermissionDenied(METHOD_RESERVED_ADMIN)
13851390
1386 @classmethod1391 @classmethod
1387 def resource_uri(cls):1392 def resource_uri(cls):
@@ -1418,7 +1423,7 @@
1418 Each NodeGroup has its own uuid.1423 Each NodeGroup has its own uuid.
1419 """1424 """
14201425
1421 create = update = delete = None1426 create = delete = None
1422 fields = DISPLAYED_NODEGROUP_FIELDS1427 fields = DISPLAYED_NODEGROUP_FIELDS
14231428
1424 def read(self, request, uuid):1429 def read(self, request, uuid):
@@ -1433,6 +1438,27 @@
1433 uuid = nodegroup.uuid1438 uuid = nodegroup.uuid
1434 return ('nodegroup_handler', [uuid])1439 return ('nodegroup_handler', [uuid])
14351440
1441 def update(self, request, uuid):
1442 """Update a specific cluster.
1443
1444 :param name: The new DNS name for this cluster.
1445 :type name: basestring
1446 :param cluster_name: The new name for this cluster.
1447 :type cluster_name: basestring
1448 :param status: The new status for this cluster (see
1449 vocabulary `NODEGROUP_STATUS`).
1450 :type status: int
1451 """
1452 if not request.user.is_superuser:
1453 raise PermissionDenied(METHOD_RESERVED_ADMIN)
1454 nodegroup = get_object_or_404(NodeGroup, uuid=uuid)
1455 data = get_overrided_query_dict(model_to_dict(nodegroup), request.data)
1456 form = NodeGroupEdit(instance=nodegroup, data=data)
1457 if form.is_valid():
1458 return form.save()
1459 else:
1460 raise ValidationError(form.errors)
1461
1436 @operation(idempotent=False)1462 @operation(idempotent=False)
1437 def update_leases(self, request, uuid):1463 def update_leases(self, request, uuid):
1438 """Submit latest state of DHCP leases within the cluster.1464 """Submit latest state of DHCP leases within the cluster.
14391465
=== modified file 'src/maasserver/models/node.py'
--- src/maasserver/models/node.py 2013-01-14 16:16:57 +0000
+++ src/maasserver/models/node.py 2013-04-25 07:58:26 +0000
@@ -395,6 +395,8 @@
395 node.cpu_count = cpu_count or 0395 node.cpu_count = cpu_count or 0
396 node.memory = memory396 node.memory = memory
397 for tag in tag_manager.all():397 for tag in tag_manager.all():
398 if not tag.definition:
399 continue
398 has_tag = evaluator(tag.definition)400 has_tag = evaluator(tag.definition)
399 if has_tag:401 if has_tag:
400 node.tags.add(tag)402 node.tags.add(tag)
401403
=== modified file 'src/maasserver/testing/factory.py'
--- src/maasserver/testing/factory.py 2013-03-07 16:26:00 +0000
+++ src/maasserver/testing/factory.py 2013-04-25 07:58:26 +0000
@@ -210,6 +210,25 @@
210 ng.save()210 ng.save()
211 return ng211 return ng
212212
213 def make_unrenamable_nodegroup_with_node(self):
214 """Create a `NodeGroup` that can't be renamed, and `Node`.
215
216 Node groups can't be renamed while they are in an accepted state, have
217 DHCP and DNS management enabled, and have a node that is in allocated
218 state.
219
220 :return: tuple: (`NodeGroup`, `Node`).
221 """
222 name = self.make_name('original-name')
223 nodegroup = self.make_node_group(
224 name=name, status=NODEGROUP_STATUS.ACCEPTED)
225 interface = nodegroup.get_managed_interface()
226 interface.management = NODEGROUPINTERFACE_MANAGEMENT.DHCP_AND_DNS
227 interface.save()
228 node = self.make_node(
229 nodegroup=nodegroup, status=NODE_STATUS.ALLOCATED)
230 return nodegroup, node
231
213 def make_node_group_interface(self, nodegroup, ip=None,232 def make_node_group_interface(self, nodegroup, ip=None,
214 router_ip=None, network=None,233 router_ip=None, network=None,
215 subnet_mask=None, broadcast_ip=None,234 subnet_mask=None, broadcast_ip=None,
216235
=== modified file 'src/maasserver/tests/test_api.py'
--- src/maasserver/tests/test_api.py 2013-03-12 16:28:26 +0000
+++ src/maasserver/tests/test_api.py 2013-04-25 07:58:26 +0000
@@ -77,6 +77,7 @@
77 NODE_STATUS,77 NODE_STATUS,
78 NODE_STATUS_CHOICES_DICT,78 NODE_STATUS_CHOICES_DICT,
79 NODEGROUP_STATUS,79 NODEGROUP_STATUS,
80 NODEGROUP_STATUS_CHOICES,
80 NODEGROUPINTERFACE_MANAGEMENT,81 NODEGROUPINTERFACE_MANAGEMENT,
81 )82 )
82from maasserver.exceptions import (83from maasserver.exceptions import (
@@ -4394,6 +4395,51 @@
4394 self.get_uri('nodegroups/%s/' % factory.make_name('nodegroup')))4395 self.get_uri('nodegroups/%s/' % factory.make_name('nodegroup')))
4395 self.assertEqual(httplib.NOT_FOUND, response.status_code)4396 self.assertEqual(httplib.NOT_FOUND, response.status_code)
43964397
4398 def test_PUT_reserved_to_admin_users(self):
4399 nodegroup = factory.make_node_group()
4400 response = self.client.put(
4401 reverse('nodegroup_handler', args=[nodegroup.uuid]),
4402 {'name': factory.make_name("new-name")})
4403
4404 self.assertEqual(httplib.FORBIDDEN, response.status_code)
4405
4406 def test_PUT_updates_nodegroup(self):
4407 # The api allows the updating of a NodeGroup.
4408 nodegroup = factory.make_node_group()
4409 self.become_admin()
4410 new_name = factory.make_name("new-name")
4411 new_cluster_name = factory.make_name("new-cluster-name")
4412 new_status = factory.getRandomChoice(
4413 NODEGROUP_STATUS_CHOICES, but_not=[nodegroup.status])
4414 response = self.client.put(
4415 reverse('nodegroup_handler', args=[nodegroup.uuid]),
4416 {
4417 'name': new_name,
4418 'cluster_name': new_cluster_name,
4419 'status': new_status,
4420 })
4421
4422 self.assertEqual(httplib.OK, response.status_code, response.content)
4423 nodegroup = reload_object(nodegroup)
4424 self.assertEqual(
4425 (new_name, new_cluster_name, new_status),
4426 (nodegroup.name, nodegroup.cluster_name, nodegroup.status))
4427
4428 def test_PUT_updates_nodegroup_validates_data(self):
4429 nodegroup, _ = factory.make_unrenamable_nodegroup_with_node()
4430 self.become_admin()
4431 new_name = factory.make_name("new-name")
4432 response = self.client.put(
4433 reverse('nodegroup_handler', args=[nodegroup.uuid]),
4434 {'name': new_name})
4435
4436 parsed_result = json.loads(response.content)
4437
4438 self.assertEqual(httplib.BAD_REQUEST, response.status_code)
4439 self.assertIn(
4440 "Can't rename DNS zone",
4441 parsed_result['name'][0])
4442
4397 def test_update_leases_processes_empty_leases_dict(self):4443 def test_update_leases_processes_empty_leases_dict(self):
4398 nodegroup = factory.make_node_group()4444 nodegroup = factory.make_node_group()
4399 factory.make_dhcp_lease(nodegroup=nodegroup)4445 factory.make_dhcp_lease(nodegroup=nodegroup)
44004446
=== modified file 'src/maasserver/tests/test_forms.py'
--- src/maasserver/tests/test_forms.py 2012-12-04 02:31:07 +0000
+++ src/maasserver/tests/test_forms.py 2013-04-25 07:58:26 +0000
@@ -878,25 +878,6 @@
878 ])878 ])
879879
880880
881def make_unrenamable_nodegroup_with_node():
882 """Create a `NodeGroup` that can't be renamed, and `Node`.
883
884 Node groups can't be renamed while they are in an accepted state, have
885 DHCP and DNS management enabled, and have a node that is in allocated
886 state.
887
888 :return: tuple: (`NodeGroup`, `Node`).
889 """
890 name = factory.make_name('original-name')
891 nodegroup = factory.make_node_group(
892 name=name, status=NODEGROUP_STATUS.ACCEPTED)
893 interface = nodegroup.get_managed_interface()
894 interface.management = NODEGROUPINTERFACE_MANAGEMENT.DHCP_AND_DNS
895 interface.save()
896 node = factory.make_node(nodegroup=nodegroup, status=NODE_STATUS.ALLOCATED)
897 return nodegroup, node
898
899
900class TestNodeGroupEdit(TestCase):881class TestNodeGroupEdit(TestCase):
901882
902 def make_form_data(self, nodegroup):883 def make_form_data(self, nodegroup):
@@ -918,14 +899,14 @@
918 self.assertEqual(new_name, reload_object(nodegroup).name)899 self.assertEqual(new_name, reload_object(nodegroup).name)
919900
920 def test_refuses_name_change_if_dns_managed_and_nodes_in_use(self):901 def test_refuses_name_change_if_dns_managed_and_nodes_in_use(self):
921 nodegroup, node = make_unrenamable_nodegroup_with_node()902 nodegroup, node = factory.make_unrenamable_nodegroup_with_node()
922 data = self.make_form_data(nodegroup)903 data = self.make_form_data(nodegroup)
923 data['name'] = factory.make_name('new-name')904 data['name'] = factory.make_name('new-name')
924 form = NodeGroupEdit(instance=nodegroup, data=data)905 form = NodeGroupEdit(instance=nodegroup, data=data)
925 self.assertFalse(form.is_valid())906 self.assertFalse(form.is_valid())
926907
927 def test_accepts_unchanged_name(self):908 def test_accepts_unchanged_name(self):
928 nodegroup, node = make_unrenamable_nodegroup_with_node()909 nodegroup, node = factory.make_unrenamable_nodegroup_with_node()
929 original_name = nodegroup.name910 original_name = nodegroup.name
930 form = NodeGroupEdit(911 form = NodeGroupEdit(
931 instance=nodegroup, data=self.make_form_data(nodegroup))912 instance=nodegroup, data=self.make_form_data(nodegroup))
@@ -934,7 +915,7 @@
934 self.assertEqual(original_name, reload_object(nodegroup).name)915 self.assertEqual(original_name, reload_object(nodegroup).name)
935916
936 def test_accepts_omitted_name(self):917 def test_accepts_omitted_name(self):
937 nodegroup, node = make_unrenamable_nodegroup_with_node()918 nodegroup, node = factory.make_unrenamable_nodegroup_with_node()
938 original_name = nodegroup.name919 original_name = nodegroup.name
939 data = self.make_form_data(nodegroup)920 data = self.make_form_data(nodegroup)
940 del data['name']921 del data['name']
@@ -944,7 +925,7 @@
944 self.assertEqual(original_name, reload_object(nodegroup).name)925 self.assertEqual(original_name, reload_object(nodegroup).name)
945926
946 def test_accepts_name_change_if_nodegroup_not_accepted(self):927 def test_accepts_name_change_if_nodegroup_not_accepted(self):
947 nodegroup, node = make_unrenamable_nodegroup_with_node()928 nodegroup, node = factory.make_unrenamable_nodegroup_with_node()
948 nodegroup.status = NODEGROUP_STATUS.PENDING929 nodegroup.status = NODEGROUP_STATUS.PENDING
949 data = self.make_form_data(nodegroup)930 data = self.make_form_data(nodegroup)
950 data['name'] = factory.make_name('new-name')931 data['name'] = factory.make_name('new-name')
@@ -952,7 +933,7 @@
952 self.assertTrue(form.is_valid())933 self.assertTrue(form.is_valid())
953934
954 def test_accepts_name_change_if_dns_managed_but_no_nodes_in_use(self):935 def test_accepts_name_change_if_dns_managed_but_no_nodes_in_use(self):
955 nodegroup, node = make_unrenamable_nodegroup_with_node()936 nodegroup, node = factory.make_unrenamable_nodegroup_with_node()
956 node.status = NODE_STATUS.READY937 node.status = NODE_STATUS.READY
957 node.save()938 node.save()
958 data = self.make_form_data(nodegroup)939 data = self.make_form_data(nodegroup)
@@ -963,7 +944,7 @@
963 self.assertEqual(data['name'], reload_object(nodegroup).name)944 self.assertEqual(data['name'], reload_object(nodegroup).name)
964945
965 def test_accepts_name_change_if_nodes_in_use_but_dns_not_managed(self):946 def test_accepts_name_change_if_nodes_in_use_but_dns_not_managed(self):
966 nodegroup, node = make_unrenamable_nodegroup_with_node()947 nodegroup, node = factory.make_unrenamable_nodegroup_with_node()
967 interface = nodegroup.get_managed_interface()948 interface = nodegroup.get_managed_interface()
968 interface.management = NODEGROUPINTERFACE_MANAGEMENT.DHCP949 interface.management = NODEGROUPINTERFACE_MANAGEMENT.DHCP
969 interface.save()950 interface.save()
@@ -975,7 +956,7 @@
975 self.assertEqual(data['name'], reload_object(nodegroup).name)956 self.assertEqual(data['name'], reload_object(nodegroup).name)
976957
977 def test_accepts_name_change_if_nodegroup_has_no_interface(self):958 def test_accepts_name_change_if_nodegroup_has_no_interface(self):
978 nodegroup, node = make_unrenamable_nodegroup_with_node()959 nodegroup, node = factory.make_unrenamable_nodegroup_with_node()
979 NodeGroupInterface.objects.filter(nodegroup=nodegroup).delete()960 NodeGroupInterface.objects.filter(nodegroup=nodegroup).delete()
980 data = self.make_form_data(nodegroup)961 data = self.make_form_data(nodegroup)
981 data['name'] = factory.make_name('new-name')962 data['name'] = factory.make_name('new-name')
982963
=== modified file 'src/maasserver/tests/test_node.py'
--- src/maasserver/tests/test_node.py 2012-11-16 13:50:43 +0000
+++ src/maasserver/tests/test_node.py 2013-04-25 07:58:26 +0000
@@ -586,6 +586,19 @@
586 node = reload_object(node)586 node = reload_object(node)
587 self.assertEqual([], list(node.tags.all()))587 self.assertEqual([], list(node.tags.all()))
588588
589 def test_hardware_updates_ignores_empty_tags(self):
590 # Tags with empty definitions are ignored when
591 # node.set_hardware_details gets called.
592 factory.make_tag(definition='')
593 node = factory.make_node()
594 node.save()
595 xmlbytes = '<node/>'
596 node.set_hardware_details(xmlbytes)
597 node = reload_object(node)
598 # The real test is that node.set_hardware_details does not blow
599 # up, see bug 1131418.
600 self.assertEqual([], list(node.tags.all()))
601
589 def test_fqdn_returns_hostname_if_dns_not_managed(self):602 def test_fqdn_returns_hostname_if_dns_not_managed(self):
590 nodegroup = factory.make_node_group(603 nodegroup = factory.make_node_group(
591 name=factory.getRandomString(),604 name=factory.getRandomString(),

Subscribers

People subscribed via source and target branches

to status/vote changes: