Add --detail option to nodepool list command

The output of the 'list' command has gotten quite large. Simplify
the default output, and output the complete info when the --detail
option is given.

Also adds/modifies the list_nodes tests to assert that the column
output changes when the new option is used.

Change-Id: I60f849225c8c7fce1c524f132e54da58b25ae752
This commit is contained in:
David Shrewsbury 2017-08-01 15:14:33 -04:00
parent b01227c9d4
commit 7383896833
3 changed files with 59 additions and 21 deletions

View File

@ -50,6 +50,9 @@ class NodePoolCmd(NodepoolApp):
cmd_list = subparsers.add_parser('list', help='list nodes')
cmd_list.set_defaults(func=self.list)
cmd_list.add_argument('--detail', action='store_true',
help='Output detailed node info')
cmd_image_list = subparsers.add_parser(
'image-list', help='list images from providers')
cmd_image_list.set_defaults(func=self.image_list)
@ -145,8 +148,10 @@ class NodePoolCmd(NodepoolApp):
l = logging.getLogger('kazoo')
l.setLevel(logging.WARNING)
def list(self, node_id=None):
print(status.node_list(self.zk, node_id))
def list(self, node_id=None, detail=False):
if hasattr(self.args, 'detail'):
detail = self.args.detail
print(status.node_list(self.zk, node_id, detail))
def dib_image_list(self):
print(status.dib_image_list(self.zk))

View File

@ -29,12 +29,17 @@ def age(timestamp):
return '%02d:%02d:%02d:%02d' % (d, h, m, s)
def node_list(zk, node_id=None):
t = PrettyTable(["ID", "Provider", "AZ", "Label",
"Launcher", "Hostname", "Server ID",
"Public IPv4", "Private IPv4", "IPv6", "SSH Port",
"State", "Age", "Locked", "Comment"])
def node_list(zk, node_id=None, detail=False):
headers = ["ID", "Provider", "AZ", "Label", "Server ID", "State",
"Age", "Locked"]
detail_headers = ["Hostname", "Public IPv4", "Private IPv4", "IPv6",
"SSH Port", "Launcher", "Comment"]
if detail:
headers += detail_headers
t = PrettyTable(headers)
t.align = 'l'
if node_id:
node = zk.getNode(node_id)
if node:
@ -46,11 +51,14 @@ def node_list(zk, node_id=None):
else:
zk.unlockNode(node)
t.add_row([node.id, node.provider, node.az, node.type,
node.launcher, node.hostname, node.external_id,
node.public_ipv4, node.private_ipv4, node.public_ipv6,
node.ssh_port, node.state, age(node.state_time), locked,
node.comment])
values = [node.id, node.provider, node.az, node.type,
node.external_id, node.state, age(node.state_time),
locked]
if detail:
values += [node.hostname, node.public_ipv4, node.private_ipv4,
node.public_ipv6, node.ssh_port, node.launcher,
node.comment]
t.add_row(values)
else:
for node in zk.nodeIterator():
locked = "unlocked"
@ -60,11 +68,15 @@ def node_list(zk, node_id=None):
locked = "locked"
else:
zk.unlockNode(node)
t.add_row([node.id, node.provider, node.az, node.type,
node.launcher, node.hostname, node.external_id,
node.public_ipv4, node.private_ipv4, node.public_ipv6,
node.ssh_port, node.state, age(node.state_time), locked,
node.comment])
values = [node.id, node.provider, node.az, node.type,
node.external_id, node.state, age(node.state_time),
locked]
if detail:
values += [node.hostname, node.public_ipv4, node.private_ipv4,
node.public_ipv6, node.ssh_port, node.launcher,
node.comment]
t.add_row(values)
return str(t)

View File

@ -35,7 +35,7 @@ class TestNodepoolCMD(tests.DBTestCase):
argv.extend(args)
self.useFixture(fixtures.MonkeyPatch('sys.argv', argv))
def assert_listed(self, configfile, cmd, col, val, count):
def assert_listed(self, configfile, cmd, col, val, count, col_count=0):
log = logging.getLogger("tests.PrettyTableMock")
self.patch_argv("-c", configfile, *cmd)
with mock.patch('prettytable.PrettyTable.add_row') as m_add_row:
@ -44,6 +44,8 @@ class TestNodepoolCMD(tests.DBTestCase):
# Find add_rows with the status were looking for
for args, kwargs in m_add_row.call_args_list:
row = args[0]
if col_count:
self.assertEquals(len(row), col_count)
log.debug(row)
if row[col] == val:
rows_with_val += 1
@ -58,8 +60,16 @@ class TestNodepoolCMD(tests.DBTestCase):
def assert_images_listed(self, configfile, image_cnt, status="ready"):
self.assert_listed(configfile, ['image-list'], 6, status, image_cnt)
def assert_nodes_listed(self, configfile, node_cnt, status="ready"):
self.assert_listed(configfile, ['list'], 11, status, node_cnt)
def assert_nodes_listed(self, configfile, node_cnt, status="ready",
detail=False, validate_col_count=False):
cmd = ['list']
col_count = 8
if detail:
cmd += ['--detail']
col_count = 15
if not validate_col_count:
col_count = 0
self.assert_listed(configfile, cmd, 5, status, node_cnt, col_count)
def test_image_list_empty(self):
self.assert_images_listed(self.setup_config("node_cmd.yaml"), 0)
@ -124,7 +134,18 @@ class TestNodepoolCMD(tests.DBTestCase):
pool.start()
self.waitForImage('fake-provider', 'fake-image')
self.waitForNodes('fake-label')
self.assert_nodes_listed(configfile, 1)
self.assert_nodes_listed(configfile, 1, detail=False,
validate_col_count=True)
def test_list_nodes_detail(self):
configfile = self.setup_config('node.yaml')
self._useBuilder(configfile)
pool = self.useNodepool(configfile, watermark_sleep=1)
pool.start()
self.waitForImage('fake-provider', 'fake-image')
self.waitForNodes('fake-label')
self.assert_nodes_listed(configfile, 1, detail=True,
validate_col_count=True)
def test_config_validate(self):
config = os.path.join(os.path.dirname(tests.__file__),