ShinobiLayer: Bluemix Infrastructure（旧SoftLayer）におけるVLANトランク設定のAPI

2022/05/09
UIからでも、以下のようにVLANの構成画面にてトランク構成ができるようになりました。
https://cloud.ibm.com/docs/vlans?topic=vlans-configuring-vlan-trunks&interface=ui&locale=en
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/3f577b90-f15c-ad51-b387-4e3cf1a1940b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/2f48ac84-20ec-2d2d-f8e3-23d65b53c0c0.png)



# 1. はじめに
Bluemix Infrastructure（旧SoftLayer）にはVLANの考え方があり、Bluemix Infrastructureの物理スイッチ側でトランクVLANの設定を行うことも可能です。つまり、物理サーバーをプロビジョニングするVLAN(Primary IPが割り当てられるVLAN）はネイティブVLANとして動作しますが、TicketやAPIを通じて別途注文したVLANをトランクすることができます。
これにより、1つのNICで複数のVLANと通信することができるようになり、VMware製品などでセグメント化する際やゾーニングに利用することが可能となります。
※注意1. 仮想サーバーではハイパーバイザーをBluemixが管理しているため、トランク設定はできません。
※注意2. Vyatta Gateway ApplianceでVLANをAssociatedした状態でrouted/bypassモードを変更することができますが、これも内部的にはトランクのON/OFFを行っています。

VLANトランクの設定作業は、Ticketで以下のように依頼することも可能ですが、、、毎回チケットを起票しなければいけないとか、本当に設定されているのかを自分で行いたいという要望もあるかと思います。よって、ここではそのためのAPI例を挙げたいと思います。
> Subject: Trunk VLANs on eth0 & eth2
> Details: Please trunk VLANs 1101,1102, and 1103 on eth0 & eth2 NIC pair for each hostxxx.softlayer.com, yyy.softlayer.com and zzz.softlayer.com

# 2. VLANトランク設定用APIのポイント
このあたりを利用すれば良さそうです。
http://developer.softlayer.com/reference/services/SoftLayer_Network_Component/addNetworkVlanTrunks
http://developer.softlayer.com/reference/services/SoftLayer_Network_Component/clearNetworkVlanTrunks
http://developer.softlayer.com/reference/services/SoftLayer_Network_Component/getNetworkVlanTrunks
http://developer.softlayer.com/reference/services/SoftLayer_Network_Component/removeNetworkVlanTrunks

ただし、このリンク中の説明によると、TrunkVLANを取得するためには、Hardware -> Network_Component -> uplinkComponent（これもNetwork_Component型） -> networkVlanTrunksとアクセスする必要がありそうです。Hardware -> Network_Component -> networkVlanTrunksでは取得できません。

Add VLANs as trunks to a network component. The VLANs given must be assigned to your account, and on the router to which this network component is connected. The current native VLAN (networkVlanId/networkVlan) cannot be added as a trunk. **This method should be called on a network component attached directly to customer assigned hardware, though all trunking operations will occur on the uplinkComponent. A current list of VLAN trunks for a network component on a customer server can be found at 'uplinkComponent->networkVlanTrunks'.**
This method returns an array of SoftLayer_Network_Vlans which were added as trunks. Any requested trunks which are already trunked will be silently ignored, and will not be returned.
Configuration of network hardware is done asynchronously, do not depend on the return of this call as an indication that the newly trunked VLANs will be accessible.

# 3. VLANトランク設定の取得例

```py:getVLANinfoByHWID.py
import SoftLayer
import sys
parm=sys.argv
hwid=parm[1]
print("HWID : %s" % hwid)

client = SoftLayer.create_client_from_env()
hwobj = client.call('Hardware', 'getObject', id=hwid, mask="networkComponents.uplinkComponent[networkVlan,networkVlanTrunks.networkVlan]")

print("fullyQualifiedDomainName   : %s" % hwobj['fullyQualifiedDomainName'])
for networkComponent in hwobj['networkComponents']:
    print("-------------------------------------------")
    print("NW Component ID  : %s" % networkComponent['id'])
    print("name+port        : %s" % networkComponent['name'] + str(networkComponent['port']))
    print("speed            : %s" % networkComponent['speed'])
    print("maxSpeed         : %s" % networkComponent['maxSpeed'])
    print("status           : %s" % networkComponent['status'])
    print("primaryIpAddress : %s" % networkComponent.get('primaryIpAddress'))
    print("macAddress       : %s" % networkComponent.get('macAddress'))
    print("ipmiIpAddress    : %s" % networkComponent.get('ipmiIpAddress'))
    print("ipmiMacAddress   : %s" % networkComponent.get('ipmiMacAddress'))

    if ('uplinkComponent' in networkComponent):
        uplinkComponent = networkComponent['uplinkComponent']
        print("SwitchFQDN       : %s" % uplinkComponent['hardware']['fullyQualifiedDomainName'])
        print("NativeVLAN-ID    : %s" % uplinkComponent['networkVlan']['id'])
        print("NativeVLAN-number: %s" % uplinkComponent['networkVlan']['vlanNumber'])
        for networkVlanTrunk in uplinkComponent['networkVlanTrunks']:
            print("TrunkVLAN-ID     : %s" % networkVlanTrunk['networkVlan']['id'])
            print("TrunkVLAN-number : %s" % networkVlanTrunk['networkVlan']['vlanNumber'])

```

HWIDをパラメーターとして指定する必要があります。取得方法は色々ありますが、以下のようにCustomer Portalからも簡単に確認することができます。
![HWID.jpg](https://qiita-image-store.s3.amazonaws.com/0/62127/4dcc5570-6fdb-83ba-4490-4fafeed56ed9.jpeg)


```txt:実行例
# python getVLANinfoByHWID.py 557457
HWID : 557457
fullyQualifiedDomainName   : esx01.softlayer.com
-------------------------------------------
NW Component ID  : 4220479
name+port        : mgmt0
speed            : 100
maxSpeed         : 100
status           : ACTIVE
primaryIpAddress : None
macAddress       : None
ipmiIpAddress    : 10.132.34.157
ipmiMacAddress   : 02:25:90:fa:9c:60
SwitchFQDN       : bms179.sr02.tok02.softlayer.com
NativeVLAN-ID    : 1227573
NativeVLAN-number: 1756
NativeVLAN-name  : 1.Mgmt(Native VLAN)
-------------------------------------------
NW Component ID  : 4220471
name+port        : eth0
speed            : 10000
maxSpeed         : 10000
status           : ACTIVE
primaryIpAddress : 10.132.34.136
macAddress       : 00:25:90:fa:9c:60
ipmiIpAddress    : None
ipmiMacAddress   : None
SwitchFQDN       : bcs179a.sr02.tok02.softlayer.com
NativeVLAN-ID    : 1227573
NativeVLAN-number: 1756
NativeVLAN-name  : 1.Mgmt(Native VLAN)
TrunkVLAN-ID     : 1228573
TrunkVLAN-number : 1930
TrunkVLAN-name   : 2.vMotion/FT/Storage
-------------------------------------------
NW Component ID  : 4220473
name+port        : eth1
speed            : 0
maxSpeed         : 10000
status           : USER_OFF
primaryIpAddress : 161.202.139.28
macAddress       : 00:25:90:fa:9c:61
ipmiIpAddress    : None
ipmiMacAddress   : None
SwitchFQDN       : fcs179a.sr02.tok02.softlayer.com
NativeVLAN-ID    : 1227571
NativeVLAN-number: 1675
NativeVLAN-name  : Public (Native VLAN)
-------------------------------------------
NW Component ID  : 4220475
name+port        : eth2
speed            : 10000
maxSpeed         : 10000
status           : ACTIVE
primaryIpAddress : None
macAddress       : 00:25:90:fa:9c:62
ipmiIpAddress    : None
ipmiMacAddress   : None
SwitchFQDN       : bcs179b.sr02.tok02.softlayer.com
NativeVLAN-ID    : 1227573
NativeVLAN-number: 1756
NativeVLAN-name  : 1.Mgmt(Native VLAN)
TrunkVLAN-ID     : 1228573
TrunkVLAN-number : 1930
TrunkVLAN-name   : 2.vMotion/FT/Storage
-------------------------------------------
NW Component ID  : 4220477
name+port        : eth3
speed            : 0
maxSpeed         : 10000
status           : USER_OFF
primaryIpAddress : None
macAddress       : 00:25:90:fa:9c:63
ipmiIpAddress    : None
ipmiMacAddress   : None
SwitchFQDN       : fcs179b.sr02.tok02.softlayer.com
NativeVLAN-ID    : 1227571
NativeVLAN-number: 1675
NativeVLAN-name  : Public (Native VLAN)

```

# 4. VLANトランク設定の追加例

```py:addVLANTrunk.py
import SoftLayer
import sys
parm=sys.argv
eth0NWComponentID=parm[1]
eth2NWComponentID=parm[2]
vlanNumber=parm[3]

client = SoftLayer.create_client_from_env()

#Add
client.call('Network_Component','addNetworkVlanTrunks', [{'vlanNumber': vlanNumber}], id=eth0NWComponentID)
client.call('Network_Component','addNetworkVlanTrunks', [{'vlanNumber': vlanNumber}], id=eth2NWComponentID)

```

```text:実行例
# python addVLANTrunk.py 4220471 4220475 1930
```

# 5. VLANトランク設定の削除例

```py:removeVLANTrunk.py
import SoftLayer
import sys
parm=sys.argv
eth0NWComponentID=parm[1]
eth2NWComponentID=parm[2]
vlanNumber=parm[3]

client = SoftLayer.create_client_from_env()

#Remove
client.call('Network_Component','removeNetworkVlanTrunks', [{'vlanNumber': vlanNumber}], id=eth0NWComponentID)
client.call('Network_Component','removeNetworkVlanTrunks', [{'vlanNumber': vlanNumber}], id=eth2NWComponentID)

```

```text:実行例
# python removeVLANTrunk.py 4220471 4220475 1930
```