diff --git a/fuelclient/__init__.py b/fuelclient/__init__.py index 05d77a0c..9e2fa4a4 100644 --- a/fuelclient/__init__.py +++ b/fuelclient/__init__.py @@ -49,6 +49,7 @@ def get_client(resource, version='v1'): version_map = { 'v1': { 'environment': v1.environment, + 'node': v1.node, } } diff --git a/fuelclient/commands/node.py b/fuelclient/commands/node.py new file mode 100644 index 00000000..aacc47b6 --- /dev/null +++ b/fuelclient/commands/node.py @@ -0,0 +1,79 @@ +# Copyright 2015 Mirantis, Inc. +# +# Licensed 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. + +from fuelclient.commands import base +from fuelclient.common import data_utils + + +class NodeMixIn(object): + entity_name = 'node' + + +class NodeList(NodeMixIn, base.BaseListCommand): + """Show list of all avaliable nodes.""" + + columns = ('id', + 'name', + 'status', + 'os_platform', + 'roles', + 'ip', + 'mac', + 'cluster', + 'platform_name', + 'online') + + def get_parser(self, prog_name): + parser = super(NodeList, self).get_parser(prog_name) + + parser.add_argument( + '-e', + '--env', + type=int, + help='Show only nodes that are in the specified environment' + ) + + return parser + + def take_action(self, parsed_args): + + data = self.client.get_all(environment_id=parsed_args.env) + data = data_utils.get_display_data_multi(self.columns, data) + + return (self.columns, data) + + +class NodeShow(NodeMixIn, base.BaseShowCommand): + """Show info about node with given id.""" + columns = ('id', + 'name', + 'status', + 'os_platform', + 'roles', + 'kernel_params', + 'pending_roles', + 'ip', + 'mac', + 'error_type', + 'pending_addition', + 'fqdn', + 'platform_name', + 'cluster', + 'online', + 'progress', + 'pending_deletion', + 'group_id', + # TODO(romcheg): network_data mostly never fits the screen + # 'network_data', + 'manufacturer') diff --git a/fuelclient/tests/cli/test_node.py b/fuelclient/tests/cli/test_node.py new file mode 100644 index 00000000..6d30bea1 --- /dev/null +++ b/fuelclient/tests/cli/test_node.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +# +# Copyright 2015 Mirantis, Inc. +# +# Licensed 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. + +import mock + +from fuelclient.tests.cli import test_v2_engine + + +class TestNodeCommand(test_v2_engine.BaseCLITest): + """Tests for fuel2 node * commands.""" + + def test_node_list(self): + args = 'node list' + self.exec_v2_command(args) + + self.m_get_client.assert_called_once_with('node', mock.ANY) + self.m_client.get_all.assert_called_once_with(environment_id=None) + + def test_node_list_with_env(self): + env_id = 42 + args = 'node list --env {env}'.format(env=env_id) + + self.exec_v2_command(args) + + self.m_get_client.assert_called_once_with('node', mock.ANY) + self.m_client.get_all.assert_called_once_with(environment_id=env_id) + + def test_node_show(self): + node_id = 42 + args = 'node show {node_id}'.format(node_id=node_id) + + self.exec_v2_command(args) + + self.m_get_client.assert_called_once_with('node', mock.ANY) + self.m_client.get_by_id.assert_called_once_with(node_id) diff --git a/fuelclient/tests/lib/test_node.py b/fuelclient/tests/lib/test_node.py new file mode 100644 index 00000000..72454cf2 --- /dev/null +++ b/fuelclient/tests/lib/test_node.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# +# Copyright 2015 Mirantis, Inc. +# +# Licensed 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. + +import requests_mock as rm + +import fuelclient +from fuelclient.tests.lib import test_api + + +class TestNodeFacade(test_api.BaseLibTest): + + def setUp(self): + super(TestNodeFacade, self).setUp() + + self.version = 'v1' + self.res_uri = '/api/{version}/nodes/'.format(version=self.version) + + self.client = fuelclient.get_client('node', self.version) + + def test_node_list(self): + self.client.get_all() + + self.assertEqual(rm.GET, self.session_adapter.last_request.method) + self.assertEqual(self.res_uri, self.session_adapter.last_request.path) + + def test_node_show(self): + node_id = 42 + expected_uri = self.get_object_uri(self.res_uri, node_id) + + self.client.get_by_id(node_id) + + self.assertEqual(rm.GET, self.session_adapter.last_request.method) + self.assertEqual(expected_uri, self.session_adapter.last_request.path) diff --git a/fuelclient/v1/__init__.py b/fuelclient/v1/__init__.py index 6759a71e..01d1acec 100644 --- a/fuelclient/v1/__init__.py +++ b/fuelclient/v1/__init__.py @@ -13,8 +13,10 @@ # under the License. from fuelclient. v1 import environment +from fuelclient. v1 import node __all__ = ( 'environment', + 'node', ) diff --git a/fuelclient/v1/node.py b/fuelclient/v1/node.py new file mode 100644 index 00000000..46dff36b --- /dev/null +++ b/fuelclient/v1/node.py @@ -0,0 +1,33 @@ +# Copyright 2015 Mirantis, Inc. +# +# Licensed 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. + +from fuelclient import objects +from fuelclient.v1 import base_v1 + + +class NodeClient(base_v1.BaseV1Client): + + _entity_wrapper = objects.Node + + def get_all(self, environment_id=None): + result = self._entity_wrapper.get_all_data() + + if environment_id is not None: + result = filter(lambda n: n['cluster'] == environment_id, result) + + return result + + +def get_client(): + return NodeClient() diff --git a/setup.cfg b/setup.cfg index 040bc29d..2e6a6b83 100644 --- a/setup.cfg +++ b/setup.cfg @@ -36,6 +36,8 @@ fuelclient = env_upgrade=fuelclient.commands.environment:EnvUpgrade env_deploy=fuelclient.commands.environment:EnvDeploy env_add_nodes=fuelclient.commands.environment:EnvAddNodes + node_list=fuelclient.commands.node:NodeList + node_show=fuelclient.commands.node:NodeShow [global] setup-hooks =