REST-API
big-ip
iControl

iControl RESTの基本

はじめに

iControl RESTとは、BIG-IPのステータスを取得したり、設定を変更したりするためのREST APIのことです。このページでは、iControl RESTを利用する上でのごく基本的な情報を記載します。

参考情報

環境

本ページの情報は、BIG-IPのバージョン v12.1.2 を対象に動作を確認しています。

免責事項

本ページの内容に誤り等があり、参考にされた方がなんらかの損害を被った場合、一切の責任は負いません。

iControlの基本

iControlは(ほぼ)TMSHをREST APIで実装したもの
と、DevCentralにありました。

iControl REST 101: What is iControl REST?

Once you’ve learned it in tmsh, you’ve learned it in iControl REST.
(TMSHで学習したことは、iControl RESTにも通用します。)
So…it’s just remote tmsh?
(つまり、iControl RESTとは、リモートですか?)
Well, sort of. It’s not quite as simple as that, but nearly.
(それほど単純には言えませんが、それに近いものと言えます。)

大雑把に言えば、iControlとは、REST APIで実装されたtmshインタフェースと言えます。例えば、任意のPoolのステータスを取得する場合、tmshでは"show ltm pool <pool名>"というコマンドを実行します。

iControl_Image_1_tmsh.png

これをiControlで実行する場合、"https:///mgmt/tm/ltm/pool/~Common~<pool名>/" というURLに対してGETリクエストを実行することになります。

iControl_Image_1_icontrol.png

tmshの応答は人間に読みやすくフォーマットされたテキストですが、iControl RESTでは、JSONフォーマットで応答します。

すでにBIG-IPをtmshで操作した経験がある人は、iControl RESTを使う上で必要なのは、RESTやJSONといった一般的なWeb APIに対する知識です。一方、RESTやJSONの経験がある人がBIG-IPのiControl RESTを扱おうとする場合、BIG-IPのコマンドラインインタフェースであるtmshについて調べることが近道になります。

iControl RESTのURI構造

iControl REST APIのURI構造については、次のページが参考になります。

F5 Python SDK: REST API Endpoints

http://192.168.1.1/mgmt/tm/ltm/pool/~Common~mypool/members/~Common~m1:80
                  |----|--|---|----|--------------|-------|-------------|
                  |root|OC|OC |Coll| Resource     | SC    |SubColl Resrc|

BIG-IPでは、様々なオブジェクト(例えばVirtual ServerやPool, Node)を作成しますが、ResourceやSubcoll Resourceの部分が、任意のオブジェクトを指定する部分になります。

Resourceを指定せずにGETリクエストを実行すれば、Collection配下の情報を一括で取得できます。例えば、

(tmos)# list ltm pool
ltm pool test-pool {
    members {
        NodeA:http {
            address 1.1.1.100
        }
    }
}
ltm pool test-pool1 {
    members {
        NodeB:http {
            address 1.1.1.101
        }
    }
}

このように二つのPoolが設定されている場合、

curl -sk -u admin:admin -X GET https://bigip-ve/mgmt/tm/ltm/pool

このようなリクエストを実行すれば、二つのPoolの情報が得られます。これは"tmsh list(またはshow) ltm pool" を実行するのと同じことです。

実行例(長いので折りたたみ表示)
$ curl -sk -u admin:admin https://bigip-ve/mgmt/tm/ltm/pool/ | jq
{
  "kind": "tm:ltm:pool:poolcollectionstate",
  "selfLink": "https://localhost/mgmt/tm/ltm/pool?ver=12.1.2",
  "items": [
    {
      "kind": "tm:ltm:pool:poolstate",
      "name": "test-pool",
      "partition": "Common",
      "fullPath": "/Common/test-pool",
      "generation": 449,
      "selfLink": "https://localhost/mgmt/tm/ltm/pool/~Common~test-pool?ver=12.1.2",
      "allowNat": "yes",
      "allowSnat": "yes",
      "ignorePersistedWeight": "disabled",
      "ipTosToClient": "pass-through",
      "ipTosToServer": "pass-through",
      "linkQosToClient": "pass-through",
      "linkQosToServer": "pass-through",
      "loadBalancingMode": "round-robin",
      "minActiveMembers": 0,
      "minUpMembers": 0,
      "minUpMembersAction": "failover",
      "minUpMembersChecking": "disabled",
      "queueDepthLimit": 0,
      "queueOnConnectionLimit": "disabled",
      "queueTimeLimit": 0,
      "reselectTries": 0,
      "serviceDownAction": "none",
      "slowRampTime": 10,
      "membersReference": {
        "link": "https://localhost/mgmt/tm/ltm/pool/~Common~test-pool/members?ver=12.1.2",
        "isSubcollection": true
      }
    },
    {
      "kind": "tm:ltm:pool:poolstate",
      "name": "test-pool1",
      "partition": "Common",
      "fullPath": "/Common/test-pool1",
      "generation": 451,
      "selfLink": "https://localhost/mgmt/tm/ltm/pool/~Common~test-pool1?ver=12.1.2",
      "allowNat": "yes",
      "allowSnat": "yes",
      "ignorePersistedWeight": "disabled",
      "ipTosToClient": "pass-through",
      "ipTosToServer": "pass-through",
      "linkQosToClient": "pass-through",
      "linkQosToServer": "pass-through",
      "loadBalancingMode": "round-robin",
      "minActiveMembers": 0,
      "minUpMembers": 0,
      "minUpMembersAction": "failover",
      "minUpMembersChecking": "disabled",
      "queueDepthLimit": 0,
      "queueOnConnectionLimit": "disabled",
      "queueTimeLimit": 0,
      "reselectTries": 0,
      "serviceDownAction": "none",
      "slowRampTime": 10,
      "membersReference": {
        "link": "https://localhost/mgmt/tm/ltm/pool/~Common~test-pool1/members?ver=12.1.2",
        "isSubcollection": true
      }
    }
  ]
}

SubCollectionもまとめて取得する

上記実行例の中に、以下のような箇所があります。

      "membersReference": {
        "link": "https://localhost/mgmt/tm/ltm/pool/~Common~test-pool1/members?ver=12.1.2",
        "isSubcollection": true
      }

これは、Resouce (今回の場合、Pool)の中に、Sub Collection(今回の場合、Pool Member)が存在することを示しています。Sub Collectionの情報を取得するには、個別にSubCollectionのURLに対してGETリクエストを送信する以外に、Poolの取得時、URLのパラメータに「?expandSubcollections=true」をつける方法があります。

「?expandSubcollections=true」を付加した場合、SubCollectionの情報もあわせて応答します。

「?expandSubcollections=true」を付加した実行例(長いので折りたたみ表示)
$ curl -sk -u admin:admin https://bigip-ve/mgmt/tm/ltm/pool/?expandSubcollections=true | jq
{
  "kind": "tm:ltm:pool:poolcollectionstate",
  "selfLink": "https://localhost/mgmt/tm/ltm/pool?expandSubcollections=true&ver=12.1.2",
  "items": [
    {
      "kind": "tm:ltm:pool:poolstate",
      "name": "test-pool",
      "partition": "Common",
      "fullPath": "/Common/test-pool",
      "generation": 449,
      "selfLink": "https://localhost/mgmt/tm/ltm/pool/~Common~test-pool?ver=12.1.2",
      "allowNat": "yes",
      "allowSnat": "yes",
      "ignorePersistedWeight": "disabled",
      "ipTosToClient": "pass-through",
      "ipTosToServer": "pass-through",
      "linkQosToClient": "pass-through",
      "linkQosToServer": "pass-through",
      "loadBalancingMode": "round-robin",
      "minActiveMembers": 0,
      "minUpMembers": 0,
      "minUpMembersAction": "failover",
      "minUpMembersChecking": "disabled",
      "queueDepthLimit": 0,
      "queueOnConnectionLimit": "disabled",
      "queueTimeLimit": 0,
      "reselectTries": 0,
      "serviceDownAction": "none",
      "slowRampTime": 10,
      "membersReference": {
        "link": "https://localhost/mgmt/tm/ltm/pool/~Common~test-pool/members?ver=12.1.2",
        "isSubcollection": true,
        "items": [
          {
            "kind": "tm:ltm:pool:members:membersstate",
            "name": "NodeA:80",
            "partition": "Common",
            "fullPath": "/Common/NodeA:80",
            "generation": 449,
            "selfLink": "https://localhost/mgmt/tm/ltm/pool/~Common~test-pool/members/~Common~NodeA:80?ver=12.1.2",
            "address": "1.1.1.100",
            "connectionLimit": 0,
            "dynamicRatio": 1,
            "ephemeral": "false",
            "fqdn": {
              "autopopulate": "disabled"
            },
            "inheritProfile": "enabled",
            "logging": "disabled",
            "monitor": "default",
            "priorityGroup": 0,
            "rateLimit": "disabled",
            "ratio": 1,
            "session": "user-enabled",
            "state": "unchecked",
            "nameReference": {
              "link": "https://localhost/mgmt/tm/ltm/node/~Common~NodeA:80?ver=12.1.2"
            }
          }
        ]
      }
    },
    {
      "kind": "tm:ltm:pool:poolstate",
      "name": "test-pool1",
      "partition": "Common",
      "fullPath": "/Common/test-pool1",
      "generation": 451,
      "selfLink": "https://localhost/mgmt/tm/ltm/pool/~Common~test-pool1?ver=12.1.2",
      "allowNat": "yes",
      "allowSnat": "yes",
      "ignorePersistedWeight": "disabled",
      "ipTosToClient": "pass-through",
      "ipTosToServer": "pass-through",
      "linkQosToClient": "pass-through",
      "linkQosToServer": "pass-through",
      "loadBalancingMode": "round-robin",
      "minActiveMembers": 0,
      "minUpMembers": 0,
      "minUpMembersAction": "failover",
      "minUpMembersChecking": "disabled",
      "queueDepthLimit": 0,
      "queueOnConnectionLimit": "disabled",
      "queueTimeLimit": 0,
      "reselectTries": 0,
      "serviceDownAction": "none",
      "slowRampTime": 10,
      "membersReference": {
        "link": "https://localhost/mgmt/tm/ltm/pool/~Common~test-pool1/members?ver=12.1.2",
        "isSubcollection": true,
        "items": [
          {
            "kind": "tm:ltm:pool:members:membersstate",
            "name": "NodeB:80",
            "partition": "Common",
            "fullPath": "/Common/NodeB:80",
            "generation": 451,
            "selfLink": "https://localhost/mgmt/tm/ltm/pool/~Common~test-pool1/members/~Common~NodeB:80?ver=12.1.2",
            "address": "1.1.1.101",
            "connectionLimit": 0,
            "dynamicRatio": 1,
            "ephemeral": "false",
            "fqdn": {
              "autopopulate": "disabled"
            },
            "inheritProfile": "enabled",
            "logging": "disabled",
            "monitor": "default",
            "priorityGroup": 0,
            "rateLimit": "disabled",
            "ratio": 1,
            "session": "user-enabled",
            "state": "unchecked",
            "nameReference": {
              "link": "https://localhost/mgmt/tm/ltm/node/~Common~NodeB:80?ver=12.1.2"
            }
          }
        ]
      }
    }
  ]
}

"membersReference"の中に、Pool Memberの情報が含まれていることがわかります。

iControl RESTのデータ構造

iControl RESTでは、データのやり取りにはJSON(JavaScript Object Notation)形式を使用します。JSONを使うことで、複雑なデータ構造を表すことができます。JSONに関しては、Qiitaや、世の中に多数の説明ページがあるので、知りたい方はそちらを参照してください。

iControl RESTのHTTPリクエストメソッド

iControl RESTではHTTPメソッドによって対象に対する操作方法を指定します。これは、tmshコマンドの先頭の引数にあたります。

     HTTP Method tmsh
設定の確認 GET show or list
設定の作成 POST create
設定の変更 PATCH modify
設定の削除 DELETE delete

iControl REST実行のサンプル

tmshコマンドの文法は、iControl RESTと類似性が高く、tmshコマンドをiContol RESTに置き換えるのは簡単です。ノードに対する操作を例に、tmshとiControl RESETでおなじ操作をするサンプルをいくつかあげてみます。iControl RESTのためのクライアントにはcurlを使います。

  • Nodeの確認
tmsh
(tmsh) $ show ltm node / list ltm node 

icontrol
$ curl -k -u admin:admin  -H "Content-Type: application/json" \
  -X GET https://bigip-ve/mgmt/tm/ltm/node
  • Nodeの新規作成
tmsh
(tmsh) $ create ltm node NodeA { address 1.1.1.100 } 

icontrol
$ curl -k -u admin:admin  -H "Content-Type: application/json" \
  -d '{"name":"NodeA", "address":"1.1.1.100"}' \
  -X POST https://bigip-ve/mgmt/tm/ltm/node
  • Nodeの設定変更
tmsh
(tmsh) $ modify ltm node NodeA { description "HTTP Server" } 

icontrol
$ curl -k -u admin:admin  -H "Content-Type: application/json" \
  -d '{"description":"HTTP Server"}' \
  -X PATCH https://bigip-ve/mgmt/tm/ltm/node/~Common~NodeA
  • Nodeの削除
tmsh
(tmsh) $ delete ltm node NodeA

icontrol
$ curl -k -u admin:admin  -H "Content-Type: application/json" \
  -d '{"description":"HTTP Server"}' \
  -X DELETE https://bigip-ve/mgmt/tm/ltm/node/~Common~NodeA

補足

URLに使用できるパラメータについて

紹介した「expandSubcollections」以外にもいくつかのパラメータを利用できます。
詳細はこちらを参照

iControlでData Group Listを更新するときの注意点

いつか書きます。

以上です。