在创建GCE实例之前,我使用带有Python 3的GCP API来创建新的VPC网络和子网络。我按这个顺序做这3个项目。创建网络后,我循环一个try/except块,试图创建子网络。如果没有循环,如果我试图过早地建立子网络,我会得到类似"The resource 'projects/{my project}/global/networks/{my network}' is not ready"
的错误。同样,当我建立子网时,它会立即返回一个响应,尽管新的子网还没有立即准备好。然后,我像以前一样循环一个compute.subnetworkds().get()
请求,但响应缺少state
字段,该字段应该出现在每个文档的输出中。
我的代码看起来像这个
# Assume `compute` is set up and authenticated already, and assume `settings` object is declared with GCP_PROJECT
# defined.
import time
from googleapiclient.errors import HttpError
region = 'us-west'
vpc_network_body = {
"routingConfig": {
"routingMode": "REGIONAL"
},
"autoCreateSubnetworks": False,
"name": "my_network",
"mtu": 1460
}
vpc_network_resp = compute.networks().insert(project=settings.GCP_PROJECT, body=vpc_network_body).execute()
vpc_network = vpc_network_resp['targetLink']
vcp_subnet_body = {
"enableFlowLogs": False,
'ipCidrRange': "10.0.0.0/24",
"name": "my_subnet",
"network": "my_network",
"privateIpGoogleAccess": False,
"region": f"{region}"
}
# Keep trying to create subnet until network is ready
while True:
try:
compute.subnetworks().insert(project=settings.GCP_PROJECT, region=region,
body=vcp_subnet_body).execute()
break
except HttpError as e:
print(f"VPC Network not ready. Retrying subnet creation soon. {e}")
time.sleep(3)
while True:
try:
subnetwork_resp = compute.subnetworks().get(project=settings.GCP_PROJECT, region=region,
subnetwork="my_subnet").execute()
print(f"Subnetwork creation resp {subnetwork_resp}")
# Ideally, this would work, but `state` isn't present
if subnetwork_resp['state'] == 'READY':
break
except HttpError as e:
print(f"Subnetwork not ready. Checking again soon. {e}")
time.sleep(3)
如注释中所述,最后(第三个(while
循环的try
块中的最后一行不起作用,因为GCP API响应中缺少state
。我目前的解决方案是反复尝试创建一个实例,直到成功为止,这表明subnetwork
已经准备好了,但我认为一定有更好的方法——它是什么?
我使用API资源管理器尝试相同的subnetworks.get
API请求(几分钟后,当子网络确实准备好时(,并得到缺少state
的响应:
{
"id": "129023512326123",
"creationTimestamp": "2021-05-31T11:58:44.000-07:00",
"name": "my_subnet",
"network": "https://www.googleapis.com/compute/v1/projects/my_project/global/networks/my_network",
"ipCidrRange": "10.0.0.0/29",
"gatewayAddress": "10.0.0.1",
"region": "https://www.googleapis.com/compute/v1/projects/my_project/regions/us-west1",
"selfLink": "https://www.googleapis.com/compute/v1/projects/my_project/regions/us-west1/subnetworks/my_subnet",
"privateIpGoogleAccess": false,
"fingerprint": "asdf",
"enableFlowLogs": false,
"privateIpv6GoogleAccess": "DISABLE_GOOGLE_ACCESS",
"purpose": "PRIVATE",
"logConfig": {
"enable": false
},
"kind": "compute#subnetwork"
}
状态不用于新创建的子网络,以指示它们是否已完成创建。从subnetwork.get()
:页面
状态
[仅输出]子网络的状态,可以是以下值:
就绪:子网络已创建并准备使用
DRAINING:仅适用于目的设置为INTERNAL_HTTPS_LOAD_BALANCER,并指示到负载平衡器正在耗尽。正在耗尽的子网络不能使用或修改,直到其达到READY 状态
这并不是说你可以用它来确定子网络是否已经创建完成。
但是,如果您使用完全相同的requestId
执行另一个subnetworks.insert()
并在那里检查status
,则可以获得状态,如查询参数部分所述。
状态
[仅输出]操作的状态,可以是以下内容:挂起、运行或完成。
请求Id
用于标识请求的可选请求ID。指定唯一的请求ID,这样如果您必须重试请求,服务器就会知道如果请求已经完成,则忽略该请求。
例如,考虑您提出初始请求的情况并且请求超时。如果您再次提出相同的请求请求ID,服务器可以检查原始操作是否与已接收到请求ID,如果是,将忽略第二个请求。这样可以防止客户端意外创建重复承诺。
请求ID必须是有效的UUID,但UUID为零的情况除外不支持(00000000-0000-0000-0000-000000000(。