Понимание интерфейса VMware REST API

Опубликовано: 17 Апреля, 2023
Понимание интерфейса VMware REST API

SOAP (Simple Object Access Protocol) — это протокол доступа к веб-службам, изначально разработанный Microsoft. Он основан исключительно на XML и был разработан, потому что существующие службы обмена сообщениями, которые Microsoft использовала, такие как DCOM (распределенная объектная модель компонентов) и COBRA (общая архитектура посредника объектных запросов), не работали должным образом в Интернете. После разработки SOAP Microsoft передала его IEFT, который стандартизировал его, породив множество других стандартов веб-сервисов, таких как WS-Federation, WS-Addressing, WS-Policy, WS-Security и т. д., которые определяются с помощью WSDL. (язык описания веб-сервисов). REST — это упрощенная альтернатива SOAP, которая использует методы HTTP 1.1, такие как GET, POST, PUT и DELETE, для выполнения запросов вместо XML, который использует SOAP. Доступно множество веб-служб на основе REST, которые могут выводить данные в простых форматах, таких как CSV, JSON и даже RSS. Это значительно упрощает использование REST, например, при использовании JavaScript для разработки динамического веб-сайта или веб-приложения. VMware vSphere 6.5 представляет ряд новых API-интерфейсов на основе REST в дополнение к существующим API-интерфейсам SOAP на платформе. Это может указывать на то, что VMware рассматривает REST как будущее по сравнению с SOAP. Чтобы помочь нам понять VMware REST API и способы его использования, я попросил Люка Декенса поделиться с нами своим опытом. Люк является vExpert и MVP и интересуется автоматизацией всех вещей, в частности, с помощью PowerShell и PowerCLI. Он является соавтором справочника по PowerCLI и регулярно выступает на конференциях. Вы можете прочитать блог Люка здесь или подписаться на него в Твиттере как @LucD22.

REST API на практике

В последние пару лет все больше и больше поставщиков рекламируют, что они предоставляют интерфейс RESTful для своего продукта. Рискуя уже начать войну флейма во вступительном разделе этой статьи, я склонен не согласиться с большинством этих поставщиков.

Нет, вы не предоставляете интерфейс RESTful для своего продукта; вы следуете некоторым правилам REST в своем новом API. Но, эй, то, что вы предоставляете, определенно делает мою жизнь как потребителя вашего продукта намного проще и легче.

Что такое REST API?

Так почему же смелое заявление в предыдущем разделе? Как и в большинстве случаев, существует разница между теорией и практикой, а точнее между интерфейсом RESTful и базовыми правилами REST. В то время как теория RESTful, первоначально описанная Роем Т. Филдингом в главе 5 его докторской диссертации «Архитектурные стили и проектирование сетевых программных архитектур», и, более конкретно, в его сообщении в блоге «REST API должны быть гипертекстовыми », подчеркивает важность обнаружения действий, которые клиент может выполнить над объектом, большинство реализаций REST, похоже, отклоняются от этого принципа.

В качестве практического примера возьмем виртуальную машину, с помощью действия GET мы можем запросить информацию об этой виртуальной машине, но это будет клиент, который должен интерпретировать возвращенное PowerState виртуальной машины, «включено» или «выключено», чтобы определить, может ли он выполнить POST действие «выключить» или «включить».

В REST API, который предлагает интерфейс RESTful, он должен соответствовать ограничениям HATEOAS (Hypermedia As The Engine Of Application State). В частности, объект, возвращаемый командой GET, должен содержать «ссылки» на действия, доступные над объектом в его текущем состоянии.

Зачем использовать REST API?

Означает ли предыдущее, что мы не должны использовать REST API, которые не являются «чистыми», то есть RESTful? Конечно нет. REST API предлагает больше, чем просто возможность обнаружения действий для потребителя. А со стороны провайдера (вендора) это дает возможность упростить их API. Кроме того, поскольку большинство реализаций REST API преимущественно используют HTTP(S) в качестве протокола, это также делает архитектуру, основанную на концепциях REST, более управляемой для сетевых команд. И, наконец, наш предпочтительный язык автоматизации, PowerShell, упрощает использование REST API через HTTP с помощью командлетов Invoke-RestMethod и Invoke-WebRequest.

VMware и REST API

Может быть несколько причин, и это моя личная интерпретация: VMware собирается использовать REST API для замены своего SOAP API. Одно из них определенно заключается в том, что это позволяет VMware переключиться на Swagger, чтобы определить их API гораздо проще, чем это было в случае с WADL (язык дизайна веб-приложений) для их SOAP API.

Например, API Explorer, доступный с версии VMware vCenter 6.5, является прямым результатом этого перехода на Swagger. Этот обозреватель API, доступный в vCenter, позволяет изучить и «опробовать» доступный REST API без фактического написания кода:

Вызов REST API

Мы уже упоминали, что в PowerShell есть встроенные командлеты для работы с REST API, но есть несколько тонкостей, которые необходимо понять, чтобы сделать правильный вызов REST API:

В VMware REST API, доступном в vCenter 6.5, есть API, который позволяет получить (получить) все доступные команды (/com/vmware/vapi/metadata/cli/command), а затем через второй API fetch (опубликовать) более подробную информацию о доступных параметрах (rest/com/vmware/vapi/metadata/cli/command?~action=get).

Простой скрипт для использования этих двух API может выглядеть так.

$vCenterName = 'vcsa.local.lab'
$ авторизация = @ {
'vmware-api-session-id' = '8d377b7ee718b9fdead33d8f3230019c'
}
$get_command = «https://$($vCenterName)/rest/com/vmware/vapi/metadata/cli/command»
$get_Command_detail = "https://$($vCenterName)/rest/com/vmware/vapi/metadata/cli/command?~action=get"
# Получить все идентификаторы команд
$result = Invoke-RestMethod -Uri $get_command -Headers $auth
$sRest = @{
Метод = "Опубликовать"
Ури = $get_Command_detail
Тело = ''
Заголовки = $ авторизация
ContentType = 'приложение/json'
}
# Получить больше информации о каждой команде
$отчет = @()
foreach($команда в $result.value){
$sRest.Body = @{'identity' = $command} | ConvertTo-Json
$detail = Invoke-RestMethod @sRest
$report += $detail.value.options |
Select-Object @{N='Путь';E={$command.path}},
@{N='Операция';E={$command.name}},
@{N='Описание';E={$detail.value.description}},
@{N='Поле';E={$_.field_name}},
@{N='Тип';E={$_.type}},
@{N='Описание поля';E={$_.description}}
}
$ отчет | Export-Csv -Путь C:Temp est-commands.csv -UseCulture

Пока не обращайте внимания на заголовок $auth, это способ сослаться на сеанс, который мы открыли ранее. Мы вернемся к этому позже.

В этом фрагменте есть два вызова Invoke-RestMethod. Первый использует API для получения всех команд, второй использует API для получения дополнительных сведений о каждой команде. Обратите внимание, что во втором вызове Invoke-RestMethod фрагмент использует «разбрызгивание» для передачи параметров командлету. Это мое личное предпочтение, так как я чувствую, что это делает код более читабельным и организованным.

Поскольку мы используем командлет Invoke-RestMethod, нам придется преобразовывать объекты, которые мы передаем в Body, в правильный формат. В этом случае мы конвертируем в JSON. Полученный файл CSV содержит информацию обо всех командах (330 на момент написания этой статьи) и доступных параметрах для каждой команды:

Обратите внимание, что это содержит ту же информацию, которую мы также находим в обозревателе API для этого конкретного вызова:

Invoke-RestMethod против Invoke-WebRequest

В предыдущем фрагменте мы использовали командлет Invoke-RestMethod для вызова REST API. Могли бы мы сделать это с помощью командлета Invoke-WebRequest?

Конечно, оба командлета можно использовать для выполнения вызовов REST API, но есть некоторые различия, о которых вам следует знать. Я предпочитаю классифицировать Invoke-WebRequest как «сырой», а Invoke-RestMethod — как «интерпретируемый». Образец должен прояснить это. Ниже приведены два вызова одного и того же REST API:

$vCenterName = 'vcsa.local.lab'
$ авторизация = @ {
'vmware-api-session-id' = '10e8e9965cd56bdd5478951fbe52c33f'
}
$uri = «https://$($vCenterName)/rest/com/vmware/cis/session?~action=get»
$sRest = @{
Ури = $ури
Метод = "Опубликовать"
Заголовки = $ авторизация
}
$resultRest = Invoke-RestMethod @sRest
$resultWeb = Invoke-WebRequest @sRest
Invoke-RestMethod возвращает «интерпретированные» данные, в чем мы можем убедиться, расширив результат:
ценность
—–
@{created_time=2017-12-04T12:38:11.232Z; last_accessed_time=2017-12-04T12:49:38.850Z; [электронная почта защищена]}
Invoke-WebRequest возвращает «сырые» данные. Обратите внимание, что свойство «Content» содержит (единственные) данные, которые мы видим с помощью Invoke-RestMethod:
Код состояния: 200
Описание статуса: ОК
Содержание: {"значение":{"created_time":"2017-12-04T12:38:11.232Z","last_accessed_time":"2017-12-04T12:49:38.859Z","пользователь":"[электронная почта защищена ]”}}
RawContent: HTTP/1.1 200 ОК
Передача-кодирование: по частям
Тип содержимого: приложение/json
Дата: пн, 04 декабря 2017 г., 12:49:38 по Гринвичу
{"value":{"created_time":"2017-12-04T12:38:11.232Z","last_accessed_time":"2017-12-04…
Формы: {}
Заголовки: {[Transfer-Encoding, chunked], [Content-Type, application/json], [Date, Mon, 04 Dec 2017 12:49:38 GMT]}
Картинки: {}
Входные поля: {}
Ссылки: {}
ParsedHtml: mshtml.HTMLDocumentClass
RawContentLength: 138

Что происходит, так это то, что командлет Invoke-RestMethod делает большую часть работы за вас. Это включает в себя перевод StatusCode в сообщение об ошибке, если он не равен 200. Но он также преобразует JSON в объект PowerShell.

Какой командлет вы используете, зависит от вашего выбора, но лично я предпочитаю использовать командлет Invoke-RestMethod. Зачем вам перекодировать некоторые функции, доступные в командлете, в каждом из ваших сценариев?

Аутентификация

Поскольку мы хотим совершать безопасные вызовы к SOAP и REST API, в обоих из них реализован механизм аутентификации. Наши сценарии, использующие вызовы SOAP API, используют тот же сеанс, который мы установили с помощью командлета Connect-VIServer.

Для вызовов REST API к vSphere нам также необходимо пройти аутентификацию. Это делается — как иначе — через специальный вызов REST API. Мы преобразуем наши учетные данные в «базовую» строку Base64:

$user = '[электронная почта защищена]'
$pswd = 'VMware1!'
$vCenterName = 'vcsa.local.lab'
$encoded = [System.Text.Encoding]::UTF8.GetBytes(($user, $pswd -Join ':'))
$encodedPassword = [System.Convert]::ToBase64String($Encoded)
$authHeader = @{
Авторизация = «Базовый $($EncodedPassword)»
}
$sRest = @{
Метод = "Опубликовать"
Uri = «https://$($vCenterName)/rest/com/vmware/cis/session»
Заголовки = $authHeader
}
$result = Invoke-RestMethod @sRest

После того, как мы таким образом создали сеанс, мы можем использовать возвращенный токен сеанса в будущих вызовах REST API. Этот заголовок авторизации может быть создан следующим образом. Обратите внимание на нестандартный способ ('vmware-api-session-id'), выбранный VMware для именования поля заголовка маркера сеанса:

$authHeader = @{
'vmware-api-session-id' = $result.value
}

За этой статьей вскоре появится другая, в которой показано, как выполнить одно и то же действие дважды, один раз через SOAP API и один раз через REST API. Различия между этими двумя должны прояснить, где находится ваша выгода, как потребителя/кодировщика.