Repository: mesos Updated Branches: refs/heads/master 7b0852f79 -> 127070329
Added 'mesos agent list' command to CLI. This command displays the agents in a cluster by reaching the slaves endpoint of a master. Review: https://reviews.apache.org/r/62065/ Project: http://git-wip-us.apache.org/repos/asf/mesos/repo Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/12707032 Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/12707032 Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/12707032 Branch: refs/heads/master Commit: 1270703291a132d8d959d71bf99e4dfe4cf4292e Parents: 7b0852f Author: Armand Grillet <agril...@mesosphere.io> Authored: Wed Sep 27 15:02:04 2017 +0200 Committer: Kevin Klues <klue...@gmail.com> Committed: Wed Sep 27 15:06:35 2017 +0200 ---------------------------------------------------------------------- src/python/cli_new/bin/settings.py | 1 + .../cli_new/lib/cli/plugins/agent/__init__.py | 22 ++++++ .../cli_new/lib/cli/plugins/agent/main.py | 82 ++++++++++++++++++++ src/python/cli_new/lib/cli/tests/__init__.py | 2 + src/python/cli_new/lib/cli/tests/agent.py | 78 +++++++++++++++++++ src/python/cli_new/tests/main.py | 1 + 6 files changed, 186 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/mesos/blob/12707032/src/python/cli_new/bin/settings.py ---------------------------------------------------------------------- diff --git a/src/python/cli_new/bin/settings.py b/src/python/cli_new/bin/settings.py index 7e37408..f501fef 100644 --- a/src/python/cli_new/bin/settings.py +++ b/src/python/cli_new/bin/settings.py @@ -38,6 +38,7 @@ PROJECT_DIR = os.path.join(os.path.dirname(__file__), os.pardir) # The builtin plugins. PLUGINS = [ + os.path.join(PROJECT_DIR, "lib", "mesos", "plugins", "agent"), os.path.join(PROJECT_DIR, "lib", "mesos", "plugins", "config"), os.path.join(PROJECT_DIR, "lib", "mesos", "plugins", "task") ] http://git-wip-us.apache.org/repos/asf/mesos/blob/12707032/src/python/cli_new/lib/cli/plugins/agent/__init__.py ---------------------------------------------------------------------- diff --git a/src/python/cli_new/lib/cli/plugins/agent/__init__.py b/src/python/cli_new/lib/cli/plugins/agent/__init__.py new file mode 100644 index 0000000..dc5cabf --- /dev/null +++ b/src/python/cli_new/lib/cli/plugins/agent/__init__.py @@ -0,0 +1,22 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +Agent module. +""" + +# pylint: disable=wildcard-import +from .main import * http://git-wip-us.apache.org/repos/asf/mesos/blob/12707032/src/python/cli_new/lib/cli/plugins/agent/main.py ---------------------------------------------------------------------- diff --git a/src/python/cli_new/lib/cli/plugins/agent/main.py b/src/python/cli_new/lib/cli/plugins/agent/main.py new file mode 100644 index 0000000..59280ec --- /dev/null +++ b/src/python/cli_new/lib/cli/plugins/agent/main.py @@ -0,0 +1,82 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +The agent plugin. +""" + +import cli.http as http + +from cli.exceptions import CLIException +from cli.plugins import PluginBase +from cli.util import Table + + +PLUGIN_NAME = "agent" +PLUGIN_CLASS = "Agent" + +VERSION = "Mesos CLI Agent Plugin" + +SHORT_HELP = "Interacts with the Mesos agents" + + +class Agent(PluginBase): + """ + The agent plugin. + """ + + COMMANDS = { + "list": { + "arguments": [], + "flags": {}, + "short_help": "List the Mesos agents.", + "long_help": "List information about the Mesos agents." + } + } + + def list(self, argv): + """ + List the agents in a cluster by checking the /slaves endpoint. + """ + # pylint: disable=unused-argument + try: + master = self.config.master() + except Exception as exception: + raise CLIException("Unable to get leading master address: {error}" + .format(error=exception)) + + try: + agents = http.get_json(master, "slaves")["slaves"] + except Exception as exception: + raise CLIException("Could not open '/slaves'" + " endpoint at '{addr}': {error}" + .format(addr=master, error=exception)) + + if len(agents) == 0: + print "The cluster does not have any agents." + return + + try: + table = Table(["Agent ID", "Hostname", "Active"]) + for agent in agents: + table.add_row([agent["id"], + agent["hostname"], + str(agent["active"])]) + except Exception as exception: + raise CLIException("Unable to build table of agents: {error}" + .format(error=exception)) + + print str(table) http://git-wip-us.apache.org/repos/asf/mesos/blob/12707032/src/python/cli_new/lib/cli/tests/__init__.py ---------------------------------------------------------------------- diff --git a/src/python/cli_new/lib/cli/tests/__init__.py b/src/python/cli_new/lib/cli/tests/__init__.py index 85ab073..b7c825f 100644 --- a/src/python/cli_new/lib/cli/tests/__init__.py +++ b/src/python/cli_new/lib/cli/tests/__init__.py @@ -20,5 +20,7 @@ Mesos CLI unit tests module. # pylint: disable=W0401 from .base import * + +from .agent import * from .task import * from .tests import * http://git-wip-us.apache.org/repos/asf/mesos/blob/12707032/src/python/cli_new/lib/cli/tests/agent.py ---------------------------------------------------------------------- diff --git a/src/python/cli_new/lib/cli/tests/agent.py b/src/python/cli_new/lib/cli/tests/agent.py new file mode 100644 index 0000000..6e5e565 --- /dev/null +++ b/src/python/cli_new/lib/cli/tests/agent.py @@ -0,0 +1,78 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +Agent plugin tests. +""" + +import cli.http as http + +from cli import config + +from cli.plugins.agent.main import Agent as AgentPlugin + +from cli.tests import capture_output +from cli.tests import CLITestCase +from cli.tests import Agent +from cli.tests import Master + +from cli.util import Table + + +class TestAgentPlugin(CLITestCase): + """ + Test class for the agent plugin. + """ + def test_list(self): + """ + Basic test for the agent `list()` sub-command. + """ + # Launch a master and agent. + master = Master() + master.launch() + + agent = Agent() + agent.launch() + + # Open the master's `/slaves` endpoint and read the + # agents' information ourselves. + agents = http.get_json(master.addr, 'slaves')["slaves"] + + self.assertEqual(type(agents), list) + self.assertEqual(len(agents), 1) + + # Invoke the agent plugin `list()` command + # and parse its output as a table. + test_config = config.Config(None) + plugin = AgentPlugin(None, test_config) + output = capture_output(plugin.list, {}) + table = Table.parse(output) + + # Verify there are two rows in the table + # and that they are formatted as expected, + # with the proper agent info in them. + self.assertEqual(table.dimensions()[0], 2) + self.assertEqual(table.dimensions()[1], 3) + self.assertEqual("Agent ID", table[0][0]) + self.assertEqual("Hostname", table[0][1]) + self.assertEqual("Active", table[0][2]) + self.assertEqual(agents[0]["id"], table[1][0]) + self.assertEqual(agents[0]["hostname"], table[1][1]) + self.assertEqual(str(agents[0]["active"]), table[1][2]) + + # Kill the agent and master. + agent.kill() + master.kill() http://git-wip-us.apache.org/repos/asf/mesos/blob/12707032/src/python/cli_new/tests/main.py ---------------------------------------------------------------------- diff --git a/src/python/cli_new/tests/main.py b/src/python/cli_new/tests/main.py index 82840c6..acf2e08 100644 --- a/src/python/cli_new/tests/main.py +++ b/src/python/cli_new/tests/main.py @@ -27,6 +27,7 @@ from cli.tests import CLITestCase # pylint: disable=unused-import # We import the tests that we want to run. +from cli.tests import TestAgentPlugin from cli.tests import TestInfrastructure from cli.tests import TestTaskPlugin