def test_not_enabled_if_not_broken(self): status = factory.pick_choice( NODE_STATUS_CHOICES, but_not=[NODE_STATUS.BROKEN]) node = factory.make_Node(status=status) actions = compile_node_actions( node, factory.make_admin(), classes=[MarkFixed]) self.assertEqual({}, actions)
def test_compile_node_actions_returns_available_actions(self): class MyAction(FakeNodeAction): display = factory.getRandomString() actions = compile_node_actions( factory.make_node(), factory.make_admin(), classes=[MyAction]) self.assertEqual([MyAction.display], actions.keys())
def test_compile_node_actions_includes_inhibited_actions(self): class MyAction(FakeNodeAction): fake_inhibition = factory.getRandomString() actions = compile_node_actions( factory.make_node(), factory.make_admin(), classes=[MyAction]) self.assertEqual([MyAction.display], actions.keys())
def test_compile_node_actions_returns_available_actions(self): class MyAction(FakeNodeAction): name = factory.make_string() actions = compile_node_actions(factory.make_Node(), factory.make_admin(), classes=[MyAction]) self.assertEqual([MyAction.name], list(actions.keys()))
def clean(self): actions = compile_node_actions(self.instance, self.user) action = actions.get(self._name) if action is None: raise ValidationError( "%s is not available because of the current state of the node." % self._display) return super().clean()
def test_compile_node_actions_includes_inhibited_actions(self): class MyAction(FakeNodeAction): fake_inhibition = factory.make_string() actions = compile_node_actions(factory.make_Node(), factory.make_admin(), classes=[MyAction]) self.assertEqual([MyAction.name], list(actions.keys()))
def test_compile_node_actions_checks_node_status(self): class MyAction(FakeNodeAction): actionable_statuses = (NODE_STATUS.READY, ) node = factory.make_Node(status=NODE_STATUS.NEW) actions = compile_node_actions(node, factory.make_admin(), classes=[MyAction]) self.assertEqual({}, actions)
def test_compile_node_actions_checks_permission(self): class MyAction(FakeNodeAction): permission = NODE_PERMISSION.EDIT node = factory.make_node(status=NODE_STATUS.COMMISSIONING) actions = compile_node_actions( node, factory.make_user(), classes=[MyAction]) self.assertEqual({}, actions)
def test_compile_node_actions_checks_node_status(self): class MyAction(FakeNodeAction): actionable_statuses = (NODE_STATUS.READY, ) node = factory.make_node(status=NODE_STATUS.DECLARED) actions = compile_node_actions( node, factory.make_admin(), classes=[MyAction]) self.assertEqual({}, actions)
def test_compile_node_actions_checks_permission(self): class MyAction(FakeNodeAction): permission = NODE_PERMISSION.EDIT node = factory.make_Node(status=NODE_STATUS.COMMISSIONING) actions = compile_node_actions(node, factory.make_User(), classes=[MyAction]) self.assertEqual({}, actions)
def test_compile_node_actions_maintains_order(self): names = [factory.make_string() for counter in range(4)] classes = [ type("Action%d" % counter, (FakeNodeAction,), {'name': name}) for counter, name in enumerate(names)] actions = compile_node_actions( factory.make_Node(), factory.make_admin(), classes=classes) self.assertSequenceEqual(names, list(actions.keys())) self.assertSequenceEqual( names, [action.name for action in list(actions.values())])
def test_compile_node_actions_maintains_order(self): labels = [factory.getRandomString() for counter in range(4)] classes = [ type(b"Action%d" % counter, (FakeNodeAction,), {'display': label}) for counter, label in enumerate(labels)] actions = compile_node_actions( factory.make_node(), factory.make_admin(), classes=classes) self.assertSequenceEqual(labels, actions.keys()) self.assertSequenceEqual( labels, [action.display for action in actions.values()])
def test_compile_node_actions_maintains_order(self): names = [factory.getRandomString() for counter in range(4)] classes = [ type(b"Action%d" % counter, (FakeNodeAction,), {'name': name}) for counter, name in enumerate(names)] actions = compile_node_actions( factory.make_node(), factory.make_admin(), classes=classes) self.assertSequenceEqual(names, actions.keys()) self.assertSequenceEqual( names, [action.name for action in actions.values()])
def action(self, params): """Perform the action on the object.""" obj = self.get_object(params) action_name = params.get("action") actions = compile_node_actions(obj, self.user, request=self.request) action = actions.get(action_name) if action is None: raise NodeActionError("%s action is not available for this node." % action_name) extra_params = params.get("extra", {}) return action.execute(**extra_params)
def test_compile_node_actions_maps_names(self): class Action1(FakeNodeAction): name = factory.make_string() class Action2(FakeNodeAction): name = factory.make_string() actions = compile_node_actions(factory.make_Node(), factory.make_admin(), classes=[Action1, Action2]) for name, action in actions.items(): self.assertEqual(name, action.name)
def test__non_actionable_for_monitored_states(self): all_statuses = MONITORED_STATUSES results = {} for status in all_statuses: node = factory.make_Node( status=status, power_type='ipmi', power_state=POWER_STATE.ON) actions = compile_node_actions( node, factory.make_admin(), classes=[PowerOff]) results[status] = list(actions.keys()) expected_results = {status: [] for status in all_statuses} self.assertEqual( expected_results, results, "Nodes with certain statuses could be powered off.")
def test__non_actionable_if_node_already_off(self): all_statuses = NON_MONITORED_STATUSES results = {} for status in all_statuses: node = factory.make_Node( status=status, power_type='ipmi', power_state=POWER_STATE.OFF) actions = compile_node_actions( node, factory.make_admin(), classes=[PowerOff]) results[status] = list(actions.keys()) expected_results = {status: [] for status in all_statuses} self.assertEqual( expected_results, results, "Nodes already powered off can be powered off.")
def test_compile_node_actions_maps_display_names(self): class Action1(FakeNodeAction): display = factory.getRandomString() class Action2(FakeNodeAction): display = factory.getRandomString() actions = compile_node_actions( factory.make_node(), factory.make_admin(), classes=[Action1, Action2]) for label, action in actions.items(): self.assertEqual(label, action.display)
def action(self, params): """Perform the action on the object.""" # `compile_node_actions` handles the permission checking internally # the default view permission check is enough at this level. obj = self.get_object(params) action_name = params.get("action") actions = compile_node_actions(obj, self.user, request=self.request) action = actions.get(action_name) if action is None: raise NodeActionError( "%s action is not available for this node." % action_name) extra_params = params.get("extra", {}) return action.execute(**extra_params)
def __init__(self, instance, *args, **kwargs): super(NodeActionForm, self).__init__(*args, **kwargs) self.node = instance self.actions = compile_node_actions(instance, self.user, self.request) self.action_buttons = self.actions.values()
def dehydrate(self, obj, data, for_list=False): """Add extra fields to `data`.""" data["fqdn"] = obj.fqdn data["actions"] = list(compile_node_actions(obj, self.user).keys()) data["node_type_display"] = obj.get_node_type_display() data["link_type"] = NODE_TYPE_TO_LINK_TYPE[obj.node_type] data["tags"] = [tag.name for tag in obj.tags.all()] if obj.node_type == NODE_TYPE.MACHINE or ( obj.is_controller and not for_list ): # Disk count and storage amount is shown on the machine listing # page and the machine and controllers details page. blockdevices = self.get_blockdevices_for(obj) physical_blockdevices = [ blockdevice for blockdevice in blockdevices if isinstance(blockdevice, PhysicalBlockDevice) ] data["physical_disk_count"] = len(physical_blockdevices) data["storage"] = round( sum(blockdevice.size for blockdevice in physical_blockdevices) / (1000 ** 3), 1, ) data["storage_tags"] = self.get_all_storage_tags(blockdevices) commissioning_script_results = [] testing_script_results = [] log_results = set() for hw_type in self._script_results.get(obj.id, {}).values(): for script_result in hw_type: if ( script_result.script_set.result_type == RESULT_TYPE.INSTALLATION ): # Don't include installation results in the health # status. continue elif script_result.status == SCRIPT_STATUS.ABORTED: # LP: #1724235 - Ignore aborted scripts. continue elif ( script_result.script_set.result_type == RESULT_TYPE.COMMISSIONING ): commissioning_script_results.append(script_result) if ( script_result.name in script_output_nsmap and script_result.status == SCRIPT_STATUS.PASSED ): log_results.add(script_result.name) elif ( script_result.script_set.result_type == RESULT_TYPE.TESTING ): testing_script_results.append(script_result) data["commissioning_status"] = self.dehydrate_test_statuses( commissioning_script_results ) data["testing_status"] = self.dehydrate_test_statuses( testing_script_results ) data["has_logs"] = ( log_results.difference(script_output_nsmap.keys()) == set() ) else: blockdevices = [] if obj.node_type != NODE_TYPE.DEVICE: # These values are not defined on a device. data["architecture"] = obj.architecture data["osystem"] = obj.osystem data["distro_series"] = obj.distro_series data["memory"] = obj.display_memory() data["status"] = obj.display_status() data["description"] = obj.description data["status_code"] = obj.status if for_list: for attr in ("numa_nodes_count", "sriov_support"): value = getattr(obj, attr, None) if value is not None: data[attr] = value # Filters are only available on machines and devices. if not obj.is_controller: # For filters subnets = self.get_all_subnets(obj) data["subnets"] = [subnet.cidr for subnet in subnets] data["fabrics"] = self.get_all_fabric_names(obj, subnets) data["spaces"] = self.get_all_space_names(subnets) data["extra_macs"] = [ "%s" % mac_address for mac_address in obj.get_extra_macs() ] data["link_speeds"] = sorted( set( [ interface.link_speed for interface in obj.interface_set.all() if interface.link_speed > 0 ] ) ) if not for_list: data["on_network"] = obj.on_network() if obj.node_type != NODE_TYPE.DEVICE: data["numa_nodes"] = [ self.dehydrate_numanode(numa_node) for numa_node in obj.numanode_set.all().order_by("index") ] # XXX lamont 2017-02-15 Much of this should be split out into # individual methods, rather than having this huge block of # dense code here. # Status of the commissioning, testing, and logs tabs data["metadata"] = { metadata.key: metadata.value for metadata in obj.nodemetadata_set.all() } # Network data["interfaces"] = [ self.dehydrate_interface(interface, obj) for interface in obj.interface_set.all().order_by("name") ] data["dhcp_on"] = self.get_providing_dhcp(obj) data["hwe_kernel"] = make_hwe_kernel_ui_text(obj.hwe_kernel) data["power_type"] = obj.power_type data["power_parameters"] = self.dehydrate_power_parameters( obj.power_parameters ) data["power_bmc_node_count"] = ( obj.bmc.node_set.count() if (obj.bmc is not None) else 0 ) # Storage data["disks"] = sorted( chain( ( self.dehydrate_blockdevice(blockdevice, obj) for blockdevice in blockdevices ), ( self.dehydrate_volume_group(volume_group) for volume_group in VolumeGroup.objects.filter_by_node( obj ) ), ( self.dehydrate_cache_set(cache_set) for cache_set in CacheSet.objects.get_cache_sets_for_node( obj ) ), ), key=itemgetter("name"), ) data["supported_filesystems"] = [ {"key": key, "ui": ui} for key, ui in FILESYSTEM_FORMAT_TYPE_CHOICES ] data["storage_layout_issues"] = obj.storage_layout_issues() data["special_filesystems"] = [ self.dehydrate_filesystem(filesystem) for filesystem in obj.get_effective_special_filesystems() ] data["grouped_storages"] = self.get_grouped_storages( physical_blockdevices ) ( layout_bd, detected_layout, ) = get_applied_storage_layout_for_node(obj) data["detected_storage_layout"] = detected_layout # The UI knows that a partition is in use when it has a mounted # partition. VMware ESXi does not directly mount the partitions # used. As MAAS can't model that inject a place holder so the # UI knows that these partitions are in use. if detected_layout == "vmfs6": for disk in data["disks"]: if disk["id"] == layout_bd.id: for partition in disk["partitions"]: if partition["name"].endswith("-part3"): # Partition 3 is for the default datastore. # This partition may be modified by the # user. continue partition[ "used_for" ] = "VMware ESXi OS partition" partition["filesystem"] = { "id": -1, "label": "RESERVED", "mount_point": "RESERVED", "mount_options": None, "fstype": None, "is_format_fstype": False, } # Events data["events"] = self.dehydrate_events(obj) # Machine logs data["installation_status"] = self.dehydrate_script_set_status( obj.current_installation_script_set ) # Third party drivers if Config.objects.get_config("enable_third_party_drivers"): # Pull modaliases from the cache modaliases = [] for script_result in commissioning_script_results: if script_result.name == LIST_MODALIASES_OUTPUT_NAME: if script_result.status == SCRIPT_STATUS.PASSED: # STDOUT is deferred in the cache so load it. script_result = ( ScriptResult.objects.filter( id=script_result.id ) .only("id", "status", "stdout") .first() ) modaliases = script_result.stdout.decode( "utf-8" ).splitlines() driver = get_third_party_driver( obj, detected_aliases=modaliases, series=obj.distro_series, ) if "module" in driver and "comment" in driver: data["third_party_driver"] = { "module": driver["module"], "comment": driver["comment"], } return data
def dehydrate_device(self, node, user, for_list=False): boot_interface = node.get_boot_interface() subnets = set( ip_address.subnet for interface in node.interface_set.all() for ip_address in interface.ip_addresses.all() if ip_address.subnet is not None) space_names = set( subnet.space.name for subnet in subnets if subnet.space is not None) fabric_names = set( iface.vlan.fabric.name for iface in node.interface_set.all() if iface.vlan is not None) fabric_names.update({subnet.vlan.fabric.name for subnet in subnets}) boot_interface = node.get_boot_interface() data = { "actions": list(compile_node_actions(node, user).keys()), "bmc": node.bmc_id, "created": dehydrate_datetime(node.created), "domain": { "id": node.domain.id, "name": node.domain.name, }, "extra_macs": [ "%s" % mac_address.mac_address for mac_address in node.get_extra_macs() ], "fqdn": node.fqdn, "hostname": node.hostname, "node_type_display": node.get_node_type_display(), "id": node.id, "primary_mac": ( "" if boot_interface is None else "%s" % boot_interface.mac_address), "parent": ( node.parent.system_id if node.parent is not None else None), "ip_address": self.dehydrate_ip_address(node, boot_interface), "ip_assignment": self.dehydrate_ip_assignment( node, boot_interface), "interfaces": [ self.dehydrate_interface(interface, node) for interface in node.interface_set.all().order_by('name') ], "subnets": [subnet.cidr for subnet in subnets], "fabrics": list(fabric_names), "spaces": list(space_names), "on_network": node.on_network(), "owner": "" if node.owner is None else node.owner.username, "swap_size": node.swap_size, "system_id": node.system_id, "tags": [ tag.name for tag in node.tags.all() ], "node_type": node.node_type, "updated": dehydrate_datetime(node.updated), "zone": { "id": node.zone.id, "name": node.zone.name, }, } if for_list: allowed_fields = DeviceHandler.Meta.list_fields + [ "actions", "fqdn", "extra_macs", "tags", "primary_mac", "ip_address", "ip_assignment", "node_type_display", "subnets", "spaces", "fabrics", ] for key in list(data): if key not in allowed_fields: del data[key] return data
def dehydrate_device(self, node, user, for_list=False): boot_interface = node.get_boot_interface() subnets = set(ip_address.subnet for interface in node.interface_set.all() for ip_address in interface.ip_addresses.all() if ip_address.subnet is not None) space_names = set(subnet.space.name for subnet in subnets if subnet.space is not None) fabric_names = set(iface.vlan.fabric.name for iface in node.interface_set.all() if iface.vlan is not None) fabric_names.update({subnet.vlan.fabric.name for subnet in subnets}) boot_interface = node.get_boot_interface() permissions = [] if user.has_perm(NodePermission.edit, node): permissions = ["edit", "delete"] data = { "actions": list(compile_node_actions(node, user).keys()), "created": dehydrate_datetime(node.created), "domain": { "id": node.domain.id, "name": node.domain.name }, "extra_macs": [ "%s" % mac_address.mac_address for mac_address in node.get_extra_macs() ], "link_speeds": sorted( set([ interface.link_speed for interface in node.interface_set.all() if interface.link_speed > 0 ])), "fqdn": node.fqdn, "hostname": node.hostname, "description": node.description, "node_type_display": node.get_node_type_display(), "link_type": NODE_TYPE_TO_LINK_TYPE[node.node_type], "id": node.id, "primary_mac": ("" if boot_interface is None else "%s" % boot_interface.mac_address), "parent": (node.parent.system_id if node.parent is not None else None), "permissions": permissions, "ip_address": self.dehydrate_ip_address(node, boot_interface), "ip_assignment": self.dehydrate_ip_assignment(node, boot_interface), "interfaces": [ self.dehydrate_interface(interface, node) for interface in node.interface_set.all().order_by("name") ], "subnets": [subnet.cidr for subnet in subnets], "fabrics": list(fabric_names), "spaces": list(space_names), "on_network": node.on_network(), "owner": "" if node.owner is None else node.owner.username, "locked": node.locked, "swap_size": node.swap_size, "system_id": node.system_id, "tags": [tag.name for tag in node.tags.all()], "node_type": node.node_type, "updated": dehydrate_datetime(node.updated), "zone": { "id": node.zone.id, "name": node.zone.name }, "pool": None, } if for_list: allowed_fields = DeviceHandler.Meta.list_fields + [ "actions", "extra_macs", "fabrics", "fqdn", "installation_status", "ip_address", "ip_assignment", "link_type", "node_type_display", "permissions", "primary_mac", "spaces", "subnets", "link_speeds", "tags", "interface_speed", "link_connected", "link_speed", ] for key in list(data): if key not in allowed_fields: del data[key] return data
def test_delete_action_last_for_node(self): node = factory.make_Node() actions = compile_node_actions( node, factory.make_admin(), classes=ACTION_CLASSES) self.assertEqual('delete', list(actions)[-1])
def dehydrate(self, obj, data, for_list=False): """Add extra fields to `data`.""" data["fqdn"] = obj.fqdn data["actions"] = list(compile_node_actions(obj, self.user).keys()) data["node_type_display"] = obj.get_node_type_display() data["link_type"] = NODE_TYPE_TO_LINK_TYPE[obj.node_type] data["extra_macs"] = [ "%s" % mac_address for mac_address in obj.get_extra_macs() ] subnets = self.get_all_subnets(obj) data["subnets"] = [subnet.cidr for subnet in subnets] data["fabrics"] = self.get_all_fabric_names(obj, subnets) data["spaces"] = self.get_all_space_names(subnets) data["tags"] = [tag.name for tag in obj.tags.all()] data["metadata"] = { metadata.key: metadata.value for metadata in obj.nodemetadata_set.all() } if obj.node_type != NODE_TYPE.DEVICE: data["architecture"] = obj.architecture data["memory"] = obj.display_memory() data["status"] = obj.display_status() data["status_code"] = obj.status boot_interface = obj.get_boot_interface() if boot_interface is not None: data["pxe_mac"] = "%s" % boot_interface.mac_address data["pxe_mac_vendor"] = obj.get_pxe_mac_vendor() else: data["pxe_mac"] = data["pxe_mac_vendor"] = "" blockdevices = self.get_blockdevices_for(obj) physical_blockdevices = [ blockdevice for blockdevice in blockdevices if isinstance(blockdevice, PhysicalBlockDevice) ] data["physical_disk_count"] = len(physical_blockdevices) data["storage"] = "%3.1f" % ( sum(blockdevice.size for blockdevice in physical_blockdevices) / (1000**3)) data["storage_tags"] = self.get_all_storage_tags(blockdevices) data["grouped_storages"] = self.get_grouped_storages( physical_blockdevices) data["osystem"] = obj.get_osystem(default=self.default_osystem) data["distro_series"] = obj.get_distro_series( default=self.default_distro_series) data["dhcp_on"] = self.get_providing_dhcp(obj) if obj.node_type != NODE_TYPE.DEVICE: commissioning_script_results = [] testing_script_results = [] log_results = set() for hw_type in self._script_results.get(obj.id, {}).values(): for script_result in hw_type: if (script_result.script_set.result_type == RESULT_TYPE.INSTALLATION): # Don't include installation results in the health # status. continue elif script_result.status == SCRIPT_STATUS.ABORTED: # LP: #1724235 - Ignore aborted scripts. continue elif (script_result.script_set.result_type == RESULT_TYPE.COMMISSIONING): commissioning_script_results.append(script_result) if (script_result.name in script_output_nsmap and script_result.status == SCRIPT_STATUS.PASSED): log_results.add(script_result.name) elif (script_result.script_set.result_type == RESULT_TYPE.TESTING): testing_script_results.append(script_result) data["commissioning_script_count"] = len( commissioning_script_results) data["commissioning_status"] = get_status_from_qs( commissioning_script_results) data["commissioning_status_tooltip"] = ( self.dehydrate_hardware_status_tooltip( commissioning_script_results).replace( 'test', 'commissioning script')) data["testing_script_count"] = len(testing_script_results) data["testing_status"] = get_status_from_qs(testing_script_results) data["testing_status_tooltip"] = ( self.dehydrate_hardware_status_tooltip(testing_script_results)) data["has_logs"] = (log_results.difference( script_output_nsmap.keys()) == set()) if not for_list: data["on_network"] = obj.on_network() if obj.node_type != NODE_TYPE.DEVICE: # XXX lamont 2017-02-15 Much of this should be split out into # individual methods, rather than having this huge block of # dense code here. # Network data["interfaces"] = [ self.dehydrate_interface(interface, obj) for interface in obj.interface_set.all().order_by('name') ] data["hwe_kernel"] = make_hwe_kernel_ui_text(obj.hwe_kernel) data["power_type"] = obj.power_type data["power_parameters"] = self.dehydrate_power_parameters( obj.power_parameters) data["power_bmc_node_count"] = obj.bmc.node_set.count() if ( obj.bmc is not None) else 0 # Storage data["disks"] = sorted(chain( (self.dehydrate_blockdevice(blockdevice, obj) for blockdevice in blockdevices), (self.dehydrate_volume_group(volume_group) for volume_group in VolumeGroup.objects.filter_by_node(obj)), (self.dehydrate_cache_set(cache_set) for cache_set in CacheSet.objects.get_cache_sets_for_node(obj)), ), key=itemgetter("name")) data["supported_filesystems"] = [{ 'key': key, 'ui': ui } for key, ui in FILESYSTEM_FORMAT_TYPE_CHOICES] data["storage_layout_issues"] = obj.storage_layout_issues() data["special_filesystems"] = [ self.dehydrate_filesystem(filesystem) for filesystem in obj.special_filesystems.order_by("id") ] # Events data["events"] = self.dehydrate_events(obj) # Machine logs data["installation_status"] = self.dehydrate_script_set_status( obj.current_installation_script_set) # Third party drivers if Config.objects.get_config('enable_third_party_drivers'): driver = get_third_party_driver(obj) if "module" in driver and "comment" in driver: data["third_party_driver"] = { "module": driver["module"], "comment": driver["comment"], } return data
def dehydrate(self, obj, data, for_list=False): """Add extra fields to `data`.""" data["fqdn"] = obj.fqdn data["actions"] = list(compile_node_actions(obj, self.user).keys()) data["node_type_display"] = obj.get_node_type_display() data["extra_macs"] = [ "%s" % mac_address for mac_address in obj.get_extra_macs() ] subnets = self.get_all_subnets(obj) data["subnets"] = [subnet.cidr for subnet in subnets] data["fabrics"] = self.get_all_fabric_names(obj, subnets) data["spaces"] = self.get_all_space_names(subnets) data["tags"] = [ tag.name for tag in obj.tags.all() ] if obj.node_type != NODE_TYPE.DEVICE: data["memory"] = obj.display_memory() data["status"] = obj.display_status() data["status_code"] = obj.status boot_interface = obj.get_boot_interface() if boot_interface is not None: data["pxe_mac"] = "%s" % boot_interface.mac_address data["pxe_mac_vendor"] = obj.get_pxe_mac_vendor() else: data["pxe_mac"] = data["pxe_mac_vendor"] = "" blockdevices = self.get_blockdevices_for(obj) physical_blockdevices = [ blockdevice for blockdevice in blockdevices if isinstance(blockdevice, PhysicalBlockDevice) ] data["physical_disk_count"] = len(physical_blockdevices) data["storage"] = "%3.1f" % ( sum( blockdevice.size for blockdevice in physical_blockdevices ) / (1000 ** 3)) data["storage_tags"] = self.get_all_storage_tags(blockdevices) data["osystem"] = obj.get_osystem( default=self.default_osystem) data["distro_series"] = obj.get_distro_series( default=self.default_distro_series) data["dhcp_on"] = self.get_providing_dhcp(obj) if not for_list: data["on_network"] = obj.on_network() if obj.node_type != NODE_TYPE.DEVICE: # XXX lamont 2017-02-15 Much of this should be split out into # individual methods, rather than having this huge block of # dense code here. # Network data["interfaces"] = [ self.dehydrate_interface(interface, obj) for interface in obj.interface_set.all().order_by('name') ] data["hwe_kernel"] = make_hwe_kernel_ui_text(obj.hwe_kernel) data["power_type"] = obj.power_type data["power_parameters"] = self.dehydrate_power_parameters( obj.power_parameters) data["power_bmc_node_count"] = obj.bmc.node_set.count() if ( obj.bmc is not None) else 0 # Storage data["disks"] = sorted(chain( (self.dehydrate_blockdevice(blockdevice, obj) for blockdevice in blockdevices), (self.dehydrate_volume_group(volume_group) for volume_group in VolumeGroup.objects.filter_by_node(obj)), (self.dehydrate_cache_set(cache_set) for cache_set in CacheSet.objects.get_cache_sets_for_node(obj)), ), key=itemgetter("name")) data["supported_filesystems"] = [ {'key': key, 'ui': ui} for key, ui in FILESYSTEM_FORMAT_TYPE_CHOICES ] data["storage_layout_issues"] = obj.storage_layout_issues() data["special_filesystems"] = [ self.dehydrate_filesystem(filesystem) for filesystem in obj.special_filesystems.order_by("id") ] # Events data["events"] = self.dehydrate_events(obj) # Machine output data = self.dehydrate_summary_output(obj, data) data["commissioning_results"] = self.dehydrate_script_set( obj.current_commissioning_script_set) data["commissioning_script_set_status"] = ( self.dehydrate_script_set_status( obj.current_commissioning_script_set)) data["testing_results"] = self.dehydrate_script_set( obj.current_testing_script_set) data["testing_script_set_status"] = ( self.dehydrate_script_set_status( obj.current_testing_script_set)) data["installation_results"] = self.dehydrate_script_set( obj.current_installation_script_set) data["installation_script_set_status"] = ( self.dehydrate_script_set_status( obj.current_installation_script_set)) # Third party drivers if Config.objects.get_config('enable_third_party_drivers'): driver = get_third_party_driver(obj) if "module" in driver and "comment" in driver: data["third_party_driver"] = { "module": driver["module"], "comment": driver["comment"], } return data
def test_delete_action_last_for_controller(self): controller = factory.make_RackController() actions = compile_node_actions( controller, factory.make_admin(), classes=ACTION_CLASSES) self.assertEqual('delete', list(actions)[-1])
def __init__(self, instance, *args, **kwargs): super(NodeActionForm, self).__init__(*args, **kwargs) self.node = instance self.actions = compile_node_actions(instance, self.user, self.request) self.action_buttons = self.actions.values()