Пример #1
0
 def test_update_updates_node(self):
     user = factory.make_admin()
     handler = DeviceHandler(user, {}, None)
     node = factory.make_Node(interface=True, node_type=NODE_TYPE.DEVICE)
     node_data = self.dehydrate_device(node, user)
     new_zone = factory.make_Zone()
     new_hostname = factory.make_name("hostname")
     new_description = factory.make_name("description")
     new_tags = [factory.make_name("tag") for _ in range(3)]
     node_data["hostname"] = new_hostname
     node_data["description"] = new_description
     node_data["zone"] = {
         "name": new_zone.name,
     }
     node_data["tags"] = new_tags
     updated_node = handler.update(node_data)
     self.assertEqual(updated_node["hostname"], new_hostname)
     self.assertEqual(updated_node["description"], new_description)
     self.assertEqual(updated_node["zone"]["id"], new_zone.id)
     self.assertItemsEqual(updated_node["tags"], new_tags)
Пример #2
0
 def test_POST_set_zone_rbac_pool_admin_allowed(self):
     self.patch(auth, "validate_user_external_auth").return_value = True
     rbac = self.useFixture(RBACEnabled())
     self.become_non_local()
     machine = factory.make_Machine()
     zone = factory.make_Zone()
     rbac.store.add_pool(machine.pool)
     rbac.store.allow(self.user.username, machine.pool, "admin-machines")
     rbac.store.allow(self.user.username, machine.pool, "view")
     response = self.client.post(
         reverse("nodes_handler"),
         {
             "op": "set_zone",
             "nodes": [machine.system_id],
             "zone": zone.name,
         },
     )
     self.assertEqual(http.client.OK, response.status_code)
     machine = reload_object(machine)
     self.assertEqual(zone, machine.zone)
Пример #3
0
 def test_list_returns_zone_list(self):
     [factory.make_Zone(sortable_name=True) for _ in range(3)]
     zones = Zone.objects.all()
     response = self.client.get(reverse("zones_handler"), {})
     self.assertEqual(http.client.OK, response.status_code,
                      response.content)
     parsed_result = json.loads(
         response.content.decode(settings.DEFAULT_CHARSET))
     self.assertItemsEqual(
         [(
             zone.name,
             zone.description,
             reverse("zone_handler", args=[zone.name]),
         ) for zone in zones],
         [(
             zone.get("name"),
             zone.get("description"),
             zone.get("resource_uri"),
         ) for zone in parsed_result],
     )
Пример #4
0
    def test_zone_list_contains_edit_links(self):
        self.client_log_in(as_admin=True)
        zones = [factory.make_Zone() for _ in range(3)]
        default_zone = Zone.objects.get_default_zone()
        zone_edit_links = [
            reverse('zone-edit', args=[zone.name]) for zone in zones
        ]
        zone_delete_links = [
            reverse('zone-del', args=[zone.name]) for zone in zones
        ]
        zone_default_edit = reverse('zone-edit', args=[default_zone.name])
        zone_default_delete = reverse('zone-del', args=[default_zone.name])

        response = self.client.get(reverse('zone-list'))
        all_links = get_content_links(response)

        self.assertThat(all_links,
                        ContainsAll(zone_edit_links + zone_delete_links))
        self.assertThat(all_links, Not(Contains(zone_default_edit)))
        self.assertThat(all_links, Not(Contains(zone_default_delete)))
Пример #5
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)
Пример #6
0
 def test_creates_pod_with_discovered_information(self):
     discovered_pod, discovered_racks, failed_racks = (
         self.fake_pod_discovery())
     zone = factory.make_Zone()
     pod_info = self.make_pod_info()
     pod_info['zone'] = zone.id
     request = MagicMock()
     request.user = factory.make_User()
     form = PodForm(data=pod_info, request=request)
     self.assertTrue(form.is_valid(), form._errors)
     pod = form.save()
     self.assertThat(
         pod,
         MatchesStructure(
             architectures=Equals(['amd64/generic']),
             name=MatchesAll(Not(Is(None)), Not(Equals(''))),
             cores=Equals(discovered_pod.cores),
             memory=Equals(discovered_pod.memory),
             cpu_speed=Equals(discovered_pod.cpu_speed),
             zone=Equals(zone),
             power_type=Equals(pod_info['type']),
             power_parameters=Equals({
                 'power_address':
                 pod_info['power_address'],
                 'power_pass':
                 pod_info['power_pass'],
             }),
             ip_address=MatchesStructure(ip=Equals(pod_info['ip_address'])),
         ))
     routable_racks = [
         relation.rack_controller
         for relation in pod.routable_rack_relationships.all()
         if relation.routable
     ]
     not_routable_racks = [
         relation.rack_controller
         for relation in pod.routable_rack_relationships.all()
         if not relation.routable
     ]
     self.assertItemsEqual(routable_racks, discovered_racks)
     self.assertItemsEqual(not_routable_racks, failed_racks)
Пример #7
0
 def make_pod_info(self):
     # Use virsh pod type as the required fields are specific to the
     # type of pod being created.
     pod_type = "virsh"
     pod_ip_adddress = factory.make_ipv4_address()
     pod_power_address = "qemu+ssh://user@%s/system" % pod_ip_adddress
     pod_password = factory.make_name("password")
     pod_tags = [factory.make_name("tag") for _ in range(3)]
     pod_zone = factory.make_Zone()
     pod_cpu_over_commit_ratio = random.randint(0, 10)
     pod_memory_over_commit_ratio = random.randint(0, 10)
     return {
         "type": pod_type,
         "power_address": pod_power_address,
         "power_pass": pod_password,
         "ip_address": pod_ip_adddress,
         "tags": ",".join(pod_tags),
         "zone": pod_zone.name,
         "cpu_over_commit_ratio": pod_cpu_over_commit_ratio,
         "memory_over_commit_ratio": pod_memory_over_commit_ratio,
     }
Пример #8
0
 def make_pod_info(self):
     # Use virsh pod type as the required fields are specific to the
     # type of pod being created.
     pod_type = 'virsh'
     pod_ip_adddress = factory.make_ipv4_address()
     pod_power_address = 'qemu+ssh://user@%s/system' % pod_ip_adddress
     pod_password = factory.make_name('password')
     pod_tags = [factory.make_name("tag") for _ in range(3)]
     pod_zone = factory.make_Zone()
     pod_cpu_over_commit_ratio = random.randint(0, 10)
     pod_memory_over_commit_ratio = random.randint(0, 10)
     return {
         'type': pod_type,
         'power_address': pod_power_address,
         'power_pass': pod_password,
         'ip_address': pod_ip_adddress,
         'tags': ",".join(pod_tags),
         'zone': pod_zone.name,
         'cpu_over_commit_ratio': pod_cpu_over_commit_ratio,
         'memory_over_commit_ratio': pod_memory_over_commit_ratio
     }
Пример #9
0
    def test_set_zone_works_if_rbac_pool_admin(self):
        rbac = self.useFixture(RBACEnabled())
        user = factory.make_User()
        machine = factory.make_Machine()
        zone = factory.make_Zone()
        rbac.store.add_pool(machine.pool)
        rbac.store.allow(user.username, machine.pool, "admin-machines")
        rbac.store.allow(user.username, machine.pool, "view")
        form = BulkNodeSetZoneForm(
            user=user,
            data={
                "zone": zone.name,
                "system_id": [machine.system_id]
            },
        )
        self.assertTrue(form.is_valid(), form._errors)
        done, not_actionable, not_permitted = form.save()

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

        machine = reload_object(machine)
        self.assertEqual(zone, machine.zone)
Пример #10
0
 def test_GET_prev_and_next_uris_contain_search_parameters(self):
     machine = factory.make_Machine(domain=factory.make_Domain(),
                                    zone=factory.make_Zone())
     interface = factory.make_Interface(node=machine)
     machine.agent_name = factory.make_name("agent")
     machine.save()
     query = {
         "op": "query",
         "level": "DEBUG",
         # Node filtering parameters.
         "agent_name": machine.agent_name,
         "domain": machine.domain.name,
         "hostname": machine.hostname,
         "id": machine.system_id,
         "mac_address": interface.mac_address.raw,
         "zone": machine.zone.name,
     }
     event = factory.make_Event(node=machine)
     prev_params, next_params = self.assertURIs(query, event.id, event.id)
     params_expected = {p: Equals(v) for p, v in query.items()}
     self.assertThat(prev_params, ContainsDict(params_expected))
     self.assertThat(next_params, ContainsDict(params_expected))
Пример #11
0
 def test_takes_over_bmc_with_pod(self):
     discovered_pod, _, _ = self.fake_pod_discovery()
     zone = factory.make_Zone()
     pod_info = self.make_pod_info()
     pod_info['zone'] = zone.name
     bmc = factory.make_BMC(zone=zone,
                            tags=pod_info['tags'].split(','),
                            power_type=pod_info['type'],
                            power_parameters={
                                'power_address':
                                pod_info['power_address'],
                                'power_pass':
                                pod_info['power_pass'],
                                'default_storage_pool':
                                pod_info['default_storage_pool'],
                            })
     request = MagicMock()
     request.user = factory.make_User()
     form = PodForm(data=pod_info, request=request)
     self.assertTrue(form.is_valid(), form._errors)
     pod = form.save()
     self.assertEquals(bmc.id, pod.id)
     self.assertEquals(BMC_TYPE.POD, reload_object(bmc).bmc_type)
Пример #12
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)
Пример #13
0
 def test_PUT_updates(self):
     self.patch(pods, "post_commit_do")
     pod = factory.make_Pod(pod_type="virsh")
     new_name = factory.make_name("pod")
     new_tags = [
         factory.make_name("tag"),
         factory.make_name("tag"),
         "pod-console-logging",
     ]
     new_pool = factory.make_ResourcePool()
     new_zone = factory.make_Zone()
     new_power_parameters = {
         "power_address": "qemu+ssh://1.2.3.4/system",
         "power_pass": factory.make_name("pass"),
     }
     discovered_pod, _, _ = self.fake_pod_discovery()
     response = self.client.put(
         get_pod_uri(pod),
         {
             "name": new_name,
             "tags": ",".join(new_tags),
             "power_address": new_power_parameters["power_address"],
             "power_pass": new_power_parameters["power_pass"],
             "zone": new_zone.name,
             "pool": new_pool.name,
         },
     )
     self.assertEqual(
         http.client.OK, response.status_code, response.content
     )
     pod.refresh_from_db()
     self.assertIsNotNone(Tag.objects.get(name="pod-console-logging"))
     self.assertEqual(new_name, pod.name)
     self.assertEqual(new_pool, pod.pool)
     self.assertItemsEqual(new_tags, pod.tags)
     self.assertEqual(new_power_parameters, pod.power_parameters)
     self.assertEqual(new_zone, pod.zone)
Пример #14
0
 def test_discover_and_sync_existing_pod(self):
     discovered_pod, discovered_racks, failed_racks = (
         self.fake_pod_discovery())
     zone = factory.make_Zone()
     pod_info = self.make_pod_info()
     orig_pod = factory.make_Pod(zone=zone, pod_type=pod_info['type'])
     request = MagicMock()
     request.user = factory.make_User()
     form = PodForm(data=pod_info, request=request, instance=orig_pod)
     pod = form.discover_and_sync_pod()
     self.assertThat(
         pod,
         MatchesStructure(
             id=Equals(orig_pod.id),
             bmc_type=Equals(BMC_TYPE.POD),
             architectures=Equals(['amd64/generic']),
             name=Equals(orig_pod.name),
             cores=Equals(discovered_pod.cores),
             memory=Equals(discovered_pod.memory),
             cpu_speed=Equals(discovered_pod.cpu_speed),
             zone=Equals(zone),
             power_type=Equals(pod_info['type']),
             power_parameters=Equals({}),
             ip_address=Is(None),
         ))
     routable_racks = [
         relation.rack_controller
         for relation in pod.routable_rack_relationships.all()
         if relation.routable
     ]
     not_routable_racks = [
         relation.rack_controller
         for relation in pod.routable_rack_relationships.all()
         if not relation.routable
     ]
     self.assertItemsEqual(routable_racks, discovered_racks)
     self.assertItemsEqual(not_routable_racks, failed_racks)
Пример #15
0
 def test_is_default_returns_False_for_normal_zone(self):
     self.assertFalse(factory.make_Zone().is_default())
Пример #16
0
 def test_delete_deletes_zone(self):
     zone = factory.make_Zone()
     zone.delete()
     self.assertIsNone(reload_object(zone))
Пример #17
0
 def test_get_default_zone_ignores_other_zones(self):
     factory.make_Zone()
     self.assertEqual(
         DEFAULT_ZONE_NAME, Zone.objects.get_default_zone().name
     )
Пример #18
0
 def test_PUT_requires_admin(self):
     zone = factory.make_Zone()
     response = self.client.put(get_zone_uri(zone),
                                {"description": factory.make_string()})
     self.assertEqual(http.client.FORBIDDEN, response.status_code)
Пример #19
0
 def test_make_Zone_adds_nodes(self):
     node = factory.make_Node()
     zone = factory.make_Zone(nodes=[node])
     node = reload_object(node)
     self.assertEqual(zone, node.zone)
Пример #20
0
 def test_redirects_to_listing(self):
     self.client_log_in(as_admin=True)
     zone = factory.make_Zone()
     response = self.client.post(reverse('zone-del', args=[zone.name]),
                                 {'post': 'yes'})
     self.assertEqual(reverse('zone-list'), extract_redirect(response))
Пример #21
0
 def test_make_Zone_returns_physical_zone(self):
     self.assertIsNotNone(factory.make_Zone())
Пример #22
0
 def test_make_Zone_assigns_name(self):
     name = factory.make_Zone().name
     self.assertIsNotNone(name)
     self.assertNotEqual(0, len(name))
Пример #23
0
 def test_make_Zone_adds_no_nodes_by_default(self):
     previous_zone = factory.make_Zone()
     node = factory.make_Node(zone=previous_zone)
     factory.make_Zone()
     node = reload_object(node)
     self.assertEqual(previous_zone, node.zone)
Пример #24
0
 def test_make_Zone_does_not_add_other_nodes(self):
     previous_zone = factory.make_Zone()
     node = factory.make_Node(zone=previous_zone)
     factory.make_Zone(nodes=[factory.make_Node()])
     node = reload_object(node)
     self.assertEqual(previous_zone, node.zone)
Пример #25
0
 def test_delete_as_non_admin_asserts(self):
     user = factory.make_User()
     handler = ZoneHandler(user, {}, None)
     zone = factory.make_Zone()
     with ExpectedException(AssertionError, "Permission denied."):
         handler.delete({"id": zone.id})
Пример #26
0
 def test_DELETE_removes_zone(self):
     self.become_admin()
     zone = factory.make_Zone()
     response = self.client.delete(get_zone_uri(zone))
     self.assertEqual(http.client.NO_CONTENT, response.status_code)
     self.assertIsNone(reload_object(zone))
Пример #27
0
def populate_main():
    """Populate the main data all in one transaction."""
    admin = factory.make_admin(username="******",
                               password="******",
                               completed_intro=False)  # noqa
    user1, _ = factory.make_user_with_keys(username="******",
                                           password="******",
                                           completed_intro=False)
    user2, _ = factory.make_user_with_keys(username="******",
                                           password="******",
                                           completed_intro=False)

    # Physical zones.
    zones = [
        factory.make_Zone(name="zone-north"),
        factory.make_Zone(name="zone-south"),
    ]

    # DNS domains.
    domains = [
        Domain.objects.get_default_domain(),
        factory.make_Domain("sample"),
        factory.make_Domain("ubnt"),
    ]

    # Create the fabrics that will be used by the regions, racks,
    # machines, and devices.
    fabric0 = Fabric.objects.get_default_fabric()
    fabric0_untagged = fabric0.get_default_vlan()
    fabric0_vlan10 = factory.make_VLAN(fabric=fabric0, vid=10)
    fabric1 = factory.make_Fabric()
    fabric1_untagged = fabric1.get_default_vlan()
    fabric1_vlan42 = factory.make_VLAN(fabric=fabric1, vid=42)
    empty_fabric = factory.make_Fabric()  # noqa

    # Create some spaces.
    space_mgmt = factory.make_Space("management")
    space_storage = factory.make_Space("storage")
    space_internal = factory.make_Space("internal")
    space_ipv6_testbed = factory.make_Space("ipv6-testbed")

    # Subnets used by regions, racks, machines, and devices.
    subnet_1 = factory.make_Subnet(
        cidr="172.16.1.0/24",
        gateway_ip="172.16.1.1",
        vlan=fabric0_untagged,
        space=space_mgmt,
    )
    subnet_2 = factory.make_Subnet(
        cidr="172.16.2.0/24",
        gateway_ip="172.16.2.1",
        vlan=fabric1_untagged,
        space=space_mgmt,
    )
    subnet_3 = factory.make_Subnet(
        cidr="172.16.3.0/24",
        gateway_ip="172.16.3.1",
        vlan=fabric0_vlan10,
        space=space_storage,
    )
    subnet_4 = factory.make_Subnet(  # noqa
        cidr="172.16.4.0/24",
        gateway_ip="172.16.4.1",
        vlan=fabric0_vlan10,
        space=space_internal,
    )
    subnet_2001_db8_42 = factory.make_Subnet(  # noqa
        cidr="2001:db8:42::/64",
        gateway_ip="",
        vlan=fabric1_vlan42,
        space=space_ipv6_testbed,
    )
    ipv4_subnets = [subnet_1, subnet_2, subnet_3, subnet_4]

    # Static routes on subnets.
    factory.make_StaticRoute(source=subnet_1, destination=subnet_2)
    factory.make_StaticRoute(source=subnet_1, destination=subnet_3)
    factory.make_StaticRoute(source=subnet_1, destination=subnet_4)
    factory.make_StaticRoute(source=subnet_2, destination=subnet_1)
    factory.make_StaticRoute(source=subnet_2, destination=subnet_3)
    factory.make_StaticRoute(source=subnet_2, destination=subnet_4)
    factory.make_StaticRoute(source=subnet_3, destination=subnet_1)
    factory.make_StaticRoute(source=subnet_3, destination=subnet_2)
    factory.make_StaticRoute(source=subnet_3, destination=subnet_4)
    factory.make_StaticRoute(source=subnet_4, destination=subnet_1)
    factory.make_StaticRoute(source=subnet_4, destination=subnet_2)
    factory.make_StaticRoute(source=subnet_4, destination=subnet_3)

    # Load builtin scripts in the database so we can generate fake results
    # below.
    load_builtin_scripts()

    hostname = gethostname()
    region_rack = get_one(
        Node.objects.filter(node_type=NODE_TYPE.REGION_AND_RACK_CONTROLLER,
                            hostname=hostname))
    # If "make run" executes before "make sampledata", the rack may have
    # already registered.
    if region_rack is None:
        region_rack = factory.make_Node(
            node_type=NODE_TYPE.REGION_AND_RACK_CONTROLLER,
            hostname=hostname,
            interface=False,
        )

        # Get list of mac addresses that should be used for the region
        # rack controller. This will make sure the RegionAdvertisingService
        # picks the correct region on first start-up and doesn't get multiple.
        mac_addresses = get_mac_addresses()

        def get_next_mac():
            try:
                return mac_addresses.pop()
            except IndexError:
                return factory.make_mac_address()

        # Region and rack controller (hostname of dev machine)
        #   eth0     - fabric 0 - untagged
        #   eth1     - fabric 0 - untagged
        #   eth2     - fabric 1 - untagged - 172.16.2.2/24 - static
        #   bond0    - fabric 0 - untagged - 172.16.1.2/24 - static
        #   bond0.10 - fabric 0 - 10       - 172.16.3.2/24 - static
        eth0 = factory.make_Interface(
            INTERFACE_TYPE.PHYSICAL,
            name="eth0",
            node=region_rack,
            vlan=fabric0_untagged,
            mac_address=get_next_mac(),
        )
        eth1 = factory.make_Interface(
            INTERFACE_TYPE.PHYSICAL,
            name="eth1",
            node=region_rack,
            vlan=fabric0_untagged,
            mac_address=get_next_mac(),
        )
        eth2 = factory.make_Interface(
            INTERFACE_TYPE.PHYSICAL,
            name="eth2",
            node=region_rack,
            vlan=fabric1_untagged,
            mac_address=get_next_mac(),
        )
        bond0 = factory.make_Interface(
            INTERFACE_TYPE.BOND,
            name="bond0",
            node=region_rack,
            vlan=fabric0_untagged,
            parents=[eth0, eth1],
            mac_address=eth0.mac_address,
        )
        bond0_10 = factory.make_Interface(
            INTERFACE_TYPE.VLAN,
            node=region_rack,
            vlan=fabric0_vlan10,
            parents=[bond0],
        )
        factory.make_StaticIPAddress(
            alloc_type=IPADDRESS_TYPE.STICKY,
            ip="172.16.1.2",
            subnet=subnet_1,
            interface=bond0,
        )
        factory.make_StaticIPAddress(
            alloc_type=IPADDRESS_TYPE.STICKY,
            ip="172.16.2.2",
            subnet=subnet_2,
            interface=eth2,
        )
        factory.make_StaticIPAddress(
            alloc_type=IPADDRESS_TYPE.STICKY,
            ip="172.16.3.2",
            subnet=subnet_3,
            interface=bond0_10,
        )
        fabric0_untagged.primary_rack = region_rack
        fabric0_untagged.save()
        fabric1_untagged.primary_rack = region_rack
        fabric1_untagged.save()
        fabric0_vlan10.primary_rack = region_rack
        fabric0_vlan10.save()

    # Rack controller (happy-rack)
    #   eth0     - fabric 0 - untagged
    #   eth1     - fabric 0 - untagged
    #   eth2     - fabric 1 - untagged - 172.16.2.3/24 - static
    #   bond0    - fabric 0 - untagged - 172.16.1.3/24 - static
    #   bond0.10 - fabric 0 - 10       - 172.16.3.3/24 - static
    rack = factory.make_Node(
        node_type=NODE_TYPE.RACK_CONTROLLER,
        hostname="happy-rack",
        interface=False,
    )
    eth0 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL,
                                  name="eth0",
                                  node=rack,
                                  vlan=fabric0_untagged)
    eth1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL,
                                  name="eth1",
                                  node=rack,
                                  vlan=fabric0_untagged)
    eth2 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL,
                                  name="eth2",
                                  node=rack,
                                  vlan=fabric1_untagged)
    bond0 = factory.make_Interface(
        INTERFACE_TYPE.BOND,
        name="bond0",
        node=rack,
        vlan=fabric0_untagged,
        parents=[eth0, eth1],
    )
    bond0_10 = factory.make_Interface(INTERFACE_TYPE.VLAN,
                                      node=rack,
                                      vlan=fabric0_vlan10,
                                      parents=[bond0])
    factory.make_StaticIPAddress(
        alloc_type=IPADDRESS_TYPE.STICKY,
        ip="172.16.1.3",
        subnet=subnet_1,
        interface=bond0,
    )
    factory.make_StaticIPAddress(
        alloc_type=IPADDRESS_TYPE.STICKY,
        ip="172.16.2.3",
        subnet=subnet_2,
        interface=eth2,
    )
    factory.make_StaticIPAddress(
        alloc_type=IPADDRESS_TYPE.STICKY,
        ip="172.16.3.3",
        subnet=subnet_3,
        interface=bond0_10,
    )
    fabric0_untagged.secondary_rack = rack
    fabric0_untagged.save()
    fabric1_untagged.secondary_rack = rack
    fabric1_untagged.save()
    fabric0_vlan10.secondary_rack = rack
    fabric0_vlan10.save()

    # Region controller (happy-region)
    #   eth0     - fabric 0 - untagged
    #   eth1     - fabric 0 - untagged
    #   eth2     - fabric 1 - untagged - 172.16.2.4/24 - static
    #   bond0    - fabric 0 - untagged - 172.16.1.4/24 - static
    #   bond0.10 - fabric 0 - 10       - 172.16.3.4/24 - static
    region = factory.make_Node(
        node_type=NODE_TYPE.REGION_CONTROLLER,
        hostname="happy-region",
        interface=False,
    )
    eth0 = factory.make_Interface(
        INTERFACE_TYPE.PHYSICAL,
        name="eth0",
        node=region,
        vlan=fabric0_untagged,
    )
    eth1 = factory.make_Interface(
        INTERFACE_TYPE.PHYSICAL,
        name="eth1",
        node=region,
        vlan=fabric0_untagged,
    )
    eth2 = factory.make_Interface(
        INTERFACE_TYPE.PHYSICAL,
        name="eth2",
        node=region,
        vlan=fabric1_untagged,
    )
    bond0 = factory.make_Interface(
        INTERFACE_TYPE.BOND,
        name="bond0",
        node=region,
        vlan=fabric0_untagged,
        parents=[eth0, eth1],
    )
    bond0_10 = factory.make_Interface(INTERFACE_TYPE.VLAN,
                                      node=region,
                                      vlan=fabric0_vlan10,
                                      parents=[bond0])
    factory.make_StaticIPAddress(
        alloc_type=IPADDRESS_TYPE.STICKY,
        ip="172.16.1.4",
        subnet=subnet_1,
        interface=bond0,
    )
    factory.make_StaticIPAddress(
        alloc_type=IPADDRESS_TYPE.STICKY,
        ip="172.16.2.4",
        subnet=subnet_2,
        interface=eth2,
    )
    factory.make_StaticIPAddress(
        alloc_type=IPADDRESS_TYPE.STICKY,
        ip="172.16.3.4",
        subnet=subnet_3,
        interface=bond0_10,
    )

    # Create one machine for every status. Each machine has a random interface
    # and storage configration.
    node_statuses = [
        status for status in map_enum(NODE_STATUS).items() if status not in
        [NODE_STATUS.MISSING, NODE_STATUS.RESERVED, NODE_STATUS.RETIRED]
    ]
    machines = []
    test_scripts = [
        script.name
        for script in Script.objects.filter(script_type=SCRIPT_TYPE.TESTING)
    ]
    for _, status in node_statuses:
        owner = None
        if status in ALLOCATED_NODE_STATUSES:
            owner = random.choice([admin, user1, user2])
        elif status in [
                NODE_STATUS.COMMISSIONING,
                NODE_STATUS.FAILED_RELEASING,
        ]:
            owner = admin

        machine = factory.make_Node(
            status=status,
            owner=owner,
            zone=random.choice(zones),
            interface=False,
            with_boot_disk=False,
            power_type="manual",
            domain=random.choice(domains),
            memory=random.choice([1024, 4096, 8192]),
            description=random.choice([
                "",
                "Scheduled for removeal",
                "Firmware old",
                "Earmarked for Project Fuse in April",
            ]),
            cpu_count=random.randint(2, 8),
        )
        machine.set_random_hostname()
        machines.append(machine)

        # Create random network configuration.
        RandomInterfaceFactory.create_random(machine)

        # Add random storage devices and set a random layout.
        for _ in range(random.randint(1, 5)):
            factory.make_PhysicalBlockDevice(
                node=machine,
                size=random.randint(LARGE_BLOCK_DEVICE,
                                    LARGE_BLOCK_DEVICE * 10),
            )
        if status in [
                NODE_STATUS.READY,
                NODE_STATUS.ALLOCATED,
                NODE_STATUS.DEPLOYING,
                NODE_STATUS.DEPLOYED,
                NODE_STATUS.FAILED_DEPLOYMENT,
                NODE_STATUS.RELEASING,
                NODE_STATUS.FAILED_RELEASING,
        ]:
            machine.set_storage_layout(
                random.choice([
                    layout for layout in STORAGE_LAYOUTS.keys()
                    if layout != "vmfs6"
                ]))
            if status != NODE_STATUS.READY:
                machine._create_acquired_filesystems()

        # Add a random amount of events.
        for _ in range(random.randint(25, 100)):
            factory.make_Event(node=machine)

        # Add in commissioning and testing results.
        if status != NODE_STATUS.NEW:
            for _ in range(0, random.randint(1, 10)):
                css = ScriptSet.objects.create_commissioning_script_set(
                    machine)
                scripts = set()
                for __ in range(1, len(test_scripts)):
                    scripts.add(random.choice(test_scripts))
                tss = ScriptSet.objects.create_testing_script_set(
                    machine, list(scripts))
            machine.current_commissioning_script_set = css
            machine.current_testing_script_set = tss
            machine.save()

        # Fill in historic results
        for script_set in machine.scriptset_set.all():
            if script_set in [css, tss]:
                continue
            for script_result in script_set:
                # Can't use script_result.store_result as it will try to
                # process the result and fail on the fake data.
                script_result.exit_status = random.randint(0, 255)
                if script_result.exit_status == 0:
                    script_result.status = SCRIPT_STATUS.PASSED
                else:
                    script_result.status = random.choice(
                        list(SCRIPT_STATUS_FAILED))
                script_result.started = factory.make_date()
                script_result.ended = script_result.started + timedelta(
                    seconds=random.randint(0, 10000))
                script_result.stdout = Bin(
                    factory.make_string().encode("utf-8"))
                script_result.stderr = Bin(
                    factory.make_string().encode("utf-8"))
                script_result.output = Bin(
                    factory.make_string().encode("utf-8"))
                script_result.save()

        # Only add in results in states where commissiong should be completed.
        if status not in [NODE_STATUS.NEW, NODE_STATUS.COMMISSIONING]:
            if status == NODE_STATUS.FAILED_COMMISSIONING:
                exit_status = random.randint(1, 255)
                script_status = random.choice(list(SCRIPT_STATUS_FAILED))
            else:
                exit_status = 0
                script_status = SCRIPT_STATUS.PASSED
            for script_result in css:
                # Can't use script_result.store_result as it will try to
                # process the result and fail on the fake data.
                script_result.status = script_status
                script_result.exit_status = exit_status
                script_result.started = factory.make_date()
                script_result.ended = script_result.started + timedelta(
                    seconds=random.randint(0, 10000))
                script_result.stdout = Bin(
                    factory.make_string().encode("utf-8"))
                script_result.stderr = Bin(
                    factory.make_string().encode("utf-8"))
                script_result.output = Bin(
                    factory.make_string().encode("utf-8"))
                script_result.save()
        elif status == NODE_STATUS.COMMISSIONING:
            for script_result in css:
                script_result.status = random.choice(
                    list(SCRIPT_STATUS_RUNNING_OR_PENDING))
                if script_result.status != SCRIPT_STATUS.PENDING:
                    script_result.started = factory.make_date()
                script_result.save()

        # Only add in results in states where testing should be completed.
        if status not in [NODE_STATUS.NEW, NODE_STATUS.TESTING]:
            if status == NODE_STATUS.FAILED_TESTING:
                exit_status = random.randint(1, 255)
                script_status = random.choice(list(SCRIPT_STATUS_FAILED))
            else:
                exit_status = 0
                script_status = SCRIPT_STATUS.PASSED
            for script_result in tss:
                # Can't use script_result.store_result as it will try to
                # process the result and fail on the fake data.
                script_result.status = script_status
                script_result.exit_status = exit_status
                script_result.started = factory.make_date()
                script_result.ended = script_result.started + timedelta(
                    seconds=random.randint(0, 10000))
                script_result.stdout = Bin(
                    factory.make_string().encode("utf-8"))
                script_result.stderr = Bin(
                    factory.make_string().encode("utf-8"))
                script_result.output = Bin(
                    factory.make_string().encode("utf-8"))
                script_result.save()
        elif status == NODE_STATUS.TESTING:
            for script_result in tss:
                script_result.status = random.choice(
                    list(SCRIPT_STATUS_RUNNING_OR_PENDING))
                if script_result.status != SCRIPT_STATUS.PENDING:
                    script_result.started = factory.make_date()
                script_result.save()

        # Add installation results.
        if status in [
                NODE_STATUS.DEPLOYING,
                NODE_STATUS.DEPLOYED,
                NODE_STATUS.FAILED_DEPLOYMENT,
        ]:
            script_set = ScriptSet.objects.create_installation_script_set(
                machine)
            machine.current_installation_script_set = script_set
            machine.save()

        if status == NODE_STATUS.DEPLOYED:
            for script_result in machine.current_installation_script_set:
                stdout = factory.make_string().encode("utf-8")
                script_result.store_result(0, stdout)
        elif status == NODE_STATUS.FAILED_DEPLOYMENT:
            for script_result in machine.current_installation_script_set:
                exit_status = random.randint(1, 255)
                stdout = factory.make_string().encode("utf-8")
                stderr = factory.make_string().encode("utf-8")
                script_result.store_result(exit_status, stdout, stderr)

        # Add children devices to the deployed machine.
        if status == NODE_STATUS.DEPLOYED:
            boot_interface = machine.get_boot_interface()
            for _ in range(5):
                device = factory.make_Device(
                    interface=True,
                    domain=machine.domain,
                    parent=machine,
                    vlan=boot_interface.vlan,
                )
                device.set_random_hostname()
                RandomInterfaceFactory.assign_ip(
                    device.get_boot_interface(),
                    alloc_type=IPADDRESS_TYPE.STICKY,
                )

    # Create a few pods to and assign a random set of the machines to the pods.
    pods = [None]
    pod_storage_pools = defaultdict(list)
    machines_in_pods = defaultdict(list)
    for _ in range(3):
        subnet = random.choice(ipv4_subnets)
        ip = factory.pick_ip_in_Subnet(subnet)
        ip_address = factory.make_StaticIPAddress(
            alloc_type=IPADDRESS_TYPE.STICKY, ip=ip, subnet=subnet)
        power_address = "qemu+ssh://ubuntu@%s/system" % ip
        pod = factory.make_Pod(
            pod_type="virsh",
            parameters={"power_address": power_address},
            ip_address=ip_address,
            capabilities=[
                Capabilities.DYNAMIC_LOCAL_STORAGE,
                Capabilities.COMPOSABLE,
            ],
        )
        for _ in range(3):
            pool = factory.make_PodStoragePool(pod)
            pod_storage_pools[pod].append(pool)
        pod.default_storage_pool = pool
        pod.save()
        pods.append(pod)
    for _ in range(3):
        subnet = random.choice(ipv4_subnets)
        ip = factory.pick_ip_in_Subnet(subnet)
        ip_address = factory.make_StaticIPAddress(
            alloc_type=IPADDRESS_TYPE.STICKY, ip=ip, subnet=subnet)
        power_address = "%s" % ip
        pod = factory.make_Pod(
            pod_type="rsd",
            parameters={
                "power_address": power_address,
                "power_user": "******",
                "power_pass": "******",
            },
            ip_address=ip_address,
            capabilities=[
                Capabilities.DYNAMIC_LOCAL_STORAGE,
                Capabilities.COMPOSABLE,
            ],
        )
        for _ in range(3):
            pool = factory.make_PodStoragePool(pod)
            pod_storage_pools[pod].append(pool)
        pod.default_storage_pool = pool
        pod.save()
        pods.append(pod)
    for machine in machines:
        # Add the machine to the pod if its lucky day!
        pod = random.choice(pods)
        if pod is not None:
            machine.bmc = pod
            machine.instance_power_parameters = {"power_id": machine.hostname}
            machine.save()
            machines_in_pods[pod].append(machine)

            # Assign the block devices on the machine to a storage pool.
            for block_device in machine.physicalblockdevice_set.all():
                block_device.storage_pool = random.choice(
                    pod_storage_pools[pod])
                block_device.save()

    # Update the pod attributes so that it has more available then used.
    for pod in pods[1:]:
        pod.cores = pod.get_used_cores() + random.randint(4, 8)
        pod.memory = pod.get_used_memory() + random.choice(
            [1024, 2048, 4096, 4096 * 4, 4096 * 8])
        pod.local_storage = sum(pool.storage
                                for pool in pod_storage_pools[pod])
        pod.save()

    # Create a few devices.
    for _ in range(10):
        device = factory.make_Device(interface=True)
        device.set_random_hostname()

    # Add some DHCP snippets.
    # - Global
    factory.make_DHCPSnippet(
        name="foo class",
        description="adds class for vender 'foo'",
        value=VersionedTextFile.objects.create(data=dedent("""\
            class "foo" {
                match if substring (
                    option vendor-class-identifier, 0, 3) = "foo";
            }
        """)),
    )
    factory.make_DHCPSnippet(
        name="bar class",
        description="adds class for vender 'bar'",
        value=VersionedTextFile.objects.create(data=dedent("""\
            class "bar" {
                match if substring (
                    option vendor-class-identifier, 0, 3) = "bar";
            }
        """)),
        enabled=False,
    )
    # - Subnet
    factory.make_DHCPSnippet(
        name="600 lease time",
        description="changes lease time to 600 secs.",
        value=VersionedTextFile.objects.create(data="default-lease-time 600;"),
        subnet=subnet_1,
    )
    factory.make_DHCPSnippet(
        name="7200 max lease time",
        description="changes max lease time to 7200 secs.",
        value=VersionedTextFile.objects.create(data="max-lease-time 7200;"),
        subnet=subnet_2,
        enabled=False,
    )
    # - Node
    factory.make_DHCPSnippet(
        name="boot from other server",
        description="instructs device to boot from other server",
        value=VersionedTextFile.objects.create(data=dedent("""\
            filename "test-boot";
            server-name "boot.from.me";
        """)),
        node=device,
    )

    # Add notifications for admins, users, and each individual user, and for
    # each notification category.
    factory.make_Notification(
        "Attention admins! Core critical! Meltdown imminent! Evacuate "
        "habitat immediately!",
        admins=True,
        category="error",
    )
    factory.make_Notification(
        "Dear users, rumours of a core meltdown are unfounded. Please "
        "return to your home-pods and places of business.",
        users=True,
        category="warning",
    )
    factory.make_Notification(
        "FREE! For the next 2 hours get FREE blueberry and iodine pellets "
        "at the nutri-dispensers.",
        users=True,
        category="success",
    )
    for user in User.objects.all():
        context = {"name": user.username.capitalize()}
        factory.make_Notification(
            "Greetings, {name}! Get away from the habitat for the weekend and "
            "visit the Mare Nubium with MAAS Tours. Use the code METAL to "
            "claim a special gift!",
            user=user,
            context=context,
            category="info",
        )
Пример #28
0
 def test_DELETE_requires_admin(self):
     zone = factory.make_Zone()
     response = self.client.delete(get_zone_uri(zone))
     self.assertEqual(http.client.FORBIDDEN, response.status_code)
Пример #29
0
 def create_zone(self, params=None):
     if params is None:
         params = {}
     return factory.make_Zone(**params)
Пример #30
0
 def test_make_Zone_returns_unique_zone(self):
     self.assertNotEqual(factory.make_Zone(), factory.make_Zone())