두 개의 서로 다른 애플리케이션을 연결하기 위해 Webhook을 사용할 수 있습니다. Webhook을 사용하여 이벤트 알림을 설정할 수 있습니다.

Webhook은 HTTP 콜백입니다. 이벤트가 발생하면 Webhook을 구현하는 웹 애플리케이션이 해당 이벤트에 대한 데이터를 브로드캐스트하고 애플리케이션에서 정보를 수신하려는 Webhook URL로 전송합니다. 자세한 내용은 클라우드 개발자 플랫폼을 참조하십시오.

VMware Cloud Director의 컨텍스트에서 Webhook 동작을 사용하여 Webhook을 구성할 수 있습니다. Webhook 동작은 원격 Webhook 서버에 POST 요청을 보냅니다. 요청의 본문에는 동작 호출 및 동작이 호출된 엔티티에 대한 정보가 포함됩니다. 템플릿을 사용하여 본문을 사용자 지정할 수도 있습니다. Webhook 서버 응답은 동작 호출 작업의 결과를 결정합니다. 서버가 반환할 수 있는 응답에는 세 가지 유형이 있습니다.

원격 Webhook 서버는 VMware Cloud Director가 연결할 수 있는 모든 서버일 수 있습니다. 그러나 Webhook 동작을 생성하기 전에 Webhook의 끝점이 안전한지 확인해야 합니다.

  • Webhook 끝점이 HTTPS 끝점인지 확인합니다.
  • 동작을 호출하는 사용자의 조직이 Webhook 서버 인증서를 신뢰하는지 확인합니다. 즉, 인증서가 VMware Cloud Director 신뢰 저장소에 있더라도 동작을 호출하는 사용자의 조직이 인증서를 신뢰하지 않으면 Webhook 동작이 실행되지 않습니다.
  • UI 또는 VMware Cloud Director API를 사용하여 신뢰 저장소에 인증서를 추가할 수 있습니다. VMware Cloud Director를 사용하여 인증서 관리의 내용을 참조하십시오.

Webhook 동작 생성

요청:
"POST https"://host/cloudapi/1.0.0/interfaces/<interface_id>/behaviors{
   "name":"webhookBehavior",
   "execution":{
      "type":"WebHook",
      "id":"testWebHook",
      "href":"https://hooks.slack.com:443/services/T07UZFN0N/B01EW5NC42D/rfjhHCGIwzuzQFrpPZiuLkIX",
      "key":"secretKey",
      "execution_properties":{
         "template":{
            "content":"<template_content_string>"
         },
         "_secure_token":"secureToken",
         "invocation_timeout":7
      }
   }
}
필드 설명
type 필수 필드. WebHook여야 합니다.
id 선택적 문자열 필드.
href VMware Cloud Director에서 요청을 수신해야 하는 URL의 필수 필드.
_internal_key Webhook 끝점에 전송된 요청에 서명하는 데 사용되는 공유 암호의 필수 필드.
invocation_timeout Webhook 서버의 응답에 대한 시간 초과(초)를 지정하는 선택적 필드
template.content Webhook 서버로 전송되는 페이로드의 사용자 지정을 위한 선택적 필드. 템플릿을 문자열로 제공할 수 있습니다. 템플릿에 액세스할 수 있는 execution_properties에 다른 필드를 추가할 수 있습니다.
_secure_ 접두사가 _secure_인 필드는 선택 사항입니다. 필드는 쓰기 전용이며 동작에 대한 GET 요청을 통해 가져올 수 없습니다. 필드 값은 VMware Cloud Director 데이터베이스에 저장되기 전에 암호화됩니다. 필드는 템플릿에 액세스할 수 있습니다.

VMware Cloud Director에서 Webhook 서버로의 페이로드

Webhook 서버로 전송되는 페이로드의 기본 형식이 있습니다. 템플릿을 사용하여 페이로드를 사용자 지정할 수도 있습니다.

기본 페이로드 예:
{
   "entityId":"urn:vcloud:entity:vmware:test_entity_type:b95d96ec-c294-4a64-b5c4-9009abe6ab06",
   "typeId":"urn:vcloud:type:vmware:test_entity_type:1.0.0",
   "arguments":{
      "x":7
   },
   "_metadata":{
      "executionId":"testWebHook",
      "execution":{
         "href":"https://webhook.site/3ca4588f-c9f1-4c0f-911f-734ab598b2dc"
      },
      "invocation":{
         
      },
      "apiVersion":"36.0",
      "behaviorId":"urn:vcloud:behavior-interface:webhookBehavior:vmware:test_interface_3:1.0.0",
      "requestId":"8312df21-712c-4b85-86d4-c9b00669662f",
      "executionType":"WebHook",
      "invocationId":"115c5b99-09e8-44f7-8189-4b9d96e067b1",
      "taskId":"a9e0556b-7699-4ded-b56b-c51fee659008"
   },
   "entity":{
      "cluster":{
         "name":"testCluster0"
      },
      "clusterState":{
         "host":"testHost",
         "status":"valid"
      }
   }
}

템플릿이 있는 사용자 지정 페이로드의 경우 Webhook 서버로 전송되는 페이로드에 대한 템플릿을 지정할 수 있습니다. 템플릿을 지정하지 않으면 VMware Cloud Director가 기본 요청 페이로드를 Webhook 서버로 전송합니다. Apache FreeMarker 템플릿 엔진은 제공된 템플릿 및 데이터 모델에서 페이로드를 렌더링합니다.

데이터 모델은 템플릿에 대해 준비된 모든 데이터, 즉 페이로드에 포함할 수 있는 모든 데이터를 나타냅니다. 데이터 모델에는 Webhook 동작의 호출 인수(예: 인수, 메타데이터, 실행 속성 및 엔티티 정보)가 포함됩니다. 다음 예는 데이터 모델의 트리형 구조를 보여줍니다.
+ - entityId 
|
+ - typeId 
|   
+ - arguments
|  
+ - arguments_string 
|
+ - _execution_properties 
|                      
+ - _metadata
|   |
|   + - executionId
|   + - behaviorId
|   + - executionType
|   + - taskId
|   + - execution 
|   |   |
|   |   + - href
|   + - invocation 
|   + - invocationId
|   + - requestId
|   + - apiVersion
|  
+ - entity 
|
+ - entity_string
표 1. 호출 인수
인수 설명
entityId 호출된 정의된 엔티티의 ID입니다.
typeId 호출된 정의된 엔티티의 엔티티 유형 ID입니다.
arguments 동작 호출에 전달된 인수입니다.
arguments_string JSON 형식의 인수 문자열입니다. 모든 인수를 페이로드에 추가하려는 경우 사용할 수 있습니다.
_execution_properties 키 이름으로 execution_properties 호출 인수의 모든 값을 선택할 수 있습니다.
execution 키 이름으로 execution 호출 인수의 모든 값을 선택할 수 있습니다.
invocation 키 이름으로 invocation 인수의 모든 값을 선택할 수 있습니다.
entity 엔티티 컨텐츠의 맵입니다. 키 이름으로 엔티티의 모든 값을 선택할 수 있습니다.
entity_string JSON 형식의 엔티티 문자열입니다.

페이로드에 대한 템플릿의 Apache FreeMarker 표현식 언어에 대한 자세한 내용은 https://freemarker.apache.org/docs/dgui_quickstart_template.html 항목을 참조하십시오.

샘플 템플릿:
<#assign header_Content\-Type= "application/json" />
{
"text": "Behavior with id ${_metadata.behaviorId} was executed on entity with id ${entityId}"   
}
Webhook 서버로 전송되는 POST 요청에 추가할 사용자 지정 헤더를 지정할 수 있습니다. Webhook 템플릿을 사용하여 접두사가 header_인 템플릿의 변수인 사용자 지정 헤더를 추가할 수 있습니다. 예를 들어 템플릿에 다음 줄을 추가하여 Authorization 헤더의 값을 지정할 수 있습니다.
<#assign header_Authorization = "${_execution_properties._secure_token}" />

Webhook 서버에서 VMware Cloud Director로의 페이로드

  • 기본 응답
    Webhook 서버에서 VMware Cloud Director로의 기본 페이로드에는 다음이 포함되어야 합니다.
    • 응답에 Content-Type 헤더가 없거나 text/plain 값이 있는 Content-Type 헤더가 있을 수 있습니다.
    • 응답 본문은 문자열이어야 합니다.
    • 응답 본문은 동작 호출의 결과로 사용됩니다. 동작 호출 작업의 상태는 success입니다. 작업 결과는 응답의 본문으로 설정됩니다.
  • 단일 작업 업데이트 응답
    동작 결과와는 별도로, 작업 업데이트 응답은 status, details, operation, error, progressresult와 같은 다른 동작 호출 작업 속성을 설정할 수 있습니다. 일회성 작업 업데이트이므로 응답으로 작업이 완료되어야 합니다. 응답이 작업 상태를 success, error 또는 aborted로 설정하지 않으면 오류로 인해 작업이 실패합니다. 오류 메시지는 상태가 허용되지 않음을 나타냅니다.
    • 응답에는 application/vnd.vmware.vcloud.task+json 값이 있는 Content-Type 헤더가 있어야 합니다.
    • 응답 본문에는 수정할 작업 속성이 포함된 TaskType 클래스의 JSON 표현이 포함되어야 합니다.
    • 상태가 success인 샘플 응답 본문:
      {
         "status":"success",
         "details":"example details",
         "operation":"example operation",
         "progress":100,
         "result":{
            "resultContent":"example result"
         }
      }
    • 상태가 error인 샘플 응답 본문:
      {
         "status":"error",
         "details":"example details",
         "operation":"example operation",
         "progress":50,
         "error":{
            "majorErrorCode":404,
            "minorErrorCode":"ERROR",
            "message":"example error message"
         }
      }
  • 지속적인 작업 업데이트 응답
    Webhook 서버는 다중 파트 HTTP 응답을 사용하여 여러 작업 업데이트를 보낼 수 있습니다. 각 업데이트는 응답 본문의 별도 본문 파트입니다. Webhook 서버 응답 본문의 마지막 본문 파트는 작업을 완료해야 합니다. 응답 본문이 작업을 완료하지 못하면 오류로 인해 작업이 실패합니다.
    • 응답에는 multipart/form-data; boundary=... 값이 있는 Content-Type 헤더가 있어야 합니다.
    • 응답 본문은 경계 문자열 --<boundary_string>로 시작하고 끝나야 합니다. 응답 본문의 각 부분은 경계 문자열로 끝나야 합니다. Webhook 서버에서 보내는 HTTP 응답의 Content-Type 헤더에 경계를 지정해야 합니다.
      Headers:
      ...
      Content-Type: multipart/form-data; boundary=<boundary_string>
      
      Body: 
      --<boundary_string>
      Content-Type: application/vnd.vmware.vcloud.task+json
      {                             
      "details": "example details",                      
      "operation": "example operation",
      "progress": 50
      }
      --<boundary_string>
      Content-Type: application/vnd.vmware.vcloud.task+json
      {
      "status": "success",
      "progress": 100,
      "result": {
      "resultContent": "example result"
      }
      }
      --<boundary_string>

    응답 본문의 본문 파트는 작업 업데이트의 형식이거나 최종 업데이트의 형식이어야 합니다.

    작업 업데이트 예:
    Content-Type: application/vnd.vmware.vcloud.task+json
    {
    "details": "example details",
    "operation": "example operation",
    "progress": 50
    }
    최종 업데이트 예:
    Content-Type: text/plain
    <string>

Webhook 동작 요청 인증

HMAC(해시 기반 메시지 인증 코드) 인증은 Webhook 동작 요청을 보호합니다. HMAC는 HTTP 요청의 신뢰성과 무결성을 보장하는 메커니즘입니다. 신뢰성과 무결성을 보장하기 위해 HMAC는 각 HTTP 요청에 대해 두 개의 사용자 지정 헤더를 포함합니다. 사용자 지정 헤더는 서명 헤더와 다이제스트입니다. VMware Cloud Director의 경우 서명 헤더는 x-vcloud-signature이고 다이제스트는 x-vcloud-digest입니다.

서명 헤더 x-vcloud-signature는 각 Webhook 요청과 함께 전송되는 사용자 지정 헤더입니다. 서명 헤더는 HMACSHA512 알고리즘, 헤더 및 VMware Cloud Director 생성 서명으로 구성됩니다. 헤더는 서명을 생성하기 위해 서명된 기본 문자열에 있는 내용을 표시합니다.
표 2. 헤더 필드
필드 설명
host Webhook 서버 호스트
date 요청 날짜
(request-target) 연결된 소문자 HTTP 메서드, ASCII 공백 및 요청 경로 헤더. 예: post /webhook.
digest 요청 본문의 SHA-512 다이제스트

서명 헤더를 생성하려면 공유 암호가 필요합니다. 공유 암호는 VMware Cloud Director 및 Webhook 서버만 알고 있는 문자열입니다.

다이제스트 헤더 x-vcloud-digest는 요청 본문의 Base64로 인코딩된 SHA-512 다이제스트입니다.

VMware Cloud Director의 각 Webhook 요청은 공유 암호를 사용하여 서명을 생성하고 이것을 VMware Cloud Director의 서명 헤더에 있는 서명과 비교하여 확인할 수 있습니다.

Webhook 동작 호출

다른 동작과 마찬가지로 Webhook 동작을 호출할 수 있습니다.
{
"arguments": {
"argument1": "data1",
"argument2": "data2",
...
 }
}