使用 Python API 删除 GCP 实例元数据

Remove GCP instance metadata using Python API

我正在尝试使用 Google Python API 和以下代码删除实例的元数据,但似乎我只能添加一个新的或更新一个现有一个:

from googleapiclient import discovery
from google.oauth2.service_account import Credentials

auth = Credentials.from_service_account_file("my/jwt/file.json")

service = discovery.build(
    serviceName="compute",
    version="v1",
    credentials=auth,
    cache_discovery=False
)

project, zone, instance = ("my-project", "us-east1-c", "my-instance")

result = service.instances().get(project=project, zone=zone,
                                 instance=instance).execute()

fingerprint = result["metadata"]["fingerprint"]
kind = result["metadata"]["kind"]

body = {
    "items": [{
        "key": "want-to-remove-this-key",
        "value": None
    }],
    "kind": kind,
    "fingerprint": fingerprint
}

service.instances().setMetadata(project=project, zone=zone,
                                instance=instance, body=body).execute()

使用该代码,我的实例保留了元数据键但没有值,我什至想从元数据中删除键。

有什么办法吗,还是只能留空?

IIRC Items 的集合被视为文档(从中导出 fingerprint 散列)。

应该能够使用instances.get and setMetadata中的metadata.fingerprint使用metadata.fingerprint 您想要的元数据中的值。

请在牺牲实例上试试这个以确认我的理解是正确的

Compute Engine 只允许更新或添加元数据,因此您需要处理这个问题。

如果您想从一个实例中删除所有元数据,可以这样做:

import googleapiclient.discovery

compute = googleapiclient.discovery.build('compute', 'v1')

project= "YOUR_PROJECT_ID"
zone= "A_ZONE"
instance_name = "INSTANCE_NAME"

instance_data = compute.instances().get(project=project, zone=zone, instance=instance_name).execute()

body = {
  "fingerprint": instance_data["metadata"]["fingerprint"],
  "items": []
}

compute.instances().setMetadata(project=project, zone=zone, instance=instance_name, body=body).execute()

如果您需要删除特定密钥,您需要获取当前元数据,请删除该密钥并重新设置:

import googleapiclient.discovery

compute = googleapiclient.discovery.build('compute', 'v1')

project= "YOUR_PROJECT_ID"
zone= "A_ZONE"
instance_name = "INSTANCE_NAME"

instance_data = compute.instances().get(project=project, zone=zone, instance=instance_name).execute()

metadata_items = instance_data["metadata"]["items"]

body = {
    "fingerprint": instance_data["metadata"]["fingerprint"],
    "items": list(filter(lambda i: i['key'] != "KEY_TO_DELETE", metadata_items))
}

compute.instances().setMetadata(project=project, zone=zone, instance=instance_name, body=body).execute()

这可以扩展为删除多个键,但这可以给你一个想法。