Webhook
通过使用 Port 的通用 webhook 集成,您可以将数据从任何提供外发 webhook 的源或服务摄入软件目录,即使 Port 没有为该源提供本地集成。
💡 Webhook 常见用例
例如,我们的通用 webhook 可让您直接从第三方服务中获取实时数据,从而轻松填充软件目录:
- 映射所有Snyk 漏洞、Jira 问题、SonarQube 报告和其他数据源;
- 进行单一属性更新--根据来自 Pager Duty 或 OpsGenie 的事件更新服务的当前待命状态;
- 对软件目录进行基于事件的实时更新;
- 为您使用的第三方服务所提供的所有数据创建单一视图;
- 等等。
工作原理
Port 可为您提供自定义 webhook 端点,您可以将其用作您所引用服务(如GitHub 、Sentry 等)提供的自定义集成的目标。
每个 webhook 端点都能接收custom mapping ,这样就能轻松地将 来自第三方服务的事件有效载荷转化为软件目录中的实体。
自定义映射利用JQ JSON processor 对来自 webhook 有效负载的现有字段和值进行选择、修改、连接、转换和其他操作。
Webhook 配置
webhook 配置就是你指定的方式:
- 自定义 webhook 集成的基本metadata ;
- 控制从有效负载创建实体的mapping configuration ;
- 用于确保到达 Port 的有效负载确实是由您授权的第三方发送的security configuration 。
下面是一个 webhook 配置示例:
[
{
"blueprint": "pullRequest",
"filter": ".headers.\"X-GitHub-Event\" == \"pull_request\"",
"entity": {
"identifier": ".body.pull_request.id | tostring",
"title": ".body.pull_request.title",
"properties": {
"author": ".body.pull_request.user.login",
"url": ".body.pull_request.html_url"
}
}
}
]
配置结构
元数据配置
网络钩子的元数据配置除了控制网络钩子是否处于活动状态外,还包括与网络钩子在 Port 用户界面中的可见性和显示有关的所有属性。
下面是一个元数据配置示例:
- API
- Terraform
{
"identifier": "pullRequestMapper",
"title": "Pull Request Mapper",
"description": "A webhook configuration for pull-request events from GitHub",
"icon": "Github",
"enabled": true,
"mappings": {
...
},
"security": {
...
}
}
resource "port_webhook" "myWebhook" {
identifier = "pullRequestMapper"
title = "Pull Request Mapper"
description = "A webhook configuration for pull-request events from GitHub"
icon = "Github"
enabled = true
mappings = {
...
}
security = {
...
}
}
结构表
Field | Description | Notes |
---|---|---|
identifier | Unique identifier | The identifier is used for API calls, programmatic access and distinguishing between different webhooks |
title | Name | Required. Human-readable name for the webhook |
description | Description | |
icon | Icon for the webhook | See the full icon list |
enabled | Is the webhook active | If the integration id disabled ("enabled": false ) then any incoming event will be dropped |
映射配置
webhook 的映射配置定义了如何将 webhook 事件有效负载映射到一个(或多个)Port实体。
映射配置利用JQ JSON processor ,将事件有效载荷中的信息提取到 Port 实体属性中。
下面是一个映射配置示例:
- API
- Terraform
{
"identifier": "pullRequestMapper",
"title": "Pull Request Mapper",
"enabled": true,
...
"mappings": [
{
"blueprint": "pullRequest",
"filter": ".headers.\"X-GitHub-Event\" == \"pull_request\"",
"entity": {
"identifier": ".body.pull_request.id | tostring",
"title": ".body.pull_request.title",
"properties": {
"author": ".body.pull_request.user.login",
"url": ".body.pull_request.html_url"
}
}
}
],
"security": {
...
}
}
resource "port_webhook" "myWebhook" {
identifier = "pullRequestMapper"
title = "Pull Request Mapper"
enabled = true
...
mappings = [
{
blueprint = "pullRequest"
filter = ".headers.\"X-GitHub-Event\" == \"pull_request\""
entity = {
identifier = ".body.pull_request.id | tostring"
title = ".body.pull_request.title"
properties = {
author = ".body.pull_request.user.login"
url = ".body.pull_request.html_url"
}
}
}
]
security = {
...
}
}
结构
- 映射配置的根键是
mappings
键:
{
...
"mappings": [
{
# mapping
}
]
...
}
映射键存储映射的***数组,这样就可以通过同一有效载荷在多个蓝图中创建/更新多个实体。
现在,让我们来探讨一下单个映射对象的结构:
- 蓝图 "键被用来引用蓝图的标识符,以便根据 webhook 有效负载创建/更新实体:
{
...
"mappings": [
{
"blueprint": "pullRequest",
"filter": ".headers.\"X-GitHub-Event\" == \"pull_request\"",
...
}
]
...
}
- 通过
filter
键,您可以准确过滤哪些发送到 webhook 的有效负载会被处理:
{
...
"mappings": [
{
"blueprint": "pullRequest",
"filter": ".headers.\"X-GitHub-Event\" == \"pull_request\"" # JQ boolean query. If evaluated to false - skip the payload.
...
}
]
...
}
- 通过
itemsToParse
键,可以从一个 webhook 事件中创建多个实体:
{
...
"mappings": [
{
"blueprint": "commits",
"itemsToParse": ".body.pull_request.commits",
// Checks if any of the modified files are in the frontend/src folder.
"filter": ".item.modified | any(test(\"/frontend/src\"))",
"entity": {
"identifier": ".item.id | tostring",
"title": ".item.message",
"properties": {
"author": ".item.author.email",
"url": ".item.url",
"repository": ".body.pusher.email"
}
}
}
]
...
}
- 任何 JQ 表达式都可以在此被用于,只要它的 evaluated 指向一个项目数组。
- 项目 "将作为一个键添加到 JQ 上下文中,该键包含对 "itemsToParse "中指定的数组中的项目的引 用。可以使用
.item.KEY_NAME
语法访问数组中对象的键,更多信息请参阅示例 JSON。
- 实体 "键被用来通过 JQ 将 Webhook 有效负载中的信息映射到 Port 实体属性:
{
...
"mappings": [
{
...
"filter": ".headers.\"X-GitHub-Event\" == \"pull_request\"",
"entity": {
"identifier": ".body.pull_request.id | tostring",
"title": ".body.pull_request.title",
"properties": {
"author": ".body.pull_request.user.login",
"url": ".body.pull_request.html_url"
}
}
}
]
...
}
安全配置
当第三方服务向指定的 webhook URL 发送有效负载时,通常也会包含一个包含有效负载签名的标头,或一些约定的字符串,用于验证发送方。
签名可以通过在有效负载上运行 SHA-X(例如 SHA-1 或 SHA-256)散列函数,结合用户指定的或第三方服务在创建 webhook 时提供的secret值生成。
由于某些第三方服务不提供发送有效载荷签名的服务,而只提供直接发送约定字符串的服务,因此可使用安全选项 "plain"。 使用该选项时,签名将不加任何修改地与secret值进行比较。 它允许用户直接将签名与 Provider 提供的secret值进行比较。 这在需要更简单的安全机制的情况下非常有用。
webhook 的安全配置用于告诉 Port 如何验证与第三方请求一起发送的哈希签名。
下面是一个安全配置示例:
- API
- Terraform
{
"identifier": "pullRequestMapper",
...
"mappings": [
...
],
"security": {
"secret": "WEBHOOK_SECRET",
"signatureHeaderName": "X-Hub-Signature-256",
"signatureAlgorithm": "sha256",
"signaturePrefix": "sha256=",
"requestIdentifierPath": ".headers.\"X-GitHub-Delivery\""
}
}
resource "port_webhook" "myWebhook" {
identifier = "pullRequestMapper"
...
mappings = [
...
]
security = {
secret = "WEBHOOK_SECRET"
signature_header_name = "X-Hub-Signature-256"
signature_algorithm = "sha256"
signature_prefix = "sha256="
request_identifier_path = ".headers.\"X-GitHub-Delivery\""
}
}
如果不想在配置 webhook 时提供安全配置,只需在配置 webhook 时传递一个空对象: "security": {}
。
结构
- 安全配置的根是
security
密钥:
{
...
"security": {
"secret": "WEBHOOK_SECRET",
"signatureHeaderName": "X-Hub-Signature-256",
"signatureAlgorithm": "sha256",
"signaturePrefix": "sha256=",
"requestIdentifierPath": ".headers.\"X-GitHub-Delivery\""
}
...
}
- secret "密钥用于指定用于验证接收到的有效负载的哈希签名的secret值:
- 根据服务的不同,secret值可能由第三方自动生成,也可能由您手动提供给第三方。
...
"security": {
"secret": "WEBHOOK_SECRET",
"signatureHeaderName": "X-Hub-Signature-256",
"signatureAlgorithm": "sha256",
"signaturePrefix": "sha256=",
"requestIdentifierPath": ".headers.\"X-GitHub-Delivery\""
}
...
}
- signatureHeaderName "键被用来引用存储有效负载哈希签名的头的名称:
- 当 webhook 端点接收到新的有效负载时,它会将此标头的值与它将从接收到的有效负载中计算出的散列签名进行比较。
...
"security": {
"secret": "WEBHOOK_SECRET",
"signatureHeaderName": "X-Hub-Signature-256",
"signatureAlgorithm": "sha256",
"signaturePrefix": "sha256=",
"requestIdentifierPath": ".headers.\"X-GitHub-Delivery\""
}
...
}
- 签名算法 "键被用来引用哈希算法,以创建有效载荷的哈希签名:
- **可用 Values: **
sha1
、sha256
、plain
; - 当 webhook 端点接收到新的有效负载时,它将使用指定的算法来计算接收到的有效负载的散列签名。
- **可用 Values: **
...
"security": {
"secret": "WEBHOOK_SECRET",
"signatureHeaderName": "X-Hub-Signature-256",
"signatureAlgorithm": "sha256",
"signaturePrefix": "sha256=",
"requestIdentifierPath": ".headers.\"X-GitHub-Delivery\""
}
...
}
- signaturePrefix "键用于指定一个静态前缀字符串,出现在 "signatureHeaderName "键中的 hashedSignature 之前:
- 例如,在 GitHub webhook 中,包含散列签名的头总是以
sha256=
开头,因此 webhook 应配置为签名前缀"sha256="`;
- 例如,在 GitHub webhook 中,包含散列签名的头总是以
...
"security": {
"secret": "WEBHOOK_SECRET",
"signatureHeaderName": "X-Hub-Signature-256",
"signatureAlgorithm": "sha256",
"signaturePrefix": "sha256=",
"requestIdentifierPath": ".headers.\"X-GitHub-Delivery\""
}
...
}
- requestIdentifierPath "键被用来引用 JQ 模式,该模式会产生 webhook 有效负载的唯一标识符:
- 该键用于防止 Port 对一个事件进行多次处理;
- 例如,在 GitHub webhook 中,
X-GitHub-Delivery
标头包含一个用于标识交付的 GUID。因此,webhook 应配置为"requestIdentifierPath": ".headers.\"X-GitHub-Delivery/""
;
...
"security": {
"secret": "WEBHOOK_SECRET",
"signatureHeaderName": "X-Hub-Signature-256",
"signatureAlgorithm": "sha256",
"signaturePrefix": "sha256=",
"requestIdentifierPath": ".headers.\"X-GitHub-Delivery\""
}
...
}
配置 webhook 端点
- Using API
- Using Port UI
- Create webhook
- Update webhook
- Delete webhook
要创建新的 webhook,请向 https://api.getport.io/v1/webhooks
发送 HTTP POST 请求,并在请求正文中输入您的webhook configuration 。
API 响应将包括 webhook 的完整配置,包括以下重要字段:
webhookKey
- 这是您创建的新通用 webhook 路由被用于的唯一标识符;url
- 这是您需要传递给第三方网络钩子配置的完整 URL。与您创建的 webhook 配置相匹配的事件有效载荷应发送到此 URL;- url "的格式为https://ingest.getport.io/{webhookKey}`;
- **注意: **
https://ingest.getport.io
是不变的,只有webhookKey
会在不同的网络钩子配置之间发生变化。
要更新现有的 webhook,请向 "https://api.getport.io/v1/webhooks/{WEBHOOK_IDENTIFIER}"发出 HTTP PATCH 请求,并在请求正文中包含更新后的webhook configuration 。
在更新 webhook 配置时,支持部分更新,也就是说,你可以只在请求正文中传递需要更新的密钥。 任何你没有指定的密钥都将保持不变。
API 响应将包括 webhook 的更新配置。
要删除现有的 webhook,请向 https://api.getport.io/v1/webhooks/{WEBHOOK_IDENTIFIER}
发送 HTTP DELETE 请求。
- Create webhook
- Update webhook
- Delete webhook
以下是使用 Port UI 创建新 webhook 的详细步骤:
- 登录您的Port account
- 从顶部菜单中选择生成器
- 选择您现有的blueprint
- 点击蓝图展开按钮
- 点击"... "图标,选择最原始数据。
- 向下滚动到 "自定义集成 "部分。
- 选择自定义集成;
- 为您的 webhook 提供标题;
- 选择是使用标识符自动生成选项还是指定您自己的标识符;
- 为您的 webhook 提供描述;
- 从下拉菜单中选择一个图标来代表你的 webhook;
- 点击下一步 8.向下滚动到JQ 映射部分;
- 该部分显示设置蓝图时创建的属性;
- 查看映射,必要时进行修改; 9.最后,点击创建创建新的 webhook。
请注意,本明细表根据 Provider 提供的叙述,记录了使用 Port 用户界面创建 webhook 所涉及的步骤。
以下是使用 Port UI 更新 webhook 的详细步骤:
- 登录您的Port account
- 从顶部菜单中选择生成器
- 选择您现有的blueprint
- 点击蓝图展开按钮
- 点击"... "图标并选择最原始数据
- 向下滚动到自定义集成部分
- 选择要修改的 webhook
- 对 webhook 配置进行必要的更改
- 单击保存保存更改
按照以下步骤,您就能根据 Providers 提供的叙述使用 Port UI 更新 webhook。
以下是使用 Port UI 删除 webhook 的详细步骤:
- 登录您的Port account
- 从顶部菜单中选择生成器
- 选择您现有的blueprint
- 点击蓝图展开按钮
- 点击"... "图标并选择最原始数据
- 向下滚动到自定义集成部分
- 将鼠标悬停在要删除的 webhook 上
- 将出现一个删除图标
- 点击删除图标删除网络钩子
按照以下步骤,您就可以根据 Providers 提供的叙述 ,使用 Port UI 删除 webhook。
使用自定义 webhook
创建并配置好自定义 webhook 后,请转到第三方 Provider(如 GitHub、Sentry、Jira 等),按照以下步骤完成 webhook 设置:
- 进入第三方 Providers 的新 webhook 设置菜单
- 例如在 GitHub: 转到所需的组织/资源库 -> 设置 -> Webhooks -> 添加 webhook。
- 将从 Port 收到的 webhook URL (
https://ingest.getport.io/{webhookKey}
)粘贴到指定 webhook 目标 URL 的字段中;- 例如在 GitHub 中: 将 webhook URL 粘贴到
Payload URL
字段中。
- 例如在 GitHub 中: 将 webhook URL 粘贴到
- 内容类型请选择
application/json
(如适用); - 如果 "secret "值是由第三方生成的,请务必返回update ,并在security configuration 中添加secret值。
示例
有关实用配置及其相应的蓝图定义,请参阅examples 页面。