Skip to main content

PagerDuty

我们的 PagerDuty 集成允许您根据映射和定义,将 PagerDuty 账户中的 "日程"、"服务 "和 "事件 "导入 Port。

常见被用于情况

  • 映射 PagerDuty 组织环境中的 "日程"、"服务 "和 "事件"。
  • 实时观察对象更改(创建/更新/删除),并自动将更改应用到您的 Port 实体中。

先决条件

To install the integration, you need a Kubernetes cluster that the integration's container chart will be deployed to.

Please make sure that you have kubectl and helm installed on your machine, and that your kubectl CLI is connected to the Kubernetes cluster where you plan to install the integration.

安装

从以下安装方法中选择一种:

使用该安装选项意味着集成将能使用 webhook 实时更新 Port。

本表总结了安装时可用的参数,请在下面的脚本中按自己的需要进行设置,然后复制并在终端运行:

ParameterDescriptionRequired
port.clientIdYour port client id
port.clientSecretYour port client secret
port.baseUrlYour port base url, relevant only if not using the default port app
integration.identifierChange the identifier to describe your integration
integration.typeThe integration type
integration.eventListener.typeThe event listener type
integration.secrets.tokenPagerDuty API token
integration.config.apiUrlPagerduty api url. If not specified, the default will be https://api.pagerduty.com
integration.config.appHostThe host of the Port Ocean app. Used to set up the integration endpoint as the target for Webhooks created in PagerDuty
scheduledResyncIntervalThe number of minutes between each resync
initializePortResourcesDefault true, When set to true the integration will create default blueprints and the port App config Mapping

To install the integration using Helm, run the following command:

helm repo add --force-update port-labs https://port-labs.github.io/helm-charts
helm upgrade --install my-pagerduty-integration port-labs/port-ocean \
--set port.clientId="PORT_CLIENT_ID" \
--set port.clientSecret="PORT_CLIENT_SECRET" \
--set port.baseUrl="https://api.getport.io" \
--set initializePortResources=true \
--set scheduledResyncInterval=120 \
--set integration.identifier="my-pagerduty-integration" \
--set integration.type="pagerduty" \
--set integration.eventListener.type="POLLING" \
--set integration.secrets.token="string" \
--set integration.config.apiUrl="string"
高级集成配置

有关代理或自签名证书等高级配置,click here

接收 PagerDuty 对象

PagerDuty 集成使用 YAML 配置来描述将数据加载到开发人员门户的过程。 请参阅下面的examples

该集成利用JQ JSON processor 对来自 PagerDuty API 事件的现有字段和值进行选择、修改、连接、转换和其他操作。

配置结构

集成配置决定从 PagerDuty 查询哪些资源,以及在 Port 中创建哪些实体和属性。

支持的资源 以下资源可被用于来映射来自 PagerDuty 的数据,可以引用下面链接的 API 响应中出现的任何字段来进行映射配置。
  • 集成配置的根密钥是 "资源 "密钥:

    resources:
    - kind: services
    selector:
    ...
  • 类型 "键是 PagerDuty 对象的指定符:

      resources:
    - kind: services
    selector:
    ...
  • 通过 "选择器 "和 "查询 "键,您可以过滤哪些指定 "类型 "的对象将被录入软件目录:

    resources:
    - kind: services
    selector:
    query: "true" # JQ boolean expression. If evaluated to false - this object will be skipped.
    port:
  • Port"、"实体 "和 "映射 "键被用来将 PagerDuty 对象字段映射到Port实体。要创建多个同类映射,可在 resources 数组中添加另一项;

    resources:
    - kind: services
    selector:
    query: "true"
    port:
    entity:
    mappings: # Mappings between one PagerDuty object to a Port entity. Each value is a JQ query.
    identifier: .id
    title: .name
    blueprint: '"pagerdutyService"'
    properties:
    status: .status
    - kind: service # In this instance service is mapped again with a different filter
    selector:
    query: '.name == "MyProjectName"'
    port:
    entity:
    mappings: ...
蓝图键 注意 blueprint 键的值 - 如果要使用硬编码字符串,需要用 2 组引号封装,例如使用一对单引号 ('),然后再用一对双引号 (")

将数据输入Port

要使用integration configuration 引用 PagerDuty 对象,可以按照以下步骤操作:

  1. 转到 DevPortal Builder 页面。
  2. 选择要被 PagerDuty 引用的蓝图。
  3. 从菜单中选择采集数据选项。
  4. 在事件管理类别下选择 PagerDuty。
  5. 根据需要修改configuration
  6. 单击 Resync

示例

蓝图和相关集成配置示例:

时间表

Schedule blueprint
{
"identifier": "pagerdutySchedule",
"description": "This blueprint represents a PagerDuty schedule in our software catalog",
"title": "PagerDuty Schedule",
"icon": "pagerduty",
"schema": {
"properties": {
"url": {
"title": "Schedule URL",
"type": "string",
"format": "url"
},
"timezone": {
"title": "Timezone",
"type": "string"
},
"description": {
"title": "Description",
"type": "string"
},
"users": {
"title": "Users",
"type": "array"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"aggregationProperties": {},
"relations": {}
}
Integration configuration
createMissingRelatedEntities: true
deleteDependentEntities: true
resources:
- kind: schedules
selector:
query: "true"
port:
entity:
mappings:
identifier: .id
title: .name
blueprint: '"pagerdutySchedule"'
properties:
url: .html_url
timezone: .time_zone
description: .description
users: "[.users[].summary]"

服务

Service blueprint
{
"identifier": "pagerdutyService",
"description": "This blueprint represents a PagerDuty service in our software catalog",
"title": "PagerDuty Service",
"icon": "pagerduty",
"schema": {
"properties": {
"status": {
"title": "Status",
"type": "string",
"enum": [
"active",
"warning",
"critical",
"maintenance",
"disabled"
],
"enumColors": {
"active": "green",
"warning": "yellow",
"critical": "red",
"maintenance": "lightGray",
"disabled": "darkGray"
}
},
"url": {
"title": "URL",
"type": "string",
"format": "url"
},
"oncall": {
"title": "On Call",
"type": "array",
"items": {
"type": "string",
"format": "user"
}
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {}
}
Integration configuration
createMissingRelatedEntities: true
deleteDependentEntities: true
resources:
- kind: services
selector:
query: "true"
port:
entity:
mappings:
identifier: .id
title: .name
blueprint: '"pagerdutyService"'
properties:
status: .status
url: .html_url
oncall: "[.__oncall_user[].user.email]"

###事件

Incident blueprint
{
"identifier": "pagerdutyIncident",
"description": "This blueprint represents a PagerDuty incident in our software catalog",
"title": "PagerDuty Incident",
"icon": "pagerduty",
"schema": {
"properties": {
"status": {
"type": "string",
"title": "Incident Status",
"enum": [
"triggered",
"annotated",
"acknowledged",
"reassigned",
"escalated",
"reopened",
"resolved"
]
},
"url": {
"type": "string",
"format": "url",
"title": "Incident URL"
},
"urgency": {
"type": "string",
"title": "Incident Urgency",
"enum": ["high", "low"]
},
"responder": {
"type": "string",
"title": "Assignee"
},
"escalation_policy": {
"type": "string",
"title": "Escalation Policy"
},
"created_at": {
"title": "Create At",
"type": "string",
"format": "date-time"
},
"updated_at": {
"title": "Updated At",
"type": "string",
"format": "date-time"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {
"pagerdutyService": {
"title": "PagerDuty Service",
"target": "pagerdutyService",
"required": false,
"many": true
}
}
}
Integration configuration
resources:
- kind: incidents
selector:
query: "true"
port:
entity:
mappings:
identifier: .id | tostring
title: .title
blueprint: '"pagerdutyIncident"'
properties:
status: .status
url: .self
urgency: .urgency
responder: .assignments[0].assignee.summary
escalation_policy: .escalation_policy.summary
created_at: .created_at
updated_at: .updated_at
relations:
pagerdutyService: .service.id

收录事件分析

要利用分析数据丰富 PagerDuty 事件实体,请按照以下步骤操作:

  1. 更新事件蓝图以包含 "分析 "属性。

    Updated incident blueprint
    {
    "identifier": "pagerdutyIncident",
    "description": "This blueprint represents a PagerDuty incident in our software catalog",
    "title": "PagerDuty Incident",
    "icon": "pagerduty",
    "schema": {
    "properties": {
    "status": {
    "type": "string",
    "title": "Incident Status",
    "enum": [
    "triggered",
    "annotated",
    "acknowledged",
    "reassigned",
    "escalated",
    "reopened",
    "resolved"
    ]
    },
    "url": {
    "type": "string",
    "format": "url",
    "title": "Incident URL"
    },
    "urgency": {
    "type": "string",
    "title": "Incident Urgency",
    "enum": ["high", "low"]
    },
    "responder": {
    "type": "string",
    "title": "Assignee"
    },
    "escalation_policy": {
    "type": "string",
    "title": "Escalation Policy"
    },
    "created_at": {
    "title": "Create At",
    "type": "string",
    "format": "date-time"
    },
    "updated_at": {
    "title": "Updated At",
    "type": "string",
    "format": "date-time"
    },
    "analytics": {
    "title": "Analytics",
    "type": "object"
    }
    },
    "required": []
    },
    "mirrorProperties": {},
    "calculationProperties": {},
    "relations": {
    "pagerdutyService": {
    "title": "PagerDuty Service",
    "target": "pagerdutyService",
    "required": false,
    "many": true
    }
    }
    }
  2. 在集成的 selector 键中添加 incidentAnalytics 属性。设置为 true时,集成将从PagerDuty Analytics API 获取数据并摄取到 Port。默认情况下,此属性设置为 false

    resources:
    - kind: incidents
    selector:
    query: "true"
    incidentAnalytics: "true"
    port:
    entity:
    mappings:
    identifier: .id | tostring
    title: .title
    blueprint: '"pagerdutyIncident"'
    properties:
    status: .status
    url: .self
  3. 在 "分析 "蓝图属性和分析数据响应之间建立映射。

    resources:
    - kind: incidents
    selector:
    query: "true"
    incidentAnalytics: "true"
    port:
    entity:
    mappings:
    identifier: .id | tostring
    title: .title
    blueprint: '"pagerdutyIncident"'
    properties:
    status: .status
    url: .self
    urgency: .urgency
    responder: .assignments[0].assignee.summary
    escalation_policy: .escalation_policy.summary
    created_at: .created_at
    updated_at: .updated_at
    analytics: .__analytics
    relations:
    pagerdutyService: .service.id
  4. Below is the complete integration configuration for enriching the incident blueprint with analytics data.

Incident analytics integration configuration
resources:
- kind: incidents
selector:
query: "true"
incidentAnalytics: "true"
port:
entity:
mappings:
identifier: .id | tostring
title: .title
blueprint: '"pagerdutyIncident"'
properties:
status: .status
url: .self
urgency: .urgency
responder: .assignments[0].assignee.summary
escalation_policy: .escalation_policy.summary
created_at: .created_at
updated_at: .updated_at
analytics: .__analytics
relations:
pagerdutyService: .service.id

让我们来测试一下

本节包括来自 Providerduty 的响应数据示例,此外还包括根据上一节提供的 Ocean 配置从重新同步事件中创建的实体。

有效载荷

下面是 Pagerduty 的有效载荷结构示例:

Schedule response data
{
"id": "PWAXLIH",
"type": "schedule",
"summary": "Port Test Service - Weekly Rotation",
"self": "https://api.pagerduty.com/schedules/PWAXLIH",
"html_url": "https://getport-io.pagerduty.com/schedules/PWAXLIH",
"name": "Port Test Service - Weekly Rotation",
"time_zone": "Asia/Jerusalem",
"description": "This is the weekly on call schedule for Port Test Service associated with your first escalation policy.",
"users": [
{
"id": "PJCRRLH",
"type": "user_reference",
"summary": "Adam",
"self": "https://api.pagerduty.com/users/PJCRRLH",
"html_url": "https://getport-io.pagerduty.com/users/PJCRRLH"
},
{
"id": "P4K4DLP",
"type": "user_reference",
"summary": "Alice",
"self": "https://api.pagerduty.com/users/P4K4DLP",
"html_url": "https://getport-io.pagerduty.com/users/P4K4DLP"
},
{
"id": "PFZ63E2",
"type": "user_reference",
"summary": "Doe",
"self": "https://api.pagerduty.com/users/PFZ63E2",
"html_url": "https://getport-io.pagerduty.com/users/PFZ63E2"
},
{
"id": "PRGAUI4",
"type": "user_reference",
"summary": "Pages",
"self": null,
"html_url": "https://getport-io.pagerduty.com/users/PRGAUI4",
"deleted_at": "2023-10-17T18:58:07+03:00"
},
{
"id": "PYIEKLY",
"type": "user_reference",
"summary": "Demo",
"self": "https://api.pagerduty.com/users/PYIEKLY",
"html_url": "https://getport-io.pagerduty.com/users/PYIEKLY"
}
],
"escalation_policies": [
{
"id": "P7LVMYP",
"type": "escalation_policy_reference",
"summary": "Test Escalation Policy",
"self": "https://api.pagerduty.com/escalation_policies/P7LVMYP",
"html_url": "https://getport-io.pagerduty.com/escalation_policies/P7LVMYP"
}
],
"teams": []
}
Service response data
{
"id": "PGAAJBE",
"name": "My Test Service",
"description": "For testing",
"created_at": "2023-08-03T16:53:48+03:00",
"updated_at": "2023-08-03T16:53:48+03:00",
"status": "active",
"teams": [],
"alert_creation": "create_alerts_and_incidents",
"addons": [],
"scheduled_actions": [],
"support_hours": "None",
"last_incident_timestamp": "None",
"escalation_policy": {
"id": "P7LVMYP",
"type": "escalation_policy_reference",
"summary": "Test Escalation Policy",
"self": "https://api.pagerduty.com/escalation_policies/P7LVMYP",
"html_url": "https://getport-io.pagerduty.com/escalation_policies/P7LVMYP"
},
"incident_urgency_rule": {
"type": "constant",
"urgency": "high"
},
"acknowledgement_timeout": "None",
"auto_resolve_timeout": "None",
"integrations": [],
"type": "service",
"summary": "My Test Service",
"self": "https://api.pagerduty.com/services/PGAAJBE",
"html_url": "https://getport-io.pagerduty.com/service-directory/PGAAJBE",
"__oncall_user": [
{
"escalation_policy": {
"id": "P7LVMYP",
"type": "escalation_policy_reference",
"summary": "Test Escalation Policy",
"self": "https://api.pagerduty.com/escalation_policies/P7LVMYP",
"html_url": "https://getport-io.pagerduty.com/escalation_policies/P7LVMYP"
},
"escalation_level": 1,
"schedule": {
"id": "PWAXLIH",
"type": "schedule_reference",
"summary": "Port Test Service - Weekly Rotation",
"self": "https://api.pagerduty.com/schedules/PWAXLIH",
"html_url": "https://getport-io.pagerduty.com/schedules/PWAXLIH"
},
"user": {
"name": "demo",
"email": "[email protected]",
"time_zone": "Asia/Jerusalem",
"color": "teal",
"avatar_url": "https://secure.gravatar.com/avatar/5cc831a4e778f54460efc4cd20d13acd.png?d=mm&r=PG",
"billed": true,
"role": "admin",
"description": "None",
"invitation_sent": true,
"job_title": "None",
"teams": [],
"contact_methods": [
{
"id": "POKPUFD",
"type": "email_contact_method_reference",
"summary": "Default",
"self": "https://api.pagerduty.com/users/PYIEKLY/contact_methods/POKPUFD",
"html_url": "None"
}
],
"notification_rules": [
{
"id": "P9NWEKF",
"type": "assignment_notification_rule_reference",
"summary": "0 minutes: channel POKPUFD",
"self": "https://api.pagerduty.com/users/PYIEKLY/notification_rules/P9NWEKF",
"html_url": "None"
},
{
"id": "PPJHFA5",
"type": "assignment_notification_rule_reference",
"summary": "0 minutes: channel POKPUFD",
"self": "https://api.pagerduty.com/users/PYIEKLY/notification_rules/PPJHFA5",
"html_url": "None"
}
],
"id": "PYIEKLY",
"type": "user",
"summary": "demo",
"self": "https://api.pagerduty.com/users/PYIEKLY",
"html_url": "https://getport-io.pagerduty.com/users/PYIEKLY"
},
"start": "2023-10-17T15:57:50Z",
"end": "2024-02-13T22:16:48Z"
}
]
}
Incident response data
{
"incident_number": 2,
"title": "Example Incident",
"description": "Example Incident",
"created_at": "2023-05-15T13:59:45Z",
"updated_at": "2023-05-15T13:59:45Z",
"status": "triggered",
"incident_key": "89809d37f4344d36a90c0a192c20c617",
"service": {
"id": "PWJAGSD",
"type": "service_reference",
"summary": "Port Test Service",
"self": "https://api.pagerduty.com/services/PWJAGSD",
"html_url": "https://getport-io.pagerduty.com/service-directory/PWJAGSD"
},
"assignments": [
{
"at": "2023-05-15T13:59:45Z",
"assignee": {
"id": "PJCRRLH",
"type": "user_reference",
"summary": "Username",
"self": "https://api.pagerduty.com/users/PJCRRLH",
"html_url": "https://getport-io.pagerduty.com/users/PJCRRLH"
}
}
],
"assigned_via": "escalation_policy",
"last_status_change_at": "2023-05-15T13:59:45Z",
"resolved_at": null,
"first_trigger_log_entry": {
"id": "R5S5T07QR1SZRQFYB7SXEO2EKZ",
"type": "trigger_log_entry_reference",
"summary": "Triggered through the website.",
"self": "https://api.pagerduty.com/log_entries/R5S5T07QR1SZRQFYB7SXEO2EKZ",
"html_url": "https://getport-io.pagerduty.com/incidents/Q1P3AHC3KLGVAS/log_entries/R5S5T07QR1SZRQFYB7SXEO2EKZ"
},
"alert_counts": {
"all": 0,
"triggered": 0,
"resolved": 0
},
"is_mergeable": true,
"escalation_policy": {
"id": "P7LVMYP",
"type": "escalation_policy_reference",
"summary": "Test Escalation Policy",
"self": "https://api.pagerduty.com/escalation_policies/P7LVMYP",
"html_url": "https://getport-io.pagerduty.com/escalation_policies/P7LVMYP"
},
"teams": [],
"pending_actions": [],
"acknowledgements": [],
"basic_alert_grouping": null,
"alert_grouping": null,
"last_status_change_by": {
"id": "PWJAGSD",
"type": "service_reference",
"summary": "Port Test Service",
"self": "https://api.pagerduty.com/services/PWJAGSD",
"html_url": "https://getport-io.pagerduty.com/service-directory/PWJAGSD"
},
"urgency": "high",
"id": "Q1P3AHC3KLGVAS",
"type": "incident",
"summary": "[#2] Example Incident",
"self": "https://api.pagerduty.com/incidents/Q1P3AHC3KLGVAS",
"html_url": "https://getport-io.pagerduty.com/incidents/Q1P3AHC3KLGVAS"
}

映射结果

结合样本有效载荷和 Ocean 配置,可生成以下 Port 实体:

Schedule entity in Port
{
"identifier": "PWAXLIH",
"title": "Port Test Service - Weekly Rotation",
"icon": null,
"blueprint": "pagerdutySchedule",
"team": [],
"properties": {
"url": "https://getport-io.pagerduty.com/schedules/PWAXLIH",
"timezone": "Asia/Jerusalem",
"description": "Asia/Jerusalem",
"users": ["Adam", "Alice", "Doe", "Demo", "Pages"]
},
"relations": {},
"createdAt": "2023-12-01T13:18:02.215Z",
"createdBy": "hBx3VFZjqgLPEoQLp7POx5XaoB0cgsxW",
"updatedAt": "2023-12-01T13:18:02.215Z",
"updatedBy": "hBx3VFZjqgLPEoQLp7POx5XaoB0cgsxW"
}
Service entity in Port
{
"identifier": "PGAAJBE",
"title": "My Test Service",
"icon": null,
"blueprint": "pagerdutyService",
"team": [],
"properties": {
"status": "active",
"url": "https://getport-io.pagerduty.com/service-directory/PGAAJBE",
"oncall": "[email protected]"
},
"relations": {},
"createdAt": "2023-11-01T13:18:02.215Z",
"createdBy": "hBx3VFZjqgLPEoQLp7POx5XaoB0cgsxW",
"updatedAt": "2023-11-01T13:18:02.215Z",
"updatedBy": "hBx3VFZjqgLPEoQLp7POx5XaoB0cgsxW"
}
Incident entity in Port
{
"identifier": "Q1P3AHC3KLGVAS",
"title": "Example Incident",
"icon": null,
"blueprint": "pagerdutyIncident",
"team": [],
"properties": {
"status": "triggered",
"url": "https://api.pagerduty.com/incidents/Q1P3AHC3KLGVAS",
"urgency": "high",
"responder": "Username",
"escalation_policy": "Test Escalation Policy",
"created_at": "2023-07-30T11:29:21.000Z",
"updated_at": "2023-07-30T11:29:21.000Z"
},
"relations": {
"pagerdutyService": "PWJAGSD"
},
"createdAt": "2023-08-07T07:56:04.384Z",
"createdBy": "hBx3VFZjqgLPEoQLp7POx5XaoB0cgsxW",
"updatedAt": "2023-08-07T07:56:04.384Z",
"updatedBy": "hBx3VFZjqgLPEoQLp7POx5XaoB0cgsxW"
}

通过 webhook 进行替代安装

虽然上述 Ocean 集成是推荐的安装方法,但您可能更喜欢使用 webhook 从 PagerDuty 引用数据。 如果是这样,请使用以下说明:

Webhook installation (click to expand)

在本示例中,您将在PagerDuty 和 Port 之间创建 webhook 集成,将 PagerDuty 服务及其相关事件导入 Port。该集成将涉及设置 webhook,以便在创建或更新事件时接收来自 PagerDuty 的通知,使 Port 能够相应地导入和处理事件实体。

Import PagerDuty services and incidents

Port configuration

创建以下蓝图定义:

PagerDuty service blueprint
{
"identifier": "microservice",
"title": "Microservice",
"icon": "Service",
"schema": {
"properties": {
"status": {
"title": "Status",
"type": "string"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {
"service": {
"title": "Service URL",
"calculation": "'https://api.pagerduty.com/services/' + .identifier",
"type": "string",
"format": "url"
}
},
"relations": {}
}
PagerDuty incident blueprint
{
"identifier": "pagerdutyIncident",
"description": "This blueprint represents a PagerDuty incident in our software catalog",
"title": "PagerDuty Incident",
"icon": "pagerduty",
"schema": {
"properties": {
"status": {
"type": "string",
"title": "Incident Status",
"enum": [
"triggered",
"annotated",
"acknowledged",
"reassigned",
"escalated",
"reopened",
"resolved"
]
},
"url": {
"type": "string",
"format": "url",
"title": "Incident URL"
},
"details": {
"type": "string",
"title": "Details"
},
"priority": {
"type": "string",
"title": "Priority"
},
"urgency": {
"type": "string",
"title": "Incident Urgency",
"enum": ["high", "low"]
},
"responder": {
"type": "string",
"title": "Assignee"
},
"escalation_policy": {
"type": "string",
"title": "Escalation Policy"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {
"microservice": {
"title": "Belongs To",
"target": "microservice",
"required": false,
"many": true
}
}
}

创建以下 webhook 配置using Port UI

PagerDuty webhook configuration
  1. 基本信息 选项卡 - 填写以下详细信息: 1.title: PagerDuty Mapper; 2.标识符 : pagerduty_mapper; 3.Description : 将 PagerDuty 服务及其相关事件映射到 Port 的 webhook 配置; 4.图标 : Pagerduty
  2. 集成配置选项卡 - 填写以下 JQ 映射:
    [
    {
    "blueprint": "microservice",
    "filter": ".body.event.event_type | startswith(\"service\")",
    "entity": {
    "identifier": ".body.event.data.id",
    "title": ".body.event.data.summary",
    "properties": {
    "status": ".body.event.data.event_type"
    }
    }
    },
    {
    "blueprint": "pagerdutyIncident",
    "filter": ".body.event.event_type | startswith(\"incident\")",
    "entity": {
    "identifier": ".body.event.data.id",
    "title": ".body.event.data.title",
    "properties": {
    "status": ".body.event.data.status",
    "url": ".body.event.data.html_url",
    "details": ".body.event.data.title",
    "priority": ".body.event.data.priority",
    "urgency": ".body.event.data.urgency",
    "responder": ".body.event.data.assignees[0].summary",
    "escalation_policy": ".body.event.data.escalation_policy.summary"
    },
    "relations": {
    "microservice": ".body.event.data.service.id"
    }
    }
    }
    ]

3.向下滚动到高级设置,输入以下详细信息:

  1. secret: WEBHOOK_SECRET; 2.签名头名称: X-Pagerduty-Signature; 3.签名算法: 从下拉选项中选择 sha256; 4.签名前缀 : v1=. 5.点击页面底部的保存。 切记用在 PagerDuty 中订阅 webhook 后收到的真实secret更新 WEBHOOK_SECRET

Create a webhook in PagerDuty

  1. 转到PagerDuty ,选择要配置 webhook 的账户。
  2. 导航至导航栏中的集成,然后点击通用 Webhook (v3)
  3. 点击 ** 新建 Webhook**,并提供以下信息:
    1. Webhook URL- 输入[creating the webhook configuration](/build-your-software-catalog/sync-data-to-catalog/webhook/?operation=ui#configuring-webhook-endpoints) 后收到的url` 键的值。
    2. 范围类型"- 选择是接收特定服务的 webhook 事件(如果适用,请选择 "服务"),还是接收账户中所有服务的 webhook 事件(如果适用,请选择 "账户")。
    3. Description - 为您的 webhook 提供可选描述。
    4. 事件订阅"- 选择要订阅的事件类型。 5.自定义标头"- 输入要添加到 webhook 有效负载的任何可选 HTTP 标头。 4.单击 ** 添加 webhook** 创建您的 webhook。 5.或者,你也可以使用 curl 方法来创建 webhook。复制下面的代码并在终端运行:
curl --request POST \
--url \
https://api.pagerduty.com/webhook_subscriptions
--header 'Accept: application/vnd.pagerduty+json;version=2' \
--header 'Authorization: Token token=<YOUR_PAGERDUTY_API_TOKEN>' \
--header 'Content-Type: application/json' \
--data \
'{
"webhook_subscription": {
"delivery_method": {
"type": "http_delivery_method",
"url": "https://ingest.getport.io/<YOUR_PORT_WEBHOOK_KEY>",
"custom_headers": [
{
"name": "your-header-name",
"value": "your-header-value"
}
]
},
"description": "Sends PagerDuty v3 webhook events to Port.",
"events": [
"service.created",
"service.updated",
"incident.triggered",
"incident.responder.added",
"incident.acknowledged",
"incident.annotated",
"incident.delegated",
"incident.escalated",
"incident.priority_updated",
"incident.reassigned",
"incident.reopened",
"incident.resolved",
"incident.responder.replied",
"incident.status_update_published",
"incident.unacknowledged"
],
"filter": {
"type": "account_reference"
},
"type": "webhook_subscription"
}
}'
为了查看 PagerDuty webhooks 中可用的不同事件、look here

完成!您在 PagerDuty 中的服务或事件发生的任何变化都将触发指向 Port 提供的 webhook URL 的 webhook 事件。 Port 将根据映射解析事件并相应地更新目录实体。

Let's Test It

本节包括当创建或更新事件时从 PagerDuty 发送的 webhook 事件示例。 此外,本节还包括根据上一节提供的 webhook 配置从事件中创建的实体。

Payload

下面是创建 PagerDuty 事件时发送到 webhook URL 的有效载荷结构示例:

Webhook event payload
{
"event": {
"id": "01DVUHO6P4XQDFJ9AHOADT3UQ4",
"event_type": "incident.triggered",
"resource_type": "incident",
"occurred_at": "2023-06-12T11:56:08.355Z",
"agent": {
"html_url": "https://your_account.pagerduty.com/users/PJCRRLH",
"id": "PJCRRLH",
"self": "https://api.pagerduty.com/users/PJCRRLH",
"summary": "username",
"type": "user_reference"
},
"client": "None",
"data": {
"id": "Q01J2OS7YBWLNY",
"type": "incident",
"self": "https://api.pagerduty.com/incidents/Q01J2OS7YBWLNY",
"html_url": "https://your_account.pagerduty.com/incidents/Q01J2OS7YBWLNY",
"number": 7,
"status": "triggered",
"incident_key": "acda20953f7446248f90260db65144f8",
"created_at": "2023-06-12T11:56:08Z",
"title": "Test PagerDuty Incident",
"service": {
"html_url": "https://your_account.pagerduty.com/services/PWJAGSD",
"id": "PWJAGSD",
"self": "https://api.pagerduty.com/services/PWJAGSD",
"summary": "Port Internal Service",
"type": "service_reference"
},
"assignees": [
{
"html_url": "https://your_account.pagerduty.com/users/PRGAUI4",
"id": "PRGAUI4",
"self": "https://api.pagerduty.com/users/PRGAUI4",
"summary": "username",
"type": "user_reference"
}
],
"escalation_policy": {
"html_url": "https://your_account.pagerduty.com/escalation_policies/P7LVMYP",
"id": "P7LVMYP",
"self": "https://api.pagerduty.com/escalation_policies/P7LVMYP",
"summary": "Test Escalation Policy",
"type": "escalation_policy_reference"
},
"teams": [],
"priority": "None",
"urgency": "high",
"conference_bridge": "None",
"resolve_reason": "None"
}
}
}

Mapping Result

结合示例有效载荷和 webhook 配置可生成以下 Port 实体:

{
"identifier": "Q01J2OS7YBWLNY",
"title": "Test PagerDuty Incident",
"blueprint": "pagerdutyIncident",
"team": [],
"properties": {
"status": "triggered",
"url": "https://your_account.pagerduty.com/incidents/Q01J2OS7YBWLNY",
"details": "Test PagerDuty Incident",
"urgency": "high",
"responder": "Username",
"escalation_policy": "Test Escalation Policy"
},
"relations": {
"microservice": "PWJAGSD"
}
}

Import PagerDuty historical data

在本例中,您将使用 Provider 提供的 Bash 脚本从 PagerDuty API 获取数据并将其引用到 Port。

脚本从 PagerDuty 中提取服务和事件,并分别作为微服务和事件实体发送到 Port。

Port configuration

本示例使用了上一节中相同的blueprint 定义以及新的 webhook 配置:

创建以下 webhook 配置using Port UI

PagerDuty webhook configuration for historical data
  1. 基本信息 选项卡 - 填写以下详细信息: 1.title: PagerDuty History Mapper; 2.标识符 : pagerduty_history_mapper; 3.Description : 将 PagerDuty 历史服务及其相关事件映射到 Port 的 webhook 配置; 4.图标 : Pagerduty
  2. 集成配置选项卡 - 填写以下 JQ 映射:
    [
    {
    "blueprint": "microservice",
    "filter": ".body.event.event_type | startswith(\"service\")",
    "entity": {
    "identifier": ".body.event.data.identifier",
    "title": ".body.event.data.title",
    "properties": {
    "status": ".body.event.data.properties.status"
    }
    }
    },
    {
    "blueprint": "pagerdutyIncident",
    "filter": ".body.event.event_type | startswith(\"incident\")",
    "entity": {
    "identifier": ".body.event.data.identifier",
    "title": ".body.event.data.title",
    "properties": {
    "status": ".body.event.data.properties.status",
    "url": ".body.event.data.properties.url",
    "details": ".body.event.data.properties.details",
    "priority": ".body.event.data.properties.priority",
    "urgency": ".body.event.data.properties.urgency",
    "responder": ".body.event.data.properties.responder",
    "escalation_policy": ".body.event.data.properties.escalation_policy"
    },
    "relations": {
    "microservice": ".body.event.data.relations.microservice"
    }
    }
    }
    ]

3.向下滚动到高级设置,输入以下详细信息:

  1. secret: WEBHOOK_SECRET; 2.签名头名称: X-Pagerduty-Signature; 3.签名算法: 从下拉选项中选择 sha256; 4.签名前缀 : v1=. 5.点击页面底部的保存

切记用在 PagerDuty 中订阅 webhook 后收到的真实secret更新WEBHOOK_SECRET

PagerDuty Bash script for historical data
#!/bin/bash

set -e
# PagerDuty API endpoints and token
PD_API_SERVICES='https://api.pagerduty.com/services'
PD_API_INCIDENTS='https://api.pagerduty.com/incidents'
PD_TOKEN='API_TOKEN'

# Port webhook URL
PORT_URL='https://ingest.getport.io/WEBHOOK_SECRET'

# Fetch services from PagerDuty
services=$(curl --silent --header "Authorization: Token token=${PD_TOKEN}" --header "Accept: application/vnd.pagerduty+json;version=2" --request GET ${PD_API_SERVICES})

# Extract services array
services_list=$(echo ${services} | jq '.services')

# Iterate over services and push to Port
for i in $(seq 0 $(($(echo ${services_list} | jq '. | length') - 1)))
do
service=$(echo ${services_list} | jq ".[$i]")

# Prepare payload for Port
payload=$(jq -n \
--arg id "$(echo ${service} | jq -r '.id')" \
--arg name "$(echo ${service} | jq -r '.name')" \
--arg status "$(echo ${service} | jq -r '.status')" \
'{event: {event_type: "service", data: {identifier: $id, title: $name, properties: {status: $status}}}}')

# Push to Port
curl --silent --header 'Content-Type: application/json' --request POST --data "${payload}" ${PORT_URL}

# Output payload to output.json file
echo ${payload} >> output.json
done

# Fetch incidents from PagerDuty
incidents=$(curl --silent --header "Authorization: Token token=${PD_TOKEN}" --header "Accept: application/vnd.pagerduty+json;version=2" --request GET ${PD_API_INCIDENTS})

# Extract incidents array
incidents_list=$(echo ${incidents} | jq '.incidents')

# Iterate over incidents and push to Port
for i in $(seq 0 $(($(echo ${incidents_list} | jq '. | length') - 1)))
do
incident=$(echo ${incidents_list} | jq ".[$i]")

# Prepare payload for Port
payload=$(jq -n \
--arg id "$(echo ${incident} | jq -r '.id')" \
--arg title "$(echo ${incident} | jq -r '.title')" \
--arg status "$(echo ${incident} | jq -r '.status')" \
--arg url "$(echo ${incident} | jq -r '.html_url')" \
--arg description "$(echo ${incident} | jq -r '.description')" \
--arg urgency "$(echo ${incident} | jq -r '.urgency')" \
--arg responder "$(echo ${incident} | jq -r '.last_status_change_by.summary')" \
--arg escalation_policy "$(echo ${incident} | jq -r '.escalation_policy.summary')" \
--arg service "$(echo ${incident} | jq -r '.service.id')" \
'{event: {event_type: "incident", data: {identifier: $id, title: $title, properties: {status: $status, url: $url, details: $description, urgency: $urgency, responder: $responder, escalation_policy: $escalation_policy}, relations: {microservice: $service}}}}')

# Push to Port
curl --header 'Content-Type: application/json' --request POST --data "${payload}" ${PORT_URL}

# Output payload to output.json file
echo ${payload} >> output.json
done


How to Run the script

该脚本需要两个配置值:

  1. PD_TOKEN": 您的 PagerDuty API 标记;
  2. PORT_URL: 您的 Port webhook URL。

然后运行脚本触发:

bash pagerduty_to_port.sh

该脚本从 PagerDuty 获取服务和事件,并将其发送到 Port。

脚本会将每个服务和事件的 JSON 有效载荷写入名为 output.json 的文件。 如果遇到任何问题,这将有助于调试。

完成!现在您可以将历史数据从 PagerDuty 导入 Port。 Port 将根据映射解析事件并相应更新目录实体。