ShinobiLayer: SoftLayer API 次の一歩: 明確にデータ型を宣言してEvaultの情報を取得する

#はじめに
ある特定のデータを取得したい時には、API Referenceでデータ型オブジェクトの一覧から検索を行うと思います。しかし、特定のデータ型はどうやってrelationを辿っても、該当のmethodにたどり着けないものがあるのです。。。
今回の例もまさにそういう例外（？）の１例です。下記記事ではさらっとしか書かなかった、「maskによる明確なデータ型の宣言」が今回のテーマです。
http://qiita.com/testnin2/items/80b7808b1a69babcde65


#明確なデータ型の宣言を行う
デフォルトでは、method実行によって返ってきたデータ型オブジェクトの型は暗黙として決まっており、特に設定を行う必要はありません。しかし、特定のプロパティ値を取得するために明確に型を宣言する必要がある場合があります。
例えば、eVaultのデータ型オブジェクトを取得するために、SoftLayer_AccountサービスのgetEvaultNetworkStorage（http://sldn.softlayer.com/reference/services/SoftLayer_Account/getEvaultNetworkStorage）を見てみましょう。
![getEvault.jpg](https://qiita-image-store.s3.amazonaws.com/0/62127/30f05690-3cb0-da0e-544c-4ccc979b1bc0.jpeg)

よく見ると、戻り値の型が**SoftLayer_Network_Storage**になっています。せっかくEvaultのストレージに関するオブジェクトを返しているのに、ネットワークストレージ全般を表すSoftLayer_Network_Storageという広義のデータ型が返ってきています。残念ながら、このままだとネットワークストレージという広義のデータに対してのプロパティにはアクセスできても、eVault固有のプロパティが取得できないのです。

というので、「これは単なるSoftLayer_Network_Storageじゃなくて、SoftLayer_Network_Storage_Backup_Evault_Version6なのだ！」と型を宣言してあげて、データ固有のプロパティにもアクセスできるようにしてあげるのが今回の肝となります。これは、SoftLayer_Network_Storage_Backup_Evault_Version6がSoftLayer_Network_Storageを拡張して作られているからできるワザですが、*こういう親子関係を見つけるのは非常に難しいです。正直、感を働かせながら試行錯誤せざるを得ない気がします。*　

型はmask値を指定する時に設定します。具体的には、
1.  `mask=xxx, yyy, zzz`という風に指定ができると以前解説しましたが、これは
2.  `mask=mask[xxx, yyy, zzz`]のように書けます。これを`mask=mask(データ型）[xxx, yyy, zzz]`のように書いて明確なデータ型を指定するというのが今回の手法です。この点に限っては、2のように記述する方法は優れています。


#Evault情報を取得するスクリプト例
SoftLayer_Network_Storage_Backup_Evault_Version6（http://sldn.softlayer.com/reference/datatypes/SoftLayer_Network_Storage_Backup_Evault_Version6） にしか存在しない totalBytesUsed, backupJobDetails, restoreJobDetails, agentStatusesなどのプロパティを以下のように取得することができます。これらは、SoftLayer_Network_Storageの型のままではアクセスできなかったプロパティです。明示的に型を宣言したおかげですね。

```py:getEvaultDetails.py
import SoftLayer
import pprint
pp = pprint.PrettyPrinter(indent=4)
client = SoftLayer.create_client_from_env()
objectmask = """
        mask(SoftLayer_Network_Storage_Backup_Evault_Version6)
        [
            totalBytesUsed,
            backupJobDetails,
            restoreJobDetails,
            agentStatuses
        ]
"""
acct = client['Account'].getEvaultNetworkStorage(mask=objectmask)
pp.pprint(acct)
```

```
実行結果
#python getEvaultDetails.py
（途中略）
    {   'accountId': XXXXXX,
        'agentStatuses': [   {   'lastBackup': '2014-11-30T21:39:06-06:00',
                                 'status': 'Backup(s) Successful'}],
        'backupJobDetails': [   {   'bytesUsed': 19358283,
                                    'description': 'MSSQL',
                                    'hardwareId': '',
                                    'lastRunDate': '2014-11-29T12:50:13-06:00',
                                    'name': 'MSSQL',
                                    'originalSize': 6378256,
                                    'percentageOfTotalUsage': 65,
                                    'result': 'Completed',
                                    'virtualGuestId': ''},
                                {   'bytesUsed': 10309207,
                                    'description': '',
                                    'hardwareId': '',
                                    'lastRunDate': '2014-11-30T21:39:06-06:00',
                                    'name': 'SAPSQL',
                                    'originalSize': 56797368,
                                    'percentageOfTotalUsage': 35,
                                    'result': 'Completed',
                                    'virtualGuestId': ''}],
        'capacityGb': 250,
        'createDate': '2014-11-19T16:30:06-06:00',
        'guestId': XXXXXXX,
        'hardwareId': '',
        'hostId': XXXXXXX,
        'id': XXXXXXX,
        'nasType': 'EVAULT',
        'password': 'XXXXXXXX',
        'restoreJobDetails': [   {   'description': 'MSSQL',
                                     'hardwareId': '',
                                     'lastRunDate': '2014-11-29T12:51:50-06:00',
                                     'name': 'MSSQL',
                                     'percentageOfTotalUsage': '',
                                     'result': 'Completed',
                                     'virtualGuestId': ''},
                                 {   'description': '',
                                     'hardwareId': '',
                                     'lastRunDate': '2014-11-30T22:10:02-06:00',
                                     'name': 'SAPSQL',
                                     'percentageOfTotalUsage': '',
                                     'result': 'Completed',
                                     'virtualGuestId': ''}],
        'serviceProviderId': 1,
        'serviceResource': {   'attributes': [],
                               'backendIpAddress': 'ev-vaultsng0101.service.softlayer.com',
                               'frontendIpAddress': '',
                               'id': 441,
                               'name': 'ev-vaultsng0101.service.softlayer.com',
                               'type': {   'type': 'EVAULT_VAULT'}},
        'serviceResourceBackendIpAddress': 'ev-vaultsng0101.service.softlayer.com',
        'serviceResourceName': 'ev-vaultsng0101.service.softlayer.com',
        'totalBytesUsed': 29667490,
        'upgradableFlag': True,
        'username': 'XXXXXXXXX-5'},

（途中略）
```

#終わりに
とはいっても、具体的に型まで意識してコードを書くのは、慣れてくるまでは大変だと思います。そもそも今回のようにどの型を拡張してどの型ができているのかを見つけるのは非常に難しいです。。。頑張って慣れていくしかないですね。

今回は、以下の記事を参考にしました。
https://forums.softlayer.com/forum/softlayer-developer-network/general-discussion/7033-softlayer-network-storage-backup-evault-version6