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)
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)
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], )
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)))
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)
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)
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, }
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 }
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)
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))
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)
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)
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)
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)
def test_is_default_returns_False_for_normal_zone(self): self.assertFalse(factory.make_Zone().is_default())
def test_delete_deletes_zone(self): zone = factory.make_Zone() zone.delete() self.assertIsNone(reload_object(zone))
def test_get_default_zone_ignores_other_zones(self): factory.make_Zone() self.assertEqual( DEFAULT_ZONE_NAME, Zone.objects.get_default_zone().name )
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)
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)
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))
def test_make_Zone_returns_physical_zone(self): self.assertIsNotNone(factory.make_Zone())
def test_make_Zone_assigns_name(self): name = factory.make_Zone().name self.assertIsNotNone(name) self.assertNotEqual(0, len(name))
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)
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)
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})
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))
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", )
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)
def create_zone(self, params=None): if params is None: params = {} return factory.make_Zone(**params)
def test_make_Zone_returns_unique_zone(self): self.assertNotEqual(factory.make_Zone(), factory.make_Zone())