SoftLayer

SoftLayerのネットワークストレージをAPIで見てみる

More than 3 years have passed since last update.

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

実行結果

screenshot-sl-iscsi2.png

ちなみに

ちなみに、sl iscsi listでは、Legacy iSCSIのボリュームのみ表示されてCPSのボリュームは表示されませんが、sl iscsi detail <id>にCPSボリュームのIDを指定すると、CPSボリュームの詳細情報を取得できます(GitHubのsoftlayer-python v3.3.0)。ちょっと不思議な動作ですね。

これはsl iscsi listsl iscsi detail <id>で、ボリュームの情報の取得に使っているAPIが異なるためです。

CLIの処理は直接APIを呼び出すのではなくManagerクラスを通して行われますが、iSCSIの場合はISCSIManagerというクラスを使用しています。

sl iscsi list で使われているISCSIManager.list_iscsi()は、(上記のスクリプトで使っているAccount.getNetworkStorage()ではなく) 内部でAccount.getIscsiNetworkStorage()を呼び出していますが、このメソッドはLegacy iSCSIのボリュームのリストを返しますが、CPSのiSCSIボリュームは返しません。

CLI/iscsi/list.py
    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ボリュームの情報も返します。

CLI/iscsi/detail.py
    iscsi_mgr = SoftLayer.ISCSIManager(env.client)

    iscsi_id = helpers.resolve_id(iscsi_mgr.resolve_ids, identifier, 'iSCSI')
    result = iscsi_mgr.get_iscsi(iscsi_id)
managers/iscsi.py
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に上げておこうかと思います。

参考