From 069e75885aaaf17964d5820e32554c39d0e9c7ac Mon Sep 17 00:00:00 2001 From: Adam Collard Date: Fri, 28 Feb 2020 10:37:50 +0000 Subject: [PATCH] Fix machine details for a machine with tags (#236) Viscera layer produces a Tags.Managed object for machines with tags, this can't be str()ified. --- maas/client/bones/testing/server.py | 8 +-- maas/client/flesh/tables.py | 10 +++- maas/client/flesh/tests/test_machines.py | 66 +++++++++++++++++++++++- 3 files changed, 78 insertions(+), 6 deletions(-) diff --git a/maas/client/bones/testing/server.py b/maas/client/bones/testing/server.py index 9fd8d63..15648e8 100644 --- a/maas/client/bones/testing/server.py +++ b/maas/client/bones/testing/server.py @@ -22,9 +22,11 @@ def __init__(self, description): super(ApplicationBuilder, self).__init__() self._description = desc.Description(description) self._application = aiohttp.web.Application() - self._rootpath, self._basepath, self._version = ( - self._discover_version_and_paths() - ) + ( + self._rootpath, + self._basepath, + self._version, + ) = self._discover_version_and_paths() self._wire_up_description() self._actions = {} self._views = {} diff --git a/maas/client/flesh/tables.py b/maas/client/flesh/tables.py index 53acf3f..7004759 100644 --- a/maas/client/flesh/tables.py +++ b/maas/client/flesh/tables.py @@ -155,6 +155,14 @@ def render(self, target, data): return super().render(target, data.name) +class NodeTagsColumn(Column): + def render(self, target, data): + if data: + return super().render(target, [tag.name for tag in data]) + else: + return "" + + class NodesTable(Table): def __init__(self): super().__init__( @@ -215,7 +223,7 @@ def __init__(self, with_type=False): NodeResourcePoolColumn("pool", "Resource pool"), NodeZoneColumn("zone", "Zone"), NodeOwnerColumn("owner", "Owner"), - Column("tags", "Tags"), + NodeTagsColumn("tags", "Tags"), ] if with_type: columns.insert(1, NodeTypeColumn("node_type", "Type")) diff --git a/maas/client/flesh/tests/test_machines.py b/maas/client/flesh/tests/test_machines.py index 22f946d..6e3c941 100644 --- a/maas/client/flesh/tests/test_machines.py +++ b/maas/client/flesh/tests/test_machines.py @@ -1,5 +1,6 @@ """Tests for `maas.client.flesh.machines`.""" +from functools import partial from operator import itemgetter import yaml @@ -10,13 +11,14 @@ from ...viscera.testing import bind from ...viscera.machines import Machine, Machines from ...viscera.resource_pools import ResourcePool +from ...viscera.tags import Tag, Tags from ...viscera.users import User from ...viscera.zones import Zone def make_origin(): """Make origin for machines.""" - return bind(Machines, Machine, User, ResourcePool, Zone) + return bind(Machines, Machine, User, ResourcePool, Zone, Tag, Tags) class TestMachines(TestCaseWithProfile): @@ -55,7 +57,7 @@ def test_returns_table_with_machines(self): cmd = machines.cmd_machines(parser) subparser = machines.cmd_machines.register(parser) options = subparser.parse_args([]) - output = yaml.load( + output = yaml.safe_load( cmd.execute(origin, options, target=tabular.RenderTarget.yaml) ) self.assertEquals( @@ -101,3 +103,63 @@ def test_calls_handler_with_hostnames(self): options = subparser.parse_args(hostnames) cmd.execute(origin, options, target=tabular.RenderTarget.yaml) origin.Machines._handler.read.assert_called_once_with(hostname=hostnames) + + +class TestMachine(TestCaseWithProfile): + """Tests for `cmd_machine`.""" + + def setUp(self): + super().setUp() + origin = make_origin() + parser = ArgumentParser() + self.hostname = make_name_without_spaces() + machine_objs = [ + { + "hostname": self.hostname, + "architecture": "amd64/generic", + "status": NodeStatus.READY.value, + "status_name": NodeStatus.READY.name, + "owner": None, + "power_state": PowerState.OFF.value, + "cpu_count": 2, + "memory": 1024, + "pool": {"id": 1, "name": "pool1", "description": "pool1"}, + "zone": {"id": 1, "name": "zone1", "description": "zone1"}, + "tag_names": ["tag1", "tag2"], + "distro_series": "", + "power_type": "Manual", + }, + ] + origin.Machines._handler.read.return_value = machine_objs + cmd = machines.cmd_machine(parser) + subparser = machines.cmd_machine.register(parser) + options = subparser.parse_args([machine_objs[0]["hostname"]]) + self.cmd = partial(cmd.execute, origin, options) + + def test_yaml_machine_details_with_tags(self): + yaml_output = yaml.safe_load(self.cmd(target=tabular.RenderTarget.yaml)) + self.assertEqual(yaml_output.get("tags"), ["tag1", "tag2"]) + + def test_plain_machine_details_with_tags(self): + plain_output = self.cmd(target=tabular.RenderTarget.plain) + self.assertEqual( + plain_output, + f"""\ ++---------------+-------------+ +| Hostname | {self.hostname} | +| Status | READY | +| Image | (none) | +| Power | Off | +| Power Type | Manual | +| Arch | amd64 | +| #CPUs | 2 | +| RAM | 1.0 GB | +| Interfaces | 0 physical | +| IP addresses | | +| Resource pool | pool1 | +| Zone | zone1 | +| Owner | (none) | +| Tags | tag1 | +| | tag2 | ++---------------+-------------+""", + )