AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / server / 问题 / 1135179
Accepted
motorbass
motorbass
Asked: 2023-06-29 23:40:06 +0800 CST2023-06-29 23:40:06 +0800 CST 2023-06-29 23:40:06 +0800 CST

使用 Powershell 和 Nutanix API 更新 JSON 有效负载

  • 772

我目前正在编写一个允许更新 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

powershell
  • 1 1 个回答
  • 28 Views

1 个回答

  • Voted
  1. Best Answer
    motorbass
    2023-06-30T17:40:34+08:002023-06-30T17:40:34+08:00

    感谢那些鼓舞人心的 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

    所以就我而言(提醒:类别=键:值)我创建一个要更新的值

    $to_update = 'My_Value' 
    

    然后使用这个Add-Member方法添加我需要的密钥

    $get_vm.metadata.categories | Add-Member -value $to_update -MemberType NoteProperty -Name 'My_Key'
    

    注意:这对 Nutanix 来说似乎是正确的,但我必须将spec_version参数增加 1

    ($get_vm.metadata.spec_version)++
    

    最后创建 Web 请求中使用的有效负载

    $payload = (($get_vm | select spec,api_version,metadata) | convertto-json -depth 100)
    

    然后我就可以成功启动 PUT Web 请求,并且类别已正确更新!现在我将尝试提高我的脚本效率,我知道有些东西可能是多余的或者可以减轻。

    • 1

相关问题

  • 资源锁和电源外壳

  • 脚本 - 如何断开远程桌面会话?

  • 如何限制向通讯组发送到外部地址?

  • Powershell对值与数组的作用不同?

  • Windows Powershell Vim 键绑定

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    新安装后 postgres 的默认超级用户用户名/密码是什么?

    • 5 个回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve