zaki work log

作業ログやら生活ログやらなんやら

[NetBox] 「VMを登録してIPアドレス割り当て」をREST APIでお試し

NetBoxのREST APIをざっくりと使って「VMを登録してIPアドレスを割り当てる」をやってみる。
APIについては、NetBoxの画面下部の{} APIのリンク先を開くと、Swaggerが表示されるので、エンドポイントとHTTPリクエストメソッド一覧や必要なパラメタ、レスポンス等を確認できる。
NetBoxにおけるSwaggerの操作はこの辺を参照。

f:id:zaki-hmkc:20210113090328p:plain

netbox.readthedocs.io


環境

本環境ではNetBoxは http://192.168.0.19:28080/ で稼働している。
下記参照。

zaki-hmkc.hatenablog.com

また、記事内のHTTPアクセスの内容は基本的にVS CodeのREST Client拡張を使って確認したときのもの。
curlを使う場合はヘッダ指定の-Hや、リクエストBodyを指定するための-dを使用する。

qiita.com

トーク

APIを実行した操作にはトークンが必要。 Docker ComposeでデプロイしたNetBoxは、デフォルトでは 0123456789abcdef0123456789abcdef01234567 になっている。

トークンの値はAdministration画面のTokensから確認できる。

f:id:zaki-hmkc:20210113090553p:plain

HTTPアクセス時には Authorization: Token ${TOKEN値} という書式のリクエストヘッダを付与すれば良い。

netbox.readthedocs.io

Cluster IDを確認

VM情報の登録にはCluster IDが必須項目なので、登録済みCluster IDを確認する。
エンドポイントは /virtualization/clusters/ を使用。

全Clusterを取得するには、特にQuery String無し。

GET http://192.168.0.19:28080/api/virtualization/clusters/
Authorization: Token {{ token }}

Cluster名を指定してフィルタするには以下の通り。(スペースは+エスケープ)

GET http://192.168.0.19:28080/api/virtualization/clusters/?name=vm+network
Authorization: Token {{ token }}

レスポンスは以下の通りで、これから使いたい"vm network"Clusterはid=3`であることが分かる。

HTTP/1.1 200 OK
Server: nginx
Date: Tue, 12 Jan 2021 22:40:09 GMT
Content-Type: application/json
Content-Length: 537
Connection: close
Vary: Accept, Cookie, Origin
Allow: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS
API-Version: 2.10
X-Content-Type-Options: nosniff
Referrer-Policy: same-origin
X-Frame-Options: SAMEORIGIN
P3P: CP="ALL DSP COR PSAa PSDa OUR NOR ONL UNI COM NAV"

{
  "count": 1,
  "next": null,
  "previous": null,
  "results": [
    {
      "id": 3,
      "url": "http://192.168.0.19:28080/api/virtualization/clusters/3/",
      "name": "vm network",
      "type": {
        "id": 2,
        "url": "http://192.168.0.19:28080/api/virtualization/cluster-types/2/",
        "name": "ESXi",
        "slug": "esxi"
      },
      "group": null,
      "tenant": null,
      "site": {
        "id": 1,
        "url": "http://192.168.0.19:28080/api/dcim/sites/1/",
        "name": "自宅",
        "slug": "home"
      },
      "comments": "",
      "tags": [],
      "custom_fields": {},
      "created": "2021-01-11",
      "last_updated": "2021-01-11T06:02:43.351913Z",
      "device_count": 0,
      "virtualmachine_count": 4
    }
  ]
}

VM情報の登録

使用するCluster IDが3わかったのでVMを登録する。
エンドポイントは /virtualization/virtual-machines/ を使用。

必須パラメタはnameclusterになっているので、ひとまずそれだけ指定する。
ここでは client-dev というVMを登録する。

POST http://192.168.0.19:28080/api/virtualization/virtual-machines/
Authorization: Token {{ token }}
Content-Type: application/json

{
    "name": "client-dev",
    "cluster": 3
}

レスポンスは以下。

HTTP/1.1 201 Created
Server: nginx
Date: Tue, 12 Jan 2021 22:45:46 GMT
Content-Type: application/json
Content-Length: 642
Connection: close
Location: http://192.168.0.19:28080/api/virtualization/virtual-machines/6/
Vary: Accept, Cookie, Origin
Allow: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS
API-Version: 2.10
X-Content-Type-Options: nosniff
Referrer-Policy: same-origin
X-Frame-Options: SAMEORIGIN
P3P: CP="ALL DSP COR PSAa PSDa OUR NOR ONL UNI COM NAV"

{
  "id": 6,
  "url": "http://192.168.0.19:28080/api/virtualization/virtual-machines/6/",
  "name": "client-dev",
  "status": {
    "value": "active",
    "label": "Active"
  },
  "site": {
    "id": 1,
    "url": "http://192.168.0.19:28080/api/dcim/sites/1/",
    "name": "自宅",
    "slug": "home"
  },
  "cluster": {
    "id": 3,
    "url": "http://192.168.0.19:28080/api/virtualization/clusters/3/",
    "name": "vm network"
  },
  "role": null,
  "tenant": null,
  "platform": null,
  "primary_ip": null,
  "primary_ip4": null,
  "primary_ip6": null,
  "vcpus": null,
  "memory": null,
  "disk": null,
  "comments": "",
  "local_context_data": null,
  "tags": [],
  "custom_fields": {},
  "config_context": {},
  "created": "2021-01-12",
  "last_updated": "2021-01-12T22:45:46.414175Z"
}

画面で見てもVMが登録されたことを確認できる。

f:id:zaki-hmkc:20210113090842p:plain

インタフェース作成

IPアドレスの設定のためにはインタフェースを作成する。
上記のVM作成時のレスポンスでVMのIDは6だとわかっているので、それを使用する。
エンドポイントは /virtualization/interfaces/ を使用する。

必須項目は virtual_machine(integer)と、name(string)の二つ

POST http://192.168.0.19:28080/api/virtualization/interfaces/
Authorization: Token {{ token }}
Content-Type: application/json

{
    "virtual_machine": 6,
    "name": "ens192"
}

レスポンスは以下の通り。

HTTP/1.1 201 Created
Server: nginx
Date: Tue, 12 Jan 2021 22:50:55 GMT
Content-Type: application/json
Content-Length: 334
Connection: close
Location: http://192.168.0.19:28080/api/virtualization/interfaces/8/
Vary: Accept, Cookie, Origin
Allow: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS
API-Version: 2.10
X-Content-Type-Options: nosniff
Referrer-Policy: same-origin
X-Frame-Options: SAMEORIGIN
P3P: CP="ALL DSP COR PSAa PSDa OUR NOR ONL UNI COM NAV"

{
  "id": 8,
  "url": "http://192.168.0.19:28080/api/virtualization/interfaces/8/",
  "virtual_machine": {
    "id": 6,
    "url": "http://192.168.0.19:28080/api/virtualization/virtual-machines/6/",
    "name": "client-dev"
  },
  "name": "ens192",
  "enabled": true,
  "mtu": null,
  "mac_address": null,
  "description": "",
  "mode": null,
  "untagged_vlan": null,
  "tagged_vlans": [],
  "tags": []
}

VMの詳細画面を開くと、インタフェースが追加されたことを確認できる。

f:id:zaki-hmkc:20210113091026p:plain

IPアドレスの作成とインタフェースへのアサイ

作成したインタフェースのIDは上記で8になっている。
IPアドレスを作成し、このインタフェースへ割り当てを行う。 (割り当ては行わずにIPアドレス作成のみも可能)

エンドポイントは /ipam/ip-addresses/ を使用。

必須項目は address(string) で、インタフェースへの割り当てにはオプションの assigned_object_type(string) と assigned_object_id(integer) を指定する。
あとAPIドキュメントだと nat_outside にも必須(required)のマークが付いているが、無くても動く。

assigned_object_typeに何を指定するかドキュメントでちょっと確認できなかったが、「作成済みIPアドレス一覧を取得(/ipam/ip-addresses/にGET)」すると、以下のようになっていたのでそれを指定。

オブジェクト種別 assigned_object_typeの値
Device "dcim.interface"
Virtual Machine "virtualization.vminterface"

ということでリクエストは以下の通り。

POST http://192.168.0.19:28080/api/ipam/ip-addresses/
Authorization: Token {{ token }}
Content-Type: application/json

{
    "address": "192.168.0.17/24",
    "assigned_object_type": "virtualization.vminterface",
    "assigned_object_id": 8
}

レスポンスは以下の通り。

HTTP/1.1 201 Created
Server: nginx
Date: Tue, 12 Jan 2021 23:00:55 GMT
Content-Type: application/json
Content-Length: 685
Connection: close
Location: http://192.168.0.19:28080/api/ipam/ip-addresses/48/
Vary: Accept, Cookie, Origin
Allow: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS
API-Version: 2.10
X-Content-Type-Options: nosniff
Referrer-Policy: same-origin
X-Frame-Options: SAMEORIGIN
P3P: CP="ALL DSP COR PSAa PSDa OUR NOR ONL UNI COM NAV"

{
  "id": 48,
  "url": "http://192.168.0.19:28080/api/ipam/ip-addresses/48/",
  "family": {
    "value": 4,
    "label": "IPv4"
  },
  "address": "192.168.0.17/24",
  "vrf": null,
  "tenant": null,
  "status": {
    "value": "active",
    "label": "Active"
  },
  "role": null,
  "assigned_object_type": "virtualization.vminterface",
  "assigned_object_id": 8,
  "assigned_object": {
    "id": 8,
    "url": "http://192.168.0.19:28080/api/virtualization/interfaces/8/",
    "virtual_machine": {
      "id": 6,
      "url": "http://192.168.0.19:28080/api/virtualization/virtual-machines/6/",
      "name": "client-dev"
    },
    "name": "ens192"
  },
  "nat_inside": null,
  "nat_outside": null,
  "dns_name": "",
  "description": "",
  "tags": [],
  "custom_fields": {},
  "created": "2021-01-12",
  "last_updated": "2021-01-12T23:00:55.356643Z"
}

これでインタフェースにIPアドレスが割り当て状態となる。

f:id:zaki-hmkc:20210113091135p:plain

IPアドレスの詳細はこの通り。

f:id:zaki-hmkc:20210113091235p:plain

Primary IPに設定

f:id:zaki-hmkc:20210113091336p:plain

IPアドレスの割り当てはこれで完了したが、「Primary IPアドレス設定」になっていないため、このままだと一覧で表示されない。
Primary IPアドレスVMの設定で行う。

エンドポイントは /virtualization/virtual-machines/{id}/ を使用。

ここまでの作成手順で、VMのIDは6、作ったIPアドレスのID(IPじゃないよ)は48なので、リクエストは以下の通り。
(ついでなのでroleも指定)

PUT http://192.168.0.19:28080/api/virtualization/virtual-machines/6/
Authorization: Token {{ token }}
Content-Type: application/json

{
    "name": "client-dev",
    "cluster": 3,
    "primary_ip4": 48,
    "role": 2
}

レスポンスは以下の通り。

HTTP/1.1 200 OK
Server: nginx
Date: Tue, 12 Jan 2021 23:42:42 GMT
Content-Type: application/json
Content-Length: 945
Connection: close
Vary: Accept, Cookie, Origin
Allow: GET, PUT, PATCH, DELETE, HEAD, OPTIONS
API-Version: 2.10
X-Content-Type-Options: nosniff
Referrer-Policy: same-origin
X-Frame-Options: SAMEORIGIN
P3P: CP="ALL DSP COR PSAa PSDa OUR NOR ONL UNI COM NAV"

{
  "id": 6,
  "url": "http://192.168.0.19:28080/api/virtualization/virtual-machines/6/",
  "name": "client-dev",
  "status": {
    "value": "active",
    "label": "Active"
  },
  "site": {
    "id": 1,
    "url": "http://192.168.0.19:28080/api/dcim/sites/1/",
    "name": "自宅",
    "slug": "home"
  },
  "cluster": {
    "id": 3,
    "url": "http://192.168.0.19:28080/api/virtualization/clusters/3/",
    "name": "vm network"
  },
  "role": {
    "id": 2,
    "url": "http://192.168.0.19:28080/api/dcim/device-roles/2/",
    "name": "client",
    "slug": "client"
  },
  "tenant": null,
  "platform": null,
  "primary_ip": {
    "id": 48,
    "url": "http://192.168.0.19:28080/api/ipam/ip-addresses/48/",
    "family": 4,
    "address": "192.168.0.17/24"
  },
  "primary_ip4": {
    "id": 48,
    "url": "http://192.168.0.19:28080/api/ipam/ip-addresses/48/",
    "family": 4,
    "address": "192.168.0.17/24"
  },
  "primary_ip6": null,
  "vcpus": null,
  "memory": null,
  "disk": null,
  "comments": "",
  "local_context_data": null,
  "tags": [],
  "custom_fields": {},
  "config_context": {},
  "created": "2021-01-12",
  "last_updated": "2021-01-12T23:42:42.492869Z"
}

Primary IPアドレスが設定できました。

f:id:zaki-hmkc:20210113091421p:plain


UpdateせずにCreateだけでPrimary IPを設定する方法はちょっとわからなかった。
とはいえ、手動でなく自動処理するのであれば、この点はそこまでこだわらなくても良い気もする。

  • Primary IPの設定はVMの設定項目
  • ただしIPアドレスがインタフェースへ設定済みでないとエラー
  • IPアドレスは単体で作成できるがインタフェース割り当てはインタフェースを作成しておく必要がある
  • インタフェースを作成するにはVMを作成しておく必要がある