Пример #1
0
 def test_get_db_state_returns_db_state(self):
     status = factory.getRandomChoice(NODE_STATUS_CHOICES)
     node = factory.make_node(status=status)
     another_status = factory.getRandomChoice(NODE_STATUS_CHOICES,
                                              but_not=[status])
     node.status = another_status
     self.assertEqual(status, get_db_state(node, 'status'))
Пример #2
0
 def test_get_db_state_returns_db_state(self):
     status = factory.getRandomChoice(NODE_STATUS_CHOICES)
     node = factory.make_node(status=status)
     another_status = factory.getRandomChoice(
         NODE_STATUS_CHOICES, but_not=[status])
     node.status = another_status
     self.assertEqual(status, get_db_state(node, 'status'))
Пример #3
0
    def test_admin_can_edit_nodes(self):
        node = factory.make_node(owner=factory.make_user())
        node_edit_link = reverse('node-edit', args=[node.system_id])
        params = {
            'hostname': factory.getRandomString(),
            'after_commissioning_action': factory.getRandomEnum(
                NODE_AFTER_COMMISSIONING_ACTION),
            'power_type': factory.getRandomChoice(POWER_TYPE_CHOICES),
            'architecture': factory.getRandomChoice(ARCHITECTURE_CHOICES),
        }
        response = self.client.post(node_edit_link, params)

        node = reload_object(node)
        self.assertEqual(httplib.FOUND, response.status_code)
        self.assertAttributes(node, params)
Пример #4
0
    def test_POST_new_creates_node_with_subarchitecture(self):
        # The API allows a Node to be created.
        architecture = factory.getRandomChoice(ARCHITECTURE_CHOICES)
        response = self.client.post(
            reverse('nodes_handler'), {
                'op':
                'new',
                'hostname':
                'diane',
                'architecture':
                architecture.split('/')[0],
                'subarchitecture':
                architecture.split('/')[1],
                'after_commissioning_action':
                (NODE_AFTER_COMMISSIONING_ACTION.DEFAULT),
                'mac_addresses': ['aa:bb:cc:dd:ee:ff', '22:bb:cc:dd:ee:ff'],
            })

        self.assertEqual(httplib.OK, response.status_code)
        parsed_result = json.loads(response.content)
        self.assertIn('application/json', response['Content-Type'])
        self.assertEqual('diane', parsed_result['hostname'])
        self.assertNotEqual(0, len(parsed_result.get('system_id')))
        [diane] = Node.objects.filter(hostname='diane')
        self.assertEqual(architecture, diane.architecture)
Пример #5
0
 def test_POST_returns_limited_fields(self):
     response = self.client.post(
         reverse('nodes_handler'), {
             'op':
             'new',
             'hostname':
             factory.getRandomString(),
             'architecture':
             factory.getRandomChoice(ARCHITECTURE_CHOICES),
             'after_commissioning_action':
             (NODE_AFTER_COMMISSIONING_ACTION.DEFAULT),
             'mac_addresses': ['aa:bb:cc:dd:ee:ff', '22:bb:cc:dd:ee:ff'],
         })
     parsed_result = json.loads(response.content)
     self.assertItemsEqual([
         'hostname',
         'owner',
         'system_id',
         'macaddress_set',
         'architecture',
         'status',
         'netboot',
         'power_type',
         'resource_uri',
         'tag_names',
         'ip_addresses',
         'cpu_count',
         'storage',
         'memory',
         'routers',
     ], list(parsed_result))
Пример #6
0
 def test_full_clean_passes_if_status_unchanged(self):
     status = factory.getRandomChoice(NODE_STATUS_CHOICES)
     node = factory.make_node(status=status)
     node.status = status
     node.full_clean()
     # The test is that this does not raise an error.
     pass
Пример #7
0
 def test_POST_returns_limited_fields(self):
     response = self.client.post(
         reverse('nodes_handler'),
         {
             'op': 'new',
             'hostname': factory.getRandomString(),
             'architecture': factory.getRandomChoice(ARCHITECTURE_CHOICES),
             'after_commissioning_action': (
                 NODE_AFTER_COMMISSIONING_ACTION.DEFAULT),
             'mac_addresses': ['aa:bb:cc:dd:ee:ff', '22:bb:cc:dd:ee:ff'],
         })
     parsed_result = json.loads(response.content)
     self.assertItemsEqual(
         [
             'hostname',
             'owner',
             'system_id',
             'macaddress_set',
             'architecture',
             'status',
             'netboot',
             'power_type',
             'resource_uri',
             'tag_names',
             'ip_addresses',
             'cpu_count',
             'storage',
             'memory',
             'routers',
         ],
         list(parsed_result))
Пример #8
0
 def test_POST_new_creates_node_with_power_parameters(self):
     # We're setting power parameters so we disable start_commissioning to
     # prevent anything from attempting to issue power instructions.
     self.patch(Node, "start_commissioning")
     hostname = factory.make_name("hostname")
     architecture = factory.getRandomChoice(ARCHITECTURE_CHOICES)
     power_type = POWER_TYPE.IPMI
     power_parameters = {
         "power_user": factory.make_name("power-user"),
         "power_pass": factory.make_name("power-pass"),
         }
     response = self.client.post(
         reverse('nodes_handler'),
         {
             'op': 'new',
             'hostname': hostname,
             'architecture': architecture,
             'mac_addresses': factory.getRandomMACAddress(),
             'power_parameters': json.dumps(power_parameters),
             'power_type': power_type,
         })
     self.assertEqual(httplib.OK, response.status_code)
     [node] = Node.objects.filter(hostname=hostname)
     self.assertEqual(power_parameters, node.power_parameters)
     self.assertEqual(power_type, node.power_type)
Пример #9
0
 def test_created_node_has_domain_from_cluster(self):
     hostname_without_domain = factory.make_name('hostname')
     hostname_with_domain = '%s.%s' % (hostname_without_domain,
                                       factory.getRandomString())
     domain = factory.make_name('domain')
     factory.make_node_group(
         status=NODEGROUP_STATUS.ACCEPTED,
         name=domain,
         management=NODEGROUPINTERFACE_MANAGEMENT.DHCP_AND_DNS)
     response = self.client.post(
         reverse('nodes_handler'), {
             'op':
             'new',
             'hostname':
             hostname_with_domain,
             'architecture':
             factory.getRandomChoice(ARCHITECTURE_CHOICES),
             'after_commissioning_action':
             (NODE_AFTER_COMMISSIONING_ACTION.DEFAULT),
             'mac_addresses': [factory.getRandomMACAddress()],
         })
     self.assertEqual(httplib.OK, response.status_code, response.content)
     parsed_result = json.loads(response.content)
     expected_hostname = '%s.%s' % (hostname_without_domain, domain)
     self.assertEqual(expected_hostname, parsed_result.get('hostname'))
Пример #10
0
 def test_full_clean_passes_if_status_unchanged(self):
     status = factory.getRandomChoice(NODE_STATUS_CHOICES)
     node = factory.make_node(status=status)
     node.status = status
     node.full_clean()
     # The test is that this does not raise an error.
     pass
Пример #11
0
    def test_PUT_non_admin_cannot_change_power_type(self):
        original_power_type = factory.getRandomChoice(
            POWER_TYPE_CHOICES)
        new_power_type = factory.getRandomChoice(
            POWER_TYPE_CHOICES, but_not=original_power_type)
        node = factory.make_node(
            owner=self.logged_in_user,
            power_type=original_power_type,
            after_commissioning_action=(
                NODE_AFTER_COMMISSIONING_ACTION.DEFAULT))
        self.client_put(
            self.get_node_uri(node),
            {'power_type': new_power_type}
            )

        self.assertEqual(
            original_power_type, reload_object(node).power_type)
Пример #12
0
 def test_PUT_omitted_hostname(self):
     hostname = factory.make_name('hostname')
     node = factory.make_node(hostname=hostname, owner=self.logged_in_user)
     response = self.client_put(
         self.get_node_uri(node),
         {'architecture': factory.getRandomChoice(ARCHITECTURE_CHOICES)})
     self.assertEqual(httplib.OK, response.status_code, response.content)
     self.assertTrue(Node.objects.filter(hostname=hostname).exists())
Пример #13
0
    def test_NodeForm_changes_node(self):
        node = factory.make_node()
        hostname = factory.getRandomString()
        after_commissioning_action = factory.getRandomChoice(
            NODE_AFTER_COMMISSIONING_ACTION_CHOICES)

        form = NodeForm(
            data={
                'hostname': hostname,
                'after_commissioning_action': after_commissioning_action,
                'architecture': factory.getRandomChoice(ARCHITECTURE_CHOICES),
                },
            instance=node)
        form.save()

        self.assertEqual(hostname, node.hostname)
        self.assertEqual(
            after_commissioning_action, node.after_commissioning_action)
Пример #14
0
 def test_power_type_set_but_no_parameters(self):
     # When power_type is valid, it is set. However, if power_parameters is
     # not specified, the node's power_parameters is left alone, and the
     # node is saved.
     power_type = factory.getRandomChoice(POWER_TYPE_CHOICES)
     self.request.POST = {"power_type": power_type}
     store_node_power_parameters(self.node, self.request)
     self.assertEqual(power_type, self.node.power_type)
     self.assertEqual("", self.node.power_parameters)
     self.save.assert_called_once_with()
Пример #15
0
 def test_power_type_set_but_no_parameters(self):
     # When power_type is valid, it is set. However, if power_parameters is
     # not specified, the node's power_parameters is left alone, and the
     # node is saved.
     power_type = factory.getRandomChoice(POWER_TYPE_CHOICES)
     self.request.POST = {"power_type": power_type}
     store_node_power_parameters(self.node, self.request)
     self.assertEqual(power_type, self.node.power_type)
     self.assertEqual("", self.node.power_parameters)
     self.save.assert_called_once_with()
Пример #16
0
 def test_POST_with_no_hostname_auto_populates_hostname(self):
     architecture = factory.getRandomChoice(ARCHITECTURE_CHOICES)
     response = self.client.post(
         reverse('nodes_handler'), {
             'op': 'new',
             'architecture': architecture,
             'mac_addresses': [factory.getRandomMACAddress()],
         })
     node = Node.objects.get(
         system_id=json.loads(response.content)['system_id'])
     self.assertEqual(5, len(strip_domain(node.hostname)))
Пример #17
0
 def test_POST_new_initializes_nodegroup_to_master_by_default(self):
     hostname = factory.make_name('host')
     self.client.post(
         reverse('nodes_handler'), {
             'op': 'new',
             'hostname': hostname,
             'architecture': factory.getRandomChoice(ARCHITECTURE_CHOICES),
             'mac_addresses': [factory.getRandomMACAddress()],
         })
     self.assertEqual(NodeGroup.objects.ensure_master(),
                      Node.objects.get(hostname=hostname).nodegroup)
Пример #18
0
 def test_POST_new_power_type_defaults_to_asking_config(self):
     architecture = factory.getRandomChoice(ARCHITECTURE_CHOICES)
     response = self.client.post(
         reverse('nodes_handler'), {
             'op': 'new',
             'architecture': architecture,
             'mac_addresses': ['00:11:22:33:44:55'],
         })
     node = Node.objects.get(
         system_id=json.loads(response.content)['system_id'])
     self.assertEqual(POWER_TYPE.DEFAULT, node.power_type)
Пример #19
0
 def test_power_type_set_with_invalid_parameters(self):
     # When power_type is valid, but power_parameters is invalid JSON, the
     # node is not saved, and an exception is raised.
     power_type = factory.getRandomChoice(POWER_TYPE_CHOICES)
     self.request.POST = {
         "power_type": power_type,
         "power_parameters": "Not JSON.",
     }
     self.assertRaises(MAASAPIBadRequest, store_node_power_parameters,
                       self.node, self.request)
     self.save.assert_has_calls([])
Пример #20
0
 def test_POST_new_power_type_defaults_to_asking_config(self):
     architecture = factory.getRandomChoice(ARCHITECTURE_CHOICES)
     response = self.client.post(
         reverse('nodes_handler'), {
             'op': 'new',
             'architecture': architecture,
             'mac_addresses': ['00:11:22:33:44:55'],
             })
     node = Node.objects.get(
         system_id=json.loads(response.content)['system_id'])
     self.assertEqual(POWER_TYPE.DEFAULT, node.power_type)
Пример #21
0
 def test_POST_with_no_hostname_auto_populates_hostname(self):
     architecture = factory.getRandomChoice(ARCHITECTURE_CHOICES)
     response = self.client.post(
         reverse('nodes_handler'),
         {
             'op': 'new',
             'architecture': architecture,
             'mac_addresses': [factory.getRandomMACAddress()],
         })
     node = Node.objects.get(
         system_id=json.loads(response.content)['system_id'])
     self.assertEqual(5, len(strip_domain(node.hostname)))
Пример #22
0
 def test_POST_new_sets_power_type_if_admin(self):
     response = self.client.post(
         reverse('nodes_handler'), {
             'op': 'new',
             'architecture': factory.getRandomChoice(ARCHITECTURE_CHOICES),
             'power_type': POWER_TYPE.WAKE_ON_LAN,
             'mac_addresses': ['00:11:22:33:44:55'],
             })
     node = Node.objects.get(
         system_id=json.loads(response.content)['system_id'])
     self.assertEqual(POWER_TYPE.WAKE_ON_LAN, node.power_type)
     self.assertEqual('', node.power_parameters)
Пример #23
0
 def test_power_type_set_with_invalid_parameters(self):
     # When power_type is valid, but power_parameters is invalid JSON, the
     # node is not saved, and an exception is raised.
     power_type = factory.getRandomChoice(POWER_TYPE_CHOICES)
     self.request.POST = {
         "power_type": power_type,
         "power_parameters": "Not JSON.",
         }
     self.assertRaises(
         MAASAPIBadRequest, store_node_power_parameters,
         self.node, self.request)
     self.save.assert_has_calls([])
Пример #24
0
 def test_POST_new_sets_power_type_if_admin(self):
     response = self.client.post(
         reverse('nodes_handler'), {
             'op': 'new',
             'architecture': factory.getRandomChoice(ARCHITECTURE_CHOICES),
             'power_type': POWER_TYPE.WAKE_ON_LAN,
             'mac_addresses': ['00:11:22:33:44:55'],
         })
     node = Node.objects.get(
         system_id=json.loads(response.content)['system_id'])
     self.assertEqual(POWER_TYPE.WAKE_ON_LAN, node.power_type)
     self.assertEqual('', node.power_parameters)
Пример #25
0
 def test_power_type_set_with_parameters(self):
     # When power_type is valid, and power_parameters is valid JSON, both
     # fields are set on the node, and the node is saved.
     power_type = factory.getRandomChoice(POWER_TYPE_CHOICES)
     power_parameters = {"foo": [1, 2, 3]}
     self.request.POST = {
         "power_type": power_type,
         "power_parameters": json.dumps(power_parameters),
     }
     store_node_power_parameters(self.node, self.request)
     self.assertEqual(power_type, self.node.power_type)
     self.assertEqual(power_parameters, self.node.power_parameters)
     self.save.assert_called_once_with()
Пример #26
0
 def test_power_type_set_with_parameters(self):
     # When power_type is valid, and power_parameters is valid JSON, both
     # fields are set on the node, and the node is saved.
     power_type = factory.getRandomChoice(POWER_TYPE_CHOICES)
     power_parameters = {"foo": [1, 2, 3]}
     self.request.POST = {
         "power_type": power_type,
         "power_parameters": json.dumps(power_parameters),
         }
     store_node_power_parameters(self.node, self.request)
     self.assertEqual(power_type, self.node.power_type)
     self.assertEqual(power_parameters, self.node.power_parameters)
     self.save.assert_called_once_with()
Пример #27
0
 def test_POST_new_initializes_nodegroup_to_master_by_default(self):
     hostname = factory.make_name('host')
     self.client.post(
         reverse('nodes_handler'),
         {
             'op': 'new',
             'hostname': hostname,
             'architecture': factory.getRandomChoice(ARCHITECTURE_CHOICES),
             'mac_addresses': [factory.getRandomMACAddress()],
         })
     self.assertEqual(
         NodeGroup.objects.ensure_master(),
         Node.objects.get(hostname=hostname).nodegroup)
Пример #28
0
    def test_POST_new_creates_node(self):
        # The API allows a non-admin logged-in user to create a Node.
        architecture = factory.getRandomChoice(ARCHITECTURE_CHOICES)
        response = self.client.post(
            reverse('nodes_handler'),
            {
                'op': 'new',
                'hostname': factory.getRandomString(),
                'architecture': architecture,
                'after_commissioning_action': (
                    NODE_AFTER_COMMISSIONING_ACTION.DEFAULT),
                'mac_addresses': ['aa:bb:cc:dd:ee:ff', '22:bb:cc:dd:ee:ff'],
            })

        self.assertEqual(httplib.OK, response.status_code)
Пример #29
0
    def test_AdminNodeForm_changes_node_with_skip_check(self):
        node = factory.make_node()
        hostname = factory.getRandomString()
        after_commissioning_action = factory.getRandomChoice(
            NODE_AFTER_COMMISSIONING_ACTION_CHOICES)
        power_type = factory.getRandomChoice(POWER_TYPE_CHOICES)
        power_parameters_field = factory.getRandomString()
        form = AdminNodeForm(
            data={
                'hostname': hostname,
                'after_commissioning_action': after_commissioning_action,
                'architecture': factory.getRandomChoice(ARCHITECTURE_CHOICES),
                'power_type': power_type,
                'power_parameters_field': power_parameters_field,
                'power_parameters_skip_check': True,
                },
            instance=node)
        form.save()

        self.assertEqual(
            (hostname, after_commissioning_action, power_type,
                {'field': power_parameters_field}),
            (node.hostname, node.after_commissioning_action, node.power_type,
                node.power_parameters))
Пример #30
0
    def test_POST_updates_power_parameters_rejects_unknown_param(self):
        hostname = factory.getRandomString()
        response = self.client.post(
            reverse('nodes_handler'), {
                'op': 'new',
                'hostname': hostname,
                'architecture': factory.getRandomChoice(ARCHITECTURE_CHOICES),
                'power_type': POWER_TYPE.WAKE_ON_LAN,
                'power_parameters_unknown_param': factory.getRandomString(),
                'mac_addresses': [factory.getRandomMACAddress()],
            })

        self.assertEqual((httplib.BAD_REQUEST, {
            'power_parameters': ["Unknown parameter(s): unknown_param."]
        }), (response.status_code, json.loads(response.content)))
        self.assertFalse(Node.objects.filter(hostname=hostname).exists())
Пример #31
0
 def test_POST_new_creates_node_default_values_for_power_settings(self):
     architecture = factory.getRandomChoice(ARCHITECTURE_CHOICES)
     mac_address = 'AA:BB:CC:DD:EE:FF'
     response = self.client.post(
         reverse('nodes_handler'), {
             'op': 'new',
             'architecture': architecture,
             'mac_addresses': [mac_address],
         })
     node = Node.objects.get(
         system_id=json.loads(response.content)['system_id'])
     self.assertAttributes(
         node,
         dict(architecture=architecture,
              power_type=POWER_TYPE.DEFAULT,
              power_parameters=''))
Пример #32
0
 def test_POST_new_creates_node_default_values_for_power_settings(self):
     architecture = factory.getRandomChoice(ARCHITECTURE_CHOICES)
     mac_address = 'AA:BB:CC:DD:EE:FF'
     response = self.client.post(
         reverse('nodes_handler'), {
             'op': 'new',
             'architecture': architecture,
             'mac_addresses': [mac_address],
             })
     node = Node.objects.get(
         system_id=json.loads(response.content)['system_id'])
     self.assertAttributes(
         node,
         dict(
             architecture=architecture, power_type=POWER_TYPE.DEFAULT,
             power_parameters=''))
Пример #33
0
    def test_POST_new_creates_node(self):
        # The API allows a non-admin logged-in user to create a Node.
        architecture = factory.getRandomChoice(ARCHITECTURE_CHOICES)
        response = self.client.post(
            reverse('nodes_handler'), {
                'op':
                'new',
                'hostname':
                factory.getRandomString(),
                'architecture':
                architecture,
                'after_commissioning_action':
                (NODE_AFTER_COMMISSIONING_ACTION.DEFAULT),
                'mac_addresses': ['aa:bb:cc:dd:ee:ff', '22:bb:cc:dd:ee:ff'],
            })

        self.assertEqual(httplib.OK, response.status_code)
Пример #34
0
 def test_created_node_uses_default_nodegroup_if_origin_not_found(self):
     unknown_host = factory.make_name('host')
     response = self.client.post(
         reverse('nodes_handler'),
         data={
             'op': 'new',
             'hostname': factory.make_name('hostname'),
             'architecture': factory.getRandomChoice(ARCHITECTURE_CHOICES),
             'after_commissioning_action': (
                 NODE_AFTER_COMMISSIONING_ACTION.DEFAULT),
             'mac_addresses': [factory.getRandomMACAddress()],
         },
         HTTP_HOST=unknown_host)
     self.assertEqual(httplib.OK, response.status_code, response.content)
     parsed_result = json.loads(response.content)
     node = Node.objects.get(system_id=parsed_result.get('system_id'))
     self.assertEqual(NodeGroup.objects.ensure_master(), node.nodegroup)
Пример #35
0
    def test_POST_new_sets_power_parameters_field(self):
        # The api allows the setting of a Node's power_parameters field.
        # Create a power_parameter valid for the selected power_type.
        new_mac_address = factory.getRandomMACAddress()
        response = self.client.post(
            reverse('nodes_handler'), {
                'op': 'new',
                'architecture': factory.getRandomChoice(ARCHITECTURE_CHOICES),
                'power_type': POWER_TYPE.WAKE_ON_LAN,
                'power_parameters_mac_address': new_mac_address,
                'mac_addresses': ['AA:BB:CC:DD:EE:FF'],
            })

        node = Node.objects.get(
            system_id=json.loads(response.content)['system_id'])
        self.assertEqual(httplib.OK, response.status_code)
        self.assertEqual({'mac_address': new_mac_address},
                         reload_object(node).power_parameters)
Пример #36
0
 def test_POST_new_fails_node_with_double_subarchitecture(self):
     architecture = factory.getRandomChoice(ARCHITECTURE_CHOICES)
     response = self.client.post(
         reverse('nodes_handler'),
         {
             'op': 'new',
             'hostname': 'diane',
             'architecture': architecture,
             'subarchitecture': architecture.split('/')[1],
             'after_commissioning_action': (
                 NODE_AFTER_COMMISSIONING_ACTION.DEFAULT),
             'mac_addresses': ['aa:bb:cc:dd:ee:ff', '22:bb:cc:dd:ee:ff'],
         })
     self.assertEqual(httplib.BAD_REQUEST, response.status_code)
     self.assertIn('text/plain', response['Content-Type'])
     self.assertEqual(
         "Subarchitecture cannot be specified twice.",
         response.content)
Пример #37
0
    def test_POST_new_generates_hostname_if_ip_based_hostname(self):
        hostname = '192-168-5-19.domain'
        response = self.client.post(
            reverse('nodes_handler'),
            {
                'op': 'new',
                'hostname': hostname,
                'architecture': factory.getRandomChoice(ARCHITECTURE_CHOICES),
                'after_commissioning_action': (
                    NODE_AFTER_COMMISSIONING_ACTION.DEFAULT),
                'mac_addresses': [factory.getRandomMACAddress()],
            })
        parsed_result = json.loads(response.content)

        self.assertEqual(httplib.OK, response.status_code)
        system_id = parsed_result.get('system_id')
        node = Node.objects.get(system_id=system_id)
        self.assertNotEqual(hostname, node.hostname)
Пример #38
0
 def test_POST_new_associates_mac_addresses(self):
     # The API allows a Node to be created and associated with MAC
     # Addresses.
     architecture = factory.getRandomChoice(ARCHITECTURE_CHOICES)
     self.client.post(
         reverse('nodes_handler'),
         {
             'op': 'new',
             'hostname': 'diane',
             'architecture': architecture,
             'after_commissioning_action': (
                 NODE_AFTER_COMMISSIONING_ACTION.DEFAULT),
             'mac_addresses': ['aa:bb:cc:dd:ee:ff', '22:bb:cc:dd:ee:ff'],
         })
     diane = get_one(Node.objects.filter(hostname='diane'))
     self.assertItemsEqual(
         ['aa:bb:cc:dd:ee:ff', '22:bb:cc:dd:ee:ff'],
         [mac.mac_address for mac in diane.macaddress_set.all()])
Пример #39
0
    def test_POST_fails_if_mac_duplicated(self):
        # Mac Addresses should be unique.
        mac = 'aa:bb:cc:dd:ee:ff'
        factory.make_mac_address(mac)
        architecture = factory.getRandomChoice(ARCHITECTURE_CHOICES)
        response = self.client.post(
            reverse('nodes_handler'), {
                'op': 'new',
                'architecture': architecture,
                'hostname': factory.getRandomString(),
                'mac_addresses': [mac],
            })
        parsed_result = json.loads(response.content)

        self.assertEqual(httplib.BAD_REQUEST, response.status_code)
        self.assertIn('application/json', response['Content-Type'])
        self.assertEqual(["Mac address %s already in use." % mac],
                         parsed_result['mac_addresses'])
Пример #40
0
 def test_POST_admin_creates_node_in_commissioning_state(self):
     # When an admin user enlists a node, it goes into the
     # Commissioning state.
     response = self.client.post(
         reverse('nodes_handler'),
         {
             'op': 'new',
             'hostname': factory.getRandomString(),
             'architecture': factory.getRandomChoice(ARCHITECTURE_CHOICES),
             'after_commissioning_action': (
                 NODE_AFTER_COMMISSIONING_ACTION.DEFAULT),
             'mac_addresses': ['aa:bb:cc:dd:ee:ff'],
         })
     self.assertEqual(httplib.OK, response.status_code)
     system_id = json.loads(response.content)['system_id']
     self.assertEqual(
         NODE_STATUS.COMMISSIONING,
         Node.objects.get(system_id=system_id).status)
Пример #41
0
 def test_POST_non_admin_creates_node_in_declared_state(self):
     # Upon non-admin enlistment, a node goes into the Declared
     # state.  Deliberate approval is required before we start
     # reinstalling the system, wiping its disks etc.
     response = self.client.post(
         reverse('nodes_handler'),
         {
             'op': 'new',
             'hostname': factory.getRandomString(),
             'architecture': factory.getRandomChoice(ARCHITECTURE_CHOICES),
             'after_commissioning_action': (
                 NODE_AFTER_COMMISSIONING_ACTION.DEFAULT),
             'mac_addresses': ['aa:bb:cc:dd:ee:ff'],
         })
     self.assertEqual(httplib.OK, response.status_code)
     system_id = json.loads(response.content)['system_id']
     self.assertEqual(
         NODE_STATUS.DECLARED,
         Node.objects.get(system_id=system_id).status)
Пример #42
0
    def test_POST_new_sets_power_parameters_field(self):
        # The api allows the setting of a Node's power_parameters field.
        # Create a power_parameter valid for the selected power_type.
        new_mac_address = factory.getRandomMACAddress()
        response = self.client.post(
            reverse('nodes_handler'), {
                'op': 'new',
                'architecture': factory.getRandomChoice(ARCHITECTURE_CHOICES),
                'power_type': POWER_TYPE.WAKE_ON_LAN,
                'power_parameters_mac_address': new_mac_address,
                'mac_addresses': ['AA:BB:CC:DD:EE:FF'],
                })

        node = Node.objects.get(
            system_id=json.loads(response.content)['system_id'])
        self.assertEqual(httplib.OK, response.status_code)
        self.assertEqual(
            {'mac_address': new_mac_address},
            reload_object(node).power_parameters)
Пример #43
0
    def test_POST_updates_power_parameters_rejects_unknown_param(self):
        hostname = factory.getRandomString()
        response = self.client.post(
            reverse('nodes_handler'), {
                'op': 'new',
                'hostname': hostname,
                'architecture': factory.getRandomChoice(ARCHITECTURE_CHOICES),
                'power_type': POWER_TYPE.WAKE_ON_LAN,
                'power_parameters_unknown_param': factory.getRandomString(),
                'mac_addresses': [factory.getRandomMACAddress()],
                })

        self.assertEqual(
            (
                httplib.BAD_REQUEST,
                {'power_parameters': ["Unknown parameter(s): unknown_param."]}
            ),
            (response.status_code, json.loads(response.content)))
        self.assertFalse(Node.objects.filter(hostname=hostname).exists())
Пример #44
0
    def test_POST_simple_user_can_set_power_type_and_parameters(self):
        new_power_address = factory.getRandomString()
        response = self.client.post(
            reverse('nodes_handler'), {
                'op': 'new',
                'architecture': factory.getRandomChoice(ARCHITECTURE_CHOICES),
                'power_type': POWER_TYPE.WAKE_ON_LAN,
                'power_parameters': json.dumps(
                    {"power_address": new_power_address}),
                'mac_addresses': ['AA:BB:CC:DD:EE:FF'],
                })

        node = Node.objects.get(
            system_id=json.loads(response.content)['system_id'])
        self.assertEqual(
            (httplib.OK, {"power_address": new_power_address},
             POWER_TYPE.WAKE_ON_LAN),
            (response.status_code, node.power_parameters,
             node.power_type))
Пример #45
0
    def test_POST_new_sets_power_parameters_skip_check(self):
        # The api allows to skip the validation step and set arbitrary
        # power parameters.
        param = factory.getRandomString()
        response = self.client.post(
            reverse('nodes_handler'), {
                'op': 'new',
                'architecture': factory.getRandomChoice(ARCHITECTURE_CHOICES),
                'power_type': POWER_TYPE.WAKE_ON_LAN,
                'power_parameters_param': param,
                'power_parameters_skip_check': 'true',
                'mac_addresses': ['AA:BB:CC:DD:EE:FF'],
            })

        node = Node.objects.get(
            system_id=json.loads(response.content)['system_id'])
        self.assertEqual(httplib.OK, response.status_code)
        self.assertEqual({'param': param},
                         reload_object(node).power_parameters)
Пример #46
0
 def test_POST_new_when_logged_in_creates_node_in_declared_state(self):
     # When a user enlists a node, it goes into the Declared state.
     # This will change once we start doing proper commissioning.
     response = self.client.post(
         reverse('nodes_handler'), {
             'op':
             'new',
             'hostname':
             factory.getRandomString(),
             'architecture':
             factory.getRandomChoice(ARCHITECTURE_CHOICES),
             'after_commissioning_action':
             (NODE_AFTER_COMMISSIONING_ACTION.DEFAULT),
             'mac_addresses': ['aa:bb:cc:dd:ee:ff'],
         })
     self.assertEqual(httplib.OK, response.status_code)
     system_id = json.loads(response.content)['system_id']
     self.assertEqual(NODE_STATUS.DECLARED,
                      Node.objects.get(system_id=system_id).status)
Пример #47
0
    def test_POST_new_creates_node(self):
        architecture = factory.getRandomChoice(ARCHITECTURE_CHOICES)
        response = self.client.post(
            reverse('nodes_handler'),
            {
                'op': 'new',
                'hostname': 'diane',
                'architecture': architecture,
                'after_commissioning_action': (
                    NODE_AFTER_COMMISSIONING_ACTION.DEFAULT),
                'mac_addresses': ['aa:bb:cc:dd:ee:ff', '22:bb:cc:dd:ee:ff'],
            })

        self.assertEqual(httplib.OK, response.status_code)
        parsed_result = json.loads(response.content)
        self.assertIn('application/json', response['Content-Type'])
        self.assertEqual('diane', parsed_result['hostname'])
        self.assertNotEqual(0, len(parsed_result.get('system_id')))
        [diane] = Node.objects.filter(hostname='diane')
        self.assertEqual(architecture, diane.architecture)
Пример #48
0
    def test_POST_new_sets_power_parameters_skip_check(self):
        # The api allows to skip the validation step and set arbitrary
        # power parameters.
        param = factory.getRandomString()
        response = self.client.post(
            reverse('nodes_handler'), {
                'op': 'new',
                'architecture': factory.getRandomChoice(ARCHITECTURE_CHOICES),
                'power_type': POWER_TYPE.WAKE_ON_LAN,
                'power_parameters_param': param,
                'power_parameters_skip_check': 'true',
                'mac_addresses': ['AA:BB:CC:DD:EE:FF'],
                })

        node = Node.objects.get(
            system_id=json.loads(response.content)['system_id'])
        self.assertEqual(httplib.OK, response.status_code)
        self.assertEqual(
            {'param': param},
            reload_object(node).power_parameters)
Пример #49
0
    def test_PUT_updates_nodegroup(self):
        # The api allows the updating of a NodeGroup.
        nodegroup = factory.make_node_group()
        self.become_admin()
        new_name = factory.make_name("new-name")
        new_cluster_name = factory.make_name("new-cluster-name")
        new_status = factory.getRandomChoice(NODEGROUP_STATUS_CHOICES,
                                             but_not=[nodegroup.status])
        response = self.client_put(
            reverse('nodegroup_handler', args=[nodegroup.uuid]), {
                'name': new_name,
                'cluster_name': new_cluster_name,
                'status': new_status,
            })

        self.assertEqual(httplib.OK, response.status_code, response.content)
        nodegroup = reload_object(nodegroup)
        self.assertEqual(
            (new_name, new_cluster_name, new_status),
            (nodegroup.name, nodegroup.cluster_name, nodegroup.status))
Пример #50
0
 def test_POST_non_admin_creates_node_in_declared_state(self):
     # Upon non-admin enlistment, a node goes into the Declared
     # state.  Deliberate approval is required before we start
     # reinstalling the system, wiping its disks etc.
     response = self.client.post(
         reverse('nodes_handler'), {
             'op':
             'new',
             'hostname':
             factory.getRandomString(),
             'architecture':
             factory.getRandomChoice(ARCHITECTURE_CHOICES),
             'after_commissioning_action':
             (NODE_AFTER_COMMISSIONING_ACTION.DEFAULT),
             'mac_addresses': ['aa:bb:cc:dd:ee:ff'],
         })
     self.assertEqual(httplib.OK, response.status_code)
     system_id = json.loads(response.content)['system_id']
     self.assertEqual(NODE_STATUS.DECLARED,
                      Node.objects.get(system_id=system_id).status)
Пример #51
0
    def test_POST_new_generates_hostname_if_ip_based_hostname(self):
        hostname = '192-168-5-19.domain'
        response = self.client.post(
            reverse('nodes_handler'), {
                'op':
                'new',
                'hostname':
                hostname,
                'architecture':
                factory.getRandomChoice(ARCHITECTURE_CHOICES),
                'after_commissioning_action':
                (NODE_AFTER_COMMISSIONING_ACTION.DEFAULT),
                'mac_addresses': [factory.getRandomMACAddress()],
            })
        parsed_result = json.loads(response.content)

        self.assertEqual(httplib.OK, response.status_code)
        system_id = parsed_result.get('system_id')
        node = Node.objects.get(system_id=system_id)
        self.assertNotEqual(hostname, node.hostname)
Пример #52
0
 def test_created_node_nodegroup_is_inferred_from_origin_network(self):
     network = IPNetwork('192.168.0.3/24')
     origin_ip = factory.getRandomIPInNetwork(network)
     NodeGroup.objects.ensure_master()
     nodegroup = factory.make_node_group(network=network)
     response = self.client.post(
         reverse('nodes_handler'),
         data={
             'op': 'new',
             'hostname': factory.make_name('hostname'),
             'architecture': factory.getRandomChoice(ARCHITECTURE_CHOICES),
             'after_commissioning_action': (
                 NODE_AFTER_COMMISSIONING_ACTION.DEFAULT),
             'mac_addresses': [factory.getRandomMACAddress()],
         },
         REMOTE_ADDR=origin_ip)
     self.assertEqual(httplib.OK, response.status_code, response.content)
     parsed_result = json.loads(response.content)
     node = Node.objects.get(system_id=parsed_result.get('system_id'))
     self.assertEqual(nodegroup, node.nodegroup)
Пример #53
0
 def test_POST_new_associates_mac_addresses(self):
     # The API allows a Node to be created and associated with MAC
     # Addresses.
     architecture = factory.getRandomChoice(ARCHITECTURE_CHOICES)
     self.client.post(
         reverse('nodes_handler'), {
             'op':
             'new',
             'hostname':
             'diane',
             'architecture':
             architecture,
             'after_commissioning_action':
             (NODE_AFTER_COMMISSIONING_ACTION.DEFAULT),
             'mac_addresses': ['aa:bb:cc:dd:ee:ff', '22:bb:cc:dd:ee:ff'],
         })
     diane = get_one(Node.objects.filter(hostname='diane'))
     self.assertItemsEqual(
         ['aa:bb:cc:dd:ee:ff', '22:bb:cc:dd:ee:ff'],
         [mac.mac_address for mac in diane.macaddress_set.all()])
Пример #54
0
 def test_POST_new_fails_node_with_double_subarchitecture(self):
     architecture = factory.getRandomChoice(ARCHITECTURE_CHOICES)
     response = self.client.post(
         reverse('nodes_handler'), {
             'op':
             'new',
             'hostname':
             'diane',
             'architecture':
             architecture,
             'subarchitecture':
             architecture.split('/')[1],
             'after_commissioning_action':
             (NODE_AFTER_COMMISSIONING_ACTION.DEFAULT),
             'mac_addresses': ['aa:bb:cc:dd:ee:ff', '22:bb:cc:dd:ee:ff'],
         })
     self.assertEqual(httplib.BAD_REQUEST, response.status_code)
     self.assertIn('text/plain', response['Content-Type'])
     self.assertEqual("Subarchitecture cannot be specified twice.",
                      response.content)
Пример #55
0
 def test_created_node_uses_default_nodegroup_if_origin_not_found(self):
     unknown_host = factory.make_name('host')
     response = self.client.post(
         reverse('nodes_handler'),
         data={
             'op':
             'new',
             'hostname':
             factory.make_name('hostname'),
             'architecture':
             factory.getRandomChoice(ARCHITECTURE_CHOICES),
             'after_commissioning_action':
             (NODE_AFTER_COMMISSIONING_ACTION.DEFAULT),
             'mac_addresses': [factory.getRandomMACAddress()],
         },
         HTTP_HOST=unknown_host)
     self.assertEqual(httplib.OK, response.status_code, response.content)
     parsed_result = json.loads(response.content)
     node = Node.objects.get(system_id=parsed_result.get('system_id'))
     self.assertEqual(NodeGroup.objects.ensure_master(), node.nodegroup)
Пример #56
0
 def test_handle_when_URL_is_repeated(self):
     # bin/maas-enlist (in the maas-enlist package) has a bug where the
     # path it uses is doubled up. This was not discovered previously
     # because the API URL patterns were not anchored (see bug 1131323).
     # For compatibility, MAAS will handle requests to obviously incorrect
     # paths. It does *not* redirect because (a) it's not clear that curl
     # (used by maas-enlist) supports HTTP 307 redirects, which are needed
     # to support redirecting POSTs, and (b) curl does not follow redirects
     # by default anyway.
     architecture = factory.getRandomChoice(ARCHITECTURE_CHOICES)
     response = self.client.post(
         '/api/1.0/nodes/MAAS/api/1.0/nodes/', {
             'op': 'new',
             'hostname': factory.getRandomString(),
             'architecture': architecture,
             'mac_addresses': ['aa:bb:cc:dd:ee:ff'],
         })
     self.assertEqual(httplib.OK, response.status_code)
     system_id = json.loads(response.content)['system_id']
     nodes = Node.objects.filter(system_id=system_id)
     self.assertIsNotNone(get_one(nodes))
Пример #57
0
    def test_POST_simple_user_can_set_power_type_and_parameters(self):
        new_power_address = factory.getRandomString()
        response = self.client.post(
            reverse('nodes_handler'), {
                'op':
                'new',
                'architecture':
                factory.getRandomChoice(ARCHITECTURE_CHOICES),
                'power_type':
                POWER_TYPE.WAKE_ON_LAN,
                'power_parameters':
                json.dumps({"power_address": new_power_address}),
                'mac_addresses': ['AA:BB:CC:DD:EE:FF'],
            })

        node = Node.objects.get(
            system_id=json.loads(response.content)['system_id'])
        self.assertEqual(
            (httplib.OK, {
                "power_address": new_power_address
            }, POWER_TYPE.WAKE_ON_LAN),
            (response.status_code, node.power_parameters, node.power_type))
Пример #58
0
 def test_created_node_nodegroup_is_inferred_from_origin_network(self):
     network = IPNetwork('192.168.0.3/24')
     origin_ip = factory.getRandomIPInNetwork(network)
     NodeGroup.objects.ensure_master()
     nodegroup = factory.make_node_group(network=network)
     response = self.client.post(
         reverse('nodes_handler'),
         data={
             'op':
             'new',
             'hostname':
             factory.make_name('hostname'),
             'architecture':
             factory.getRandomChoice(ARCHITECTURE_CHOICES),
             'after_commissioning_action':
             (NODE_AFTER_COMMISSIONING_ACTION.DEFAULT),
             'mac_addresses': [factory.getRandomMACAddress()],
         },
         REMOTE_ADDR=origin_ip)
     self.assertEqual(httplib.OK, response.status_code, response.content)
     parsed_result = json.loads(response.content)
     node = Node.objects.get(system_id=parsed_result.get('system_id'))
     self.assertEqual(nodegroup, node.nodegroup)