diff --git a/cli/dcoscli/node/main.py b/cli/dcoscli/node/main.py index 27bd601..ebd7f4c 100644 --- a/cli/dcoscli/node/main.py +++ b/cli/dcoscli/node/main.py @@ -463,9 +463,21 @@ def _list(json_, extra_field_names): """ client = mesos.DCOSClient() + masters = mesos.MesosDNSClient().hosts('master.mesos.') + master_state = client.get_master_state() slaves = client.get_state_summary()['slaves'] + for master in masters: + if master['ip'] == master_state['hostname']: + master['type'] = 'master (leader)' + for key in ('id', 'pid', 'version'): + master[key] = master_state.get(key) + else: + master['type'] = 'master' + for slave in slaves: + slave['type'] = 'agent' + nodes = masters + slaves if json_: - emitter.publish(slaves) + emitter.publish(nodes) else: for extra_field_name in extra_field_names: field_name = extra_field_name.split(':')[-1] @@ -476,7 +488,7 @@ def _list(json_, extra_field_names): emitter.publish(errors.DefaultError( 'Field "%s" is invalid.' % field_name)) return - table = tables.slave_table(slaves, extra_field_names) + table = tables.node_table(nodes, extra_field_names) output = six.text_type(table) if output: emitter.publish(output) diff --git a/cli/dcoscli/tables.py b/cli/dcoscli/tables.py index 93250c5..8de99af 100644 --- a/cli/dcoscli/tables.py +++ b/cli/dcoscli/tables.py @@ -870,20 +870,21 @@ def auth_provider_table(providers): return tb -def slave_table(slaves, field_names=()): - """Returns a PrettyTable representation of the provided DC/OS slaves +def node_table(nodes, field_names=()): + """Returns a PrettyTable representation of the provided DC/OS nodes - :param slaves: slaves to render. dicts from /mesos/state-summary - :type slaves: [dict] + :param nodes: nodes to render. + :type nodes: [dict] :param field_names: Extra fields to add to the table - :type slaves: [str] + :type nodes: [str] :rtype: PrettyTable """ fields = OrderedDict([ - ('HOSTNAME', lambda s: s['hostname']), - ('IP', lambda s: mesos.parse_pid(s['pid'])[1]), - ('ID', lambda s: s['id']) + ('HOSTNAME', lambda s: s.get('host', s.get('hostname'))), + ('IP', lambda s: s.get('ip') or mesos.parse_pid(s['pid'])[1]), + ('ID', lambda s: s['id']), + ('TYPE', lambda s: s['type']), ]) for field_name in field_names: @@ -896,7 +897,8 @@ def slave_table(slaves, field_names=()): fields[heading.upper()] = _dotted_itemgetter(field_name.lower()) sortby = list(fields.keys())[0] - tb = table(fields, slaves, sortby=sortby) + tb = table(fields, nodes, sortby=sortby) + tb.align['TYPE'] = 'l' return tb diff --git a/cli/tests/fixtures/node.py b/cli/tests/fixtures/node.py index 74e2262..9c2a6a6 100644 --- a/cli/tests/fixtures/node.py +++ b/cli/tests/fixtures/node.py @@ -14,6 +14,7 @@ def slave_fixture(): "TASK_STAGING": 0, "TASK_STARTING": 0, "active": True, + "type": "agent", "attributes": {}, "framework_ids": [], "hostname": "dcos-01", diff --git a/cli/tests/integrations/test_marathon_debug.py b/cli/tests/integrations/test_marathon_debug.py index e509aae..903deb2 100644 --- a/cli/tests/integrations/test_marathon_debug.py +++ b/cli/tests/integrations/test_marathon_debug.py @@ -151,7 +151,10 @@ def test_debug_details(): assert returncode == 0 assert stderr == b'' - agent_count = len(json.loads(stdout.decode('utf-8'))) + agent_count = len( + [n for n in json.loads(stdout.decode('utf-8')) + if n['type'] == 'agent'] + ) """The extra two lines come from the heading and the empty line at the end of the table. @@ -193,7 +196,10 @@ def test_debug_details_pod(): assert returncode == 0 assert stderr == b'' - agent_count = len(json.loads(stdout.decode('utf-8'))) + agent_count = len( + [n for n in json.loads(stdout.decode('utf-8')) + if n['type'] == 'agent'] + ) """The extra two lines come from the heading and the empty line at the end of the table. diff --git a/cli/tests/integrations/test_node.py b/cli/tests/integrations/test_node.py index 7de081a..29c2aff 100644 --- a/cli/tests/integrations/test_node.py +++ b/cli/tests/integrations/test_node.py @@ -32,8 +32,9 @@ def test_node(): assert stderr == b'' nodes = json.loads(stdout.decode('utf-8')) + slave_nodes = [node for node in nodes if node['type'] == 'agent'] schema = _get_schema(slave_fixture()) - for node in nodes: + for node in slave_nodes: assert not util.validate_json(node, schema) @@ -53,7 +54,7 @@ def test_node_table_field_option(): assert stderr == b'' lines = stdout.decode('utf-8').splitlines() assert len(lines) > 2 - assert lines[0].split() == ['HOSTNAME', 'IP', 'ID', 'DISK_USED'] + assert lines[0].split() == ['HOSTNAME', 'IP', 'ID', 'TYPE', 'DISK_USED'] def test_node_log_empty(): @@ -242,7 +243,9 @@ def _node_ssh(args, expected_returncode=None, expected_stdout=None): args.append('--master-proxy') stdout, stderr, returncode = _node_ssh_output(args) - assert returncode is expected_returncode + assert returncode is expected_returncode, \ + 'returncode = %r; stdout: = %s; stderr = %s' % ( + returncode, stdout, stderr) if expected_stdout is not None: assert stdout.decode('utf-8').startswith(expected_stdout) assert b"Running `" in stderr @@ -271,4 +274,5 @@ def _node(): assert returncode == 0 assert stderr == b'' - return json.loads(stdout.decode('utf-8')) + return [n for n in json.loads(stdout.decode('utf-8')) + if n['type'] == 'agent'] diff --git a/cli/tests/unit/data/node.txt b/cli/tests/unit/data/node.txt index 2f48ca8..ce7609a 100644 --- a/cli/tests/unit/data/node.txt +++ b/cli/tests/unit/data/node.txt @@ -1,2 +1,2 @@ -HOSTNAME IP ID -dcos-01 172.17.8.101 20150630-004309-1695027628-5050-1649-S0 \ No newline at end of file +HOSTNAME IP ID TYPE +dcos-01 172.17.8.101 20150630-004309-1695027628-5050-1649-S0 agent \ No newline at end of file diff --git a/cli/tests/unit/test_tables.py b/cli/tests/unit/test_tables.py index 8da4534..a1e2367 100644 --- a/cli/tests/unit/test_tables.py +++ b/cli/tests/unit/test_tables.py @@ -140,7 +140,7 @@ def test_package_search_table(): def test_node_table(): - _test_table(tables.slave_table, + _test_table(tables.node_table, [slave_fixture()], 'tests/unit/data/node.txt')