SoftLayerでは実に多様な種類のネットワークストレージを提供していて、Portalから簡単にオーダーして利用できます。
これらのネットワークストレージの情報はPortalから参照することもできますが、詳細を一覧で表示するためにスクリプトを作ってみました。実は、SoftLayer CLIの sl iscsi list
コマンド や sl iscsi detail <id>
コマンドでもほぼ同じ情報が取得できますが、
- 詳細まで一覧で見られるほうが便利
- CPSのボリュームは
sl iscsi list
コマンドでは表示されない
という理由から、その対応も含めて作成してみました。
仕組み
Account.getNetworkStorage()
メソッドを呼び出して、ネットワークストレージの情報を取得して、必要なプロパティを取得しているだけの単純な仕組みです。このメソッドは、SoftLayerが提供する以下のネットワークストレージサービスの情報を返します。
- NAS
- Legacy iSCSI Storage
- Consistent Performance Storage
- Object Storage
- EVault Backup
QuantaStorやローカルストレージなどの情報は、このメソッドでは取得できません。
スクリプト
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from prettytable import PrettyTable
import SoftLayer
import sluser
SL_USERNAME = sluser.SL_USERNAME
SL_API_KEY = sluser.SL_API_KEY
_maskNetworkStorage = '''
hardware,
iops,
osTypeId,
serviceResource,
serviceResource.datacenter,
serviceResourceName,
serviceResourceBackendIpAddress,
storageGroups,
vendorName
'''
_tableHeader = [
'id',
'nasType',
'datacenter',
'username',
'gb',
'iops',
'serviceResourceName',
'serviceResourceBackendIpAddress',
'serviceResourceType',
'hardware',
'vendorName',
'osTypeId'
]
def lookup(dic, key, *keys):
if keys:
return lookup(dic.get(key, {}), *keys)
return dic.get(key)
client = SoftLayer.Client(username=SL_USERNAME, api_key=SL_API_KEY)
networkStorage = client['Account'].getNetworkStorage(mask=_maskNetworkStorage)
# Table definition
table = PrettyTable(_tableHeader)
table.padding_width = 1
for ns in networkStorage:
table.add_row(
[
ns['id'],
ns['nasType'],
ns['serviceResource']['datacenter'].get('name'),
ns['username'],
ns['capacityGb'],
lookup(ns, 'iops') or '-' ,
ns['serviceResourceName'],
ns['serviceResourceBackendIpAddress'],
lookup(ns, 'serviceResource', 'type', 'type') or '-',
lookup(ns, 'hardware') or '-',
lookup(ns, 'vendorName') or '-',
lookup(ns, 'osTypeId') or '-',
]
)
print(table)
実行方法
python sl_getNetworkStorage.py
実行結果
ちなみに
ちなみに、sl iscsi list
では、Legacy iSCSIのボリュームのみ表示されてCPSのボリュームは表示されませんが、sl iscsi detail <id>
にCPSボリュームのIDを指定すると、CPSボリュームの詳細情報を取得できます(GitHubのsoftlayer-python v3.3.0)。ちょっと不思議な動作ですね。
これはsl iscsi list
とsl iscsi detail <id>
で、ボリュームの情報の取得に使っているAPIが異なるためです。
CLIの処理は直接APIを呼び出すのではなくManagerクラスを通して行われますが、iSCSIの場合はISCSIManager
というクラスを使用しています。
sl iscsi list
で使われているISCSIManager.list_iscsi()
は、(上記のスクリプトで使っているAccount.getNetworkStorage()
ではなく) 内部でAccount.getIscsiNetworkStorage()
を呼び出していますが、このメソッドはLegacy iSCSIのボリュームのリストを返しますが、CPSのiSCSIボリュームは返しません。
iscsi_mgr = SoftLayer.ISCSIManager(env.client)
iscsi_list = iscsi_mgr.list_iscsi()
一方、sl iscsi detail <id>
で使われているISCSIManager.get_iscsi()
は、内部でAccount.Network_Storage_Iscsi.getObject()
を呼び出しています。idを指定してこのメソッドを呼び出すと、Legacy iSCSIだけでなく、CPSボリュームの情報も返します。
iscsi_mgr = SoftLayer.ISCSIManager(env.client)
iscsi_id = helpers.resolve_id(iscsi_mgr.resolve_ids, identifier, 'iSCSI')
result = iscsi_mgr.get_iscsi(iscsi_id)
class ISCSIManager(utils.IdentifierMixin, object):
"""Manages iSCSI storages."""
def __init__(self, client):
self.configuration = {}
self.client = client
self.iscsi_svc = self.client['Network_Storage_Iscsi']
self.product_order = self.client['Product_Order']
...
def list_iscsi(self):
"""List iSCSI volume."""
account = self.client['Account']
iscsi_list = account.getIscsiNetworkStorage(
mask='eventCount,serviceResource[datacenter.name]')
return iscsi_list
def get_iscsi(self, volume_id, **kwargs):
...
return self.iscsi_svc.getObject(id=volume_id, **kwargs)
この違いから上のような動作になっているわけです。
CPSボリュームもsl iscsi list
で表示されるようにしてね、できたらストレージの種類もわかるといいな、ってissueをGitHubに上げておこうかと思います。