Exemple #1
0
    def test_send_event_mac_address_stores_event_with_timestamp_received(self):
        # Use a random time in the recent past and coerce the responder to use
        # it as the time-stamp for the event. We'll check this later on.
        timestamp = datetime.now() - timedelta(seconds=randint(99, 99999))
        self.patch(regionservice, "datetime").now.return_value = timestamp

        event_type = factory.make_name("type_name")
        yield deferToDatabase(self.create_event_type, event_type, "", 0)
        interface = yield deferToDatabase(self.make_interface)
        mac_address = interface.mac_address.get_raw()

        yield eventloop.start()
        try:
            yield call_responder(
                Region(),
                SendEventMACAddress,
                {
                    "mac_address": mac_address,
                    "type_name": event_type,
                    "description": factory.make_name("description"),
                },
            )
        finally:
            yield eventloop.reset()

        event = yield deferToDatabase(self.get_event, mac_address, event_type)
        self.expectThat(event.created, Equals(timestamp))
Exemple #2
0
    def test_returns_proxy_configuration(self):
        def _db_work():
            cidrs = [
                factory.make_Subnet(allow_proxy=True).cidr for _ in range(3)
            ]
            for _ in range(3):
                factory.make_Subnet(allow_proxy=False)
            enabled = factory.pick_bool()
            Config.objects.set_config("enable_http_proxy", enabled)
            port = random.randint(1000, 8000)
            Config.objects.set_config("maas_proxy_port", port)
            prefer_v4_proxy = factory.pick_bool()
            Config.objects.set_config("prefer_v4_proxy", prefer_v4_proxy)
            return cidrs, enabled, port, prefer_v4_proxy

        cidrs, enabled, port, prefer_v4_proxy = yield deferToDatabase(_db_work)

        system_id = factory.make_name("id")
        response = yield call_responder(
            Region(), GetProxyConfiguration, {"system_id": system_id}
        )
        self.assertThat(
            response,
            Equals(
                {
                    "enabled": enabled,
                    "port": port,
                    "allowed_cidrs": cidrs,
                    "prefer_v4_proxy": prefer_v4_proxy,
                }
            ),
        )
Exemple #3
0
    def test_calls_create_node_function(self):
        create_node_function = self.patch(regionservice, "create_node")
        create_node_function.return_value = yield deferToDatabase(
            self.create_node
        )

        params = {
            "architecture": factory.make_name("arch"),
            "power_type": factory.make_name("power_type"),
            "power_parameters": dumps({}),
            "mac_addresses": [factory.make_mac_address()],
            "domain": factory.make_name("domain"),
            "hostname": None,
        }

        response = yield call_responder(Region(), CreateNode, params)
        self.assertIsNotNone(response)

        self.assertThat(
            create_node_function,
            MockCalledOnceWith(
                params["architecture"],
                params["power_type"],
                params["power_parameters"],
                params["mac_addresses"],
                domain=params["domain"],
                hostname=params["hostname"],
            ),
        )
        self.assertEqual(
            create_node_function.return_value.system_id, response["system_id"]
        )
Exemple #4
0
    def test_calls_update_services_in_database_thread(self):
        system_id = factory.make_name("system_id")
        services = [
            {
                "name": factory.make_name("service"),
                "status": factory.make_name("status"),
                "status_info": factory.make_name("status_info"),
            }
        ]

        mock_deferToDatabase = self.patch(regionservice, "deferToDatabase")
        mock_deferToDatabase.return_value = succeed({})

        yield eventloop.start()
        try:
            yield call_responder(
                Region(),
                UpdateServices,
                {"system_id": system_id, "services": services},
            )
        finally:
            yield eventloop.reset()

        self.assertThat(
            mock_deferToDatabase,
            MockCalledWith(update_services, system_id, services),
        )
Exemple #5
0
    def test_report_boot_images_with_real_things_to_report(self):
        # tftppath.report_boot_images()'s return value matches the
        # arguments schema that ReportBootImages declares, and is
        # serialised correctly.

        # Example boot image definitions.
        archs = "i386", "amd64"
        subarchs = "generic", "special"
        releases = "precise", "trusty"
        purposes = "commission", "install"

        # Create a TFTP file tree with a variety of subdirectories.
        tftpdir = self.make_dir()
        for options in product(archs, subarchs, releases, purposes):
            os.makedirs(os.path.join(tftpdir, *options))

        # Ensure that report_boot_images() uses the above TFTP file tree.
        self.useFixture(ClusterConfigurationFixture(tftp_root=tftpdir))

        images = [
            {"architecture": arch, "subarchitecture": subarch,
             "release": release, "purpose": purpose}
            for arch, subarch, release, purpose in product(
                archs, subarchs, releases, purposes)
        ]

        d = call_responder(Region(), ReportBootImages, {
            "uuid": factory.make_name("uuid"), "images": images,
        })

        def check(response):
            self.assertEqual({}, response)

        return d.addCallback(check)
    def test_calls_request_node_info_by_mac_address_function(self):
        purpose = factory.make_name('purpose')
        node = yield deferToDatabase(self.create_node)
        node_info_function = self.patch(regionservice,
                                        'request_node_info_by_mac_address')
        node_info_function.return_value = (node, purpose)
        interface = yield deferToDatabase(self.make_interface, node)

        params = {
            'mac_address': interface.mac_address.get_raw(),
        }

        response = yield call_responder(Region(), RequestNodeInfoByMACAddress,
                                        params)
        self.assertIsNotNone(response)
        self.assertThat(node_info_function,
                        MockCalledOnceWith(params['mac_address']))
        response_purpose = response.pop('purpose')
        self.assertEqual(purpose, response_purpose)
        # Remove the boot_type from the response as node no longer has that
        # attribute.
        copy_response = dict(response)
        del copy_response["boot_type"]
        self.assertAttributes(node, copy_response)
        self.assertEquals("fastpath", response["boot_type"])
    def test_send_event_logs_if_unknown_node(self):
        log = self.patch(events_module, 'log')
        name = factory.make_name('type_name')
        description = factory.make_name('description')
        level = random.randint(0, 100)
        yield deferToDatabase(self.create_event_type, name, description, level)

        system_id = factory.make_name('system_id')
        event_description = factory.make_name('event-description')

        yield eventloop.start()
        try:
            yield call_responder(
                Region(), SendEvent, {
                    'system_id': system_id,
                    'type_name': name,
                    'description': event_description,
                })
        finally:
            yield eventloop.reset()

        self.assertThat(
            log.debug,
            MockCalledOnceWith(
                "Event '{type}: {description}' sent for "
                "non-existent node '{node_id}'.",
                type=name,
                description=event_description,
                node_id=system_id))
    def test_send_event_mac_address_does_not_fail_if_unknown_type(self):
        name = factory.make_name('type_name')
        mac_address = factory.make_mac_address()
        description = factory.make_name('description')

        logger = self.useFixture(TwistedLoggerFixture())

        yield eventloop.start()
        try:
            yield call_responder(
                Region(), SendEventMACAddress, {
                    'mac_address': mac_address,
                    'type_name': name,
                    'description': description,
                })
        finally:
            yield eventloop.reset()

        # The log records the issue. FIXME: Why reject logs if the type is not
        # registered? Seems like the region should record all logs and figure
        # out how to present them.
        self.assertDocTestMatches(
            """\
            Unhandled failure in database task.
            Traceback (most recent call last):
            ...
            provisioningserver.rpc.exceptions.NoSuchEventType:
            ...
            """, logger.output)
    def test_identify_reports_event_loop_name(self):
        d = call_responder(Region(), Identify, {})

        def check(response):
            self.assertEqual({"ident": eventloop.loop.name}, response)

        return d.addCallback(check)
 def test_get_archive_mirrors_with_main_archive_port_archive_default(self):
     response = yield call_responder(Region(), GetArchiveMirrors, {})
     self.assertEqual(
         {
             "main": urlparse("http://archive.ubuntu.com/ubuntu"),
             "ports": urlparse("http://ports.ubuntu.com/ubuntu-ports")
         }, response)
    def test_send_event_stores_event(self):
        name = factory.make_name('type_name')
        description = factory.make_name('description')
        level = random.randint(0, 100)
        yield deferToDatabase(self.create_event_type, name, description, level)
        system_id = yield deferToDatabase(self.create_node)

        event_description = factory.make_name('description')

        yield eventloop.start()
        try:
            response = yield call_responder(
                Region(), SendEvent, {
                    'system_id': system_id,
                    'type_name': name,
                    'description': event_description,
                })
        finally:
            yield eventloop.reset()

        self.assertEqual({}, response)
        event = yield deferToDatabase(self.get_event, system_id, name)
        self.expectThat(event.node.system_id, Equals(system_id))
        self.expectThat(event.description, Equals(event_description))
        self.expectThat(event.type.name, Equals(name))
    def test__returns_correct_arguments(self):
        rack = yield deferToDatabase(self.create_rack_controller,
                                     power_type='')

        nodes = []
        for _ in range(3):
            node = yield deferToDatabase(self.create_node,
                                         power_type="virsh",
                                         power_state_updated=None,
                                         bmc_connected_to=rack)
            power_params = yield deferToDatabase(
                self.get_node_power_parameters, node)
            nodes.append({
                'system_id': node.system_id,
                'hostname': node.hostname,
                'power_state': node.power_state,
                'power_type': node.get_effective_power_type(),
                'context': power_params,
            })

        # Create a node with an invalid power type (i.e. the empty string).
        # This will not be reported by the call to ListNodePowerParameters.
        yield deferToDatabase(self.create_node,
                              power_type="",
                              power_state_updated=None)

        response = yield call_responder(Region(), ListNodePowerParameters,
                                        {'uuid': rack.system_id})

        self.maxDiff = None
        self.assertItemsEqual(nodes, response['nodes'])
    def test_calls_create_node_function(self):
        create_node_function = self.patch(regionservice, 'create_node')
        create_node_function.return_value = yield deferToDatabase(
            self.create_node)

        params = {
            'architecture': factory.make_name('arch'),
            'power_type': factory.make_name('power_type'),
            'power_parameters': dumps({}),
            'mac_addresses': [factory.make_mac_address()],
            'domain': factory.make_name('domain'),
            'hostname': None,
        }

        response = yield call_responder(Region(), CreateNode, params)
        self.assertIsNotNone(response)

        self.assertThat(
            create_node_function,
            MockCalledOnceWith(params['architecture'],
                               params['power_type'],
                               params['power_parameters'],
                               params['mac_addresses'],
                               domain=params['domain'],
                               hostname=params['hostname']))
        self.assertEqual(create_node_function.return_value.system_id,
                         response['system_id'])
    def test_send_event_mac_address_stores_event(self):
        name = factory.make_name('type_name')
        description = factory.make_name('description')
        level = random.randint(0, 100)
        yield deferToDatabase(self.create_event_type, name, description, level)
        interface = yield deferToDatabase(self.make_interface)
        mac_address = interface.mac_address
        event_description = factory.make_name('description')

        yield eventloop.start()
        try:
            response = yield call_responder(
                Region(), SendEventMACAddress, {
                    'mac_address': mac_address.get_raw(),
                    'type_name': name,
                    'description': event_description,
                })
        finally:
            yield eventloop.reset()

        self.assertEqual({}, response)
        event = yield deferToDatabase(self.get_event, mac_address, name)
        self.expectThat(event.node.system_id, Equals(interface.node.system_id))
        self.expectThat(event.description, Equals(event_description))
        self.expectThat(event.type.name, Equals(name))
 def test_register_sets_hostIsRemote_calls_rpcRegisterConnection(self):
     yield self.installFakeRegion()
     rack_controller = yield deferToDatabase(factory.make_RackController)
     ipcWorker = MagicMock()
     protocol = self.make_Region(ipcWorker)
     protocol.transport = MagicMock()
     host = IPv4Address(
         type="TCP",
         host=factory.make_ipv4_address(),
         port=random.randint(1, 400),
     )
     protocol.transport.getHost.return_value = host
     mock_deferToDatabase = self.patch(regionservice, "deferToDatabase")
     mock_deferToDatabase.side_effect = [succeed(rack_controller)]
     yield call_responder(
         protocol,
         RegisterRackController,
         {
             "system_id": rack_controller.system_id,
             "hostname": rack_controller.hostname,
             "interfaces": {},
         },
     )
     self.assertTrue(sentinel.host, protocol.hostIsRemote)
     self.assertThat(
         ipcWorker.rpcRegisterConnection,
         MockCalledOnceWith(protocol.connid, protocol.ident, host.host,
                            host.port),
     )
    def test_register_updates_interfaces(self):
        yield self.installFakeRegion()
        rack_controller = yield deferToDatabase(factory.make_RackController)
        protocol = self.make_Region()
        protocol.transport = MagicMock()
        nic_name = factory.make_name("eth0")
        interfaces = {
            nic_name: {
                "type": "physical",
                "mac_address": factory.make_mac_address(),
                "parents": [],
                "links": [],
                "enabled": True,
            }
        }
        response = yield call_responder(
            protocol,
            RegisterRackController,
            {
                "system_id": rack_controller.system_id,
                "hostname": rack_controller.hostname,
                "interfaces": interfaces,
            },
        )

        @transactional
        def has_interface(system_id, nic_name):
            rack_controller = RackController.objects.get(system_id=system_id)
            interfaces = rack_controller.interface_set.filter(name=nic_name)
            self.assertThat(interfaces, HasLength(1))

        yield deferToDatabase(has_interface, response["system_id"], nic_name)
    def test_get_boot_config_returns_expected_result(self):
        rack_controller = yield deferToDatabase(
            transactional(factory.make_RackController))
        yield deferToDatabase(make_usable_architecture, self)
        local_ip = factory.make_ip_address()
        remote_ip = factory.make_ip_address()

        response = yield call_responder(
            Region(), GetBootConfig, {
                "system_id": rack_controller.system_id,
                "local_ip": local_ip,
                "remote_ip": remote_ip,
            })

        self.assertThat(
            response,
            ContainsAll([
                "arch",
                "subarch",
                "osystem",
                "release",
                "kernel",
                "initrd",
                "boot_dtb",
                "purpose",
                "hostname",
                "domain",
                "preseed_url",
                "fs_host",
                "log_host",
                "extra_opts",
            ]))
    def test_send_event_mac_address_logs_if_unknown_node(self):
        log = self.patch(events_module, 'log')
        name = factory.make_name('type_name')
        description = factory.make_name('description')
        level = random.randint(0, 100)
        yield deferToDatabase(self.create_event_type, name, description, level)
        mac_address = factory.make_mac_address()
        event_description = factory.make_name('event-description')

        yield eventloop.start()
        try:
            yield call_responder(
                Region(), SendEventMACAddress, {
                    'mac_address': mac_address,
                    'type_name': name,
                    'description': event_description,
                })
        finally:
            yield eventloop.reset()

        self.assertThat(
            log.debug,
            MockCalledOnceWith(
                "Event '{type}: {description}' sent for non-existent node "
                "with MAC address '{mac}'.",
                type=name,
                description=event_description,
                mac=mac_address))
Exemple #19
0
    def test_register_event_type_does_not_error_for_existing_event_types(self):
        # This is a regression test for bug 1373357.
        name = factory.make_name('name')
        old_description = factory.make_name('old-description')
        level = random.randint(0, 100)
        response = yield call_responder(
            Region(), RegisterEventType,
            {'name': name, 'description': old_description, 'level': level})
        self.assertEqual({}, response)

        new_description = factory.make_name('new-description')
        response = yield call_responder(
            Region(), RegisterEventType,
            {'name': name, 'description': new_description, 'level': level})
        # If we get this far, no error has been raised, even though we
        # sent a duplicate request for registration.
        self.assertEqual({}, response)
Exemple #20
0
    def test__raises_exception_if_nodegroup_doesnt_exist(self):
        uuid = factory.make_UUID()

        d = call_responder(
            Region(), ListNodePowerParameters,
            {'uuid': uuid})

        return assert_fails_with(d, NoSuchCluster)
    def test_calls_refresh(self):
        rack = yield deferToDatabase(factory.make_RackController)
        self.patch(regionservice,
                   'deferToDatabase').return_value = succeed(rack)
        mock_refresh = self.patch(rack, 'refresh')
        response = yield call_responder(Region(), RequestRackRefresh,
                                        {'system_id': rack.system_id})
        self.assertIsNotNone(response)

        self.assertThat(mock_refresh, MockCalledOnce())
    def test_get_proxies_with_http_proxy_not_set(self):
        # Disable boot source cache signals.
        self.addCleanup(bootsources.signals.enable)
        bootsources.signals.disable()

        yield deferToDatabase(self.set_http_proxy, None)

        response = yield call_responder(Region(), GetProxies, {})

        self.assertEqual({"http": None, "https": None}, response)
    def test_get_boot_sources_v2_returns_simplestreams_endpoint(self):
        uuid = factory.make_name("uuid")

        d = call_responder(Region(), GetBootSourcesV2, {"uuid": uuid})

        def check(response):
            self.assertEqual({"sources": [get_simplestream_endpoint()]},
                             response)

        return d.addCallback(check)
Exemple #24
0
 def test_register_creates_new_rack(self):
     yield self.installFakeRegion()
     protocol = self.make_Region()
     protocol.transport = MagicMock()
     hostname = factory.make_hostname()
     yield call_responder(protocol, RegisterRackController, {
         "system_id": None,
         "hostname": hostname,
         "interfaces": {},
     })
     yield deferToDatabase(RackController.objects.get, hostname=hostname)
    def test_get_proxies_with_http_proxy_set(self):
        # Disable boot source cache signals.
        self.addCleanup(bootsources.signals.enable)
        bootsources.signals.disable()

        url = factory.make_parsed_url()
        yield deferToDatabase(self.set_http_proxy, url.geturl())

        response = yield call_responder(Region(), GetProxies, {})

        self.assertEqual({"http": url, "https": url}, response)
    def test_authenticate_calculates_digest_with_salt(self):
        message = factory.make_bytes()
        secret = yield get_shared_secret()

        args = {"message": message}
        response = yield call_responder(Region(), Authenticate, args)
        digest = response["digest"]
        salt = response["salt"]

        expected_digest = HMAC(secret, message + salt, sha256).digest()
        self.assertEqual(expected_digest, digest)
        self.assertThat(salt, HasLength(16))
Exemple #27
0
    def test__changes_power_state(self):
        power_state = factory.pick_enum(POWER_STATE)
        node = yield deferToDatabase(self.create_node, power_state)

        new_state = factory.pick_enum(POWER_STATE, but_not=power_state)
        yield call_responder(
            Region(), UpdateNodePowerState,
            {'system_id': node.system_id, 'power_state': new_state})

        db_state = yield deferToDatabase(
            self.get_node_power_state, node.system_id)
        self.assertEqual(new_state, db_state)
Exemple #28
0
 def test_register_sets_ident(self):
     yield self.installFakeRegion()
     rack_controller = yield deferToDatabase(factory.make_RackController)
     protocol = self.make_Region()
     protocol.transport = MagicMock()
     yield call_responder(
         protocol, RegisterRackController, {
             "system_id": rack_controller.system_id,
             "hostname": rack_controller.hostname,
             "interfaces": {},
         })
     self.assertEquals(rack_controller.system_id, protocol.ident)
 def test_calls_get_controller_type(self):
     example_response = {
         "is_region": factory.pick_bool(),
         "is_rack": factory.pick_bool(),
     }
     deferToDatabase = self.patch(regionservice, 'deferToDatabase')
     deferToDatabase.return_value = succeed(example_response)
     system_id = factory.make_name("id")
     response = yield call_responder(Region(), GetControllerType,
                                     {'system_id': system_id})
     self.assertThat(response, Equals(example_response))
     self.assertThat(deferToDatabase,
                     MockCalledOnceWith(get_controller_type, system_id))
    def test_StartTLS_returns_nothing(self):
        # The StartTLS command does some funky things - see _TLSBox and
        # _LocalArgument for an idea - so the parameters returned from
        # get_tls_parameters() - the registered responder - don't end up
        # travelling over the wire as part of an AMP message. However,
        # the responder is not aware of this, and is called just like
        # any other.
        d = call_responder(Region(), amp.StartTLS, {})

        def check(response):
            self.assertEqual({}, response)

        return d.addCallback(check)