我目前正在编写一个允许更新 Nutanix VM 类别的脚本。类别格式为键:值,虚拟机可以没有类别,可以有 1 个或多个类别。
执行此操作的过程非常简单:首先,我创建一个请求来获取现有 VM 信息 (GET)(然后检索其 UUID)。
第二次,我创建另一个请求,通过使用之前检索到的 UUID 来更新现有 VM (PUT),并更改我需要更改的内容(更新类别,但应该添加磁盘、网卡等...)
目前,获取虚拟机的请求很简单并且工作顺利,但当我需要使用第二个请求来更新虚拟机时遇到了问题。我们到了 :
用于此请求的有效负载在 JSON 中如下所示
{
"spec": {
"cluster_reference": {
"kind": "cluster",
"name": "my_cluster",
"uuid": "0004f63d-6664-35ce-0126-88e9a456d3fc"
},
"name": "test-vm",
"resources": {
"num_threads_per_core": 1,
"vnuma_config": {
"num_vnuma_nodes": 0
},
"serial_port_list": [],
"nic_list": [
{
"nic_type": "NORMAL_NIC",
"uuid": "334e302a-db6a-48fb-b138-c3e3b2f1d8f6",
"ip_endpoint_list": [
{
"ip": "10.230.172.84",
"type": "ASSIGNED"
}
],
"vlan_mode": "ACCESS",
"mac_address": "50:6b:8d:c5:6c:f0",
"subnet_reference": {
"kind": "subnet",
"name": "vlanXXX",
"uuid": "6de66666-05ec-46ac-6666-aea60e8e831f"
},
"is_connected": true,
"trunked_vlan_list": []
}
],
"num_vcpus_per_socket": 1,
"num_sockets": 1,
"gpu_list": [],
"is_agent_vm": false,
"memory_size_mib": 4096,
"boot_config": {
"boot_device_order_list": [
"CDROM",
"DISK",
"NETWORK"
],
"boot_type": "LEGACY"
},
"hardware_clock_timezone": "UTC",
"power_state_mechanism": {
"guest_transition_config": {
"should_fail_on_script_failure": false,
"enable_script_exec": false
},
"mechanism": "HARD"
},
"power_state": "ON",
"machine_type": "PC",
"vga_console_enabled": true,
"memory_overcommit_enabled": false,
"disk_list": [
{
"uuid": "6f6ad0ba-5b81-487d-8c7b-6c5249a51f4b",
"disk_size_bytes": 48318382080,
"storage_config": {
"storage_container_reference": {
"kind": "storage_container",
"uuid": "13611573-1364-4065-a03d-67a7da51c14d",
"name": "SelfServiceContainer"
}
},
"device_properties": {
"disk_address": {
"device_index": 0,
"adapter_type": "SCSI"
},
"device_type": "DISK"
},
"data_source_reference": {
"kind": "image",
"uuid": "50a186ef-2538-43f3-9d6c-9150dd464ad7"
},
"disk_size_mib": 46080
}
]
},
"description": "test sync categorie"
},
"api_version": "3.1",
"metadata": {
"last_update_time": "2023-06-29T14:25:48Z",
"kind": "vm",
"uuid": "6e1b8781-8a2a-4830-a15a-0af30daccf89",
"project_reference": {
"kind": "project",
"name": "_internal",
"uuid": "706f34c2-98be-4034-92e2-859be84040f3"
},
"creation_time": "2023-06-29T14:25:48Z",
"spec_version": 3,
"categories_mapping": {
"AppType": [
"Exchange"
],
"AppTier": [
"Default"
]
},
"entity_version": "2",
"owner_reference": {
"kind": "user",
"name": "OWNER",
"uuid": "6caba9b0-00a9-57ea-8ba0-10162c0b1dd4"
},
"categories": {
"AppType": "Exchange",
"AppTier": "Default"
}
}
}
在 Powershell 中转换后看起来像这样(注意:我们只对元数据感兴趣,你会明白为什么)
PS C:\Users\XXX> $payload.metadata
last_update_time : 29/06/2023 14:25:48
kind : vm
uuid : 6e1b8781-8a2a-4830-a15a-0af30daccf89
project_reference : @{kind=project; name=_internal; uuid=706f34c2-98be-4034-92e2-859be84040f3}
creation_time : 29/06/2023 14:25:48
spec_version : 3
categories_mapping : @{AppType=System.Object[]; AppTier=System.Object[]}
entity_version : 2
owner_reference : @{kind=user; name=owner; uuid=6caba9b0-00a9-57ea-8ba0-10162c0b1dd4}
categories : @{AppType=Exchange; AppTier=Default}
PS C:\Users\XXX> $payload.metadata.categories
AppType AppTier
------- -------
Exchange Default
正如你从PS的角度看到的,$payload
它的属性是PSCustomObject,所以我不能使用像.Add(), .Remove()
etc这样的方法...都不是+=
目前,我可以使用原始 JSON 有效负载手动更新虚拟机,并以 JSON 格式手动添加类别并通过 Postman 进行测试。效果很好。
问题是,正如您可能已经理解的那样,我必须保留 GET 方法中的所有原始有效负载 > 实现添加新类别 > 发送 PUT 请求以完全更新它而不会出现错误。
我的问题是:从 PS 的角度来看,如何轻松创建和添加新的 key:value 对象,并通过保留现有对象将其正确添加到类别中?(=如何在“categories”中插入新值:{“AppType”:“Exchange”,“AppTier”:“Default”})
PS:作为参考,这里是我在 PS 中用于 GET/PUT 的 Web 请求。PUT 请求正在工作,但除了 PUT 与原始值相同的值之外什么都不做:
#### -- HEADER
$Header_Prism = @{
'Accept' = 'application/json'
'Content-Type' = 'application/json'
'Authorization' = $basicAuthValue
}
#### --- GET VM
$get_vm = Invoke-RestMethod -Uri "https://mynutanix.net/vms/6e1b8781-6666-4830-a15a-0af30daccf89" `
-Method GET `
-Headers $Header_Prism
### --- PUT VM
$payload = $get_vm | select spec,api_version,metadata | convertTo-Json -depth 100
$put_vm = Invoke-RestMethod -Uri "https://mynutanix.net/vms/6e1b8781-6666-4830-a15a-0af30daccf89" `
-Method PUT `
-Headers $Header_Prism `
-Body $payload
感谢那些鼓舞人心的 StackOverflow 帖子,终于找到了解决方案:
https://stackoverflow.com/questions/48597871/how-to-add-an-object-in-array-on-parsed-json
https://stackoverflow.com/questions/23720045/powershell-how-to-add-something-on-parsed-json
所以就我而言(提醒:类别=键:值)我创建一个要更新的值
然后使用这个
Add-Member
方法添加我需要的密钥注意:这对 Nutanix 来说似乎是正确的,但我必须将
spec_version
参数增加 1最后创建 Web 请求中使用的有效负载
然后我就可以成功启动 PUT Web 请求,并且类别已正确更新!现在我将尝试提高我的脚本效率,我知道有些东西可能是多余的或者可以减轻。