diff --git a/doc/source/osc/v1/index.rst b/doc/source/osc/v1/index.rst index ee45f5c..68c30cc 100644 --- a/doc/source/osc/v1/index.rst +++ b/doc/source/osc/v1/index.rst @@ -101,3 +101,10 @@ BaremetalCompute availability zone .. autoprogram-cliff:: openstack.baremetal_compute.v1 :command: baremetalcompute availability zone * + +================================== +BaremetalCompute manageable server +================================== + +.. autoprogram-cliff:: openstack.baremetal_compute.v1 + :command: baremetalcompute manageable server * diff --git a/moganclient/osc/v1/manageable_server.py b/moganclient/osc/v1/manageable_server.py new file mode 100644 index 0000000..692887e --- /dev/null +++ b/moganclient/osc/v1/manageable_server.py @@ -0,0 +1,93 @@ +# Copyright 2017 Fiberhome, Inc. All rights reserved. +# +# 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. +# + + +"""Mogan v1 manageable servers action implementations""" + +import json +import logging + +from osc_lib.command import command +from osc_lib import utils + +from moganclient.common.i18n import _ + +LOG = logging.getLogger(__name__) + + +class ListManageableServer(command.Lister): + """List all manageable servers""" + + def get_parser(self, prog_name): + parser = super(ListManageableServer, self).get_parser(prog_name) + parser.add_argument( + '--long', + action='store_true', + default=False, + help=_("List additional fields in output") + ) + return parser + + def take_action(self, parsed_args): + bc_client = self.app.client_manager.baremetal_compute + + if parsed_args.long: + # This is the easiest way to change column headers + column_headers = ( + "UUID", + "Name", + "Power State", + "Provision State", + "Image Id", + "Resource Class", + "Ports", + "Port Groups" + ) + columns = ( + "uuid", + "name", + "power_state", + "provision_state", + "image_source", + "resource_class", + "ports", + "portgroups" + ) + else: + column_headers = ( + "UUID", + "Name", + "Power State", + "Provision State", + "Image Id", + "Resource Class" + ) + columns = ( + "uuid", + "name", + "power_state", + "provision_state", + "image_source", + "resource_class" + ) + + data = bc_client.manageable_server.list() + net_formatter = lambda s: json.dumps(s, indent=2, sort_keys=True) + formatters = {'ports': net_formatter, + 'portgroups': net_formatter + } + return (column_headers, + (utils.get_item_properties( + s, columns, formatters=formatters) for s in data)) diff --git a/moganclient/tests/unit/fakes.py b/moganclient/tests/unit/fakes.py index 737212e..371b1f0 100644 --- a/moganclient/tests/unit/fakes.py +++ b/moganclient/tests/unit/fakes.py @@ -24,6 +24,7 @@ from moganclient.common import base from moganclient.v1 import aggregate from moganclient.v1 import availability_zone from moganclient.v1 import flavor +from moganclient.v1 import manageable_server from moganclient.v1 import node from moganclient.v1 import server from moganclient.v1 import server_group @@ -74,6 +75,8 @@ class FakeBaremetalComputeV1Client(object): self.fake_http_client) self.aggregate_node = aggregate.AggregateNodeManager( self.fake_http_client) + self.manageable_server = manageable_server.ManageableServerManager( + self.fake_http_client) class FakeHTTPClient(object): diff --git a/moganclient/tests/unit/osc/v1/test_manageable_server.py b/moganclient/tests/unit/osc/v1/test_manageable_server.py new file mode 100644 index 0000000..b2edf00 --- /dev/null +++ b/moganclient/tests/unit/osc/v1/test_manageable_server.py @@ -0,0 +1,90 @@ +# Copyright 2017 Fiberhome, Inc. All rights reserved. +# +# 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 copy +import json + +import mock + +from moganclient.osc.v1 import manageable_server +from moganclient.tests.unit import base as test_base +from moganclient.tests.unit import fakes +from moganclient.v1 import manageable_server as ms_mgr + + +@mock.patch.object(ms_mgr.ManageableServerManager, '_list') +class TestManageableServerList(test_base.TestBaremetalComputeV1): + def setUp(self): + super(TestManageableServerList, self).setUp() + self.cmd = manageable_server.ListManageableServer(self.app, None) + self.fake_ms = { + "uuid": "166f5efc-f1c8-421b-b909-47cea4e59f25", + "image_source": "755cac03-a460-4de0-8d8e-d1ac842768bf", + "name": "node-0", + "power_state": "power on", + "provision_state": "active", + "resource_class": "baremetal", + "ports": [{ + "uuid": "935ff2f1-89ca-4d6e-b7ab-286c01dc40bb", + "address": "52:54:00:01:c6:db", + "neutron_port_id": "0c19889a-67f1-443a-85a9-21afcedcfc92"}], + "portgroups": [{ + "neutron_port_id": None, + "address": "52:54:00:0e:00:ef", + "uuid": "5c84edb4-66f8-4199-aa57-6c08be362bbc"}] + } + self.fake_ms_obj = fakes.FakeResource( + manager=None, + info=copy.deepcopy(self.fake_ms), + loaded=True) + + def test_list_manageable_server(self, mock_list): + arglist = [] + verifylist = [] + mock_list.return_value = [self.fake_ms_obj] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + mock_list.assert_called_once_with('/manageable_servers', + response_key='manageable_servers') + self.assertEqual(('UUID', 'Name', 'Power State', 'Provision State', + 'Image Id', 'Resource Class'), columns) + self.assertEqual((("166f5efc-f1c8-421b-b909-47cea4e59f25", + "node-0", "power on", "active", + "755cac03-a460-4de0-8d8e-d1ac842768bf", + "baremetal"),), tuple(data)) + + def test_list_manageable_server_long(self, mock_list): + arglist = [ + '--long', + ] + verifylist = [ + ('long', True), + ] + mock_list.return_value = [self.fake_ms_obj] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + mock_list.assert_called_once_with('/manageable_servers', + response_key='manageable_servers') + self.assertEqual(('UUID', 'Name', 'Power State', 'Provision State', + 'Image Id', 'Resource Class', 'Ports', + 'Port Groups'), columns) + p_str = json.dumps(self.fake_ms_obj.ports, indent=2, sort_keys=True) + pg_str = json.dumps(self.fake_ms_obj.portgroups, indent=2, + sort_keys=True) + self.assertEqual((("166f5efc-f1c8-421b-b909-47cea4e59f25", + "node-0", "power on", "active", + "755cac03-a460-4de0-8d8e-d1ac842768bf", + "baremetal", p_str, pg_str + ),), tuple(data)) diff --git a/moganclient/v1/client.py b/moganclient/v1/client.py index 25b13c1..51ceea4 100644 --- a/moganclient/v1/client.py +++ b/moganclient/v1/client.py @@ -18,6 +18,7 @@ from moganclient.v1 import aggregate from moganclient.v1 import availability_zone from moganclient.v1 import flavor from moganclient.v1 import keypair +from moganclient.v1 import manageable_server from moganclient.v1 import node from moganclient.v1 import server from moganclient.v1 import server_group @@ -40,3 +41,5 @@ class Client(object): self.aggregate = aggregate.AggregateManager(self.http_client) self.server_group = server_group.ServerGroupManager(self.http_client) self.aggregate_node = aggregate.AggregateNodeManager(self.http_client) + self.manageable_server = manageable_server.ManageableServerManager( + self.http_client) diff --git a/moganclient/v1/manageable_server.py b/moganclient/v1/manageable_server.py new file mode 100644 index 0000000..efabaf2 --- /dev/null +++ b/moganclient/v1/manageable_server.py @@ -0,0 +1,28 @@ +# Copyright 2017 Fiberhome, Inc. All rights reserved. +# +# 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 moganclient.common import base + + +class ManageableServer(base.Resource): + pass + + +class ManageableServerManager(base.ManagerWithFind): + resource_class = ManageableServer + + def list(self): + url = '/manageable_servers' + return self._list(url, response_key='manageable_servers') diff --git a/releasenotes/notes/support-manageable-servers-list-fc88f061cda5c2f4.yaml b/releasenotes/notes/support-manageable-servers-list-fc88f061cda5c2f4.yaml new file mode 100644 index 0000000..72f7dfc --- /dev/null +++ b/releasenotes/notes/support-manageable-servers-list-fc88f061cda5c2f4.yaml @@ -0,0 +1,4 @@ +--- +features: + - Support to list all manageable servers from Mogan. This will help users + to manage those existing servers using different drivers, like Ironic. diff --git a/setup.cfg b/setup.cfg index f3cafb2..fd0c9f6 100644 --- a/setup.cfg +++ b/setup.cfg @@ -72,6 +72,7 @@ openstack.baremetal_compute.v1 = baremetalcompute_aggregate_add_node = moganclient.osc.v1.aggregate:AggregateAddNode baremetalcompute_aggregate_list_node = moganclient.osc.v1.aggregate:AggregateListNode baremetalcompute_aggregate_remove_node = moganclient.osc.v1.aggregate:AggregateRemoveNode + baremetalcompute_manageable_server_list = moganclient.osc.v1.manageable_server:ListManageableServer [build_sphinx] source-dir = doc/source