# What this PR does Refactors the PagerDuty migration script to be a bit more generic + adds a migration script to migrate from Splunk OnCall (VictorOps) tldr; ```bash ❯ docker build -t oncall-migrator . [+] Building 0.4s (10/10) FINISHED ❯ docker run --rm \ -e MIGRATING_FROM="pagerduty" \ -e MODE="plan" \ -e ONCALL_API_URL="http://localhost:8080" \ -e ONCALL_API_TOKEN="<ONCALL_API_TOKEN>" \ -e PAGERDUTY_API_TOKEN="<PAGERDUTY_API_TOKEN>" \ oncall-migrator running pagerduty migration script... ❯ docker run --rm \ -e MIGRATING_FROM="splunk" \ -e MODE="plan" \ -e ONCALL_API_URL="http://localhost:8080" \ -e ONCALL_API_TOKEN="<ONCALL_API_TOKEN>" \ -e SPLUNK_API_ID="<SPLUNK_API_ID>" \ -e SPLUNK_API_KEY="<SPLUNK_API_KEY>" \ oncall-migrator migrating from splunk oncall... ``` https://www.loom.com/share/a855062d436a4ef79f030e22528d8c71 ## Checklist - [x] Unit, integration, and e2e (if applicable) tests updated - [x] Documentation added (or `pr:no public docs` PR label added if not required) - [x] Added the relevant release notes label (see labels prefixed w/ `release:`). These labels dictate how your PR will show up in the autogenerated release notes.
48 lines
1.6 KiB
Python
48 lines
1.6 KiB
Python
from contextlib import suppress
|
|
from time import sleep
|
|
from urllib.parse import urljoin
|
|
|
|
import requests
|
|
from requests import HTTPError
|
|
from requests.adapters import HTTPAdapter, Retry
|
|
|
|
|
|
def api_call(method: str, base_url: str, path: str, **kwargs) -> requests.Response:
|
|
url = urljoin(base_url, path)
|
|
|
|
# Retry on network errors
|
|
session = requests.Session()
|
|
retries = Retry(total=5, backoff_factor=0.1)
|
|
session.mount("http://", HTTPAdapter(max_retries=retries))
|
|
session.mount("https://", HTTPAdapter(max_retries=retries))
|
|
|
|
response = session.request(method, url, **kwargs)
|
|
|
|
try:
|
|
response.raise_for_status()
|
|
except HTTPError as e:
|
|
if e.response.status_code == 429:
|
|
cooldown_seconds = int(e.response.headers["Retry-After"])
|
|
sleep(cooldown_seconds)
|
|
return api_call(method, path, **kwargs)
|
|
elif e.response.status_code == 400:
|
|
resp_json = None
|
|
with suppress(requests.exceptions.JSONDecodeError):
|
|
resp_json = response.json()
|
|
|
|
# if no JSON payload is available, just raise the original exception
|
|
if not resp_json:
|
|
raise
|
|
|
|
# this is mostly taken from requests.models.Response.raise_for_status, but with additional JSON payload
|
|
http_error_msg = (
|
|
"%s Client Error: %s for url: %s, response payload JSON: %s"
|
|
% (response.status_code, e.response.reason, response.url, resp_json)
|
|
)
|
|
raise requests.exceptions.HTTPError(
|
|
http_error_msg, response=e.response
|
|
) from e
|
|
else:
|
|
raise
|
|
|
|
return response
|