~ubuntu-branches/ubuntu/quantal/maas/quantal-security

« back to all changes in this revision

Viewing changes to src/maasserver/tests/test_forms.py

  • Committer: Package Import Robot
  • Author(s): Seth Arnold
  • Date: 2013-11-01 17:15:48 UTC
  • mfrom: (20.1.2 quantal-proposed)
  • Revision ID: package-import@ubuntu.com-20131101171548-2zswm101618z3kn6
Tags: 1.2+bzr1373+dfsg-0ubuntu1.1
* SECURITY UPDATE: failure to authenticate downloaded content (LP: #1039513)
  - debian/patches/CVE-2013-1058.patch: Authenticate downloaded files with
    GnuPG and MD5SUM files. Thanks to Julian Edwards.
  - CVE-2013-1058
* SECURITY UPDATE: configuration options may be loaded from current working
  directory (LP: #1158425)
  - debian/patches/CVE-2013-1057-1-2.patch: Do not load configuration
    options from the current working directory. Thanks to Julian Edwards.
  - CVE-2013-1057

Show diffs side-by-side

added added

removed removed

Lines of Context:
44
44
    NewUserCreationForm,
45
45
    NodeActionForm,
46
46
    NodeForm,
 
47
    NodeGroupEdit,
47
48
    NodeGroupInterfaceForm,
48
49
    NodeGroupWithInterfacesForm,
49
50
    NodeWithMACAddressesForm,
56
57
    MACAddress,
57
58
    Node,
58
59
    NodeGroup,
 
60
    NodeGroupInterface,
59
61
    )
60
62
from maasserver.models.config import DEFAULT_CONFIG
61
63
from maasserver.node_action import (
111
113
        return query_dict
112
114
 
113
115
    def make_params(self, mac_addresses=None, architecture=None,
114
 
                    nodegroup=None):
 
116
                    hostname=None, nodegroup=None):
115
117
        if mac_addresses is None:
116
118
            mac_addresses = [factory.getRandomMACAddress()]
117
119
        if architecture is None:
118
120
            architecture = factory.getRandomEnum(ARCHITECTURE)
 
121
        if hostname is None:
 
122
            hostname = factory.make_name('hostname')
119
123
        params = {
120
124
            'mac_addresses': mac_addresses,
121
125
            'architecture': architecture,
 
126
            'hostname': hostname,
122
127
        }
123
128
        if nodegroup is not None:
124
129
            params['nodegroup'] = nodegroup
198
203
            NodeGroup.objects.ensure_master(),
199
204
            NodeWithMACAddressesForm(self.make_params()).save().nodegroup)
200
205
 
201
 
    def test_sets_nodegroup_on_new_node_if_requested(self):
202
 
        nodegroup = factory.make_node_group(
203
 
            network=IPNetwork("192.168.14.0/24"), ip_range_low='192.168.14.2',
204
 
            ip_range_high='192.168.14.254', ip='192.168.14.1')
205
 
        form = NodeWithMACAddressesForm(
206
 
            self.make_params(nodegroup=nodegroup.get_managed_interface().ip))
207
 
        self.assertEqual(nodegroup, form.save().nodegroup)
208
 
 
209
206
    def test_leaves_nodegroup_alone_if_unset_on_existing_node(self):
210
207
        # Selecting a node group for a node is only supported on new
211
208
        # nodes.  You can't change it later.
217
214
        form.save()
218
215
        self.assertEqual(original_nodegroup, reload_object(node).nodegroup)
219
216
 
 
217
    def test_form_without_hostname_generates_hostname(self):
 
218
        form = NodeWithMACAddressesForm(self.make_params(hostname=''))
 
219
        node = form.save()
 
220
        self.assertTrue(len(node.hostname) > 0)
 
221
 
 
222
    def test_form_with_ip_based_hostname_generates_hostname(self):
 
223
        ip_based_hostname = '192-168-12-10.domain'
 
224
        form = NodeWithMACAddressesForm(
 
225
            self.make_params(hostname=ip_based_hostname))
 
226
        node = form.save()
 
227
        self.assertNotEqual(ip_based_hostname, node.hostname)
 
228
 
220
229
 
221
230
class TestOptionForm(ConfigForm):
222
231
    field1 = forms.CharField(label="Field 1", max_length=10)
334
343
            after_commissioning_action, node.after_commissioning_action)
335
344
        self.assertEqual(power_type, node.power_type)
336
345
 
 
346
    def test_AdminNodeForm_refuses_to_update_hostname_on_allocated_node(self):
 
347
        old_name = factory.make_name('old-hostname')
 
348
        new_name = factory.make_name('new-hostname')
 
349
        node = factory.make_node(
 
350
            hostname=old_name, status=NODE_STATUS.ALLOCATED)
 
351
        form = AdminNodeForm(
 
352
            data={
 
353
                'hostname': new_name,
 
354
                'architecture': node.architecture,
 
355
                },
 
356
            instance=node)
 
357
        self.assertFalse(form.is_valid())
 
358
        self.assertEqual(
 
359
            ["Can't change hostname to %s: node is in use." % new_name],
 
360
            form._errors['hostname'])
 
361
 
 
362
    def test_AdminNodeForm_accepts_unchanged_hostname_on_allocated_node(self):
 
363
        old_name = factory.make_name('old-hostname')
 
364
        node = factory.make_node(
 
365
            hostname=old_name, status=NODE_STATUS.ALLOCATED)
 
366
        form = AdminNodeForm(
 
367
            data={
 
368
                'hostname': old_name,
 
369
                'architecture': node.architecture,
 
370
            },
 
371
            instance=node)
 
372
        self.assertTrue(form.is_valid(), form._errors)
 
373
        form.save()
 
374
        self.assertEqual(old_name, reload_object(node).hostname)
 
375
 
337
376
    def test_remove_None_values_removes_None_values_in_dict(self):
338
377
        random_input = factory.getRandomString()
339
378
        self.assertEqual(
678
717
 
679
718
class TestNodeGroupWithInterfacesForm(TestCase):
680
719
 
681
 
    def test_NodeGroupWithInterfacesForm_creates_pending_nodegroup(self):
 
720
    def test_creates_pending_nodegroup(self):
682
721
        name = factory.make_name('name')
683
722
        uuid = factory.getRandomUUID()
684
723
        form = NodeGroupWithInterfacesForm(
694
733
                nodegroup.nodegroupinterface_set.count(),
695
734
            ))
696
735
 
697
 
    def test_NodeGroupWithInterfacesForm_creates_nodegroup_with_status(self):
 
736
    def test_creates_nodegroup_with_status(self):
698
737
        name = factory.make_name('name')
699
738
        uuid = factory.getRandomUUID()
700
739
        form = NodeGroupWithInterfacesForm(
704
743
        nodegroup = form.save()
705
744
        self.assertEqual(NODEGROUP_STATUS.ACCEPTED, nodegroup.status)
706
745
 
707
 
    def test_NodeGroupWithInterfacesForm_validates_parameters(self):
 
746
    def test_validates_parameters(self):
708
747
        name = factory.make_name('name')
709
748
        too_long_uuid = 'test' * 30
710
749
        form = NodeGroupWithInterfacesForm(
715
754
                ['Ensure this value has at most 36 characters (it has 120).']},
716
755
            form._errors)
717
756
 
718
 
    def test_NodeGroupWithInterfacesForm_rejects_invalid_json_interfaces(self):
 
757
    def test_rejects_invalid_json_interfaces(self):
719
758
        name = factory.make_name('name')
720
759
        uuid = factory.getRandomUUID()
721
760
        invalid_interfaces = factory.make_name('invalid_json_interfaces')
727
766
            {'interfaces': ['Invalid json value.']},
728
767
            form._errors)
729
768
 
730
 
    def test_NodeGroupWithInterfacesForm_rejects_invalid_list_interfaces(self):
 
769
    def test_rejects_invalid_list_interfaces(self):
731
770
        name = factory.make_name('name')
732
771
        uuid = factory.getRandomUUID()
733
772
        invalid_interfaces = json.dumps('invalid interface list')
739
778
            {'interfaces': [INTERFACES_VALIDATION_ERROR_MESSAGE]},
740
779
            form._errors)
741
780
 
742
 
    def test_NodeGroupWithInterfacesForm_rejects_invalid_interface(self):
 
781
    def test_rejects_invalid_interface(self):
743
782
        name = factory.make_name('name')
744
783
        uuid = factory.getRandomUUID()
745
784
        interface = make_interface_settings()
753
792
            "Enter a valid IPv4 or IPv6 address",
754
793
            form._errors['interfaces'][0])
755
794
 
756
 
    def test_NodeGroupWithInterfacesForm_creates_interface_from_params(self):
 
795
    def test_creates_interface_from_params(self):
757
796
        name = factory.make_name('name')
758
797
        uuid = factory.getRandomUUID()
759
798
        interface = make_interface_settings()
767
806
            nodegroup.nodegroupinterface_set.all()[0],
768
807
            MatchesStructure.byEquality(**interface))
769
808
 
770
 
    def test_form_checks_presence_of_other_managed_interfaces(self):
 
809
    def test_checks_presence_of_other_managed_interfaces(self):
771
810
        name = factory.make_name('name')
772
811
        uuid = factory.getRandomUUID()
773
812
        interfaces = []
785
824
            "Only one managed interface can be configured for this cluster",
786
825
            form._errors['interfaces'][0])
787
826
 
788
 
    def test_NodeGroupWithInterfacesForm_creates_multiple_interfaces(self):
 
827
    def test_creates_multiple_interfaces(self):
789
828
        name = factory.make_name('name')
790
829
        uuid = factory.getRandomUUID()
791
830
        interface1 = make_interface_settings()
800
839
        nodegroup = NodeGroup.objects.get(uuid=uuid)
801
840
        self.assertEqual(2,  nodegroup.nodegroupinterface_set.count())
802
841
 
803
 
    def test_NodeGroupWithInterfacesForm_populates_cluster_name_default(self):
 
842
    def test_populates_cluster_name_default(self):
804
843
        name = factory.make_name('name')
805
844
        uuid = factory.getRandomUUID()
806
845
        form = NodeGroupWithInterfacesForm(
810
849
        nodegroup = form.save()
811
850
        self.assertIn(uuid, nodegroup.cluster_name)
812
851
 
813
 
    def test_NodeGroupWithInterfacesForm_populates_cluster_name(self):
 
852
    def test_populates_cluster_name(self):
814
853
        cluster_name = factory.make_name('cluster_name')
815
854
        uuid = factory.getRandomUUID()
816
855
        form = NodeGroupWithInterfacesForm(
820
859
        nodegroup = form.save()
821
860
        self.assertEqual(cluster_name, nodegroup.cluster_name)
822
861
 
823
 
    def test_NodeGroupWithInterfacesForm_creates_unmanaged_interfaces(self):
 
862
    def test_creates_unmanaged_interfaces(self):
824
863
        name = factory.make_name('name')
825
864
        uuid = factory.getRandomUUID()
826
865
        interface = make_interface_settings()
837
876
                nodegroup.management for nodegroup in
838
877
                nodegroup.nodegroupinterface_set.all()
839
878
            ])
 
879
 
 
880
 
 
881
def 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
 
 
900
class TestNodeGroupEdit(TestCase):
 
901
 
 
902
    def make_form_data(self, nodegroup):
 
903
        """Create `NodeGroupEdit` form data based on `nodegroup`."""
 
904
        return {
 
905
            'name': nodegroup.name,
 
906
            'cluster_name': nodegroup.cluster_name,
 
907
            'status': nodegroup.status,
 
908
        }
 
909
 
 
910
    def test_changes_name(self):
 
911
        nodegroup = factory.make_node_group(name=factory.make_name('old-name'))
 
912
        new_name = factory.make_name('new-name')
 
913
        data = self.make_form_data(nodegroup)
 
914
        data['name'] = new_name
 
915
        form = NodeGroupEdit(instance=nodegroup, data=data)
 
916
        self.assertTrue(form.is_valid())
 
917
        form.save()
 
918
        self.assertEqual(new_name, reload_object(nodegroup).name)
 
919
 
 
920
    def test_refuses_name_change_if_dns_managed_and_nodes_in_use(self):
 
921
        nodegroup, node = make_unrenamable_nodegroup_with_node()
 
922
        data = self.make_form_data(nodegroup)
 
923
        data['name'] = factory.make_name('new-name')
 
924
        form = NodeGroupEdit(instance=nodegroup, data=data)
 
925
        self.assertFalse(form.is_valid())
 
926
 
 
927
    def test_accepts_unchanged_name(self):
 
928
        nodegroup, node = make_unrenamable_nodegroup_with_node()
 
929
        original_name = nodegroup.name
 
930
        form = NodeGroupEdit(
 
931
            instance=nodegroup, data=self.make_form_data(nodegroup))
 
932
        self.assertTrue(form.is_valid())
 
933
        form.save()
 
934
        self.assertEqual(original_name, reload_object(nodegroup).name)
 
935
 
 
936
    def test_accepts_omitted_name(self):
 
937
        nodegroup, node = make_unrenamable_nodegroup_with_node()
 
938
        original_name = nodegroup.name
 
939
        data = self.make_form_data(nodegroup)
 
940
        del data['name']
 
941
        form = NodeGroupEdit(instance=nodegroup, data=data)
 
942
        self.assertTrue(form.is_valid())
 
943
        form.save()
 
944
        self.assertEqual(original_name, reload_object(nodegroup).name)
 
945
 
 
946
    def test_accepts_name_change_if_nodegroup_not_accepted(self):
 
947
        nodegroup, node = make_unrenamable_nodegroup_with_node()
 
948
        nodegroup.status = NODEGROUP_STATUS.PENDING
 
949
        data = self.make_form_data(nodegroup)
 
950
        data['name'] = factory.make_name('new-name')
 
951
        form = NodeGroupEdit(instance=nodegroup, data=data)
 
952
        self.assertTrue(form.is_valid())
 
953
 
 
954
    def test_accepts_name_change_if_dns_managed_but_no_nodes_in_use(self):
 
955
        nodegroup, node = make_unrenamable_nodegroup_with_node()
 
956
        node.status = NODE_STATUS.READY
 
957
        node.save()
 
958
        data = self.make_form_data(nodegroup)
 
959
        data['name'] = factory.make_name('new-name')
 
960
        form = NodeGroupEdit(instance=nodegroup, data=data)
 
961
        self.assertTrue(form.is_valid())
 
962
        form.save()
 
963
        self.assertEqual(data['name'], reload_object(nodegroup).name)
 
964
 
 
965
    def test_accepts_name_change_if_nodes_in_use_but_dns_not_managed(self):
 
966
        nodegroup, node = make_unrenamable_nodegroup_with_node()
 
967
        interface = nodegroup.get_managed_interface()
 
968
        interface.management = NODEGROUPINTERFACE_MANAGEMENT.DHCP
 
969
        interface.save()
 
970
        data = self.make_form_data(nodegroup)
 
971
        data['name'] = factory.make_name('new-name')
 
972
        form = NodeGroupEdit(instance=nodegroup, data=data)
 
973
        self.assertTrue(form.is_valid())
 
974
        form.save()
 
975
        self.assertEqual(data['name'], reload_object(nodegroup).name)
 
976
 
 
977
    def test_accepts_name_change_if_nodegroup_has_no_interface(self):
 
978
        nodegroup, node = make_unrenamable_nodegroup_with_node()
 
979
        NodeGroupInterface.objects.filter(nodegroup=nodegroup).delete()
 
980
        data = self.make_form_data(nodegroup)
 
981
        data['name'] = factory.make_name('new-name')
 
982
        form = NodeGroupEdit(instance=nodegroup, data=data)
 
983
        self.assertTrue(form.is_valid())
 
984
        form.save()
 
985
        self.assertEqual(data['name'], reload_object(nodegroup).name)