ESXiでvim-cmdを使う

自由にESXiが使える研究室で，仮想マシンが自由に作成，使用される環境では，構成管理データベースのようなものが必要なはず．
スプレッドシートのようなものにまとめるとしても，手動でまとめるのはめんどくさい．
そこで，ESXiのCUIでコマンドを使って取得できる仮想マシンの情報をまとめてみました．

## 構成管理データベースとは
構成管理データベースとは，その組織のIT関連のすべてを記録するものらしいです．
とりあえず，どんな仮想マシンがあるのかだけでもまとめておく価値はあると思います．

## vim-cmd
ESXiのCUIで仮想マシンの情報を取得，操作するためのコマンドにvim-cmdがあります．

```sh
vim-cmd vmsvc/
```

仮想マシンを操作するときのコマンドは基本的に上の形です．実行すると

```
[user@esxi:~] vim-cmd vmsvc/
Commands available under vmsvc/:
acquiremksticket                 get.snapshotinfo
acquireticket                    get.spaceNeededForConsolidation
createdummyvm                    get.summary
destroy                          get.tasklist
device.connection                getallvms
device.connusbdev                gethostconstraints
device.ctlradd                   message
device.ctlrremove                power.getstate
device.disconnusbdev             power.hibernate
device.diskadd                   power.off
device.diskaddexisting           power.on
device.diskextend                power.reboot
device.diskremove                power.reset
device.getdevices                power.shutdown
device.nvdimmadd                 power.suspend
device.nvdimmremove              power.suspendResume
device.toolsSyncSet              queryftcompat
devices.createnic                reload
get.capability                   setscreenres
get.config                       snapshot.create
get.config.cpuidmask             snapshot.dumpoption
get.configoption                 snapshot.get
get.datastores                   snapshot.remove
get.disabledmethods              snapshot.removeall
get.environment                  snapshot.revert
get.filelayout                   snapshot.setoption
get.filelayoutex                 tools.cancelinstall
get.guest                        tools.install
get.guestheartbeatStatus         tools.upgrade
get.managedentitystatus          unregister
get.networks                     upgrade
get.runtime
```

こんなのが返ってきます．どんなコマンドがあるか教えてくれます．
今回は，仮想マシンの情報が知りたいので，使うコマンドは``get``ってついてるやつです．

### getallvms
まずはこのコマンドを使います．このコマンドは，登録されている仮想マシンのリストを表示します．

```
[user@esxi:~] vim-cmd vmsvc/getallvms
Vmid      Name                  File                          Guest OS      Version   Annotation
1      vm1          [StoreNAS-esxi] vm1/vm1.vmx             ubuntu64Guest   vmx-20
2      vm2          [StoreNAS-esxi] vm2/vm2.vmx             ubuntu64Guest   vmx-20
3      vm3          [StoreNAS-esxi] vm3/vm3.vmx             ubuntu64Guest   vmx-20
```

こんな感じになります．一番左の``Vmid``を使うことで，仮想マシンの詳細な情報を取得できます．

### get.guest

```
[user@esxi:~] vim-cmd vmsvc/get.guest 1
Guest information:

(vim.vm.GuestInfo) {
   toolsStatus = "toolsOk",
   toolsVersionStatus = "guestToolsUnmanaged",
   toolsVersionStatus2 = "guestToolsUnmanaged",
   toolsRunningStatus = "guestToolsRunning",
   toolsVersion = "12389",
   toolsInstallType = "guestToolsTypeOpenVMTools",
   toolsUpdateStatus = (vim.vm.GuestInfo.ToolsUpdateStatus) null,
   guestId = "ubuntu64Guest",
   guestFamily = "linuxGuest",
   guestFullName = "Ubuntu Linux (64-bit)",
   guestDetailedData = "architecture='X86' bitness='64' distroAddlVersion='22.04.4 LTS (Jammy Jellyfish)' distroName='Ubuntu' distroVersion='22.04' familyName='Linux' kernelVersion='5.15.0-125-generic' prettyName='Ubuntu 22.04.4 LTS'",
   hostName = "vm1",
   ipAddress = "192.168.100.2",
   net = (vim.vm.GuestInfo.NicInfo) [
      (vim.vm.GuestInfo.NicInfo) {
         network = "private",
         ipAddress = (string) [
            "192.168.100.1",
            "fe80::20c:29ff:fe23:3fa"
         ],
         macAddress = "00:0c:29:23:03:fa",
         connected = true,
         deviceConfigId = 4000,
         dnsConfig = (vim.net.DnsConfigInfo) null,
         ipConfig = (vim.net.IpConfigInfo) {
            ipAddress = (vim.net.IpConfigInfo.IpAddress) [
               (vim.net.IpConfigInfo.IpAddress) {
                  ipAddress = "192.168.100.2",
                  prefixLength = 24,
                  origin = <unset>,
                  state = "preferred",
                  lifetime = <unset>
               },
               (vim.net.IpConfigInfo.IpAddress) {
                  ipAddress = "fe80::20c:29ff:fe23:3fa",
                  prefixLength = 64,
                  origin = <unset>,
                  state = "unknown",
                  lifetime = <unset>
               }
            ],
            dhcp = (vim.net.DhcpConfigInfo) null,
            autoConfigurationEnabled = <unset>
         },
         netBIOSConfig = (vim.net.NetBIOSConfigInfo) null
      }
   ],
   ipStack = (vim.vm.GuestInfo.StackInfo) [
      (vim.vm.GuestInfo.StackInfo) {
         dnsConfig = (vim.net.DnsConfigInfo) {
            dhcp = false,
            hostName = "vm1",
            domainName = "a910.tak-cslab.org",
            ipAddress = (string) [
               "192.168.100.3"
            ],
            searchDomain = (string) [
               "a910.tak-cslab.org"
            ]
         },
         ipRouteConfig = (vim.net.IpRouteConfigInfo) {
            ipRoute = (vim.net.IpRouteConfigInfo.IpRoute) [
               (vim.net.IpRouteConfigInfo.IpRoute) {
                  network = "0.0.0.0",
                  prefixLength = 0,
                  gateway = (vim.net.IpRouteConfigInfo.Gateway) {
                     ipAddress = "192.168.100.1",
                     device = "0"
                  }
               },
               (vim.net.IpRouteConfigInfo.IpRoute) {
                  network = "10.200.70.35",
                  prefixLength = 32,
                  gateway = (vim.net.IpRouteConfigInfo.Gateway) {
                     ipAddress = "192.168.100.1",
                     device = "0"
                  }
               },
               (vim.net.IpRouteConfigInfo.IpRoute) {
                  network = "192.168.100.0",
                  prefixLength = 24,
                  gateway = (vim.net.IpRouteConfigInfo.Gateway) {
                     ipAddress = <unset>,
                     device = "0"
                  }
               },
               (vim.net.IpRouteConfigInfo.IpRoute) {
                  network = "192.168.100.1",
                  prefixLength = 32,
                  gateway = (vim.net.IpRouteConfigInfo.Gateway) {
                     ipAddress = <unset>,
                     device = "0"
                  }
               },
               (vim.net.IpRouteConfigInfo.IpRoute) {
                  network = "192.168.100.35",
                  prefixLength = 32,
                  gateway = (vim.net.IpRouteConfigInfo.Gateway) {
                     ipAddress = <unset>,
                     device = "0"
                  }
               },
               (vim.net.IpRouteConfigInfo.IpRoute) {
                  network = "fe80::",
                  prefixLength = 64,
                  gateway = (vim.net.IpRouteConfigInfo.Gateway) {
                     ipAddress = <unset>,
                     device = "0"
                  }
               },
               (vim.net.IpRouteConfigInfo.IpRoute) {
                  network = "fe80::20c:29ff:fe23:3fa",
                  prefixLength = 128,
                  gateway = (vim.net.IpRouteConfigInfo.Gateway) {
                     ipAddress = <unset>,
                     device = "0"
                  }
               },
               (vim.net.IpRouteConfigInfo.IpRoute) {
                  network = "ff00::",
                  prefixLength = 8,
                  gateway = (vim.net.IpRouteConfigInfo.Gateway) {
                     ipAddress = <unset>,
                     device = "0"
                  }
               }
            ]
         },
         ipStackConfig = <unset>,
         dhcpConfig = (vim.net.DhcpConfigInfo) null
      }
   ],
   disk = (vim.vm.GuestInfo.DiskInfo) [
      (vim.vm.GuestInfo.DiskInfo) {
         diskPath = "/",
         capacity = 91768348672,
         freeSpace = 55241244672,
         filesystemType = "ext4",
         mappings = (vim.vm.GuestInfo.VirtualDiskMapping) [
            (vim.vm.GuestInfo.VirtualDiskMapping) {
               key = 2000
            }
         ]
      },
      (vim.vm.GuestInfo.DiskInfo) {
         diskPath = "/boot",
         capacity = 2040373248,
         freeSpace = 1661591552,
         filesystemType = "ext4",
         mappings = (vim.vm.GuestInfo.VirtualDiskMapping) [
            (vim.vm.GuestInfo.VirtualDiskMapping) {
               key = 2000
            }
         ]
      },
      (vim.vm.GuestInfo.DiskInfo) {
         diskPath = "/boot/efi",
         capacity = 1124999168,
         freeSpace = 1118629888,
         filesystemType = "vfat",
         mappings = (vim.vm.GuestInfo.VirtualDiskMapping) [
            (vim.vm.GuestInfo.VirtualDiskMapping) {
               key = 2000
            }
         ]
      }
   ],
   screen = (vim.vm.GuestInfo.ScreenInfo) {
      width = 1024,
      height = 768
   },
   guestState = "running",
   powerPolicy = (vim.vm.PowerPolicy) null,
   appHeartbeatStatus = "appStatusGray",
   guestKernelCrashed = false,
   appState = "none",
   guestOperationsReady = true,
   interactiveGuestOperationsReady = false,
   guestStateChangeSupported = true,
   generationInfo = <unset>,
   hwVersion = "vmx-20",
   toolsHealthEvents = <unset>,
   customizationInfo = (vim.vm.GuestInfo.CustomizationInfo) {
      customizationStatus = "TOOLSDEPLOYPKG_IDLE",
      startTime = <unset>,
      endTime = <unset>,
      errorMsg = <unset>
   }
}
```


このように使うと，仮想マシンの情報が取得できます．
このコマンドだけでほとんどの情報が取得できます．
電源が入ってない仮想マシンの情報はほとんど出力されません．

- ホスト名
- IPアドレス

データベースに必要な情報はこのあたりだと思います．

## おわりに
他にもコマンドで取得できる情報があるので，自動で情報を取得できる自作データベースを作れたら面白そうだなと思います．