Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pagerduty improved syntax #58

Merged
merged 7 commits into from
Aug 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion integrations/pagerduty/.port/spec.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: v0.1.1
version: v0.1.2
type: pagerduty
description: pagerduty integration for Port Ocean
icon: pagerduty
Expand Down
1 change: 1 addition & 0 deletions integrations/pagerduty/changelog/improvement.1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Bump to ocean 0.1.3 for support in the terraform deployment method
1 change: 1 addition & 0 deletions integrations/pagerduty/changelog/improvement.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Improved the integration syntax
43 changes: 16 additions & 27 deletions integrations/pagerduty/clients/pagerduty.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from typing import Any

import httpx
from loguru import logger

Expand Down Expand Up @@ -66,13 +67,7 @@ async def paginate_request_to_pager_duty(self, data_key: str) -> list[Any]:
)
response.raise_for_status()
data = response.json()

# Fetch and update on-call user information for services
if data_key == "services":
service_data = await self.update_oncall_users(data, data_key)
all_data.extend(service_data)
else:
all_data.extend(data[data_key])
all_data.extend(data[data_key])

has_more_data = data["more"]
if has_more_data:
Expand Down Expand Up @@ -138,49 +133,43 @@ async def create_webhooks_if_not_exists(self) -> None:
f"HTTP error with status code: {e.response.status_code} and response text: {e.response.text}"
)

async def get_oncall_user(self, escalation_policy_id: str) -> dict[str, Any]:
async def get_oncall_user(
self, *escalation_policy_ids: str
) -> list[dict[str, Any]]:
url = f"{self.api_url}/oncalls"

async with httpx.AsyncClient() as client:
try:
response = await client.get(
url,
params={
"escalation_policy_ids[]": escalation_policy_id,
"escalation_policy_ids[]": ",".join(escalation_policy_ids),
"include[]": "users",
},
headers=self.api_auth_header,
)
response.raise_for_status()
data = response.json()
return data
return response.json()["oncalls"]
except httpx.HTTPStatusError as e:
logger.error(
f"HTTP error with status code: {e.response.status_code} and response text: {e.response.text}"
)
raise

async def update_oncall_users(
self, data: dict[str, Any], data_key: str
) -> list[Any]:
self, services: list[dict[str, Any]]
) -> list[dict[str, Any]]:
logger.info("Fetching and matching who is on-call for services")
escalation_policy_ids = [
service["escalation_policy"]["id"] for service in data[data_key]
]

oncall_users = await self.get_oncall_user(",".join(escalation_policy_ids))
all_data = []
oncall_users = await self.get_oncall_user(
*[service["escalation_policy"]["id"] for service in services]
)

for service in data[data_key]:
for service in services:
escalation_policy_id = service["escalation_policy"]["id"]

matching_oncall_user = [
service["__oncall_user"] = [
user
for user in oncall_users["oncalls"]
for user in oncall_users
if user["escalation_policy"]["id"] == escalation_policy_id
]

if matching_oncall_user:
service["oncall_user"] = matching_oncall_user
all_data.append(service)
return all_data
return services
10 changes: 5 additions & 5 deletions integrations/pagerduty/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
# Please copy this file to config.yaml file in the integration folder and edit it to your needs.
initializePortResources: true
port:
clientId: {{ from env PORT_CLIENT_ID }} # Can be loaded via environment variable: PORT_CLIENT_ID
clientSecret: {{ from env PORT_CLIENT_SECRET }} # Can be loaded via environment variable: PORT_CLIENT_SECRET
clientId: "{{ from env PORT_CLIENT_ID }}" # Can be loaded via environment variable: PORT_CLIENT_ID
clientSecret: "{{ from env PORT_CLIENT_SECRET }}" # Can be loaded via environment variable: PORT_CLIENT_SECRET
# The event listener to use for the integration service.
eventListener:
type: POLLING
Expand All @@ -13,6 +13,6 @@ integration:
# The type of the integration.
type: "pagerduty"
config:
token: {{ from env PAGERDUTY_TOKEN }}
appHost: {{ from env APP_HOST }}
apiUrl: {{ from env API_URL }}
token: "{{ from env PAGERDUTY_TOKEN }}"
appHost: "{{ from env APP_HOST }}"
apiUrl: "{{ from env API_URL }}"
26 changes: 12 additions & 14 deletions integrations/pagerduty/main.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from typing import Any

from loguru import logger

from clients.pagerduty import PagerDutyClient
from port_ocean.context.ocean import ocean
from loguru import logger


class ObjectKind:
Expand Down Expand Up @@ -29,38 +31,34 @@ async def on_incidents_resync(kind: str) -> list[dict[str, Any]]:
async def on_services_resync(kind: str) -> list[dict[str, Any]]:
logger.info(f"Listing Pagerduty resource: {kind}")

return await pager_duty_client.paginate_request_to_pager_duty(
services = await pager_duty_client.paginate_request_to_pager_duty(
data_key=ObjectKind.SERVICES
)
return await pager_duty_client.update_oncall_users(services)


@ocean.router.post("/webhook")
async def upsert_incident_webhook_handler(data: dict[str, Any]) -> None:
logger.info(
f"Processing Pagerduty webhook for event type: {data['event']['event_type']}"
)
if data["event"]["event_type"] in pager_duty_client.service_delete_events:
event_type = data["event"]["event_type"]
logger.info(f"Processing Pagerduty webhook for event type: {event_type}")
if event_type in pager_duty_client.service_delete_events:
await ocean.unregister_raw(ObjectKind.SERVICES, [data["event"]["data"]])

elif data["event"]["event_type"] in pager_duty_client.incident_upsert_events:
elif event_type in pager_duty_client.incident_upsert_events:
incident_id = data["event"]["data"]["id"]
response = await pager_duty_client.get_singular_from_pager_duty(
object_type=ObjectKind.INCIDENTS, identifier=incident_id
)
await ocean.register_raw(ObjectKind.INCIDENTS, [response["incident"]])

elif data["event"]["event_type"] in pager_duty_client.service_upsert_events:
elif event_type in pager_duty_client.service_upsert_events:
service_id = data["event"]["data"]["id"]
response = await pager_duty_client.get_singular_from_pager_duty(
object_type=ObjectKind.SERVICES, identifier=service_id
)
service_data = response["service"]
oncall_user = await pager_duty_client.get_oncall_user(
service_data.get("escalation_policy", {}).get("id")
)
service_data["oncall_user"] = oncall_user["oncalls"]
services = await pager_duty_client.update_oncall_users([response["service"]])

await ocean.register_raw(ObjectKind.SERVICES, [service_data])
await ocean.register_raw(ObjectKind.SERVICES, services)


@ocean.on_start()
Expand Down
8 changes: 4 additions & 4 deletions integrations/pagerduty/poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions integrations/pagerduty/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
[tool.poetry]
name = "pagerduty"
version = "0.1.0"
version = "0.1.2"
description = "Pagerduty Integration"
authors = ["Port Team <support@getport.io>"]

[tool.poetry.dependencies]
python = "^3.11"
port_ocean = {version = "0.1.2", extras = ["cli"]}
port_ocean = {version = "0.1.3", extras = ["cli"]}
httpx = "^0.24.1"

[tool.poetry.group.dev.dependencies]
Expand Down