예제 #1
0
    def set_zone(self, request):
        """@description-title Assign nodes to a zone
        @description Assigns a given node to a given zone.

        @param (string) "zone" [required=true] The zone name.
        @param (string) "nodes" [required=true] The node to add.

        @success (http-status-code) "204" 204

        @error (http-status-code) "403" 403
        @error (content) "no-perms" The user does not have set the zone.
        @error-example "no-perms"
            This method is reserved for admin users.

        @error (http-status-code) "400" 400
        @error (content) "bad-param" The given parameters were not correct.
        """
        data = {
            'action': 'set_zone',
            'zone': request.data.get('zone'),
            'system_id': get_optional_list(request.data, 'nodes'),
        }
        form = BulkNodeActionForm(request.user, data=data)
        if not form.is_valid():
            raise MAASAPIValidationError(form.errors)
        form.save()
예제 #2
0
 def test_rejects_if_invalid_action(self):
     form = BulkNodeActionForm(
         user=factory.make_admin(),
         data=dict(
             action="invalid-action",
             system_id=[factory.make_Node().system_id]))
     self.assertFalse(form.is_valid(), form._errors)
예제 #3
0
    def test_performs_action(self):
        with transaction.atomic():
            node1 = factory.make_Node()
            node2 = factory.make_Node()
            node3 = factory.make_Node()
            admin = factory.make_admin()
            request = factory.make_fake_request('/')
            request.user = admin
            system_id_to_delete = [node1.system_id, node2.system_id]
            form = BulkNodeActionForm(
                request=request,
                user=admin,
                data=dict(
                    action=Delete.name,
                    system_id=system_id_to_delete))
            self.assertTrue(form.is_valid(), form._errors)

        with transaction.atomic():
            done, not_actionable, not_permitted = form.save()

        self.assertEqual(
            [2, 0, 0],
            [done, not_actionable, not_permitted])

        with transaction.atomic():
            existing_nodes = list(Node.objects.filter(
                system_id__in=system_id_to_delete))
            node3_system_id = reload_object(node3).system_id
            self.assertEqual(
                [[], node3.system_id],
                [existing_nodes, node3_system_id])
예제 #4
0
 def test_rejects_empty_system_ids(self):
     form = BulkNodeActionForm(
         user=factory.make_admin(),
         data=dict(action=Delete.name, system_id=[]))
     self.assertFalse(form.is_valid(), form._errors)
     self.assertEqual(
         ["No node selected."],
         form._errors['system_id'])
예제 #5
0
 def test_zone_field_rejects_empty_zone(self):
     # If the field is present, the zone name has to be valid
     # and the empty string is not a valid zone name.
     form = BulkNodeActionForm(user=factory.make_admin(),
                               data={
                                   'action': SetZoneBulkAction.name,
                                   'zone': '',
                               })
     self.assertFalse(form.is_valid(), form._errors)
     self.assertEqual(["This field is required."], form._errors['zone'])
예제 #6
0
 def test_rejects_invalid_system_ids(self):
     node = factory.make_Node()
     system_id_to_delete = [node.system_id, "wrong-system_id"]
     form = BulkNodeActionForm(user=factory.make_admin(),
                               data=dict(action=Delete.name,
                                         system_id=system_id_to_delete))
     self.assertFalse(form.is_valid(), form._errors)
     self.assertEqual(
         ["Some of the given system ids are invalid system ids."],
         form._errors['system_id'])
예제 #7
0
 def test_set_zone_does_not_work_if_not_admin(self):
     node = factory.make_Node()
     form = BulkNodeActionForm(user=factory.make_User(),
                               data={
                                   'action': SetZoneBulkAction.name,
                                   'zone': factory.make_Zone().name,
                                   'system_id': [node.system_id],
                               })
     self.assertFalse(form.is_valid())
     self.assertIn(
         "Select a valid choice. "
         "set_zone is not one of the available choices.",
         form._errors['action'])
예제 #8
0
    def test_gives_stat_when_action_is_inhibited(self):
        with transaction.atomic():
            node = factory.make_Node(status=NODE_STATUS.ALLOCATED,
                                     owner=factory.make_User())
            form = BulkNodeActionForm(user=factory.make_admin(),
                                      data=dict(action=PowerOn.name,
                                                system_id=[node.system_id]))
            self.assertTrue(form.is_valid(), form._errors)

        with transaction.atomic():
            done, not_actionable, not_permitted = form.save()

        self.assertEqual([0, 1, 0], [done, not_actionable, not_permitted])
예제 #9
0
    def test_gives_stat_when_not_applicable(self):
        with transaction.atomic():
            node1 = factory.make_Node(status=NODE_STATUS.NEW)
            node2 = factory.make_Node(status=NODE_STATUS.FAILED_COMMISSIONING)
            system_id_for_action = [node1.system_id, node2.system_id]
            form = BulkNodeActionForm(user=factory.make_admin(),
                                      data=dict(
                                          action=PowerOn.name,
                                          system_id=system_id_for_action))
            self.assertTrue(form.is_valid(), form._errors)

        with transaction.atomic():
            done, not_actionable, not_permitted = form.save()

        self.assertEqual([0, 2, 0], [done, not_actionable, not_permitted])
예제 #10
0
    def test_gives_stat_when_no_permission(self):
        with transaction.atomic():
            user = factory.make_User()
            node = factory.make_Node(status=NODE_STATUS.DEPLOYED,
                                     owner=factory.make_User())
            system_id_for_action = [node.system_id]
            form = BulkNodeActionForm(user=user,
                                      data=dict(
                                          action=PowerOff.name,
                                          system_id=system_id_for_action))
            self.assertTrue(form.is_valid(), form._errors)

        with transaction.atomic():
            done, not_actionable, not_permitted = form.save()

        self.assertEqual([0, 0, 1], [done, not_actionable, not_permitted])
예제 #11
0
 def test_first_action_is_empty(self):
     form = BulkNodeActionForm(user=factory.make_admin())
     action = form.fields['action']
     default_action = action.choices[0][0]
     required = action.required
     # The default action is the empty string (i.e. no action)
     # and it's a required field.
     self.assertEqual(('', True), (default_action, required))
예제 #12
0
    def test_perform_action_catches_start_action_errors(self):
        error_text = factory.make_string(prefix="NodeActionError")
        exc = NodeActionError(error_text)
        self.patch(PowerOn, "execute").side_effect = exc

        with transaction.atomic():
            user = factory.make_User()
            factory.make_SSHKey(user)
            node = factory.make_Node(status=NODE_STATUS.READY, owner=user)
            form = BulkNodeActionForm(user=user,
                                      data=dict(action=PowerOn.name,
                                                system_id=[node.system_id]))
            self.assertTrue(form.is_valid(), form._errors)

        with transaction.atomic():
            done, not_actionable, not_permitted = form.save()

        self.assertEqual([0, 1, 0], [done, not_actionable, not_permitted])
예제 #13
0
    def set_zone(self, request):
        """Assign multiple nodes to a physical zone at once.

        :param zone: Zone name.  If omitted, the zone is "none" and the nodes
            will be taken out of their physical zones.
        :param nodes: system_ids of the nodes whose zones are to be set.
           (An empty list is acceptable).

        Raises 403 if the user is not an admin.
        """
        data = {
            'action': 'set_zone',
            'zone': request.data.get('zone'),
            'system_id': get_optional_list(request.data, 'nodes'),
        }
        form = BulkNodeActionForm(request.user, data=data)
        if not form.is_valid():
            raise MAASAPIValidationError(form.errors)
        form.save()
예제 #14
0
    def set_zone(self, request):
        """Assign multiple nodes to a physical zone at once.

        :param zone: Zone name.  If omitted, the zone is "none" and the nodes
            will be taken out of their physical zones.
        :param nodes: system_ids of the nodes whose zones are to be set.
           (An empty list is acceptable).

        Raises 403 if the user is not an admin.
        """
        data = {
            'action': 'set_zone',
            'zone': request.data.get('zone'),
            'system_id': get_optional_list(request.data, 'nodes'),
        }
        form = BulkNodeActionForm(request.user, data=data)
        if not form.is_valid():
            raise ValidationError(form.errors)
        form.save()
예제 #15
0
    def test_set_zone_sets_zone_on_node(self):
        with transaction.atomic():
            node = factory.make_Node()
            zone = factory.make_Zone()
            form = BulkNodeActionForm(user=factory.make_admin(),
                                      data={
                                          'action': 'set_zone',
                                          'zone': zone.name,
                                          'system_id': [node.system_id],
                                      })
            self.assertTrue(form.is_valid(), form._errors)

        with transaction.atomic():
            done, not_actionable, not_permitted = form.save()

        self.assertEqual([1, 0, 0], [done, not_actionable, not_permitted])

        with transaction.atomic():
            node = reload_object(node)
            self.assertEqual(zone, node.zone)
예제 #16
0
    def test_set_zone_leaves_unselected_nodes_alone(self):
        with transaction.atomic():
            unselected_node = factory.make_Node()
            original_zone = unselected_node.zone
            form = BulkNodeActionForm(user=factory.make_admin(),
                                      data={
                                          'action':
                                          SetZoneBulkAction.name,
                                          'zone':
                                          factory.make_Zone().name,
                                          'system_id':
                                          [factory.make_Node().system_id],
                                      })
            self.assertTrue(form.is_valid(), form._errors)

        with transaction.atomic():
            done, not_actionable, not_permitted = form.save()

        self.assertEqual([1, 0, 0], [done, not_actionable, not_permitted])

        with transaction.atomic():
            unselected_node = reload_object(unselected_node)
            self.assertEqual(original_zone, unselected_node.zone)
예제 #17
0
 def test_zone_field_present_if_data_is_empty(self):
     form = BulkNodeActionForm(user=factory.make_admin(), data={})
     self.assertIn('zone', form.fields)
예제 #18
0
 def test_zone_field_not_present_action_is_not_SetZoneBulkAction(self):
     form = BulkNodeActionForm(user=factory.make_admin(),
                               data={'action': factory.make_name('action')})
     self.assertNotIn('zone', form.fields)
예제 #19
0
 def test_nonadmin_is_not_offered_bulk_node_change(self):
     form = BulkNodeActionForm(user=factory.make_User())
     choices = form.fields['action'].choices
     self.assertEqual(
         [], [choice for choice in choices if choice[0] == 'set_zone'])