LoginSignup
2
2

More than 5 years have passed since last update.

iControl RESTでData Group Listを更新する

Posted at

はじめに

BIG-IPのData Group Listの更新を行なっている人には、このテンプレ的な作業をiCRで行いたい(例えば自動化したい)、という需要があると思いますが、ちょっと思ったようにはいかないので。

なお、ここで取り扱うData Group Listは、BIG-IP内にレコードを登録するInternalタイプのものであり、外部ファイルを取り込むexternalタイプのData Group Listではありません。

参照情報

このページの内容は、DevCentralの以下のURLで説明されています。F5の技術者によるサンプルコードもあるので、この問題に取り組む人は参照するのが良いかと思います。

DevCentral: add value in data group via REST API

免責事項

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

問題

例えば、下記のような「test-data-group」という名前のData Group Listがあるとします。すでにレコードが3件入っています。

(tmos)# list ltm data-group internal test-data-group 
ltm data-group internal test-data-group {
    records {
        www1.example.co.jp {
            data Pool_www1
        }
        www2.example.co.jp {
            data Pool_www2
        }
        www3.example.co.jp {
            data Pool_www3
        }
    }
    type string
}

ここに新規レコードとして、name="www3.example.co.jp", value="Pool_www4" を追加するとします。

この追加作業をtmshで行う場合、以下のようなコマンドになります。

(tmos)# modify ltm data-group internal test-class records add { "www4.example.co.jp" { data "Pool_www4" } }

iCRではどうなるでしょう。上記のtmshコマンドを移植しようと考えた場合、modifyコマンドなので、PATCHメソッドを使えば移植できる気がするので、次のようなHTTPリクエストが考えられます。

curl -sku admin:admin -H "Content-Type: application/json" \
  -X PATCH \
  -d '{"records":[{"name":"www4.example.co.jp", "data":"Pool_www4"}]}' \
  https://bigip-ve/mgmt/tm/ltm/data-group/internal/test-data-group

しかし、上記のようなリクエストを実行して、変更後のData Group Listを確認してみると、

(tmos)# list ltm data-group internal test-data-group
ltm data-group internal test-data-group {
    records {
        www4.example.co.jp {
            data Pool_www4
        }
    }
    type string
}

このとおり、Data Group Listのレコードは、元々存在していたレコードが全て消えてしまい、追加しようとした一件だけになってしまいます。

解説

iCRにおいて、Data Group Listのレコードは、一つの大きな配列として扱われます(少なくともv12では)。iCRでData Group listの更新を行う場合、レコード全体が一つの設定値になるというイメージで、全部のレコードを送信する必要があります。上記の例では追加したいレコードのみを送信した為に、そのレコードでData Group Listが上書きされてしまったわけです。

つまり、Data Group Listにレコードを追加する手順は、次の3ステップになります。

  1. 変更前のData Group Listの全レコードを受け取る
  2. そこに新規追加のレコードを追加する
  3. 変更後となる全レコードを送信する

サンプルコード

Pythonで、上記の3ステップを行うサンプルコードを作成しました。

# (準備)iControlのセッションを用意
import requests
import json

b = requests.session()
b.auth = ('admin', 'admin')
b.verify = False
b.headers.update({'Content-Type':'application/json'})

# 1. 変更前のData Group Listの全レコードを取得
data_group_str = b.get('https://bigip-ve/mgmt/tm/ltm/data-group/internal/test-data-group')
data_group = json.loads(data_group_str.text)
records = data_group['records']

このタイミングでは、recordsは次のようにになっています。

[{'data': 'Pool_www1', 'name': 'www1.example.co.jp'},
 {'data': 'Pool_www2', 'name': 'www2.example.co.jp'},
 {'data': 'Pool_www3', 'name': 'www3.example.co.jp'}]

recordsに新規レコードを追加します。

new_record = {'name':'www4.example.co.jp', 'data':'Pool_www4'}
records.append(new_record)

これにより、recordsは次のようになります。

[{'data': 'Pool_www1', 'name': 'www1.example.co.jp'},
 {'data': 'Pool_www2', 'name': 'www2.example.co.jp'},
 {'data': 'Pool_www3', 'name': 'www3.example.co.jp'},
 {'data': 'Pool_www4', 'name': 'www4.example.co.jp'}]

最後に、recordsを、JSONに変換してiControlで送信します。

payload['records'] = records
res = b.patch('https://bigip-ve/mgmt/tm/ltm/data-group/internal/test-data-group', data=json.dumps(payload))

tmshコマンドで確認してみます。

(tmos)# list ltm data-group internal test-data-group
ltm data-group internal test-data-group {
    records {
        www1.example.co.jp {
            data Pool_www1
        }
        www2.example.co.jp {
            data Pool_www2
        }
        www3.example.co.jp {
            data Pool_www3
        }
        www4.example.co.jp {
            data Pool_www4
        }
    }
    type string
}

無事、元のレコード3件に、新しいレコード1件が追加されました。

このページの内容は、以上です。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2