尝试在POST URL API中发送基本的json数组以使用vmware vcenter。
我是用Python编写的,这是我的新手。
在发布此示例之前,先看了一些示例,但它们似乎不适合此应用程序。
我一直在搜索类似的示例并尝试使用它们,但没有一个起作用。
我有一个很大的JSON数组要发布在此URL中。这样做还需要身份验证,因此在执行第二个API之前首先请求cookie会话。
此API用于从库中的模板克隆VM。
只是想知道是否有人可以帮助我。不需要了解vcenter,只需在会话认证后需要有关基本URL POST的帮助即可 并能够在帖子中正确发送JSON数组。
JSON数组是使用邮递员开发的,邮递员似乎添加了许多斜杠,但无论有没有斜杠都没有运气。
可能只是我看不到的简单错字...
谢谢,堆
我尝试在代码的这一行中更改结尾标头选项,其中“ data = json”。还尝试使用参数,数据和JSON。
item_detail_json_array=s.post('https://'+vcip+'/rest/vcenter/vm-template/library-items/37a0484b-bd8c-486f-b110-36c79c2295f7?action=deploy', data=json)
还尝试使用“和”重新排列带有或不带有缩进和换行符的JSON数组。
import requests
import json
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
s=requests.Session()
s.verify=False
import json
vcip="xxx.xxx.xxx.xxx"
json = "{\r\n \"spec\": {\r\n \"description\": \"\",\r\n \"disk_storage\": {\r\n \"datastore\": \"datastore-25\",\r\n \"storage_policy\": {\r\n \"policy\": \"aa6d5a82-1c88-45da-85d3-3d74b91a5bad\",\r\n \"type\": \"USE_SPECIFIED_POLICY\"\r\n }\r\n },\r\n \"disk_storage_overrides\": [\r\n {\r\n \"key\": \"2000\",\r\n \"value\": {\r\n \"datastore\": \"datastore-25\",\r\n \"storage_policy\": {\r\n \"policy\": \"aa6d5a82-1c88-45da-85d3-3d74b91a5bad\",\r\n \"type\": \"USE_SPECIFIED_POLICY\"\r\n }\r\n }\r\n }\r\n ],\r\n \"guest_customization\": {\r\n \"name\": null\r\n },\r\n \"hardware_customization\": {\r\n \"cpu_update\": {\r\n \"num_cores_per_socket\": null,\r\n \"num_cpus\": null\r\n },\r\n \"disks_to_update\": [\r\n {\r\n \"key\": \"2000\",\r\n \"value\": {\r\n \"capacity\": 32212254721\r\n }\r\n }\r\n ],\r\n \"memory_update\": {\r\n \"memory\": null\r\n },\r\n \"nics\": [\r\n {\r\n \"key\": \"4000\",\r\n \"value\": {\r\n \"network\": \"network-26\"\r\n }\r\n }\r\n ]\r\n },\r\n \"name\": \"cloned via api6\",\r\n \"placement\": {\r\n \"folder\": \"group-v18\",\r\n \"resource_pool\": \"resgroup-23\"\r\n },\r\n \"powered_on\": true,\r\n \"vm_home_storage\": {\r\n \"datastore\": \"datastore-25\",\r\n \"storage_policy\": {\r\n \"policy\": \"aa6d5a82-1c88-45da-85d3-3d74b91a5bad\",\r\n \"type\": \"USE_SPECIFIED_POLICY\"\r\n }\r\n }\r\n }\r\n}"
def get_vc_session(vcip,username,password):
s.post('https://'+vcip+'/rest/com/vmware/cis/session', auth=(username,password))
return s
def get_vms(vcip):
item_detail_json_array=s.post('https://'+vcip+'/rest/vcenter/vm-template/library-items/37a0484b-bd8c-486f-b110-36c79c2295f7?action=deploy', data=json)
return item_detail_json_array
vcsession = get_vc_session(vcip,"administrator@vcenterserver","password1234")
itemid_json_array = get_vms(vcip) #executes the api enquiry stores as array
for x in itemid_json_array:
print(x) # just to get the response working for now
UPDATE --------------------------------
该代码正在起作用,似乎vcenter只希望此方法中的会话ID发布在标头中。丑陋而且不是很简单,但是至少可以说是有效的。我尝试仅执行一个URL请求,在其中拥有所有参数并使用AUTH参数,但是vcenter一直随口吐痰。因此,我相信我已将其范围缩小到了身份验证错误。似乎可以与我的原始解决方案一起使用,但是在这种情况下,我们将发布一个大型json数组。在这种情况下,在尝试执行会话请求之后,Vcenter似乎不喜欢以前的解决方案所吐露的内容,并且在请求第二个API在vcenter中克隆VM时,似乎更喜欢标头中显示的会话ID。这个想法大部分来自POSTMAN使用vcenter的SDK库吐出的示例。
import requests
import json
s=requests.Session()
s.verify=False
vcip = "xxx.xxx.xxx.xxx"
vmname = "testclonepython2"
username = 'administrator@vcenterdomain'
password = 'vcenterpass'
def get_vc_session(username,password):
s.post('https://'+vcip+'/rest/com/vmware/cis/session', auth=(username,password))
return s
get_vc_session(username,password)
cookie = s.cookies['vmware-api-session-id']
url = "https://"+vcip+"/rest/vcenter/vm-template/library-items/37a0484b-bd8c-486f-b110-36c79c2295f7"
querystring = {"action":"deploy"}
payload = "{\n \"spec\": {\n \"description\": \"\",\n \"disk_storage\": {\n \"datastore\": \"datastore-25\",\n \"storage_policy\": {\n \"policy\": \"aa6d5a82-1c88-45da-85d3-3d74b91a5bad\",\n \"type\": \"USE_SPECIFIED_POLICY\"\n }\n },\n \"disk_storage_overrides\": [\n {\n \"key\": \"2000\",\n \"value\": {\n \"datastore\": \"datastore-25\",\n \"storage_policy\": {\n \"policy\": \"aa6d5a82-1c88-45da-85d3-3d74b91a5bad\",\n \"type\": \"USE_SPECIFIED_POLICY\"\n }\n }\n }\n ],\n \"guest_customization\": {\n \"name\": null\n },\n \"hardware_customization\": {\n \"cpu_update\": {\n \"num_cores_per_socket\": null,\n \"num_cpus\": null\n },\n \"disks_to_update\": [\n {\n \"key\": \"2000\",\n \"value\": {\n \"capacity\": 32212254721\n }\n }\n ],\n \"memory_update\": {\n \"memory\": null\n },\n \"nics\": [\n {\n \"key\": \"4000\",\n \"value\": {\n \"network\": \"network-26\"\n }\n }\n ]\n },\n \"name\": \""+vmname+"\",\n \"placement\": {\n \"folder\": \"group-v18\",\n \"resource_pool\": \"resgroup-23\"\n },\n \"powered_on\": true,\n \"vm_home_storage\": {\n \"datastore\": \"datastore-25\",\n \"storage_policy\": {\n \"policy\": \"aa6d5a82-1c88-45da-85d3-3d74b91a5bad\",\n \"type\": \"USE_SPECIFIED_POLICY\"\n }\n }\n }\n}"
headers = {
'Content-Type': "application/json",
'Accept': "*/*",
'Cache-Control': "no-cache",
'Host': vcip,
'vmware-api-session-id': cookie,
'Accept-Encoding': "gzip, deflate",
'Connection': "keep-alive",
'cache-control': "no-cache"
}
response = requests.request("POST", url, data=payload, headers=headers, params=querystring, verify=False)
print(response.text)
答案 0 :(得分:0)
在反斜杠引号等期间,请勿尝试手动构建JSON字符串。
使用该功能传递内置于requests
中的python字典。这些参数是:
params
:用于URL参数
data
:用于POST有效负载数据
还要查看API的实际文档,以查看您的请求应该是什么样的:https://vmware.github.io/vsphere-automation-sdk-rest/6.7.1/index.html
因此template library deploy function希望发出POST请求,例如:
POST https://{server}/rest/vcenter/vm-template/library-items/{template_library_item}?action=deploy
他们给出了一个示例请求主体有效负载,除了结尾附近,几乎都是有效的python数据结构:
"powered_on": true,
应更改为:
"powered_on": True,
您确实应该根据要使这些变量成为什么来动态地构建它,但让我们继续使用示例,将其作为有效的python数据结构:
req_body = {'spec': {'description': 'string', 'disk_storage': {'datastore': 'obj-103', 'storage_policy': {'policy': 'obj-103', 'type': 'USE_SPECIFIED_POLICY'}}, 'disk_storage_overrides': [{'key': 'obj-103', 'value': {'datastore': 'obj-103', 'storage_policy': {'policy': 'obj-103', 'type': 'USE_SPECIFIED_POLICY'}}}], 'guest_customization': {'name': 'string'}, 'hardware_customization': {'cpu_update': {'num_cores_per_socket': 1, 'num_cpus': 1}, 'disks_to_remove': ['obj-103', 'obj-103'], 'disks_to_update': [{'key': 'obj-103', 'value': {'capacity': 1}}], 'memory_update': {'memory': 1}, 'nics': [{'key': 'obj-103', 'value': {'network': 'obj-103'}}]}, 'name': 'string', 'placement': {'cluster': 'obj-103', 'folder': 'obj-103', 'host': 'obj-103', 'resource_pool': 'obj-103'}, 'powered_on': True, 'vm_home_storage': {'datastore': 'obj-103', 'storage_policy': {'policy': 'obj-103', 'type': 'USE_SPECIFIED_POLICY'}}}}
请注意,URL上也有?action=deploy
,所以我们可以做类似的事情:
req_params = {'action':'deploy'}
现在构建请求,例如:
server = 'localhost' # My example
item = '37a0484b-bd8c-486f-b110-36c79c2295f7'
url = 'https://%s/rest/vcenter/vm-template/library-items/%s' % (server,item)
resp = r.post(url, params = req_params, data = req_body)
如果此时您在控制台中,则可以看到完整的URL:
>>> resp.url
'https://localhost/rest/vcenter/vm-template
/library-items/37a0484b-bd8c-486f-b110-36c79c2295f7?action=deploy'
和JSON响应:
>>> resp.json()
应显示以下内容:
{
"value": "obj-103"
}
根据API文档,value
是“已部署虚拟机的标识符”。
编辑有关身份验证
我没有要测试的软件,只有没有REST API的ESXi。我认为您需要从this section:
- 连接到查找服务
- 发现安全令牌服务(STS)端点URL
- 连接到安全令牌服务以获得SAML令牌。
但是create部分仅提到了响应,它是一个秘密字符串(大概是您然后将其提供给其他REST端点),但没有提到如何首先提供SAML令牌,除非我缺少一些东西。