Отправка массива json в запросе POST (с сеансом) в vcenter в скрипте Python - PullRequest
0 голосов
/ 30 сентября 2019

Попытка отправить базовый массив json в API-адресе POST для использования vmware vcenter.

Я пишу это на python, для которого я новичок.

Имелпосмотрите несколько примеров, прежде чем публиковать их, но они не подходят для этого приложения.

Я гуглял подобные примеры и пробовал их, ни один из них не сработал.

У меня естьбольшой массив JSON для публикации в этом URL. Для этого требуется аутентификация, поэтому перед запуском второго API сначала запрашивается сеанс cookie.

Этот API используется для клонирования виртуальной машины из шаблона в библиотеке.

Просто интереснокто-то может мне помочь. Понимание vcenter не требуется, просто нужна помощь с базовым URL POST после аутентификации сеанса и для правильной отправки массива JSON в сообщении.

Массив JSON был разработан с использованием почтальона, который, как оказалось, имелдобавил тонну косых черт, все равно не повезло с ними или без них.

Может быть, просто опечатка, которую я не вижу ...

Спасибо, куча

Я попытался изменить опцию конца заголовка в этой строке кода, где «data = json». Пробовал с использованием параметров, данных, JSON aswell.

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

ОБНОВЛЕНИЕ --------------------------------

Этот код работает вместо этого, возможно, vcenter хочет, чтобы идентификатор сеанса был опубликован взаголовок в этом методе. Уродливо и не очень просто, но это работает по меньшей мере. Я попытался просто выполнить один URL-запрос, иметь все параметры и использовать параметр AUTH, но vcenter продолжал плевать на пустышку. Полагаю, я сузил это до ошибки аутентификации. Кажется, с моим исходным решением все в порядке, но в этом случае мы публикуем большой массив json. В этом случае Vcenter, похоже, не нравится то, что выкладывается. предыдущим решением после попытки запроса сеанса, и, кажется, предпочитает идентификатор сеанса, представленный в заголовке, при запросе второго API для клонирования виртуальной машины в vcenter. Большая часть этой идеи пришла из примерае, что POSTMAN выплюнул, используя библиотеку SDK от vcenter.

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)

1 Ответ

0 голосов
/ 01 октября 2019

Не пытайтесь вручную создать строку JSON, когда кавычки обратные слэши и т. Д.

Используйте функциональность для передачи словаря Python, который встроен в requests. Эти аргументы:

params: для параметров URL

data: для данных полезной нагрузки POST

Такжепосмотрите фактическую документацию по API, чтобы увидеть, как должны выглядеть ваши запросы: https://vmware.github.io/vsphere-automation-sdk-rest/6.7.1/index.html

Итак, функция развертывания библиотеки шаблонов ожидает запрос 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"
}

Где value - «Идентификатор развернутой виртуальной машины» согласно документации API.


РЕДАКТИРОВАТЬотносительно auth

У меня нет этого программного обеспечения для тестирования, только ESXi, у которого нет REST API. Из этого раздела Я думаю, вам нужно:

  • Подключение к службе поиска
  • Обнаружение URL-адреса конечной точки службы безопасного токена (STS)
  • Подключитесь к службе безопасного токена, чтобы получить токен SAML.

Но в разделе create упоминается только ответ, который является секретной строкой (предположительно, вызатем передайте это другим конечным точкам REST), но не о том, как предоставить токен SAML, если только я что-то упустил.

Возможно, посмотрите этот ответ: https://stackoverflow.com/a/56185704/2052575

...