Add show composed node detail command
Add new command 'rsd node show' to allow user to get composed node details by specifying node ID. Change-Id: I26e4adbbf18519742cc215371e8f86fbb4b7d93e
This commit is contained in:
parent
6e9aeaaa00
commit
a69faf00c4
@ -1,4 +1,4 @@
|
||||
# Copyright 2017 99cloud, Inc.
|
||||
# Copyright 2017 Intel, Inc.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
|
43
rsdclient/common/utils.py
Normal file
43
rsdclient/common/utils.py
Normal file
@ -0,0 +1,43 @@
|
||||
# Copyright 2017 Intel, 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 six
|
||||
|
||||
|
||||
def extract_attr(redfish_obj):
|
||||
'''Extract all public attributes of python redfish object
|
||||
|
||||
:param redfish_obj: python redfish object returned by rsd_lib
|
||||
:returns: python dict of that object
|
||||
'''
|
||||
|
||||
if isinstance(redfish_obj, (int, six.string_types)):
|
||||
return redfish_obj
|
||||
if isinstance(redfish_obj, list):
|
||||
return [extract_attr(i) for i in redfish_obj]
|
||||
if isinstance(redfish_obj, dict):
|
||||
return {i: extract_attr(redfish_obj[i]) for i in redfish_obj}
|
||||
|
||||
result = {}
|
||||
try:
|
||||
for key, value in vars(redfish_obj).items():
|
||||
# Skip all private attributes
|
||||
if key.startswith('_'):
|
||||
continue
|
||||
result[key] = extract_attr(value)
|
||||
except TypeError:
|
||||
return None
|
||||
|
||||
return result
|
@ -13,6 +13,8 @@
|
||||
# under the License.
|
||||
#
|
||||
|
||||
import json
|
||||
|
||||
from osc_lib.command import command
|
||||
|
||||
|
||||
@ -59,3 +61,22 @@ class DeleteNode(command.Command):
|
||||
for node in parsed_args.node:
|
||||
rsd_client.node.delete(node)
|
||||
print("Node {0} has been deleted.".format(node))
|
||||
|
||||
|
||||
class ShowNode(command.Command):
|
||||
_description = "Display node details"
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ShowNode, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'node',
|
||||
metavar='<node>',
|
||||
help='ID of the node.')
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
self.log.debug("take_action(%s)", parsed_args)
|
||||
rsd_client = self.app.client_manager.rsd
|
||||
node_detail = rsd_client.node.show(parsed_args.node)
|
||||
print("{0}".format(json.dumps(node_detail, indent=2)))
|
||||
|
0
rsdclient/tests/common/__init__.py
Normal file
0
rsdclient/tests/common/__init__.py
Normal file
77
rsdclient/tests/common/fakes.py
Normal file
77
rsdclient/tests/common/fakes.py
Normal file
@ -0,0 +1,77 @@
|
||||
# Copyright 2017 Intel, 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.
|
||||
#
|
||||
|
||||
|
||||
FAKE_NODE_PYTHON_DICT = {
|
||||
"description": "Node for testing",
|
||||
"processor_summary": {
|
||||
"count": 1,
|
||||
"model": "fake processor model",
|
||||
"health": "OK"
|
||||
},
|
||||
"composed_node_state": "allocated",
|
||||
"boot": {
|
||||
"mode": "fake boot mode",
|
||||
"enabled": "once",
|
||||
"target": "pxe",
|
||||
"allowed_values": ["pxe", "hdd"]
|
||||
},
|
||||
"uuid": "fd011520-86a2-11e7-b4d4-5d323196a3e4",
|
||||
"power_state": "on",
|
||||
"memory_summary": {
|
||||
"size_gib": 8,
|
||||
"health": "OK"
|
||||
},
|
||||
"identity": "1",
|
||||
"name": "Test"
|
||||
}
|
||||
|
||||
|
||||
class FakeProcessorSummary(object):
|
||||
|
||||
def __init__(self):
|
||||
self.count = 1
|
||||
self.model = "fake processor model"
|
||||
self.health = "OK"
|
||||
|
||||
|
||||
class FakeBoot(object):
|
||||
|
||||
def __init__(self):
|
||||
self.mode = "fake boot mode"
|
||||
self.enabled = "once"
|
||||
self.target = "pxe"
|
||||
self.allowed_values = ["pxe", "hdd"]
|
||||
|
||||
|
||||
class FakeMemorySummary(object):
|
||||
|
||||
def __init__(self):
|
||||
self.size_gib = 8
|
||||
self.health = "OK"
|
||||
|
||||
|
||||
class FakeNode(object):
|
||||
|
||||
def __init__(self):
|
||||
self.name = "Test"
|
||||
self.description = "Node for testing"
|
||||
self.identity = "1"
|
||||
self.power_state = "on"
|
||||
self.composed_node_state = "allocated"
|
||||
self.boot = FakeBoot()
|
||||
self.processor_summary = FakeProcessorSummary()
|
||||
self.memory_summary = FakeMemorySummary()
|
||||
self.uuid = "fd011520-86a2-11e7-b4d4-5d323196a3e4"
|
28
rsdclient/tests/common/test_utils.py
Normal file
28
rsdclient/tests/common/test_utils.py
Normal file
@ -0,0 +1,28 @@
|
||||
# Copyright 2017 Intel, 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 testtools
|
||||
|
||||
from rsdclient.common import utils
|
||||
from rsdclient.tests.common import fakes
|
||||
|
||||
|
||||
class UtilsTest(testtools.TestCase):
|
||||
|
||||
def test_compose_node(self):
|
||||
fake_node = fakes.FakeNode()
|
||||
result = utils.extract_attr(fake_node)
|
||||
expected = fakes.FAKE_NODE_PYTHON_DICT
|
||||
self.assertEqual(result, expected)
|
@ -16,13 +16,14 @@
|
||||
import mock
|
||||
import testtools
|
||||
|
||||
from rsdclient.tests.common import fakes
|
||||
from rsdclient.v1 import node
|
||||
|
||||
|
||||
class ClusterManagerTest(testtools.TestCase):
|
||||
class NodeTest(testtools.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(ClusterManagerTest, self).setUp()
|
||||
super(NodeTest, self).setUp()
|
||||
self.client = mock.Mock()
|
||||
self.client._nodes_path = '/redfish/v1/Nodes'
|
||||
self.mgr = node.NodeManager(self.client)
|
||||
@ -44,3 +45,9 @@ class ClusterManagerTest(testtools.TestCase):
|
||||
self.mgr.delete(node_id)
|
||||
self.mgr.client.get_node.assert_called_once_with('/redfish/v1/Nodes/1')
|
||||
mock_node.delete_node.assert_called_once()
|
||||
|
||||
def test_show_node(self):
|
||||
self.client.get_node.return_value = fakes.FakeNode()
|
||||
result = self.mgr.show('1')
|
||||
expected = fakes.FAKE_NODE_PYTHON_DICT
|
||||
self.assertEqual(result, expected)
|
||||
|
@ -16,6 +16,7 @@
|
||||
import os
|
||||
|
||||
from rsdclient.common import base
|
||||
from rsdclient.common import utils
|
||||
|
||||
|
||||
class NodeManager(base.Manager):
|
||||
@ -35,3 +36,7 @@ class NodeManager(base.Manager):
|
||||
|
||||
def delete(self, node_id):
|
||||
self.client.get_node(self._get_node_uri(node_id)).delete_node()
|
||||
|
||||
def show(self, node_id):
|
||||
node = self.client.get_node(self._get_node_uri(node_id))
|
||||
return utils.extract_attr(node)
|
||||
|
Loading…
x
Reference in New Issue
Block a user