Add list storage services command
Add new command 'rsd storage list' to allow user to list all storage services brief info like below shows. $ openstack rsd storage list +----------+-----------------+-----------------------------+ | Identity | Name | Description | +----------+-----------------+-----------------------------+ | 1 | Storage Service | Storage Service for Testing | +----------+-----------------+-----------------------------+ Change-Id: Id54e630881de4c79f731ca93e6bf7a3c18fe6589
This commit is contained in:
parent
c07b1fe383
commit
c09c76951e
26
rsdclient/osc/v1/storage.py
Normal file
26
rsdclient/osc/v1/storage.py
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
from rsdclient.common import command
|
||||||
|
|
||||||
|
|
||||||
|
class ListStorage(command.Command):
|
||||||
|
_description = "List all storage services"
|
||||||
|
|
||||||
|
def take_action(self, parsed_args):
|
||||||
|
self.log.debug("take_action(%s)", parsed_args)
|
||||||
|
rsd_client = self.app.client_manager.rsd
|
||||||
|
storage_service_list = rsd_client.storage.list()
|
||||||
|
print(storage_service_list)
|
@ -13,6 +13,8 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
from rsdclient.common import utils
|
||||||
|
|
||||||
|
|
||||||
FAKE_NODE_PYTHON_DICT = {
|
FAKE_NODE_PYTHON_DICT = {
|
||||||
"description": "Node for testing",
|
"description": "Node for testing",
|
||||||
@ -75,3 +77,68 @@ class FakeNode(object):
|
|||||||
self.processor_summary = FakeProcessorSummary()
|
self.processor_summary = FakeProcessorSummary()
|
||||||
self.memory_summary = FakeMemorySummary()
|
self.memory_summary = FakeMemorySummary()
|
||||||
self.uuid = "fd011520-86a2-11e7-b4d4-5d323196a3e4"
|
self.uuid = "fd011520-86a2-11e7-b4d4-5d323196a3e4"
|
||||||
|
|
||||||
|
|
||||||
|
class FakeRemoteTarget(object):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.addresses = [{
|
||||||
|
'iSCSI': {
|
||||||
|
'TargetIQN': 'base_logical_volume_target',
|
||||||
|
'TargetLUN': [{
|
||||||
|
'LUN': 1,
|
||||||
|
'LogicalDrive': {
|
||||||
|
'@odata.id': '/redfish/v1/Services/1/LogicalDrives/2'
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
'TargetPortalIP': '10.2.0.4',
|
||||||
|
'TargetPortalPort': 3260
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
self.identity = '1'
|
||||||
|
self.initiator = [{'iSCSI': {'InitiatorIQN': 'ALL'}}]
|
||||||
|
self.redfish_version = '1.0.0'
|
||||||
|
self.target_type = 'iSCSITargets'
|
||||||
|
|
||||||
|
|
||||||
|
class FakePhysicalDrive(object):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.capacity_gib = 931
|
||||||
|
self.drive_type = 'HDD'
|
||||||
|
self.identity = '1'
|
||||||
|
self.interface = 'SATA'
|
||||||
|
self.manufacturer = 'fake manufacture'
|
||||||
|
self.model = 'ST1000NM0033-9ZM'
|
||||||
|
self.redfish_version = '1.0.0'
|
||||||
|
self.rpm = 7200
|
||||||
|
self.serial_number = 'Z1W23Q3V'
|
||||||
|
|
||||||
|
|
||||||
|
class FakeLogicalDrive(object):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.bootable = True
|
||||||
|
self.capacity_gib = 5589
|
||||||
|
self.drive_type = 'LVM'
|
||||||
|
self.identity = '2'
|
||||||
|
self.image = 'fake image'
|
||||||
|
self.mode = 'LVG'
|
||||||
|
self.protected = False
|
||||||
|
self.redfish_version = '1.0.0'
|
||||||
|
self.snapshot = False
|
||||||
|
|
||||||
|
|
||||||
|
class FakeStorageSerice(object):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.description = 'Storage Service for Testing'
|
||||||
|
self.identity = '1'
|
||||||
|
self.name = 'Storage Service'
|
||||||
|
self.redfish_version = '1.0.0'
|
||||||
|
self.remote_targets = [FakeRemoteTarget()]
|
||||||
|
self.physical_drives = [FakePhysicalDrive()]
|
||||||
|
self.logical_drives = [FakeLogicalDrive()]
|
||||||
|
|
||||||
|
|
||||||
|
FAKE_STORAGE_PYTHON_DICT = utils.extract_attr(FakeStorageSerice())
|
||||||
|
51
rsdclient/tests/v1/test_storage.py
Normal file
51
rsdclient/tests/v1/test_storage.py
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
# 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 mock
|
||||||
|
import testtools
|
||||||
|
|
||||||
|
from rsdclient.tests.common import fakes
|
||||||
|
from rsdclient.v1 import storage
|
||||||
|
|
||||||
|
|
||||||
|
class NodeTest(testtools.TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(NodeTest, self).setUp()
|
||||||
|
self.client = mock.Mock()
|
||||||
|
self.client._storage_service_path = '/redfish/v1/Services'
|
||||||
|
self.mgr = storage.StorageManager(self.client)
|
||||||
|
|
||||||
|
def test_list_storage(self):
|
||||||
|
mock_storage_collection = mock.Mock()
|
||||||
|
mock_storage_collection.members_identities = \
|
||||||
|
('/redfish/v1/Services/1',)
|
||||||
|
self.mgr.client.get_storage_service_collection.return_value = \
|
||||||
|
mock_storage_collection
|
||||||
|
self.mgr.client.get_storage_service.return_value = \
|
||||||
|
fakes.FakeStorageSerice()
|
||||||
|
|
||||||
|
expected = (
|
||||||
|
'+----------+-----------------+-----------------------------+\n'
|
||||||
|
'| Identity | Name | Description |\n'
|
||||||
|
'+----------+-----------------+-----------------------------+\n'
|
||||||
|
'| 1 | Storage Service | Storage Service for Testing |\n'
|
||||||
|
'+----------+-----------------+-----------------------------+')
|
||||||
|
|
||||||
|
result = self.mgr.list()
|
||||||
|
self.mgr.client.get_storage_service_collection.assert_called_once()
|
||||||
|
self.mgr.client.get_storage_service.assert_called_once_with(
|
||||||
|
'/redfish/v1/Services/1')
|
||||||
|
self.assertEqual(str(result), expected)
|
@ -16,6 +16,7 @@
|
|||||||
import rsd_lib
|
import rsd_lib
|
||||||
|
|
||||||
from rsdclient.v1 import node
|
from rsdclient.v1 import node
|
||||||
|
from rsdclient.v1 import storage
|
||||||
|
|
||||||
|
|
||||||
class Client(object):
|
class Client(object):
|
||||||
@ -24,3 +25,4 @@ class Client(object):
|
|||||||
self.client = rsd_lib.RSDLib(base_url, username, password,
|
self.client = rsd_lib.RSDLib(base_url, username, password,
|
||||||
verify=verify)
|
verify=verify)
|
||||||
self.node = node.NodeManager(self.client)
|
self.node = node.NodeManager(self.client)
|
||||||
|
self.storage = storage.StorageManager(self.client)
|
||||||
|
41
rsdclient/v1/storage.py
Normal file
41
rsdclient/v1/storage.py
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
# 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 os
|
||||||
|
|
||||||
|
from rsdclient.common import base
|
||||||
|
from rsdclient.common import utils
|
||||||
|
|
||||||
|
|
||||||
|
class StorageManager(base.Manager):
|
||||||
|
_resource_name = 'storages'
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super(StorageManager, self).__init__(*args, **kwargs)
|
||||||
|
self.storage_service_path = self.client._storage_service_path
|
||||||
|
|
||||||
|
def _get_storage_service_uri(self, storage_service_id):
|
||||||
|
return os.path.join(self.storage_service_path, storage_service_id)
|
||||||
|
|
||||||
|
def list(self):
|
||||||
|
storage_service_collection = \
|
||||||
|
self.client.get_storage_service_collection()
|
||||||
|
storages = [utils.extract_attr(self.client.
|
||||||
|
get_storage_service(storage_uri))
|
||||||
|
for storage_uri in storage_service_collection.
|
||||||
|
members_identities]
|
||||||
|
storage_info_table = utils.print_dict(
|
||||||
|
storages, ["Identity", "Name", "Description"])
|
||||||
|
return storage_info_table
|
@ -33,6 +33,8 @@ openstack.rsd.v1 =
|
|||||||
rsd_node_show = rsdclient.osc.v1.node:ShowNode
|
rsd_node_show = rsdclient.osc.v1.node:ShowNode
|
||||||
rsd_node_list = rsdclient.osc.v1.node:ListNode
|
rsd_node_list = rsdclient.osc.v1.node:ListNode
|
||||||
|
|
||||||
|
rsd_storage_list = rsdclient.osc.v1.storage:ListStorage
|
||||||
|
|
||||||
[build_sphinx]
|
[build_sphinx]
|
||||||
all-files = 1
|
all-files = 1
|
||||||
warning-is-error = 1
|
warning-is-error = 1
|
||||||
|
Loading…
x
Reference in New Issue
Block a user