SoftLayer APIで仮想サーバー&ベアメタルを一覧表示するスクリプト

あまり新しいネタではないのですが。。。


## やること

### 仮想サーバー&ベアメタルの一覧表示

SoftLayer CLIでは、仮想サーバーとベアメタルの情報を表示するコマンドが異なっています。

```bash
$ sl vs list      # 仮想サーバー
$ sl server list  # ベアメタルサーバー
```

SoftLayer APIで、仮想サーバーとベアメタルを同じリストに表示してみます。

### 属性の追加

それだけではつまらないので、デフォルトで```sl (vs|server) list```で表示される属性に加えて、以下の属性を追加しています。

| ヘッダ | ヘッダの意味 |
|-----|-----|
| bm?| ベアメタルかどうか |
| fcr | Frontend Customer Router | 
| bcr | Backend Customer Router|
| mfee$ | 月次課金の場合のFee |
| hfee$ | 時間課金の場合のfee | 
| out_bw | 使用帯域 |
| vlan | VLAN数 |


## スクリプト

```py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
from prettytable import PrettyTable
import SoftLayer
import sluser

SL_USERNAME = sluser.SL_USERNAME
SL_API_KEY = sluser.SL_API_KEY

_maskVirtualGuest = '''
    id,
    fullyQualifiedDomainName,
    primaryIpAddress,
    primaryBackendIpAddress,
    datacenter,
    location.pathString,
    billingItem.orderItem.order.userRecord.username,
    frontendRouters.hostname,
    backendRouters.hostname,
    billingItem.orderItem.recurringFee,
    billingItem.orderItem.hourlyRecurringFee,
    outboundPublicBandwidthUsage,
    networkVlans,
    networkVlanCount
    '''

_maskHardware = '''
    id,
    bareMetalInstanceFlag,
    fullyQualifiedDomainName,
    primaryIpAddress,
    primaryBackendIpAddress,
    datacenter,
    location.pathString,
    billingItem.orderItem.order.userRecord.username,
    frontendRouters.hostname,
    backendRouters.hostname,
    billingItem.orderItem.recurringFee,
    billingItem.orderItem.hourlyRecurringFee,
    outboundPublicBandwidthUsage,
    networkVlans,
    networkVlanCount
    '''

_tableHeader = [
    'id',
    'bm?',
    'fqdn',
    'public_ip',
    'backend_ip',
    'dc',
    'location',
    'owner',
    'fcr',
    'bcr',
    'mfee$',
    'hfee$',
    'out_bw',
    'vlan'
    ]

def lookup(dic, key, *keys):
    """A generic dictionary access helper.

    This helps simplify code that uses heavily nested dictionaries. It will
    return None if any of the keys in *keys do not exist.
    """
    if keys:
        return lookup(dic.get(key, {}), *keys)
    return dic.get(key)


client = SoftLayer.Client(username=SL_USERNAME, api_key=SL_API_KEY)

virtualGuests = client['Account'].getVirtualGuests(mask=_maskVirtualGuest)
hardwares = client['Account'].getHardware(mask=_maskHardware)

instances = hardwares + virtualGuests

# Table definition
table = PrettyTable(_tableHeader)
table.padding_width = 1

# Get virtualGuests
count = 0
for inst in instances:
    table.add_row(
        [
            inst['id'],
            inst.get('bareMetalInstanceFlag','-'),
            inst['fullyQualifiedDomainName'],
            inst.get('primaryIpAddress', '--'),
            inst['primaryBackendIpAddress'],
            inst['datacenter']['name'],
            inst['location']['pathString'],
            lookup(inst, 'billingItem', 'orderItem', 'order', 'userRecord','username') or '--',
            inst['frontendRouters']['hostname'].split('.')[0] if not isinstance(inst['frontendRouters'],list) else inst['frontendRouters'][0]['hostname'].split('.')[0],
            inst['backendRouters'][0]['hostname'].split('.')[0],
            lookup(inst, 'billingItem', 'orderItem', 'recurringFee') or '-',
            lookup(inst, 'billingItem', 'orderItem', 'hourlyRecurringFee') or '-',
            round(float(inst['outboundPublicBandwidthUsage']),1),
            inst['networkVlanCount']
        ]
    )
    count = count + 1

print(table)
print(count, "instances")

exit()
```

## 実行結果


![sc 2015-01-30 am1.16.27.png](https://qiita-image-store.s3.amazonaws.com/0/65167/d8dddb8a-9b9d-d468-566f-b9a235052885.png)