PowerNSX でテナント追加の自動化をしてみる。Part.4

PowerNSX でテナント追加の自動化をしてみる。Part.4

ここまでの PowerNSX でのテナント追加と削除を、

簡易的なスクリプトにして省力化してみようと思います。

これまでの流れについて。

PowerNSX でテナント追加の自動化をしてみる。Part.1

PowerNSX でテナント追加の自動化をしてみる。Part.2

PowerNSX でテナント追加の自動化をしてみる。Part.3

ここまで実施してきたことを参考に、スクリプト化してみます。

今回の環境は、複雑になりすぎないようにあえてシンプルな構成にしています。

たとえば、下記のような感じです。

  • テナントごとに、論理スイッチ(VXLAN)は 1つだけ。
  • ファイアウォール ルールの通信元 / 通信先 やサービスなどは 1つしか指定しない。
  • VM の vNIC は 1つだけ。

実際の環境で使用する場合は、オブジェクトの確認やエラー制御などが必要に

なりますが、今回はできるだけ省略しています。

作成する環境の構成について。

設定値については、スクリプトとは別のファイルに分割してみました。

テナント ネットワークにかかわる設定値と、

テナント内の VM にかかわる設定値を、それぞれファイルを分けてみました。

NSX Edge(Edge Service Gateway と DLR Control VM)については、

はじめから  Object ID を確認しておいて決め打ちしています。

下記のような構成にしています。

テナント ネットワークの構成ファイル。

テナントの名前として、tenant-04 という文字列を使っています。

ファイル名: nw_tenant-04.ps1

# テナント固有 変数

$tenant_name = "tenant-04"

$gw_addr = "10.1.40.1"

$nw_addr = "10.1.40.0"

$nw_msak_length = 24

# 共通 変数

$tz_name = "tz01"

$dlr_id = "edge-5"

$esg_id = "edge-1"

$esg_ext_addr = "192.168.1.144"

$jbox_ip = "192.168.1.223"

$dlr_if_name = "if-" + $tenant_name

$dfw_section_name = "dfw-section-" + $tenant_name

$ls_name = "ls-" + $tenant_name

VM 1台目(vm41)の構成ファイル。

ファイル名: vm_vm41.ps1

# VM 固有 変数

$vm_name = "vm41"

$ip_addr = "10.1.40.101"

$vnic_name = "Network adapter 1"

$template_name = "photon-1.0-rev2"

# テナント内共通 変数

$nw_msak = "255.255.255.0"

$tenant_dns = "10.1.1.1"

$domain_name = "go-lab.jp"

$cluster_name = "nsx-cluster-01"

$datastore_name = "ds_nfs_lab02"

VM 2台目(vm42)の構成ファイル。

1台目との差分は VM 名と IP アドレスだけにしています。

ファイル名: vm_vm42.ps1

# VM 固有 変数

$vm_name = "vm42"

$ip_addr = "10.1.40.102"

$vnic_name = "Network adapter 1"

$template_name = "photon-1.0-rev2"

# テナント内共通 変数

$nw_msak = "255.255.255.0"

$tenant_dns = "10.1.1.1"

$domain_name = "go-lab.jp"

$cluster_name = "nsx-cluster-01"

$datastore_name = "ds_nfs_lab02"

テナント作成と VM の追加のスクリプト例。

PowerNSX でテナント追加の自動化をしてみる。Part.1 のように、

ネットワーク環境と VM を作成して、VM をネットワーク(論理スイッチ)に接続します。

テナントの作成 スクリプトの内容。

1つ目の引数で、テナントネットワークの構成ファイルを指定しています。

ファイル名: add_tenant_nw.ps1

$tenant_nw_config =  $args[0]

. $tenant_nw_config

# テナント 論理スイッチ作成

$tz = Get-NsxTransportZone -name $tz_name

$ls = New-NsxLogicalSwitch -TransportZone $tz -Name $ls_name

$ls | % {"Logical Switch: " + $_.name + " => objectId: " + $_.objectId}

# DLR 接続

$dlr = Get-NsxLogicalRouter -objectId $dlr_id

$dlr_if = $dlr | New-NsxLogicalRouterInterface `

    -Type internal -PrimaryAddress $gw_addr -SubnetPrefixLength $nw_msak_length `

    -ConnectedTo $ls -Name $dlr_if_name

$dlr_if | select -ExpandProperty interface |

    % {"DLR Interface: " + $_.name + " => index: " + $_.index}

# SNAT ルール追加

$nat_original_addr = $nw_addr + "/" + $nw_msak_length

$esg = Get-NsxEdge -objectId $esg_id

$snat_rule = $esg | Get-NsxEdgeNat | New-NsxEdgeNatRule `

    -Vnic 0 -action snat `

    -OriginalAddress $nat_original_addr -TranslatedAddress $esg_ext_addr

$snat_rule | % {"SNAT Source Address: " + $_.originalAddress + " => ruleId " + $_.ruleId}

# DFW ルール追加

$dfw_section = New-NsxFirewallSection -Name $dfw_section_name

$dfw_section | % {"DFW Section: " + $_.name + " => id " + $_.id}

$dfw_rule_name = "allow jBox to tenant-ls SSH"

$dfw_section = Get-NsxFirewallSection -objectId $dfw_section.id

$svc = Get-NsxService -Name SSH | where {$_.isUniversal -eq $false}

$dfw_rule = $dfw_section | New-NsxFirewallRule -Name $dfw_rule_name `

    -Action allow -Source $jbox_ip -Destination $ls -Service $svc -AppliedTo $ls

$dfw_rule | % {"DFW Rule: " + $_.name + " => id " + $_.id}

$dfw_rule_name = "allow Any to tenant-ls HTTP"

$dfw_section = Get-NsxFirewallSection -objectId $dfw_section.id

$svc = Get-NsxService -Name HTTP | where {$_.isUniversal -eq $false}

$dfw_rule = $dfw_section | New-NsxFirewallRule -Name $dfw_rule_name `

    -Action allow -Destination $ls -Service $svc -AppliedTo $ls

$dfw_rule | % {"DFW Rule: " + $_.name + " => id " + $_.id}

$vm_folder = Get-Folder -Type VM vm | New-Folder -Name $tenant_name

$vm_folder | % {"VM Folder: " + $_.Name + " => id " + $_.ExtensionData.MoRef.Value}

少し長いスクリプトですが、実行すると下記のような出力結果となります。

get_tenant_summary.png

VM の追加 スクリプトの内容。

1つ目の引数で、テナントネットワークの構成ファイルを指定して、

2つ目の引数で、VM の構成ファイルを指定しています。

ファイル名: add_tenant_vm.ps1

$tenant_nw_config =  $args[0]

. $tenant_nw_config

$tenant_vm_config = $args[1]

. $tenant_vm_config

$ls = Get-NsxTransportZone -name $tz_name | Get-NsxLogicalSwitch -Name $ls_name

"Create Guest OS Customization Spec: " + $os_spec_name

$os_spec_name = "osspec-" + $vm_name

$spec = New-OSCustomizationSpec -Name $os_spec_name `

    -OSType Linux -DnsServer $tenant_dns -Domain $domain_name

"Edit Guest OS Customization Spec: " + $_.Name

$spec | Get-OSCustomizationNicMapping |

    Set-OSCustomizationNicMapping -IpMode UseStaticIP `

    -IpAddress $ip_addr -SubnetMask $nw_msak -DefaultGateway $gw_addr | Out-Null

$vm = Get-Template -Name $template_name |

    New-VM -Name $vm_name -Location (Get-Folder -Type VM $tenant_name) `

    -ResourcePool $cluster_name -Datastore $datastore_name -OSCustomizationSpec $spec

$vm | % {"New VM: " + $_.Name + " => id " + $_.ExtensionData.MoRef.Value}

"Delete Guest OS Customization Spec: " + $spec.Name

$spec | Remove-OSCustomizationSpec -Confirm:$false

"Connect vNIC: " + ($vm.Name + "/" + $vnic_name + " to " + $ls.Name)

$vm | Get-NetworkAdapter -Name $vnic_name | Connect-NsxLogicalSwitch $ls

$vm | Start-VM | % {"Start VM: " + $_.Name}

テナント情報取得スクリプトの例。

PowerNSX でテナント追加の自動化をしてみる。Part.2 で確認したような情報を取得してみます。

しかし、あまり詳細な情報までとらず、特徴的なサマリを表示するようにしてみました。

https://gist.github.com/gowatana/0dfab57feb0598452bccf2448c45f4d9

テナント情報取得スクリプトの内容。

1つ目の引数で、テナントネットワークの構成ファイルを指定しています。

ファイル名: get_tenant_summary.ps1

$tenant_nw_config =  $args[0]

. $tenant_nw_config

function format_output ($title, $object) {

    "=" * 60

    $title

    ""

    ($object | Out-String).Trim()

    ""

}

"#" * 60

"テナント: " + $tenant_name

"実行時刻: " + (Get-Date).DateTime

""

$ls =  Get-NsxTransportZone $tz_name | Get-NsxLogicalSwitch -Name $ls_name

$ls_id = $ls.objectId

$dvpg = $ls | Get-NsxBackingPortGroup

$dlr = Get-NsxLogicalRouter -objectId $dlr_id

$dlr_if = $dlr | Get-NsxLogicalRouterInterface | where {$_.connectedToId -eq $ls_id}

$dlr_if_addr = $dlr_if.addressGroups.addressGroup | %{$_.primaryAddress + "/" + $_.subnetPrefixLength}

$ls_info = $ls | fl `

    name,

    objectId,

    @{N="VDSwitch";E={$dvpg.VDSwitch.Name}},

    @{N="dvPortgroup";E={$dvpg.Name}},

    @{N="DlrIfIPAddress";E={$dlr_if_addr}}

format_output "Tenant Network" $ls_info

$esg = Get-NsxEdge -objectId $esg_id

$nat_original_addr = $nw_addr + "/" + $nw_msak_length

$snat_rule = $esg | Get-NsxEdgeNat | Get-NsxEdgeNatRule |

    where {$_.originalAddress -eq $nat_original_addr}

$snat_rule_info = $snat_rule | fl translatedAddress,originalAddress

format_output "ESG SNAT ルール情報" $snat_rule_info

$dfw_section = Get-NsxFirewallSection -Name $dfw_section_name

$dfw_rules = $dfw_section.rule

$dfw_rules_info = $dfw_rules | select `

    id,

    name,

    @{N="Src";E={

            $member = $_ | Get-NsxFirewallRuleMember |

                where {$_.MemberType -eq "Source"} |

                % {if($_.Name -eq $null){$_.Value}else{$_.Name}

            }

            if(($member).Count -eq 0){$member = "Any"}

            $member

        }

    },

    @{N="Dst";E={

            $member = $_ | Get-NsxFirewallRuleMember |

                where {$_.MemberType -eq "Destination"} |

                % {if($_.Name -eq $null){$_.Value}else{$_.Name}

            }

            if(($member).Count -eq 0){$member = "Any"}

            $member

        }

    },

    @{N="Service";E={$_.services.service.name}},

    action,

    @{N="appliedTo";E={$_.appliedToList.appliedTo.name}},

    logged | ft -AutoSize

format_output ("DFWセクション" + $dfw_section.name + "ルール情報") $dfw_rules_info

# 論理スイッチに接続されているVMの情報

$vms = $ls | Get-NsxBackingPortGroup | Get-VM | sort Name

$vm_info = $vms | % {

    $vm = $_

    $guest = $_ | Get-VmGuest

    $vm | select `

        @{N="VM";E={$_.Name}},

        @{N="HostName";E={$_.Guest.ExtensionData.HostName}},

        @{N="State";E={$_.Guest.State}},

        @{N="IPAddress";E={

                $_.Guest.ExtensionData.Net.IpConfig.IpAddress |

                    where {$_.PrefixLength -le 32} |

                    % {$_.IpAddress + "/" + $_.PrefixLength}

            }

        },

        @{N="Gateway";E={

                $guest_dgw = $_.Guest.ExtensionData.IpStack.IpRouteConfig.IpRoute |

                    where {$_.Network -eq "0.0.0.0"}

                $guest_dgw.Gateway.IpAddress

            }

        },

        @{N="GuestFullName";E={$_.Guest.ExtensionData.GuestFullName}}

} | ft -AutoSize

format_output "VM / ゲスト ネットワーク情報" $vm_info

テナント削除スクリプトの例。

PowerNSX でテナント追加の自動化をしてみる。Part.3​ のように、

VM を削除して、論理スイッチも削除します。

特に対話的な確認メッセージもなく、一気に削除するようにしています。

テナント削除 スクリプトの内容。

1つ目の引数で、テナントネットワークの構成ファイルを指定しています。

ファイル名: delete_tenant.ps1

$tenant_nw_config =  $args[0]

. $tenant_nw_config

$ls = Get-NsxTransportZone $tz_name | Get-NsxLogicalSwitch -Name $ls_name

"Remove VM"

$ls | Get-NsxBackingPortGroup | Get-VM | Stop-VM -Confirm:$false | Out-Null

$ls | Get-NsxBackingPortGroup | Get-VM | Remove-VM -DeletePermanently -Confirm:$false

"Remove DFW Rule"

Get-NsxFirewallSection -Name $dfw_section_name |

    Remove-NsxFirewallSection -force -Confirm:$false

"Remove SNAT Rule"

$nat_original_addr = $nw_addr + "/" + $nw_msak_length

Get-NsxEdge -objectId $esg_id | Get-NsxEdgeNat | Get-NsxEdgeNatRule |

    where {$_.originalAddress -eq $nat_original_addr} |

    Remove-NsxEdgeNatRule -Confirm:$false

"Remove NsxLogical Switch"

Get-NsxLogicalRouter -objectId $dlr_id | Get-NsxLogicalRouterInterface |

    where {$_.connectedToId -eq $ls.objectId} |

    Remove-NsxLogicalRouterInterface -Confirm:$false

$ls | Remove-NsxLogicalSwitch -Confirm:$false

"Remove VM Folder"

Get-Folder -Type VM $tenant_name | Remove-Folder -Confirm:$false

まだつづく。

PowerNSX でテナント追加の自動化をしてみる。Part.5

Version history
Revision #:
1 of 1
Last update:
‎07-12-2017 07:59 AM
Updated by: