Skip navigation

NSX-T の Policy API の「Hierarchical API」で、ネットワークの作成/削除をしてみます。

 

前回の投稿はこちら。

NSX-T の Policy API をためす。Part.4(Hierarchical API での GET 編)

 

JSON ファイルの用意。

今回は、これまでの投稿で何度か構築したラボ ネットワーク環境を Hierarchical API  で作成してみます。

 

つぎの一連の投稿で作成したネットワークと、同様のものです。

前提として、前回までに作成/確認したオブジェクトは、ひととおり削除してあります。

自宅ラボで NSX-T 2.5 環境を構築する。Simplified UI 編。Part.1 ※Web UI で作成。

NSX-T の Policy API をためす。Part.3(オブジェクト作成編) ※Policy API での別方法で作成。

 

まず、前回に Hierarchical API で GET した情報から、

必要な部分のみを残した JSON ファイルを用意しておきます。

NSX-T の Policy API をためす。Part.4(Hierarchical API での GET 編)

 

JSON ファイルはある程度あつかいやすいように、3つに分けてみました。

より多く分割、もしくは少ない JSON ファイルにまとめることも可能です。

 

ext-vlan.json ファイルの内容。

{

  "resource_type": "Infra",

  "id": "infra",

  "children": [

    {

      "Segment": {

        "id": "seg-vlan-0200",

        "display_name": "seg-vlan-0200",

        "type": "DISCONNECTED",

        "vlan_ids": [

          "200"

        ],

        "transport_zone_path": "/infra/sites/default/enforcement-points/default/transport-zones/4954eeca-decb-487a-8582-b011d60ba19f",

        "resource_type": "Segment",

        "marked_for_delete": false

      },

      "resource_type": "ChildSegment",

      "marked_for_delete": false

    }

  ]

}

 

tier0.json ファイルの内容。

{

  "resource_type": "Infra",

  "id": "infra",

  "children": [

    {

      "Tier0": {

        "id": "t0-gw-01",

        "display_name": "t0-gw-01",

        "ha_mode": "ACTIVE_STANDBY",

        "failover_mode": "NON_PREEMPTIVE",

        "transit_subnets": [

          "100.64.0.0/16"

        ],

        "internal_transit_subnets": [

          "169.254.0.0/28"

        ],

        "children": [

          {

            "LocaleServices": {

              "id": "8ad9e401-f41e-4227-8445-36b1092c76a3",

              "display_name": "8ad9e401-f41e-4227-8445-36b1092c76a3",

              "children": [

                {

                  "Tier0Interface": {

                    "id": "t0-uplink-01",

                    "display_name": "t0-uplink-01",

                    "edge_path": "/infra/sites/default/enforcement-points/default/edge-clusters/a2958967-0579-4cbf-a018-96cfa6553fae/edge-nodes/8e1b5bda-e116-49da-8b4b-bbb2961a7900",

                    "segment_path": "/infra/segments/seg-vlan-0200",

                    "type": "EXTERNAL",

                    "subnets": [

                      {

                        "ip_addresses": [

                          "192.168.200.2"

                        ],

                        "prefix_len": 24

                      }

                    ],

                    "resource_type": "Tier0Interface",

                    "marked_for_delete": false

                  },

                  "resource_type": "ChildTier0Interface",

                  "marked_for_delete": false

                }

              ],

              "resource_type": "LocaleServices",

              "marked_for_delete": false

            },

            "resource_type": "ChildLocaleServices",

            "marked_for_delete": false

          },

          {

            "PolicyNat": {

              "id": "USER",

              "display_name": "USER",

              "nat_type": "USER",

              "children": [

                {

                  "PolicyNatRule": {

                    "resource_type": "PolicyNatRule",

                    "id": "b1a7aa47-e299-4369-a06b-3d10d48e8c68",

                    "display_name": "t0-snat-01",

                    "sequence_number": 100,

                    "action": "SNAT",

                    "source_network": "172.16.0.0/16",

                    "service": "",

                    "translated_network": "192.168.200.2",

                    "scope": [],

                    "enabled": true,

                    "marked_for_delete": false

                  },

                  "resource_type": "ChildPolicyNatRule",

                  "marked_for_delete": false

                }

              ],

              "resource_type": "PolicyNat",

              "marked_for_delete": false

            },

            "resource_type": "ChildPolicyNat",

            "marked_for_delete": false

          },

          {

            "StaticRoutes": {

              "id": "t0-route-01",

              "display_name": "t0-route-01",

              "network": "0.0.0.0/0",

              "next_hops": [

                {

                  "ip_address": "192.168.200.1",

                  "admin_distance": 1

                }

              ],

              "resource_type": "StaticRoutes",

              "marked_for_delete": false

            },

            "resource_type": "ChildStaticRoutes",

            "marked_for_delete": false

          }

        ],

        "resource_type": "Tier0",

        "marked_for_delete": false

      },

      "resource_type": "ChildTier0",

      "marked_for_delete": false

    }

  ]

}

 

tier1.json ファイルの内容。

{

  "resource_type": "Infra",

  "id": "infra",

  "children": [

    {

      "PolicyDnsForwarderZone": {

        "resource_type": "PolicyDnsForwarderZone",

        "id": "dns-zone-01",

        "display_name": "dns-zone-01",

        "dns_domain_names": [],

        "upstream_servers": [

          "192.168.1.101",

          "192.168.1.102"

        ],

        "marked_for_delete": false

      },

      "resource_type": "ChildPolicyDnsForwarderZone",

      "marked_for_delete": false

    },

    {

      "DhcpServerConfig": {

        "id": "dhcp-sv-01",

        "display_name": "dhcp-sv-01",

        "server_address": "172.16.254.254/24",

        "lease_time": 86400,

        "resource_type": "DhcpServerConfig",

        "marked_for_delete": false

      },

      "resource_type": "ChildDhcpServerConfig",

      "marked_for_delete": false

    },

    {

      "Tier1": {

        "id": "t1-gw-01",

        "display_name": "t1-gw-01",

        "tier0_path": "/infra/tier-0s/t0-gw-01",

        "failover_mode": "NON_PREEMPTIVE",

        "enable_standby_relocation": false,

        "dhcp_config_paths": [

          "/infra/dhcp-server-configs/dhcp-sv-01"

        ],

        "route_advertisement_types": [

          "TIER1_DNS_FORWARDER_IP",

          "TIER1_CONNECTED"

        ],

        "children": [

          {

            "LocaleServices": {

              "id": "96770e38-3e86-4873-bef6-71d60267c957",

              "display_name": "96770e38-3e86-4873-bef6-71d60267c957",

              "edge_cluster_path": "/infra/sites/default/enforcement-points/default/edge-clusters/a2958967-0579-4cbf-a018-96cfa6553fae",

              "preferred_edge_paths": [

                "/infra/sites/default/enforcement-points/default/edge-clusters/a2958967-0579-4cbf-a018-96cfa6553fae/edge-nodes/8e1b5bda-e116-49da-8b4b-bbb2961a7900"

              ],

              "resource_type": "LocaleServices",

              "marked_for_delete": false

            },

            "resource_type": "ChildLocaleServices",

            "marked_for_delete": false

          },

          {

            "PolicyDnsForwarder": {

              "id": "dns-forwarder",

              "display_name": "dns-sv-01",

              "listener_ip": "172.16.253.254",

              "default_forwarder_zone_path": "/infra/dns-forwarder-zones/dns-zone-01",

              "resource_type": "PolicyDnsForwarder",

              "marked_for_delete": false

            },

            "resource_type": "ChildPolicyDnsForwarder",

            "marked_for_delete": false

          }

        ],

        "resource_type": "Tier1",

        "marked_for_delete": false

      },

      "resource_type": "ChildTier1",

      "marked_for_delete": false

    },

    {

      "Segment": {

        "id": "seg-overlay-01",

        "display_name": "seg-overlay-01",

        "type": "ROUTED",

        "subnets": [

          {

            "gateway_address": "172.16.1.1/24",

            "dhcp_ranges": [

              "172.16.1.10-172.16.1.250"

            ],

            "network": "172.16.1.0/24"

          }

        ],

        "transport_zone_path": "/infra/sites/default/enforcement-points/default/transport-zones/4d5e3804-e62c-40ab-af7c-99bab2d5e5e8",

        "connectivity_path": "/infra/tier-1s/t1-gw-01",

        "resource_type": "Segment",

        "marked_for_delete": false

      },

      "resource_type": "ChildSegment",

      "marked_for_delete": false

    },

    {

      "Segment": {

        "id": "seg-overlay-02",

        "display_name": "seg-overlay-02",

        "type": "ROUTED",

        "subnets": [

          {

            "gateway_address": "172.16.2.1/24",

            "dhcp_ranges": [

              "172.16.2.10-172.16.2.250"

            ],

            "network": "172.16.2.0/24"

          }

        ],

        "transport_zone_path": "/infra/sites/default/enforcement-points/default/transport-zones/4d5e3804-e62c-40ab-af7c-99bab2d5e5e8",

        "connectivity_path": "/infra/tier-1s/t1-gw-01",

        "resource_type": "Segment",

        "marked_for_delete": false

      },

      "resource_type": "ChildSegment",

      "marked_for_delete": false

    }

  ]

}

 

ネットワーク環境の作成。

これまでの投稿で紹介したように、API のコールには、Linux クライアントで curl コマンドを利用します。

変数 CREDには「ユーザ名:パスワード」、MGR には NSX Manager のアドレスを格納してあります。

$ MGR=lab-nsxt-mgr-01.go-lab.jp

$ CRED='admin:VMware1!VMware1!'

 

今回コールする API は、一律でつぎのものです。

対象のオブジェクトとその階層、作成/削除などは、リクエストに渡す JSON データで指定しています。

PATCH /policy/api/v1/infra

 

それでは、ネットワークを作成していきます。

NSX Manager の UI でも、はじめはオブジェクトがない状態です。

API コールのたびに UI を更新すると、JSON に記載したオブジェクトが作成された様子がわかるはずです。

nsxt-mgr-obj-01.png

 

ext-vlan.json を指定して、境界のネットワークになる、VLAN セグメントを作成。

$ curl -ks -u $CRED -H "Content-Type: application/json" -X PATCH -d @./ext-vlan.json https://$MGR/policy/api/v1/infra

 

tier0.json を指定して、Tier-0 ゲートウェイと一連のオブジェクトを作成。

$ curl -ks -u $CRED -H "Content-Type: application/json" -X PATCH -d @./tier0.json https://$MGR/policy/api/v1/infra

 

tier1.json を指定して、Tier-1 ゲートウェイと一連のオブジェクトを作成。

$ curl -ks -u $CRED -H "Content-Type: application/json" -X PATCH -d @./tier1.json https://$MGR/policy/api/v1/infra

 

ここまでの API コールで、NSX Manager でオブジェクトが作成されました。

nsxt-mgr-obj-02.png

 

ネットワーク環境の削除のための JSON ファイル準備。

以前紹介したように、Policy API では、DELETE メソッドでオブジェクトをひとつずつ削除できます。

NSX-T の Policy API をためす。Part.2(DELETE 編)

 

Policy API を Hierarchical で利用すると、JSON データの marked_for_delete フラグによるオブジェクト削除もできます。

この場合、環境作成時の JSON ファイルで、削除対象だけ「marked_for_delete: true」とフラグを指定します。

「marked_for_delete: true」を親階層のオブジェクトで指定すると、その配下のオブジェクトも一緒に削除します。

ちなみにこのフラグはデフォルトだと false で、省略可能です。

また、ルート階層の「infra」は削除できません。

 

今回は、オブジェクト作成時に使用した JSON を「marked_for_delete: true」にした、

~_delete.json ファイルを用意して、オブジェクトを削除します。

 

それぞれの JSON ファイルで

~_delete.json ファイルを用意して、オブジェクトを削除します。

 

ext-vlan_delete.json をもとにした ext-vlan_delete.json では、

infra 直下のオブジェクトのみ 「marked_for_delete: true」にしてあります。

(infra オブジェクト自体は削除できないため)

例として、編集のあったファイル末尾の内容だけ、tail コマンドで表示します。

$ tail ./ext-vlan_delete.json

        ],

        "transport_zone_path": "/infra/sites/default/enforcement-points/default/transport-zones/4954eeca-decb-487a-8582-b011d60ba19f",

        "resource_type": "Segment",

        "marked_for_delete": false

      },

      "resource_type": "ChildSegment",

      "marked_for_delete": true

    }

  ]

}

 

個人的な JSON ファイル記述方法の工夫として、JSON ファイルでの編集ミス防止箇所のため、

Hierarchical API でオブジェクトの種類を表す「"resource_type": "Child~"」と、

marked_for_delete フラグは、できるだけ各オブジェクトの末尾にセットで記載するようにしています。

 

tier0.json をもとにした tier0_delete.json も、

Tier0 配下に一連ののオブジェクトが収まる階層構造なので

infra 直下の「ChildTier0」でのみ「marked_for_delete: true」にしてあります。

$ tail ./tier0_delete.json

          }

        ],

        "resource_type": "Tier0",

        "marked_for_delete": false

      },

      "resource_type": "ChildTier0",

      "marked_for_delete": true

    }

  ]

}

 

tier1_delete.json は、「Tier0」配下の階層に収まっていないオブジェクトがあり、

複数個所で "marked_for_delete": true の指定が必要になる例です。

階層全体でなく、個々のオブジェクトで marked_for_delete を true にしても削除ができるので、

すこし雑な方法ですが 元の tier1.json ファイルを、sed で一括置換してしまいます。

$ cat  ./tier1.json | sed 's/"marked_for_delete": false/"marked_for_delete": true/g' > tier1_delete.json

$ diff ./tier1.json ./tier1_delete.json

15c15

<         "marked_for_delete": false

---

>         "marked_for_delete": true

18c18

<       "marked_for_delete": false

---

>       "marked_for_delete": true

27c27

<         "marked_for_delete": false

---

>         "marked_for_delete": true

30c30

<       "marked_for_delete": false

---

>       "marked_for_delete": true

56c56

<               "marked_for_delete": false

---

>               "marked_for_delete": true

59c59

<             "marked_for_delete": false

---

>             "marked_for_delete": true

68c68

<               "marked_for_delete": false

---

>               "marked_for_delete": true

71c71

<             "marked_for_delete": false

---

>             "marked_for_delete": true

75c75

<         "marked_for_delete": false

---

>         "marked_for_delete": true

78c78

<       "marked_for_delete": false

---

>       "marked_for_delete": true

97c97

<         "marked_for_delete": false

---

>         "marked_for_delete": true

100c100

<       "marked_for_delete": false

---

>       "marked_for_delete": true

119c119

<         "marked_for_delete": false

---

>         "marked_for_delete": true

122c122

<       "marked_for_delete": false

---

>       "marked_for_delete": true

 

ネットワーク環境の削除。

それではオブジェクトを削除します。

今回は、あらかじめオーバーレイ セグメントは VM の vNIC から外して(別のポートグループを割り当てて)おき、

セグメントのポートがすでにない状態から開始しています。

 

tier1_delete.json を指定して、Tier-1 ゲートウェイと一連のオブジェクトを削除します。

$ curl -ks -u $CRED -H "Content-Type: application/json" -X PATCH -d @./tier1_delete.json https://$MGR/policy/api/v1/infra

 

tier0_delete.json を指定して、Tier-0 ゲートウェイと一連のオブジェクトを削除します。

$ curl -ks -u $CRED -H "Content-Type: application/json" -X PATCH -d @./tier0_delete.json https://$MGR/policy/api/v1/infra

 

ext-vlan_delete.json を指定して、VLAN セグメントを削除します。

$ curl -ks -u $CRED -H "Content-Type: application/json" -X PATCH -d @./ext-vlan_delete.json https://$MGR/policy/api/v1/infra

 

これらの API コールによって、(JSON の内容に問題がなければ)さきほど作成したオブジェクトが削除されます。

処理が完了すると、NSX Manager の Web UI でも、今回の手順開始時と同様にオブジェクト件数がゼロ件になります。

(ブラウザの更新や、「更新」ボタンで画面に反映されるはずです)

nsxt-mgr-obj-03.png

 

オブジェクトの指定によっては、対象オブジェクト同士の参照関係によってエラーになることがありますが、

その場合は少し待つと、(おそらく内部でリトライされて)エラーとなっていたオブジェクトでも削除されたりします。

もしくは、エラーになったオブジェクトを含むコールをリトライすることで、オブジェクトを削除できることがあります。

 

NSX-T の Policy API を利用する場合は、Hierarchical API 形式にすることで、

オブジェクト同士の参照関係を気にする苦労を削減できます。

手順の簡略化や構成管理の面で Hierarchical API 形式のほうが便利かなと思います。

 

ちなみに、いまのところのおすすめ資料は下記かなと思います。

 

NSX Policy API: Getting Started Guide

https://images.nsx.techzone.vmware.com/sites/default/files/PolicyAPI-v1.0.pdf

 

以上、Policy API の Hierarchical API でオブジェクトを作成/削除してみる話でした。