Merge lp:~jtv/maas/bug-1070775 into lp:~maas-committers/maas/trunk

Proposed by Jeroen T. Vermeulen
Status: Merged
Approved by: Jeroen T. Vermeulen
Approved revision: no longer in the source branch.
Merged at revision: 1320
Proposed branch: lp:~jtv/maas/bug-1070775
Merge into: lp:~maas-committers/maas/trunk
Diff against target: 156 lines (+124/-0)
2 files modified
src/maasserver/forms.py (+26/-0)
src/maasserver/tests/test_forms.py (+98/-0)
To merge this branch: bzr merge lp:~jtv/maas/bug-1070775
Reviewer Review Type Date Requested Status
Jeroen T. Vermeulen (community) Approve
Review via email: mp+132068@code.launchpad.net

Commit message

Forward-port r1277 from 1.2: Disallow nodegroup (DNS zone) name changes while allocated nodes are still using that zone name.

Description of the change

No changes needed in porting this over from the 1.2 branch.

Jeroen

To post a comment you must log in.
Revision history for this message
Jeroen T. Vermeulen (jtv) wrote :

Self-approving: already reviewed & landed in 1.2, and unchanged here.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/maasserver/forms.py'
--- src/maasserver/forms.py 2012-10-30 10:30:34 +0000
+++ src/maasserver/forms.py 2012-10-30 11:28:36 +0000
@@ -63,6 +63,7 @@
63 NODE_AFTER_COMMISSIONING_ACTION,63 NODE_AFTER_COMMISSIONING_ACTION,
64 NODE_AFTER_COMMISSIONING_ACTION_CHOICES,64 NODE_AFTER_COMMISSIONING_ACTION_CHOICES,
65 NODE_STATUS,65 NODE_STATUS,
66 NODEGROUP_STATUS,
66 NODEGROUPINTERFACE_MANAGEMENT,67 NODEGROUPINTERFACE_MANAGEMENT,
67 NODEGROUPINTERFACE_MANAGEMENT_CHOICES,68 NODEGROUPINTERFACE_MANAGEMENT_CHOICES,
68 )69 )
@@ -820,6 +821,31 @@
820 'name',821 'name',
821 )822 )
822823
824 def clean_name(self):
825 old_name = self.instance.name
826 new_name = self.cleaned_data['name']
827 if new_name == old_name or not new_name:
828 # No change to the name. Return old name.
829 return old_name
830
831 if self.instance.status != NODEGROUP_STATUS.ACCEPTED:
832 # This nodegroup is not in use. Change it at will.
833 return new_name
834
835 interface = self.instance.get_managed_interface()
836 if interface.management != NODEGROUPINTERFACE_MANAGEMENT.DHCP_AND_DNS:
837 # MAAS is not managing DNS on this network, so the user can
838 # rename the zone at will.
839 return new_name
840
841 nodes_in_use = Node.objects.filter(
842 nodegroup=self.instance, status=NODE_STATUS.ALLOCATED)
843 if nodes_in_use.exists():
844 raise ValidationError(
845 "Can't rename DNS zone to %s; nodes are in use." % new_name)
846
847 return new_name
848
823849
824class TagForm(ModelForm):850class TagForm(ModelForm):
825851
826852
=== modified file 'src/maasserver/tests/test_forms.py'
--- src/maasserver/tests/test_forms.py 2012-10-30 10:30:34 +0000
+++ src/maasserver/tests/test_forms.py 2012-10-30 11:28:36 +0000
@@ -44,6 +44,7 @@
44 NewUserCreationForm,44 NewUserCreationForm,
45 NodeActionForm,45 NodeActionForm,
46 NodeForm,46 NodeForm,
47 NodeGroupEdit,
47 NodeGroupInterfaceForm,48 NodeGroupInterfaceForm,
48 NodeGroupWithInterfacesForm,49 NodeGroupWithInterfacesForm,
49 NodeWithMACAddressesForm,50 NodeWithMACAddressesForm,
@@ -894,3 +895,100 @@
894 nodegroup.management for nodegroup in895 nodegroup.management for nodegroup in
895 nodegroup.nodegroupinterface_set.all()896 nodegroup.nodegroupinterface_set.all()
896 ])897 ])
898
899
900def make_unrenamable_nodegroup_with_node():
901 """Create a `NodeGroup` that can't be renamed, and `Node`.
902
903 Node groups can't be renamed while they are in an accepted state, have
904 DHCP and DNS management enabled, and have a node that is in allocated
905 state.
906
907 :return: tuple: (`NodeGroup`, `Node`).
908 """
909 name = factory.make_name('original-name')
910 nodegroup = factory.make_node_group(
911 name=name, status=NODEGROUP_STATUS.ACCEPTED)
912 interface = nodegroup.get_managed_interface()
913 interface.management = NODEGROUPINTERFACE_MANAGEMENT.DHCP_AND_DNS
914 interface.save()
915 node = factory.make_node(nodegroup=nodegroup, status=NODE_STATUS.ALLOCATED)
916 return nodegroup, node
917
918
919class TestNodeGroupEdit(TestCase):
920
921 def make_form_data(self, nodegroup):
922 """Create `NodeGroupEdit` form data based on `nodegroup`."""
923 return {
924 'name': nodegroup.name,
925 'cluster_name': nodegroup.cluster_name,
926 'status': nodegroup.status,
927 }
928
929 def test_changes_name(self):
930 nodegroup = factory.make_node_group(name=factory.make_name('old-name'))
931 new_name = factory.make_name('new-name')
932 data = self.make_form_data(nodegroup)
933 data['name'] = new_name
934 form = NodeGroupEdit(instance=nodegroup, data=data)
935 self.assertTrue(form.is_valid())
936 form.save()
937 self.assertEqual(new_name, reload_object(nodegroup).name)
938
939 def test_refuses_name_change_if_dns_managed_and_nodes_in_use(self):
940 nodegroup, node = make_unrenamable_nodegroup_with_node()
941 data = self.make_form_data(nodegroup)
942 data['name'] = factory.make_name('new-name')
943 form = NodeGroupEdit(instance=nodegroup, data=data)
944 self.assertFalse(form.is_valid())
945
946 def test_accepts_unchanged_name(self):
947 nodegroup, node = make_unrenamable_nodegroup_with_node()
948 original_name = nodegroup.name
949 form = NodeGroupEdit(
950 instance=nodegroup, data=self.make_form_data(nodegroup))
951 self.assertTrue(form.is_valid())
952 form.save()
953 self.assertEqual(original_name, reload_object(nodegroup).name)
954
955 def test_accepts_omitted_name(self):
956 nodegroup, node = make_unrenamable_nodegroup_with_node()
957 original_name = nodegroup.name
958 data = self.make_form_data(nodegroup)
959 del data['name']
960 form = NodeGroupEdit(instance=nodegroup, data=data)
961 self.assertTrue(form.is_valid())
962 form.save()
963 self.assertEqual(original_name, reload_object(nodegroup).name)
964
965 def test_accepts_name_change_if_nodegroup_not_accepted(self):
966 nodegroup, node = make_unrenamable_nodegroup_with_node()
967 nodegroup.status = NODEGROUP_STATUS.PENDING
968 data = self.make_form_data(nodegroup)
969 data['name'] = factory.make_name('new-name')
970 form = NodeGroupEdit(instance=nodegroup, data=data)
971 self.assertTrue(form.is_valid())
972
973 def test_accepts_name_change_if_dns_managed_but_no_nodes_in_use(self):
974 nodegroup, node = make_unrenamable_nodegroup_with_node()
975 node.status = NODE_STATUS.READY
976 node.save()
977 data = self.make_form_data(nodegroup)
978 data['name'] = factory.make_name('new-name')
979 form = NodeGroupEdit(instance=nodegroup, data=data)
980 self.assertTrue(form.is_valid())
981 form.save()
982 self.assertEqual(data['name'], reload_object(nodegroup).name)
983
984 def test_accepts_name_change_if_nodes_in_use_but_dns_not_managed(self):
985 nodegroup, node = make_unrenamable_nodegroup_with_node()
986 interface = nodegroup.get_managed_interface()
987 interface.management = NODEGROUPINTERFACE_MANAGEMENT.DHCP
988 interface.save()
989 data = self.make_form_data(nodegroup)
990 data['name'] = factory.make_name('new-name')
991 form = NodeGroupEdit(instance=nodegroup, data=data)
992 self.assertTrue(form.is_valid())
993 form.save()
994 self.assertEqual(data['name'], reload_object(nodegroup).name)