diff --git a/plugins/pagerduty/.CHECKSUM b/plugins/pagerduty/.CHECKSUM index a121be7b80..756b77829f 100644 --- a/plugins/pagerduty/.CHECKSUM +++ b/plugins/pagerduty/.CHECKSUM @@ -1,43 +1,43 @@ { - "spec": "f20c11c35f0dbd45c4ae3207b10029b4", - "manifest": "322935ff822e9be3217f4e2227e9a00f", - "setup": "4a6275a7299d3b5523ecadf7ab8a163a", + "spec": "6527a68d9fd5097bbb7075b8b279d9b8", + "manifest": "825be40acb77734dcd402f0da001f41b", + "setup": "a4f3b2fabe8b53ce95d26b7439c5d3a8", "schemas": [ { "identifier": "create_user/schema.py", - "hash": "d20d7c28c305fdcebb96939510679ae7" + "hash": "c68031209d4fa67ccb59d29e2d9129a0" }, { "identifier": "delete_user_by_id/schema.py", - "hash": "55d6f98c36228cc8b294303f54eae49c" + "hash": "796c3831d82077d659ebc859897d3410" }, { "identifier": "get_on_call/schema.py", - "hash": "4eb592192c18a8e0a79bd263a2509e29" + "hash": "136d6977b7cf82f1d59f6affa2f3112c" }, { "identifier": "get_user_by_email/schema.py", - "hash": "79d23d5f0c61caa02bb2728c940e4503" + "hash": "ca70ed41b688a0648c824a649c5072ff" }, { "identifier": "get_user_by_id/schema.py", - "hash": "43da47a5a74bc83c3652b398f29db719" + "hash": "78552441f46e278e02110bb7742d67ac" }, { "identifier": "send_acknowledge_event/schema.py", - "hash": "24b59e94be441385f0ce8770647cfa60" + "hash": "29ad62b147f212b81ae75380983190b8" }, { "identifier": "send_resolve_event/schema.py", - "hash": "74ea18af0ba61eb8dc40923971eb7d85" + "hash": "139114bf8815c249bac54e8ed9b61ad2" }, { "identifier": "send_trigger_event/schema.py", - "hash": "2a003fe3014831f80493498c143d302f" + "hash": "60c41049677bc3b99a28a2b941239d17" }, { "identifier": "connection/schema.py", - "hash": "80f4aea21f43406ebe4afe09f912b280" + "hash": "222cae0befdc90d883e5d25ea004a33d" } ] } \ No newline at end of file diff --git a/plugins/pagerduty/Dockerfile b/plugins/pagerduty/Dockerfile index 498006599b..8c55e42f91 100644 --- a/plugins/pagerduty/Dockerfile +++ b/plugins/pagerduty/Dockerfile @@ -1,26 +1,20 @@ -FROM rapid7/insightconnect-python-3-38-slim-plugin:4 -# The three supported python parent images are: -# - komand/python-2-plugin -# - komand/python-3-plugin -# - komand/python-pypy3-plugin -# -# Update the tag to a full semver version +FROM rapid7/insightconnect-python-3-38-plugin:5 -# Add any custom package dependencies here -# NOTE: Add pip packages to requirements.txt +LABEL organization=rapid7 +LABEL sdk=python -# End package dependencies - -# Add source code WORKDIR /python/src + ADD ./plugin.spec.yaml /plugin.spec.yaml -ADD . /python/src +ADD ./requirements.txt /python/src/requirements.txt -# Install pip dependencies RUN if [ -f requirements.txt ]; then pip install -r requirements.txt; fi -# Install plugin -RUN python setup.py build && python setup.py install +ADD . /python/src + +RUN python setup.py build && python setup.py install +# User to run plugin code. The two supported users are: root, nobody +USER nobody ENTRYPOINT ["/usr/local/bin/komand_pagerduty"] diff --git a/plugins/pagerduty/bin/komand_pagerduty b/plugins/pagerduty/bin/komand_pagerduty index e84ce9d372..8c00e0e167 100755 --- a/plugins/pagerduty/bin/komand_pagerduty +++ b/plugins/pagerduty/bin/komand_pagerduty @@ -1,12 +1,12 @@ #!/usr/bin/env python -# GENERATED BY KOMAND SDK - DO NOT EDIT +# GENERATED BY INSIGHT-PLUGIN - DO NOT EDIT import os import json from sys import argv Name = "PagerDuty" Vendor = "rapid7" -Version = "2.2.0" +Version = "3.0.0" Description = "Leverage PagerDuty for incident management and response" @@ -23,7 +23,7 @@ def main(): monkey.patch_all() import insightconnect_plugin_runtime - from komand_pagerduty import connection, actions, triggers + from komand_pagerduty import connection, actions, triggers, tasks class ICONPagerduty(insightconnect_plugin_runtime.Plugin): def __init__(self): @@ -34,22 +34,22 @@ def main(): description=Description, connection=connection.Connection() ) - self.add_action(actions.CreateUser()) - - self.add_action(actions.DeleteUserById()) - self.add_action(actions.GetOnCall()) - - self.add_action(actions.GetUserByEmail()) - + self.add_action(actions.GetUserById()) - + + self.add_action(actions.GetUserByEmail()) + + self.add_action(actions.CreateUser()) + + self.add_action(actions.DeleteUserById()) + + self.add_action(actions.SendTriggerEvent()) + self.add_action(actions.SendAcknowledgeEvent()) - + self.add_action(actions.SendResolveEvent()) - - self.add_action(actions.SendTriggerEvent()) - + """Run plugin""" cli = insightconnect_plugin_runtime.CLI(ICONPagerduty()) diff --git a/plugins/pagerduty/help.md b/plugins/pagerduty/help.md index af7985adfe..48ec9bcc13 100644 --- a/plugins/pagerduty/help.md +++ b/plugins/pagerduty/help.md @@ -6,30 +6,33 @@ and incidents within workflows. The PagerDuty plugin makes requests to the V2 API. # Key Features - + * Create and manage PagerDuty incidents * Access PagerDuty user information # Requirements - + * PagerDuty API key +# Supported Product Versions + +* 2023-10-12 + # Documentation ## Setup - -The connection configuration accepts the following parameters: + +The connection configuration accepts the following parameters: |Name|Type|Default|Required|Description|Enum|Example| -|----|----|-------|--------|-----------|----|-------| -|api_key|credential_secret_key|None|True|API Key|None|None| - +| :--- | :--- | :--- | :--- | :--- | :--- | :--- | +|api_key|credential_secret_key|None|True|API Key|None|stRbCzL92kpAfwCkSiA9| + Example input: ``` { - "api_key": { - "secretKey": "stRbCzL92kpAfwCkSiA9" + "api_key": "stRbCzL92kpAfwCkSiA9" } ``` @@ -37,316 +40,953 @@ Example input: ### Actions -#### Get On-Call Users -This action is used to get a list of users on call. +#### Create User + +This action is used to create a User ##### Input |Name|Type|Default|Required|Description|Enum|Example| -|----|----|-------|--------|-----------|----|-------| -|schedule_id|string|None|False|Schedule ID|None|P9E0DZT| - +| :--- | :--- | :--- | :--- | :--- | :--- | :--- | +|color|string|None|False|The schedule color|None|green| +|email|string|None|True|The email address for the new account to be created|None|user1@example.com| +|from_email|string|None|True|The email address of user that is creating the account|None|user2@example.com| +|job_title|string|None|False|The description of the new user|None|job title| +|license|object|None|False|The license of the new user|None|{'id': 'PTDVERC', 'type': 'license_reference'}| +|name|string|None|True|Name|None|test user| +|role|string|None|False|Role|['admin', 'limited_user', 'owner', 'read_only_user', 'user']|user| +|time_zone|string|None|False|Time Zone, e.g. America/Lima|None|Europe/London| +|user_description|string|None|False|The description of the new user|None|test description of the new use| + Example input: ``` { - "schedule_id": "P9E0DZT" + "color": "green", + "email": "user1@example.com", + "from_email": "user2@example.com", + "job_title": "job title", + "license": { + "id": "PTDVERC", + "type": "license_reference" + }, + "name": "test user", + "role": "user", + "time_zone": "Europe/London", + "user_description": "test description of the new use" } ``` ##### Output -|Name|Type|Required|Description| -|----|----|--------|-----------| -|users|[]user|True|List of on-call users| - +|Name|Type|Required|Description|Example| +| :--- | :--- | :--- | :--- | :--- | +|user|user|False|User|{'avatar_url': 'https://secure.gravatar.com/avatar/abcABC123456abcABC123456abcABC123456.png?d=mm&r=PG', 'billed': True, 'color': 'purple', 'contact_methods': [{'html_url': None, 'id': 'ABC1234', 'self': 'https://api.pagerduty.com/users/ABCD123/contact_methods/ABC1234', 'summary': 'Default', 'type': 'email_contact_method_reference'}], 'coordinated_incidents': [], 'description': '', 'email': 'user1@example.com', 'html_url': 'https://api.pagerduty.com/users/ABCD123', 'id': 'ABCD123', 'invitation_sent': False, 'job_title': '', 'name': 'test user', 'notification_rules': [{'html_url': None, 'id': 'ABC1234', 'self': 'https://api.pagerduty.com/users/ABCD123/notification_rules/ABC1234', 'summary': '0 minutes: channel ABC1234', 'type': 'assignment_notification_rule_reference'}, {'html_url': None, 'id': 'ABC1234', 'self': 'https://api.pagerduty.com/users/ABCD123/notification_rules/ABC1234', 'summary': '0 minutes: channel ABC1234', 'type': 'assignment_notification_rule_reference'}], 'role': 'owner', 'self': 'https://api.pagerduty.com/users/ABCD123', 'summary': 'test summary', 'teams': [{'html_url': 'https://api.pagerduty.com/teams/ABC1234', 'id': 'ABC1234', 'self': 'https://api.pagerduty.com/teams/ABC1234', 'summary': 'Engineering', 'type': 'team_reference'}], 'time_zone': 'Europe/London', 'type': 'user'}| + Example output: ``` { - "users": [ - { - "name": "user", - "email": "user@example.com", - "time_zone": "America/New_York", - "color": "purple", - "avatar_url": "https://secure.gravatar.com/avatar/8aa943422112d40809d90abcb1dbd9c8.png?d=mm&r=PG", - "billed": true, - "role": "owner", - "description": null, - "invitation_sent": false, - "job_title": null, - "teams": [], - "contact_methods": [ - { - "id": "PLXR19K", - "type": "email_contact_method_reference", - "summary": "Default", - "self": "https://api.pagerduty.com/users/PBYG9ZF/contact_methods/PLXR19K", - "html_url": null - } - ], - "notification_rules": [ - { - "id": "PTAI1D0", - "type": "assignment_notification_rule_reference", - "summary": "0 minutes: channel PLXR19K", - "self": "https://api.pagerduty.com/users/PBYG9ZF/notification_rules/PTAI1D0", - "html_url": null - }, - { - "id": "PXN62SQ", - "type": "assignment_notification_rule_reference", - "summary": "0 minutes: channel PLXR19K", - "self": "https://api.pagerduty.com/users/PBYG9ZF/notification_rules/PXN62SQ", - "html_url": null - } - ], - "coordinated_incidents": [], - "id": "PBYG9ZF", - "type": "user", - "summary": "user1", - "self": "https://api.pagerduty.com/users/PBYG9ZF", - "html_url": "https://rapid7-1.pagerduty.com/users/PBYG9ZF" - }, - { - "name": "user2", - "email": "user@example.com", - "time_zone": "America/New_York", - "color": "red", - "avatar_url": "https://secure.gravatar.com/avatar/0232003bb841231433a0779771360902.png?d=mm&r=PG", - "billed": true, - "role": "user", - "description": null, - "invitation_sent": false, - "job_title": null, - "teams": [], - "contact_methods": [ - { - "id": "PX35LTU", - "type": "email_contact_method_reference", - "summary": "Default", - "self": "https://api.pagerduty.com/users/PUQ7882/contact_methods/PX35LTU", - "html_url": null - } - ], - "notification_rules": [ - { - "id": "PPQ1HLY", - "type": "assignment_notification_rule_reference", - "summary": "0 minutes: channel PX35LTU", - "self": "https://api.pagerduty.com/users/PUQ7882/notification_rules/PPQ1HLY", - "html_url": null - }, - { - "id": "PSMPIAL", - "type": "assignment_notification_rule_reference", - "summary": "0 minutes: channel PX35LTU", - "self": "https://api.pagerduty.com/users/PUQ7882/notification_rules/PSMPIAL", - "html_url": null - } - ], - "coordinated_incidents": [], - "id": "PUQ7882", - "type": "user", - "summary": "Joey", - "self": "https://api.pagerduty.com/users/PUQ7882", - "html_url": "https://rapid7-1.pagerduty.com/users/PUQ7882" - } + "user": { + "avatar_url": "https://secure.gravatar.com/avatar/abcABC123456abcABC123456abcABC123456.png?d=mm&r=PG", + "billed": true, + "color": "purple", + "contact_methods": [ + { + "html_url": null, + "id": "ABC1234", + "self": "https://api.pagerduty.com/users/ABCD123/contact_methods/ABC1234", + "summary": "Default", + "type": "email_contact_method_reference" + } ], - "limit": 25, - "offset": 0, - "total": null, - "more": false + "coordinated_incidents": [], + "description": "", + "email": "user1@example.com", + "html_url": "https://api.pagerduty.com/users/ABCD123", + "id": "ABCD123", + "invitation_sent": false, + "job_title": "", + "name": "test user", + "notification_rules": [ + { + "html_url": null, + "id": "ABC1234", + "self": "https://api.pagerduty.com/users/ABCD123/notification_rules/ABC1234", + "summary": "0 minutes: channel ABC1234", + "type": "assignment_notification_rule_reference" + }, + { + "html_url": null, + "id": "ABC1234", + "self": "https://api.pagerduty.com/users/ABCD123/notification_rules/ABC1234", + "summary": "0 minutes: channel ABC1234", + "type": "assignment_notification_rule_reference" + } + ], + "role": "owner", + "self": "https://api.pagerduty.com/users/ABCD123", + "summary": "test summary", + "teams": [ + { + "html_url": "https://api.pagerduty.com/teams/ABC1234", + "id": "ABC1234", + "self": "https://api.pagerduty.com/teams/ABC1234", + "summary": "Engineering", + "type": "team_reference" + } + ], + "time_zone": "Europe/London", + "type": "user" + } } ``` -#### Send Acknowledge Event - -This action is used to acknowledge an incident. +#### Delete User by ID + +This action is used to delete a User by ID ##### Input |Name|Type|Default|Required|Description|Enum|Example| -|----|----|-------|--------|-----------|----|-------| -|description|string|None|False|Text that will appear in the incident's log associated with this event|None|None| -|details|object|None|False|An arbitrary JSON object containing any data you'd like included in the incident log|None|None| -|incident_key|string|None|True|Incident Key|None|None| -|service_key|string|None|True|Service Key (aka Integration Key)|None|None| - +| :--- | :--- | :--- | :--- | :--- | :--- | :--- | +|email|string|None|True|The email address of a valid user associated with the account making the delete request|None|user1@example.com| +|id|string|None|True|User ID|None|ABCD123| + Example input: ``` +{ + "email": "user1@example.com", + "id": "ABCD123" +} ``` ##### Output -|Name|Type|Required|Description| -|----|----|--------|-----------| -|incident_key|string|False|Incident Key| -|message|string|False|Message| -|status|string|False|Status| +|Name|Type|Required|Description|Example| +| :--- | :--- | :--- | :--- | :--- | +|success|string|False|A message to show if the user was deleted as expected|The user ABCD123 has been deleted| + +Example output: -#### Create User +``` +{ + "success": "The user ABCD123 has been deleted" +} +``` -This action is used to create a user. +#### Get On-Call Users + +This action is used to get list of on-call users ##### Input |Name|Type|Default|Required|Description|Enum|Example| -|----|----|-------|--------|-----------|----|-------| -|email|string|None|True|Email|None|None| -|from_email|string|None|True|Email of creating user|None|None| -|name|string|None|True|Name|None|None| -|role|string|None|False|Role|['admin', 'limited_user', 'owner', 'read_only_user', 'user']|None| - +| :--- | :--- | :--- | :--- | :--- | :--- | :--- | +|schedule_id|string|None|True|Schedule ID|None|ABC1234| + Example input: ``` +{ + "schedule_id": "ABC1234" +} ``` ##### Output -|Name|Type|Required|Description| -|----|----|--------|-----------| -|success|boolean|False|True if created| -|user|user|False|User| +|Name|Type|Required|Description|Example| +| :--- | :--- | :--- | :--- | :--- | +|users|[]user|True|List of on-call users|[{"avatar_url": "https://secure.gravatar.com/avatar/abcABC123456abcABC123456abcABC123456.png?d=mm&r=PG", "billed": True, "color": "purple", "contact_methods": [{"html_url": None, "id": "ABC1234", "self": "https://api.pagerduty.com/users/ABCD123/contact_methods/ABC1234", "summary": "Default", "type": "email_contact_method_reference"}], "coordinated_incidents": [], "description": "", "email": "user1@example.com", "html_url": "https://api.pagerduty.com/users/ABCD123", "id": "ABCD123", "invitation_sent": False, "job_title": "", "name": "Test account", "notification_rules": [{"html_url": None, "id": "ABC1234", "self": "https://api.pagerduty.com/users/ABCD123/notification_rules/ABC1234", "summary": "0 minutes: channel ABC1234", "type": "assignment_notification_rule_reference"}, {"html_url": None, "id": "ABC1234", "self": "https://api.pagerduty.com/users/ABCD123/notification_rules/ABC1234", "summary": "0 minutes: channel ABC1234", "type": "assignment_notification_rule_reference"}], "role": "owner", "self": "https://api.pagerduty.com/users/ABCD123", "summary": "test summary", "teams": [{"html_url": "https://api.pagerduty.com/teams/ABC1234", "id": "ABC1234", "self": "https://api.pagerduty.com/teams/ABC1234", "summary": "Engineering", "type": "team_reference"}], "time_zone": "Europe/London", "type": "user"}]| + +Example output: -#### Get User by Email +``` +{ + "users": { + "avatar_url": "https://secure.gravatar.com/avatar/abcABC123456abcABC123456abcABC123456.png?d=mm&r=PG", + "billed": true, + "color": "purple", + "contact_methods": [ + { + "html_url": null, + "id": "ABC1234", + "self": "https://api.pagerduty.com/users/ABCD123/contact_methods/ABC1234", + "summary": "Default", + "type": "email_contact_method_reference" + } + ], + "coordinated_incidents": [], + "description": "", + "email": "user1@example.com", + "html_url": "https://api.pagerduty.com/users/ABCD123", + "id": "ABCD123", + "invitation_sent": false, + "job_title": "", + "name": "Test account", + "notification_rules": [ + { + "html_url": null, + "id": "ABC1234", + "self": "https://api.pagerduty.com/users/ABCD123/notification_rules/ABC1234", + "summary": "0 minutes: channel ABC1234", + "type": "assignment_notification_rule_reference" + }, + { + "html_url": null, + "id": "ABC1234", + "self": "https://api.pagerduty.com/users/ABCD123/notification_rules/ABC1234", + "summary": "0 minutes: channel ABC1234", + "type": "assignment_notification_rule_reference" + } + ], + "role": "owner", + "self": "https://api.pagerduty.com/users/ABCD123", + "summary": "test summary", + "teams": [ + { + "html_url": "https://api.pagerduty.com/teams/ABC1234", + "id": "ABC1234", + "self": "https://api.pagerduty.com/teams/ABC1234", + "summary": "Engineering", + "type": "team_reference" + } + ], + "time_zone": "Europe/London", + "type": "user" + } +} +``` -This action is used to get information about a user by email address. +#### Get User by Their Email Address + +This action is used to get a User from using their email address ##### Input |Name|Type|Default|Required|Description|Enum|Example| -|----|----|-------|--------|-----------|----|-------| -|email|string|None|True|Email|None|None| - +| :--- | :--- | :--- | :--- | :--- | :--- | :--- | +|user_email|string|None|True|User email address|None|user@example.com| + Example input: ``` +{ + "user_email": "user@example.com" +} ``` ##### Output -|Name|Type|Required|Description| -|----|----|--------|-----------| -|found|boolean|False|True if found| -|user|user|False|User| +|Name|Type|Required|Description|Example| +| :--- | :--- | :--- | :--- | :--- | +|user|user|False|User|{'avatar_url': 'https://secure.gravatar.com/avatar/abcABC123456abcABC123456abcABC123456.png?d=mm&r=PG', 'billed': True, 'color': 'purple', 'contact_methods': [{'html_url': None, 'id': 'ABC1234', 'self': 'https://api.pagerduty.com/users/ABCD123/contact_methods/ABC1234', 'summary': 'Default', 'type': 'email_contact_method_reference'}], 'coordinated_incidents': [], 'description': '', 'email': 'user1@example.com', 'html_url': 'https://api.pagerduty.com/users/ABCD123', 'id': 'ABCD123', 'invitation_sent': False, 'job_title': '', 'name': 'Test account', 'notification_rules': [{'html_url': None, 'id': 'ABC1234', 'self': 'https://api.pagerduty.com/users/ABCD123/notification_rules/ABC1234', 'summary': '0 minutes: channel ABC1234', 'type': 'assignment_notification_rule_reference'}, {'html_url': None, 'id': 'ABC1234', 'self': 'https://api.pagerduty.com/users/ABCD123/notification_rules/ABC1234', 'summary': '0 minutes: channel ABC1234', 'type': 'assignment_notification_rule_reference'}], 'role': 'owner', 'self': 'https://api.pagerduty.com/users/ABCD123', 'summary': 'test summary', 'teams': [{'html_url': 'https://api.pagerduty.com/teams/ABC1234', 'id': 'ABC1234', 'self': 'https://api.pagerduty.com/teams/ABC1234', 'summary': 'Engineering', 'type': 'team_reference'}], 'time_zone': 'Europe/London', 'type': 'user'}| + +Example output: -#### Send Trigger Event +``` +{ + "user": { + "avatar_url": "https://secure.gravatar.com/avatar/abcABC123456abcABC123456abcABC123456.png?d=mm&r=PG", + "billed": true, + "color": "purple", + "contact_methods": [ + { + "html_url": null, + "id": "ABC1234", + "self": "https://api.pagerduty.com/users/ABCD123/contact_methods/ABC1234", + "summary": "Default", + "type": "email_contact_method_reference" + } + ], + "coordinated_incidents": [], + "description": "", + "email": "user1@example.com", + "html_url": "https://api.pagerduty.com/users/ABCD123", + "id": "ABCD123", + "invitation_sent": false, + "job_title": "", + "name": "Test account", + "notification_rules": [ + { + "html_url": null, + "id": "ABC1234", + "self": "https://api.pagerduty.com/users/ABCD123/notification_rules/ABC1234", + "summary": "0 minutes: channel ABC1234", + "type": "assignment_notification_rule_reference" + }, + { + "html_url": null, + "id": "ABC1234", + "self": "https://api.pagerduty.com/users/ABCD123/notification_rules/ABC1234", + "summary": "0 minutes: channel ABC1234", + "type": "assignment_notification_rule_reference" + } + ], + "role": "owner", + "self": "https://api.pagerduty.com/users/ABCD123", + "summary": "test summary", + "teams": [ + { + "html_url": "https://api.pagerduty.com/teams/ABC1234", + "id": "ABC1234", + "self": "https://api.pagerduty.com/teams/ABC1234", + "summary": "Engineering", + "type": "team_reference" + } + ], + "time_zone": "Europe/London", + "type": "user" + } +} +``` -This action is used to trigger an incident. +#### Get User by ID + +This action is used to get a User by ID ##### Input |Name|Type|Default|Required|Description|Enum|Example| -|----|----|-------|--------|-----------|----|-------| -|client|string|None|False|The name of the monitoring client that is triggering this event|None|None| -|client_url|string|None|False|The URL of the monitoring client that is triggering this event|None|None| -|contexts|[]object|None|False|Additional context objects|None|None| -|description|string|None|True|Text that will appear in the incident's log associated with this event|None|None| -|details|object|None|False|An arbitrary JSON object containing any data you'd like included in the incident log|None|None| -|service_key|string|None|True|Service Key (aka Integration Key)|None|None| - +| :--- | :--- | :--- | :--- | :--- | :--- | :--- | +|id|string|None|True|User ID|None|ABC1234| + Example input: ``` +{ + "id": "ABC1234" +} ``` ##### Output -|Name|Type|Required|Description| -|----|----|--------|-----------| -|incident_key|string|False|Incident Key| -|message|string|False|Message| -|status|string|False|Status| +|Name|Type|Required|Description|Example| +| :--- | :--- | :--- | :--- | :--- | +|user|user|False|User|{'avatar_url': 'https://secure.gravatar.com/avatar/abcABC123456abcABC123456abcABC123456.png?d=mm&r=PG', 'billed': True, 'color': 'purple', 'contact_methods': [{'html_url': None, 'id': 'ABC1234', 'self': 'https://api.pagerduty.com/users/ABCD123/contact_methods/ABC1234', 'summary': 'Default', 'type': 'email_contact_method_reference'}], 'coordinated_incidents': [], 'description': '', 'email': 'user1@example.com', 'html_url': 'https://api.pagerduty.com/users/ABCD123', 'id': 'ABCD123', 'invitation_sent': False, 'job_title': '', 'name': 'Test account', 'notification_rules': [{'html_url': None, 'id': 'ABC1234', 'self': 'https://api.pagerduty.com/users/ABCD123/notification_rules/ABC1234', 'summary': '0 minutes: channel ABC1234', 'type': 'assignment_notification_rule_reference'}, {'html_url': None, 'id': 'ABC1234', 'self': 'https://api.pagerduty.com/users/ABCD123/notification_rules/ABC1234', 'summary': '0 minutes: channel ABC1234', 'type': 'assignment_notification_rule_reference'}], 'role': 'owner', 'self': 'https://api.pagerduty.com/users/ABCD123', 'summary': 'test summary', 'teams': [{'html_url': 'https://api.pagerduty.com/teams/ABC1234', 'id': 'ABC1234', 'self': 'https://api.pagerduty.com/teams/ABC1234', 'summary': 'Engineering', 'type': 'team_reference'}], 'time_zone': 'Europe/London', 'type': 'user'}| + +Example output: -#### Delete User by ID +``` +{ + "user": { + "avatar_url": "https://secure.gravatar.com/avatar/abcABC123456abcABC123456abcABC123456.png?d=mm&r=PG", + "billed": true, + "color": "purple", + "contact_methods": [ + { + "html_url": null, + "id": "ABC1234", + "self": "https://api.pagerduty.com/users/ABCD123/contact_methods/ABC1234", + "summary": "Default", + "type": "email_contact_method_reference" + } + ], + "coordinated_incidents": [], + "description": "", + "email": "user1@example.com", + "html_url": "https://api.pagerduty.com/users/ABCD123", + "id": "ABCD123", + "invitation_sent": false, + "job_title": "", + "name": "Test account", + "notification_rules": [ + { + "html_url": null, + "id": "ABC1234", + "self": "https://api.pagerduty.com/users/ABCD123/notification_rules/ABC1234", + "summary": "0 minutes: channel ABC1234", + "type": "assignment_notification_rule_reference" + }, + { + "html_url": null, + "id": "ABC1234", + "self": "https://api.pagerduty.com/users/ABCD123/notification_rules/ABC1234", + "summary": "0 minutes: channel ABC1234", + "type": "assignment_notification_rule_reference" + } + ], + "role": "owner", + "self": "https://api.pagerduty.com/users/ABCD123", + "summary": "test summary", + "teams": [ + { + "html_url": "https://api.pagerduty.com/teams/ABC1234", + "id": "ABC1234", + "self": "https://api.pagerduty.com/teams/ABC1234", + "summary": "Engineering", + "type": "team_reference" + } + ], + "time_zone": "Europe/London", + "type": "user" + } +} +``` -This action is used to delete a user by id. +#### Send Acknowledge Event + +This action is used to acknowledge an incident ##### Input |Name|Type|Default|Required|Description|Enum|Example| -|----|----|-------|--------|-----------|----|-------| -|id|string|None|True|User ID|None|None| - +| :--- | :--- | :--- | :--- | :--- | :--- | :--- | +|email|string|None|True|The email address of a valid user associated with the account making the request|None|user1@example.com| +|incident_id|string|None|True|The ID of the incident|None|Q1GXLD8EXPKU32| + Example input: ``` +{ + "email": "user1@example.com", + "incident_id": "Q1GXLD8EXPKU32" +} ``` ##### Output -|Name|Type|Required|Description| -|----|----|--------|-----------| -|success|boolean|False|True if deleted| -|user|user|False|User| +|Name|Type|Required|Description|Example| +| :--- | :--- | :--- | :--- | :--- | +|incident|incident_output|False|The incident object that was acknowledged|{'incident': {'acknowledgements': [{'acknowledger': {'html_url': 'https://subdomain.pagerduty.com/users/ABC1234', 'id': 'ABC1234', 'self': 'https://api.pagerduty.com/users/ABC1234', 'summary': 'Test User', 'type': 'user_reference'}, 'at': '2015-11-10T00:32:52Z'}], 'alert_counts': {'all': 0, 'resolved': 0, 'triggered': 0}, 'assigned_via': 'escalation_policy', 'assignments': [{'assignee': {'html_url': 'https://subdomain.pagerduty.com/users/ABC1234', 'id': 'ABC1234', 'self': 'https://api.pagerduty.com/users/ABC1234', 'summary': 'Test User', 'type': 'user_reference'}, 'at': '2015-11-10T00:31:52Z'}], 'conference_bridge': {'conference_number': '555-123-4567', 'conference_url': 'https://example.com/123-456-789'}, 'created_at': '2015-10-06T21:30:42Z', 'escalation_policy': {'html_url': 'https://subdomain.pagerduty.com/escalation_policies/ABC1234', 'id': 'ABC1234', 'self': 'https://api.pagerduty.com/escalation_policies/ABC1234', 'summary': 'Another Escalation Policy', 'type': 'escalation_policy_reference'}, 'first_trigger_log_entry': {'html_url': 'https://subdomain.pagerduty.com/incidents/ABC1234/log_entries/ABCDEFGH123456', 'id': 'ABCDEFGH123456', 'self': 'https://api.pagerduty.com/log_entries/ABCDEFGH123456?incident_id=ABC1234', 'summary': 'Triggered through the API', 'type': 'trigger_log_entry_reference'}, 'html_url': 'https://subdomain.pagerduty.com/incidents/ABC1234', 'id': 'ABC1234', 'incident_key': 'abcABC123456abcABC123456abcABC123456', 'incident_number': 1234, 'is_mergeable': True, 'last_status_change_at': '2015-10-06T21:38:23Z', 'last_status_change_by': {'html_url': 'https://subdomain.pagerduty.com/users/ABC1234', 'id': 'ABC1234', 'self': 'https://api.pagerduty.com/users/ABC1234', 'summary': 'Test User', 'type': 'user_reference'}, 'pending_actions': [{'at': '2015-11-10T01:02:52Z', 'type': 'unacknowledge'}, {'at': '2015-11-10T04:31:52Z', 'type': 'resolve'}], 'priority': {'id': 'ABC1234', 'self': 'https://api.pagerduty.com/priorities/ABC1234', 'summary': 'P2', 'type': 'priority_reference'}, 'self': 'https://api.pagerduty.com/incidents/ABC1234', 'service': {'html_url': 'https://subdomain.pagerduty.com/service-directory/ABC1234', 'id': 'ABC1234', 'self': 'https://api.pagerduty.com/services/ABC1234', 'summary': 'My Mail Service', 'type': 'service_reference'}, 'status': 'resolved', 'summary': '[#1234] The server is on fire.', 'teams': [{'html_url': 'https://subdomain.pagerduty.com/teams/ABC1234', 'id': 'ABC1234', 'self': 'https://api.pagerduty.com/teams/ABC1234', 'summary': 'Engineering', 'type': 'team_reference'}], 'title': 'The server is on fire.', 'type': 'incident', 'updated_at': '2015-10-08T21:30:42Z', 'urgency': 'high'}}| + +Example output: -#### Send Resolve Event +``` +{ + "incident": { + "incident": { + "acknowledgements": [ + { + "acknowledger": { + "html_url": "https://subdomain.pagerduty.com/users/ABC1234", + "id": "ABC1234", + "self": "https://api.pagerduty.com/users/ABC1234", + "summary": "Test User", + "type": "user_reference" + }, + "at": "2015-11-10T00:32:52Z" + } + ], + "alert_counts": { + "all": 0, + "resolved": 0, + "triggered": 0 + }, + "assigned_via": "escalation_policy", + "assignments": [ + { + "assignee": { + "html_url": "https://subdomain.pagerduty.com/users/ABC1234", + "id": "ABC1234", + "self": "https://api.pagerduty.com/users/ABC1234", + "summary": "Test User", + "type": "user_reference" + }, + "at": "2015-11-10T00:31:52Z" + } + ], + "conference_bridge": { + "conference_number": "555-123-4567", + "conference_url": "https://example.com/123-456-789" + }, + "created_at": "2015-10-06T21:30:42Z", + "escalation_policy": { + "html_url": "https://subdomain.pagerduty.com/escalation_policies/ABC1234", + "id": "ABC1234", + "self": "https://api.pagerduty.com/escalation_policies/ABC1234", + "summary": "Another Escalation Policy", + "type": "escalation_policy_reference" + }, + "first_trigger_log_entry": { + "html_url": "https://subdomain.pagerduty.com/incidents/ABC1234/log_entries/ABCDEFGH123456", + "id": "ABCDEFGH123456", + "self": "https://api.pagerduty.com/log_entries/ABCDEFGH123456?incident_id=ABC1234", + "summary": "Triggered through the API", + "type": "trigger_log_entry_reference" + }, + "html_url": "https://subdomain.pagerduty.com/incidents/ABC1234", + "id": "ABC1234", + "incident_key": "abcABC123456abcABC123456abcABC123456", + "incident_number": 1234, + "is_mergeable": true, + "last_status_change_at": "2015-10-06T21:38:23Z", + "last_status_change_by": { + "html_url": "https://subdomain.pagerduty.com/users/ABC1234", + "id": "ABC1234", + "self": "https://api.pagerduty.com/users/ABC1234", + "summary": "Test User", + "type": "user_reference" + }, + "pending_actions": [ + { + "at": "2015-11-10T01:02:52Z", + "type": "unacknowledge" + }, + { + "at": "2015-11-10T04:31:52Z", + "type": "resolve" + } + ], + "priority": { + "id": "ABC1234", + "self": "https://api.pagerduty.com/priorities/ABC1234", + "summary": "P2", + "type": "priority_reference" + }, + "self": "https://api.pagerduty.com/incidents/ABC1234", + "service": { + "html_url": "https://subdomain.pagerduty.com/service-directory/ABC1234", + "id": "ABC1234", + "self": "https://api.pagerduty.com/services/ABC1234", + "summary": "My Mail Service", + "type": "service_reference" + }, + "status": "resolved", + "summary": "[#1234] The server is on fire.", + "teams": [ + { + "html_url": "https://subdomain.pagerduty.com/teams/ABC1234", + "id": "ABC1234", + "self": "https://api.pagerduty.com/teams/ABC1234", + "summary": "Engineering", + "type": "team_reference" + } + ], + "title": "The server is on fire.", + "type": "incident", + "updated_at": "2015-10-08T21:30:42Z", + "urgency": "high" + } + } +} +``` -This action is used to resolve an incident. +#### Send Resolve Event + +This action is used to resolve an incident ##### Input |Name|Type|Default|Required|Description|Enum|Example| -|----|----|-------|--------|-----------|----|-------| -|description|string|None|False|Text that will appear in the incident's log associated with this event|None|None| -|details|object|None|False|An arbitrary JSON object containing any data you'd like included in the incident log|None|None| -|incident_key|string|None|True|Incident Key|None|None| -|service_key|string|None|True|Service Key (aka Integration Key)|None|None| - +| :--- | :--- | :--- | :--- | :--- | :--- | :--- | +|email|string|None|True|The email address of a valid user associated with the account making the request|None|user1@example.com| +|incident_id|string|None|True|The ID of the incident|None|Q1GXLD8EXPKU32| + Example input: ``` +{ + "email": "user1@example.com", + "incident_id": "Q1GXLD8EXPKU32" +} ``` ##### Output -|Name|Type|Required|Description| -|----|----|--------|-----------| -|incident_key|string|False|Incident Key| -|message|string|False|Message| -|status|string|False|Status| +|Name|Type|Required|Description|Example| +| :--- | :--- | :--- | :--- | :--- | +|incident|incident_output|False|The incident object that was resolved|{'incident': {'acknowledgements': [{'acknowledger': {'html_url': 'https://subdomain.pagerduty.com/users/ABC1234', 'id': 'ABC1234', 'self': 'https://api.pagerduty.com/users/ABC1234', 'summary': 'Test User', 'type': 'user_reference'}, 'at': '2015-11-10T00:32:52Z'}], 'alert_counts': {'all': 0, 'resolved': 0, 'triggered': 0}, 'assigned_via': 'escalation_policy', 'assignments': [{'assignee': {'html_url': 'https://subdomain.pagerduty.com/users/ABC1234', 'id': 'ABC1234', 'self': 'https://api.pagerduty.com/users/ABC1234', 'summary': 'Test User', 'type': 'user_reference'}, 'at': '2015-11-10T00:31:52Z'}], 'conference_bridge': {'conference_number': '555-123-4567', 'conference_url': 'https://example.com/123-456-789'}, 'created_at': '2015-10-06T21:30:42Z', 'escalation_policy': {'html_url': 'https://subdomain.pagerduty.com/escalation_policies/ABC1234', 'id': 'ABC1234', 'self': 'https://api.pagerduty.com/escalation_policies/ABC1234', 'summary': 'Another Escalation Policy', 'type': 'escalation_policy_reference'}, 'first_trigger_log_entry': {'html_url': 'https://subdomain.pagerduty.com/incidents/ABC1234/log_entries/ABCDEFGH123456', 'id': 'ABCDEFGH123456', 'self': 'https://api.pagerduty.com/log_entries/ABCDEFGH123456?incident_id=ABC1234', 'summary': 'Triggered through the API', 'type': 'trigger_log_entry_reference'}, 'html_url': 'https://subdomain.pagerduty.com/incidents/ABC1234', 'id': 'ABC1234', 'incident_key': 'abcABC123456abcABC123456abcABC123456', 'incident_number': 1234, 'is_mergeable': True, 'last_status_change_at': '2015-10-06T21:38:23Z', 'last_status_change_by': {'html_url': 'https://subdomain.pagerduty.com/users/ABC1234', 'id': 'ABC1234', 'self': 'https://api.pagerduty.com/users/ABC1234', 'summary': 'Test User', 'type': 'user_reference'}, 'pending_actions': [{'at': '2015-11-10T01:02:52Z', 'type': 'unacknowledge'}, {'at': '2015-11-10T04:31:52Z', 'type': 'resolve'}], 'priority': {'id': 'ABC1234', 'self': 'https://api.pagerduty.com/priorities/ABC1234', 'summary': 'P2', 'type': 'priority_reference'}, 'self': 'https://api.pagerduty.com/incidents/ABC1234', 'service': {'html_url': 'https://subdomain.pagerduty.com/service-directory/ABC1234', 'id': 'ABC1234', 'self': 'https://api.pagerduty.com/services/ABC1234', 'summary': 'My Mail Service', 'type': 'service_reference'}, 'status': 'resolved', 'summary': '[#1234] The server is on fire.', 'teams': [{'html_url': 'https://subdomain.pagerduty.com/teams/ABC1234', 'id': 'ABC1234', 'self': 'https://api.pagerduty.com/teams/ABC1234', 'summary': 'Engineering', 'type': 'team_reference'}], 'title': 'The server is on fire.', 'type': 'incident', 'updated_at': '2015-10-08T21:30:42Z', 'urgency': 'high'}}| + +Example output: -#### Get User by ID +``` +{ + "incident": { + "incident": { + "acknowledgements": [ + { + "acknowledger": { + "html_url": "https://subdomain.pagerduty.com/users/ABC1234", + "id": "ABC1234", + "self": "https://api.pagerduty.com/users/ABC1234", + "summary": "Test User", + "type": "user_reference" + }, + "at": "2015-11-10T00:32:52Z" + } + ], + "alert_counts": { + "all": 0, + "resolved": 0, + "triggered": 0 + }, + "assigned_via": "escalation_policy", + "assignments": [ + { + "assignee": { + "html_url": "https://subdomain.pagerduty.com/users/ABC1234", + "id": "ABC1234", + "self": "https://api.pagerduty.com/users/ABC1234", + "summary": "Test User", + "type": "user_reference" + }, + "at": "2015-11-10T00:31:52Z" + } + ], + "conference_bridge": { + "conference_number": "555-123-4567", + "conference_url": "https://example.com/123-456-789" + }, + "created_at": "2015-10-06T21:30:42Z", + "escalation_policy": { + "html_url": "https://subdomain.pagerduty.com/escalation_policies/ABC1234", + "id": "ABC1234", + "self": "https://api.pagerduty.com/escalation_policies/ABC1234", + "summary": "Another Escalation Policy", + "type": "escalation_policy_reference" + }, + "first_trigger_log_entry": { + "html_url": "https://subdomain.pagerduty.com/incidents/ABC1234/log_entries/ABCDEFGH123456", + "id": "ABCDEFGH123456", + "self": "https://api.pagerduty.com/log_entries/ABCDEFGH123456?incident_id=ABC1234", + "summary": "Triggered through the API", + "type": "trigger_log_entry_reference" + }, + "html_url": "https://subdomain.pagerduty.com/incidents/ABC1234", + "id": "ABC1234", + "incident_key": "abcABC123456abcABC123456abcABC123456", + "incident_number": 1234, + "is_mergeable": true, + "last_status_change_at": "2015-10-06T21:38:23Z", + "last_status_change_by": { + "html_url": "https://subdomain.pagerduty.com/users/ABC1234", + "id": "ABC1234", + "self": "https://api.pagerduty.com/users/ABC1234", + "summary": "Test User", + "type": "user_reference" + }, + "pending_actions": [ + { + "at": "2015-11-10T01:02:52Z", + "type": "unacknowledge" + }, + { + "at": "2015-11-10T04:31:52Z", + "type": "resolve" + } + ], + "priority": { + "id": "ABC1234", + "self": "https://api.pagerduty.com/priorities/ABC1234", + "summary": "P2", + "type": "priority_reference" + }, + "self": "https://api.pagerduty.com/incidents/ABC1234", + "service": { + "html_url": "https://subdomain.pagerduty.com/service-directory/ABC1234", + "id": "ABC1234", + "self": "https://api.pagerduty.com/services/ABC1234", + "summary": "My Mail Service", + "type": "service_reference" + }, + "status": "resolved", + "summary": "[#1234] The server is on fire.", + "teams": [ + { + "html_url": "https://subdomain.pagerduty.com/teams/ABC1234", + "id": "ABC1234", + "self": "https://api.pagerduty.com/teams/ABC1234", + "summary": "Engineering", + "type": "team_reference" + } + ], + "title": "The server is on fire.", + "type": "incident", + "updated_at": "2015-10-08T21:30:42Z", + "urgency": "high" + } + } +} +``` -This action is used to get information about a user by ID. +#### Send Trigger Event + +This action is used to trigger an incident ##### Input |Name|Type|Default|Required|Description|Enum|Example| -|----|----|-------|--------|-----------|----|-------| -|id|string|None|True|User ID|None|None| - +| :--- | :--- | :--- | :--- | :--- | :--- | :--- | +|assignments|[]assignee|None|False|Assign the incident to these assignees. Cannot be specified if an escalation policy is given|None|[{"assignee": {"id": "ABC1234", "type": "user_reference"}}]| +|conference_bridge|conference_bridge_input|None|False|The conference bridge information attached to the incident. Only returned if the include[]=conference_bridge query parameter is provided|None|{'conference_number': '555-123-4567', 'conference_url': 'https://example.com/123-456-789'}| +|email|string|None|True|The email address of a valid user associated with the account making the request|None|user1@example.com| +|escalation_policy|escalation_policy_input|None|False|Assign the incident to this escalation policy. Cannot be specified if Assignments given|None|{'html_url': 'https://subdomain.pagerduty.com/escalation_policies/ABC1234', 'id': 'ABC1234', 'self': 'https://api.pagerduty.com/escalation_policies/ABC1234', 'summary': 'Another Escalation Policy', 'type': 'escalation_policy_reference'}| +|incident_key|string|None|False|A string which identifies the incident. Sending subsequent requests referencing the same service and with the same incident_key will result in those requests being rejected if an open incident matches that incident_key|None|abcABC123456abcABC123456abcABC123456| +|priority|priority_input|None|False|The priority that the incident is to be set to|None|{'id': 'ABC1234', 'type': 'priority_reference'}| +|service|service_input|None|True|The service that the incident is related to|None|{'id': 'ABC1234', 'type': 'service_reference'}| +|title|string|None|True|A description of the nature, symptoms, cause, or effect of the incident|None|The server is on fire.| +|urgency|string|None|False|The urgency that the incident is to be set to|None|high| +|body|body_input|None|False|Details to be added to the incident body|None|{'details': 'A disk is getting full on this machine. You should investigate what is causing the disk to fill.', 'type': 'incident_body'}| + Example input: ``` +{ + "assignments": { + "assignee": { + "id": "ABC1234", + "type": "user_reference" + } + }, + "body": { + "details": "A disk is getting full on this machine. You should investigate what is causing the disk to fill.", + "type": "incident_body" + }, + "conference_bridge": { + "conference_number": "555-123-4567", + "conference_url": "https://example.com/123-456-789" + }, + "email": "user1@example.com", + "escalation_policy": { + "html_url": "https://subdomain.pagerduty.com/escalation_policies/ABC1234", + "id": "ABC1234", + "self": "https://api.pagerduty.com/escalation_policies/ABC1234", + "summary": "Another Escalation Policy", + "type": "escalation_policy_reference" + }, + "incident_key": "abcABC123456abcABC123456abcABC123456", + "priority": { + "id": "ABC1234", + "type": "priority_reference" + }, + "service": { + "id": "ABC1234", + "type": "service_reference" + }, + "title": "The server is on fire.", + "urgency": "high" +} ``` ##### Output -|Name|Type|Required|Description| -|----|----|--------|-----------| -|found|boolean|False|True if found| -|user|user|False|User| +|Name|Type|Required|Description|Example| +| :--- | :--- | :--- | :--- | :--- | +|incident|incident_output|False|The incident object that was created|{'incident': {'acknowledgements': [{'acknowledger': {'html_url': 'https://subdomain.pagerduty.com/users/ABC1234', 'id': 'ABC1234', 'self': 'https://api.pagerduty.com/users/ABC1234', 'summary': 'Test User', 'type': 'user_reference'}, 'at': '2015-11-10T00:32:52Z'}], 'alert_counts': {'all': 0, 'resolved': 0, 'triggered': 0}, 'assigned_via': 'escalation_policy', 'assignments': [{'assignee': {'html_url': 'https://subdomain.pagerduty.com/users/ABC1234', 'id': 'ABC1234', 'self': 'https://api.pagerduty.com/users/ABC1234', 'summary': 'Test User', 'type': 'user_reference'}, 'at': '2015-11-10T00:31:52Z'}], 'conference_bridge': {'conference_number': '555-123-4567', 'conference_url': 'https://example.com/123-456-789'}, 'created_at': '2015-10-06T21:30:42Z', 'escalation_policy': {'html_url': 'https://subdomain.pagerduty.com/escalation_policies/ABC1234', 'id': 'ABC1234', 'self': 'https://api.pagerduty.com/escalation_policies/ABC1234', 'summary': 'Another Escalation Policy', 'type': 'escalation_policy_reference'}, 'first_trigger_log_entry': {'html_url': 'https://subdomain.pagerduty.com/incidents/ABC1234/log_entries/ABCDEFGH123456', 'id': 'ABCDEFGH123456', 'self': 'https://api.pagerduty.com/log_entries/ABCDEFGH123456?incident_id=ABC1234', 'summary': 'Triggered through the API', 'type': 'trigger_log_entry_reference'}, 'html_url': 'https://subdomain.pagerduty.com/incidents/ABC1234', 'id': 'ABC1234', 'incident_key': 'abcABC123456abcABC123456abcABC123456', 'incident_number': 1234, 'is_mergeable': True, 'last_status_change_at': '2015-10-06T21:38:23Z', 'last_status_change_by': {'html_url': 'https://subdomain.pagerduty.com/users/ABC1234', 'id': 'ABC1234', 'self': 'https://api.pagerduty.com/users/ABC1234', 'summary': 'Test User', 'type': 'user_reference'}, 'pending_actions': [{'at': '2015-11-10T01:02:52Z', 'type': 'unacknowledge'}, {'at': '2015-11-10T04:31:52Z', 'type': 'resolve'}], 'priority': {'id': 'ABC1234', 'self': 'https://api.pagerduty.com/priorities/ABC1234', 'summary': 'P2', 'type': 'priority_reference'}, 'self': 'https://api.pagerduty.com/incidents/ABC1234', 'service': {'html_url': 'https://subdomain.pagerduty.com/service-directory/ABC1234', 'id': 'ABC1234', 'self': 'https://api.pagerduty.com/services/ABC1234', 'summary': 'My Mail Service', 'type': 'service_reference'}, 'status': 'resolved', 'summary': '[#1234] The server is on fire.', 'teams': [{'html_url': 'https://subdomain.pagerduty.com/teams/ABC1234', 'id': 'ABC1234', 'self': 'https://api.pagerduty.com/teams/ABC1234', 'summary': 'Engineering', 'type': 'team_reference'}], 'title': 'The server is on fire.', 'type': 'incident', 'updated_at': '2015-10-08T21:30:42Z', 'urgency': 'high'}}| + +Example output: +``` +{ + "incident": { + "incident": { + "acknowledgements": [ + { + "acknowledger": { + "html_url": "https://subdomain.pagerduty.com/users/ABC1234", + "id": "ABC1234", + "self": "https://api.pagerduty.com/users/ABC1234", + "summary": "Test User", + "type": "user_reference" + }, + "at": "2015-11-10T00:32:52Z" + } + ], + "alert_counts": { + "all": 0, + "resolved": 0, + "triggered": 0 + }, + "assigned_via": "escalation_policy", + "assignments": [ + { + "assignee": { + "html_url": "https://subdomain.pagerduty.com/users/ABC1234", + "id": "ABC1234", + "self": "https://api.pagerduty.com/users/ABC1234", + "summary": "Test User", + "type": "user_reference" + }, + "at": "2015-11-10T00:31:52Z" + } + ], + "conference_bridge": { + "conference_number": "555-123-4567", + "conference_url": "https://example.com/123-456-789" + }, + "created_at": "2015-10-06T21:30:42Z", + "escalation_policy": { + "html_url": "https://subdomain.pagerduty.com/escalation_policies/ABC1234", + "id": "ABC1234", + "self": "https://api.pagerduty.com/escalation_policies/ABC1234", + "summary": "Another Escalation Policy", + "type": "escalation_policy_reference" + }, + "first_trigger_log_entry": { + "html_url": "https://subdomain.pagerduty.com/incidents/ABC1234/log_entries/ABCDEFGH123456", + "id": "ABCDEFGH123456", + "self": "https://api.pagerduty.com/log_entries/ABCDEFGH123456?incident_id=ABC1234", + "summary": "Triggered through the API", + "type": "trigger_log_entry_reference" + }, + "html_url": "https://subdomain.pagerduty.com/incidents/ABC1234", + "id": "ABC1234", + "incident_key": "abcABC123456abcABC123456abcABC123456", + "incident_number": 1234, + "is_mergeable": true, + "last_status_change_at": "2015-10-06T21:38:23Z", + "last_status_change_by": { + "html_url": "https://subdomain.pagerduty.com/users/ABC1234", + "id": "ABC1234", + "self": "https://api.pagerduty.com/users/ABC1234", + "summary": "Test User", + "type": "user_reference" + }, + "pending_actions": [ + { + "at": "2015-11-10T01:02:52Z", + "type": "unacknowledge" + }, + { + "at": "2015-11-10T04:31:52Z", + "type": "resolve" + } + ], + "priority": { + "id": "ABC1234", + "self": "https://api.pagerduty.com/priorities/ABC1234", + "summary": "P2", + "type": "priority_reference" + }, + "self": "https://api.pagerduty.com/incidents/ABC1234", + "service": { + "html_url": "https://subdomain.pagerduty.com/service-directory/ABC1234", + "id": "ABC1234", + "self": "https://api.pagerduty.com/services/ABC1234", + "summary": "My Mail Service", + "type": "service_reference" + }, + "status": "resolved", + "summary": "[#1234] The server is on fire.", + "teams": [ + { + "html_url": "https://subdomain.pagerduty.com/teams/ABC1234", + "id": "ABC1234", + "self": "https://api.pagerduty.com/teams/ABC1234", + "summary": "Engineering", + "type": "team_reference" + } + ], + "title": "The server is on fire.", + "type": "incident", + "updated_at": "2015-10-08T21:30:42Z", + "urgency": "high" + } + } +} +``` ### Triggers + +*This plugin does not contain any triggers.* +### Tasks + +*This plugin does not contain any tasks.* + +### Custom Types + +**user** + +|Name|Type|Default|Required|Description|Example| +| :--- | :--- | :--- | :--- | :--- | :--- | +|avatar_url|string|None|None|Avatar URL|https://secure.gravatar.com/avatar/abcABC123456abcABC123456abcABC123456.png?d=mm&r=PG| +|color|string|None|None|Color|purple| +|description|string|None|None|Description|test description| +|email|string|None|True|Email|user1@example.com| +|id|string|None|None|ID|ABCD123| +|job_title|string|None|None|Job Title|engineer| +|name|string|None|True|Name|test user| +|role|string|None|None|Role|None| +|self|string|None|None|URL to view user|https://api.pagerduty.com/users/ABCD123| +|summary|string|None|None|Summary|test summary| +|time_zone|string|None|None|Time Zone, e.g. America/Lima|Europe/London| + +**incident_output** + +|Name|Type|Default|Required|Description|Example| +| :--- | :--- | :--- | :--- | :--- | :--- | +|acknowledgements|array|None|None|List of all acknowledgements for this incident. This list will be empty if the Incident.status is resolved or triggered. If the include[]=acknowledgers query parameter is provided, the full user or service definitions will be returned for each acknowledgement entry|[{'at': '2015-11-10T00:32:52Z', 'acknowledger': {'id': 'ABC1234', 'type': 'user_reference', 'summary': 'Test User', 'self': 'https://api.pagerduty.com/users/ABC1234', 'html_url': 'https://subdomain.pagerduty.com/users/ABC1234'}}]| +|alert_counts|object|None|None|The counts of alerts grouped into this incident|{'all': 0, 'resolved': 0, 'triggered': 0}| +|assigned_via|string|None|None|How the current incident assignments were decided. Note that direct_assignment incidents will not escalate up the attached escalation_policy|escalation_policy| +|assignments|array|None|None|Which accounts the incident will be assigned to|[{'at': '2015-11-10T00:31:52Z', 'assignee': {'id': 'ABC1234', 'type': 'user_reference', 'summary': 'Test User', 'self': 'https://api.pagerduty.com/users/ABC1234', 'html_url': 'https://subdomain.pagerduty.com/users/ABC1234'}}]| +|conference_bridge|object|None|None|The conference bridge information attached to the incident. Only returned if the include[]=conference_bridge query parameter is provided|{'conference_number': '555-123-4567', 'conference_url': 'https://example.com/123-456-789'}| +|created_at|string|None|None|The time the incident was first triggered|2015-10-06T21:30:42Z| +|escalation_policy|object|None|None|The escalation policy attached to the service that the incident is on. If the include[]=escalation_policies query parameter is provided, the full escalation policy definition will be returned|{'id': 'ABC1234', 'type': 'escalation_policy_reference', 'summary': 'Another Escalation Policy', 'self': 'https://api.pagerduty.com/escalation_policies/ABC1234', 'html_url': 'https://subdomain.pagerduty.com/escalation_policies/ABC1234'}| +|first_trigger_log_entry|object|None|None|The first log entry on the incident. The log entry will be of type TriggerLogEntry and will represent information about how the incident was triggered. If the include[]=first_trigger_log_entries query parameter is provided, the full log entry definition will be returned|{'id': 'ABCDEFGH123456', 'type': 'trigger_log_entry_reference', 'summary': 'Triggered through the API', 'self': 'https://api.pagerduty.com/log_entries/ABCDEFGH123456?incident_id=ABC1234', 'html_url': 'https://subdomain.pagerduty.com/incidents/ABC1234/log_entries/ABCDEFGH123456'}| +|html_url|string|None|None|A URL at which the entity is uniquely displayed in the Web app|https://subdomain.pagerduty.com/incidents/ABC1234| +|id|string|None|None|The id of the incident|ABC1234| +|incident_key|string|None|None|The incident's de-duplication key|abcABC123456abcABC123456abcABC123456| +|incident_number|integar|None|None|The number of the incident. This is unique across your account.|1234| +|is_mergeable|boolean|None|None|Whether the incident is mergeable. Only incidents that have alerts, or that are manually created can be merged|True| +|last_status_change_at|string|None|None|The time the status of the incident last changed. If the incident is not currently acknowledged or resolved, this will be the incident's updated_at|2015-10-06T21:38:23Z| +|last_status_change_by|object|None|None|The agent (user, service or integration) that created or modified the Incident Log Entry|{'id': 'ABC1234', 'type': 'user_reference', 'summary': 'Test User', 'self': 'https://api.pagerduty.com/users/ABC1234', 'html_url': 'https://subdomain.pagerduty.com/users/ABC1234'}| +|pending_actions|array|None|None|The list of pending_actions on the incident. A pending_action object contains a type of action which can be escalate, unacknowledge, resolve or urgency_change. A pending_action object contains at, the time at which the action will take place. An urgency_change pending_action will contain to, the urgency that the incident will change to|[{'type': 'unacknowledge', 'at': '2015-11-10T01:02:52Z'}, {'type': 'resolve', 'at': '2015-11-10T04:31:52Z'}]| +|priority|object|None|None|The priority of the object|{'id': 'ABC1234', 'type': 'priority_reference', 'summary': 'P2', 'self': 'https://api.pagerduty.com/priorities/ABC1234'}| +|self|string|None|None|The API show URL at which the object is accessible|https://api.pagerduty.com/incidents/ABC1234| +|service|object|None|None|The service the incident is on. If the include[]=services query parameter is provided, the full service definition will be returned|{'id': 'ABC1234', 'type': 'service_reference', 'summary': 'My Mail Service', 'self': 'https://api.pagerduty.com/services/ABC1234', 'html_url': 'https://subdomain.pagerduty.com/service-directory/ABC1234'}| +|status|string|None|None|The current status of the incident|resolved| +|summary|string|None|None|A short-form, server-generated string that provides succinct, important information about an object suitable for primary labelling of an entity in a client|[#1234] The server is on fire.| +|teams|array|None|None|Teams that the alert is assigned to|[{'id': 'ABC1234', 'type': 'team_reference', 'summary': 'Engineering', 'self': 'https://api.pagerduty.com/teams/ABC1234', 'html_url': 'https://subdomain.pagerduty.com/teams/ABC1234'}]| +|title|string|None|None|A succinct description of the nature, symptoms, cause, or effect of the incident|The server is on fire.| +|type|string|None|None|A string that determines the schema of the object|incident| +|updated_at|string|None|None|The time the incident was last modified|2015-10-08T21:30:42Z| +|urgency|string|None|None|The current urgency of the incident|high| + +**service_input** + +|Name|Type|Default|Required|Description|Example| +| :--- | :--- | :--- | :--- | :--- | :--- | +|id|string|None|True|The id of the service that the incident is related to|PWIXJZS| +|type|string|None|True|The type of the service that the incident is related to|service_reference| + +**priority_input** + +|Name|Type|Default|Required|Description|Example| +| :--- | :--- | :--- | :--- | :--- | :--- | +|id|string|None|True|The id of the priority that the incident is to be set to|ABC1234| +|type|string|None|True|The type of the priority that the incident is to be set to|priority_reference| + +**body_input** + +|Name|Type|Default|Required|Description|Example| +| :--- | :--- | :--- | :--- | :--- | :--- | +|details|string|None|True|The id of the priority that the incident is to be set to|A disk is getting full on this machine. You should investigate what is causing the disk to fill| +|type|string|None|True|The type of the body is to be added to|incident_body| + +**assignee** + +|Name|Type|Default|Required|Description|Example| +| :--- | :--- | :--- | :--- | :--- | :--- | +|id|string|None|None|The id of the user that the new incident will be assigned to|ABC1234| +|type|string|None|None|A string that determines the schema of the object.|user_reference| + +**escalation_policy_input** + +|Name|Type|Default|Required|Description|Example| +| :--- | :--- | :--- | :--- | :--- | :--- | +|html_url|string|None|None|A URL at which the entity is uniquely displayed in the Web app|https://subdomain.pagerduty.com/escalation_policies/ABC1234| +|id|string|None|None|The id of the escalation policy that the new incident will be assigned to|ABC1234| +|self|string|None|None|The API show URL at which the object is accessible|https://api.pagerduty.com/escalation_policies/ABC1234| +|summary|string|None|None|A short-form, server-generated string that provides succinct, important information about an object|Another Escalation Policy| +|type|string|None|None|A string that determines the schema of the object.|escalation_policy_reference| + +**conference_bridge_input** + +|Name|Type|Default|Required|Description|Example| +| :--- | :--- | :--- | :--- | :--- | :--- | +|conference_number|string|None|None|The phone number of the conference call for the conference bridge. Phone numbers should be formatted like +1 415-555-1212,,,,1234#, where a comma (,) represents a one-second wait and pound (#) completes access code input|555-123-4567| +|conference_url|string|None|None|A URL for the conference bridge. This could be a link to a web conference or Slack channel|https://example.com/123-456-789| -_This plugin does not contain any triggers._ - -### Custom Output Types - -_This plugin does not contain any custom output types._ ## Troubleshooting - -_This plugin does not contain any troubleshooting information._ + +*There is no troubleshooting for this plugin.* # Version History +* 3.0.0 - `Refactor`: Re-write plugin to use `requests` instead of `pypd` package | `Unit Tests`: Added for all actions. * 2.2.0 - Added Schedule ID optional input to Get On Call action * 2.1.0 - New action Get On Call * 2.0.1 - New spec and help.md format for the Extension Library @@ -358,6 +998,8 @@ _This plugin does not contain any troubleshooting information._ # Links -## References - * [PagerDuty API V2](https://v2.developer.pagerduty.com/v2/page/api-reference) + +## References + +* [PagerDuty API V2](https://v2.developer.pagerduty.com/v2/page/api-reference) \ No newline at end of file diff --git a/plugins/pagerduty/komand_pagerduty/actions/__init__.py b/plugins/pagerduty/komand_pagerduty/actions/__init__.py index a8317a075a..7d663f6627 100755 --- a/plugins/pagerduty/komand_pagerduty/actions/__init__.py +++ b/plugins/pagerduty/komand_pagerduty/actions/__init__.py @@ -1,9 +1,17 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT -from .create_user.action import CreateUser -from .delete_user_by_id.action import DeleteUserById +# GENERATED BY INSIGHT-PLUGIN - DO NOT EDIT + from .get_on_call.action import GetOnCall -from .get_user_by_email.action import GetUserByEmail + from .get_user_by_id.action import GetUserById + +from .create_user.action import CreateUser + +from .delete_user_by_id.action import DeleteUserById + +from .send_trigger_event.action import SendTriggerEvent + from .send_acknowledge_event.action import SendAcknowledgeEvent + from .send_resolve_event.action import SendResolveEvent -from .send_trigger_event.action import SendTriggerEvent + +from .get_user_by_email.action import GetUserByEmail \ No newline at end of file diff --git a/plugins/pagerduty/komand_pagerduty/actions/create_user/__init__.py b/plugins/pagerduty/komand_pagerduty/actions/create_user/__init__.py index 3db74725cf..88ac46866a 100755 --- a/plugins/pagerduty/komand_pagerduty/actions/create_user/__init__.py +++ b/plugins/pagerduty/komand_pagerduty/actions/create_user/__init__.py @@ -1,2 +1,2 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT +# GENERATED BY INSIGHT-PLUGIN - DO NOT EDIT from .action import CreateUser diff --git a/plugins/pagerduty/komand_pagerduty/actions/create_user/action.py b/plugins/pagerduty/komand_pagerduty/actions/create_user/action.py index 3dff219ab2..a25c626f85 100755 --- a/plugins/pagerduty/komand_pagerduty/actions/create_user/action.py +++ b/plugins/pagerduty/komand_pagerduty/actions/create_user/action.py @@ -1,9 +1,9 @@ import insightconnect_plugin_runtime -from .schema import CreateUserInput, CreateUserOutput +from insightconnect_plugin_runtime.exceptions import PluginException +from .schema import CreateUserInput, CreateUserOutput, Input, Output, Component # Custom imports below -import pypd -from komand_pagerduty.util.util import empty_user, normalize_user +from komand_pagerduty.util.util import normalize_user class CreateUser(insightconnect_plugin_runtime.Action): @@ -16,20 +16,26 @@ def __init__(self): ) def run(self, params={}): - """Run action""" - self.logger.info("Creating user %s", params) - user = pypd.User.create(data=params, from_email=params["from_email"]) - - if user: - user = normalize_user(user.json) - else: - user = None - - self.logger.debug("Returned: %s", user) - - return {"success": not not user, "user": user or empty_user} - - def test(self): - """Test action""" + # required + from_email = params.get(Input.FROM_EMAIL) + new_users_email = params.get(Input.EMAIL) + name = params.get(Input.NAME) + + # optional + dict_of_optional_fields = { + "time_zone": params.get(Input.TIME_ZONE, ""), + "color": params.get(Input.COLOR, ""), + "role": params.get(Input.ROLE, ""), + "description": params.get(Input.USER_DESCRIPTION, ""), + "job_title": params.get(Input.JOB_TITLE, ""), + "license": params.get(Input.LICENSE, {}), + } + + response = self.connection.api.create_user( + from_email=from_email, + new_users_email=new_users_email, + name=name, + dict_of_optional_fields=dict_of_optional_fields, + ) - return {"success": True, "user": empty_user} + return {Output.USER: normalize_user(response.get("user", {}))} diff --git a/plugins/pagerduty/komand_pagerduty/actions/create_user/schema.py b/plugins/pagerduty/komand_pagerduty/actions/create_user/schema.py index f120675bbc..ec4cb66c09 100755 --- a/plugins/pagerduty/komand_pagerduty/actions/create_user/schema.py +++ b/plugins/pagerduty/komand_pagerduty/actions/create_user/schema.py @@ -1,4 +1,4 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT +# GENERATED BY INSIGHT-PLUGIN - DO NOT EDIT import insightconnect_plugin_runtime import json @@ -8,35 +8,57 @@ class Component: class Input: + COLOR = "color" EMAIL = "email" FROM_EMAIL = "from_email" + JOB_TITLE = "job_title" + LICENSE = "license" NAME = "name" ROLE = "role" - + TIME_ZONE = "time_zone" + USER_DESCRIPTION = "user_description" + class Output: - SUCCESS = "success" USER = "user" - + class CreateUserInput(insightconnect_plugin_runtime.Input): - schema = json.loads(""" + schema = json.loads(r""" { "type": "object", "title": "Variables", "properties": { + "color": { + "type": "string", + "title": "Color", + "description": "The schedule color", + "order": 6 + }, "email": { "type": "string", - "title": "Email", - "description": "Email", + "title": "Email for New Account", + "description": "The email address for the new account to be created", "order": 2 }, "from_email": { "type": "string", - "title": "Email", - "description": "Email of creating user", + "title": "Email of the Creating User", + "description": "The email address of user that is creating the account", "order": 4 }, + "job_title": { + "type": "string", + "title": "Job Title", + "description": "The description of the new user", + "order": 8 + }, + "license": { + "type": "object", + "title": "License", + "description": "The license of the new user", + "order": 9 + }, "name": { "type": "string", "title": "Name", @@ -55,13 +77,26 @@ class CreateUserInput(insightconnect_plugin_runtime.Input): "user" ], "order": 3 + }, + "time_zone": { + "type": "string", + "title": "Time Zone", + "description": "Time Zone, e.g. America/Lima", + "order": 5 + }, + "user_description": { + "type": "string", + "title": "Description", + "description": "The description of the new user", + "order": 7 } }, "required": [ "email", "from_email", "name" - ] + ], + "definitions": {} } """) @@ -70,22 +105,16 @@ def __init__(self): class CreateUserOutput(insightconnect_plugin_runtime.Output): - schema = json.loads(""" + schema = json.loads(r""" { "type": "object", "title": "Variables", "properties": { - "success": { - "type": "boolean", - "title": "Success", - "description": "True if created", - "order": 1 - }, "user": { "$ref": "#/definitions/user", "title": "User", "description": "User", - "order": 2 + "order": 1 } }, "definitions": { @@ -93,51 +122,58 @@ class CreateUserOutput(insightconnect_plugin_runtime.Output): "type": "object", "title": "user", "properties": { - "avatar_url": { + "id": { "type": "string", - "title": "Avatar Url", - "description": "Avatar URL", - "order": 9 + "description": "ID", + "order": 1 }, - "color": { + "self": { "type": "string", - "title": "Color", - "description": "Color", - "order": 6 + "description": "URL to view user", + "order": 2 }, - "description": { + "name": { "type": "string", - "title": "Description", - "description": "Description", - "order": 7 + "description": "Name", + "order": 3 }, "email": { "type": "string", - "title": "Email", "description": "Email", "order": 4 }, - "id": { + "summary": { "type": "string", - "title": "Id", - "description": "ID", - "order": 1 + "description": "Summary", + "order": 5 + }, + "color": { + "type": "string", + "description": "Color", + "order": 6 + }, + "description": { + "type": "string", + "description": "Description", + "order": 7 }, "job_title": { "type": "string", - "title": "Job Title", "description": "Job Title", "order": 8 }, - "name": { + "avatar_url": { "type": "string", - "title": "Name", - "description": "Name", - "order": 3 + "description": "Avatar URL", + "order": 9 + }, + "time_zone": { + "type": "string", + "description": "Time Zone, e.g. America/Lima", + "order": 10 }, "role": { "type": "string", - "title": "Role", "description": "Role", "enum": [ "admin", @@ -147,24 +183,6 @@ class CreateUserOutput(insightconnect_plugin_runtime.Output): "user" ], "order": 11 - }, - "self": { - "type": "string", - "title": "Self", - "description": "URL to view object", - "order": 2 - }, - "summary": { - "type": "string", - "title": "Summary", - "description": "Summary", - "order": 5 - }, - "time_zone": { - "type": "string", - "title": "Time Zone", - "description": "Time Zone, e.g. America/Lima", - "order": 10 } }, "required": [ diff --git a/plugins/pagerduty/komand_pagerduty/actions/delete_user_by_id/__init__.py b/plugins/pagerduty/komand_pagerduty/actions/delete_user_by_id/__init__.py index 55b424efd2..5aebb2a813 100755 --- a/plugins/pagerduty/komand_pagerduty/actions/delete_user_by_id/__init__.py +++ b/plugins/pagerduty/komand_pagerduty/actions/delete_user_by_id/__init__.py @@ -1,2 +1,2 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT +# GENERATED BY INSIGHT-PLUGIN - DO NOT EDIT from .action import DeleteUserById diff --git a/plugins/pagerduty/komand_pagerduty/actions/delete_user_by_id/action.py b/plugins/pagerduty/komand_pagerduty/actions/delete_user_by_id/action.py index ea01017cf2..dc3effa82c 100755 --- a/plugins/pagerduty/komand_pagerduty/actions/delete_user_by_id/action.py +++ b/plugins/pagerduty/komand_pagerduty/actions/delete_user_by_id/action.py @@ -1,9 +1,9 @@ import insightconnect_plugin_runtime -from .schema import DeleteUserByIdInput, DeleteUserByIdOutput +from insightconnect_plugin_runtime.exceptions import PluginException +from .schema import DeleteUserByIdInput, DeleteUserByIdOutput, Input, Output, Component # Custom imports below -import pypd -from komand_pagerduty.util.util import empty_user, normalize_user +from komand_pagerduty.util.util import normalize_user class DeleteUserById(insightconnect_plugin_runtime.Action): @@ -16,25 +16,9 @@ def __init__(self): ) def run(self, params={}): - """Delete user""" + email = params.get(Input.EMAIL) + user_id = params.get(Input.ID) - if not params["id"]: - raise Exception("id not provided") + self.connection.api.delete_user_by_id(email=email, user_id=user_id) - user = pypd.User.find_one(id=params["id"]) - if not user: - return { - "success": False, - "user": {}, - } - - self.logger.debug("Returned: %s", user) - - success = user.remove() - user = normalize_user(user.json) - - return {"success": success, "user": user or empty_user} - - def test(self): - """Test action""" - return {"success": False, "user": empty_user} + return {Output.SUCCESS: f"The user {user_id} has been deleted"} diff --git a/plugins/pagerduty/komand_pagerduty/actions/delete_user_by_id/schema.py b/plugins/pagerduty/komand_pagerduty/actions/delete_user_by_id/schema.py index f0024883ab..41759eb696 100755 --- a/plugins/pagerduty/komand_pagerduty/actions/delete_user_by_id/schema.py +++ b/plugins/pagerduty/komand_pagerduty/actions/delete_user_by_id/schema.py @@ -1,4 +1,4 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT +# GENERATED BY INSIGHT-PLUGIN - DO NOT EDIT import insightconnect_plugin_runtime import json @@ -8,20 +8,26 @@ class Component: class Input: + EMAIL = "email" ID = "id" - + class Output: SUCCESS = "success" - USER = "user" - + class DeleteUserByIdInput(insightconnect_plugin_runtime.Input): - schema = json.loads(""" + schema = json.loads(r""" { "type": "object", "title": "Variables", "properties": { + "email": { + "type": "string", + "title": "Email", + "description": "The email address of a valid user associated with the account making the delete request", + "order": 2 + }, "id": { "type": "string", "title": "User ID", @@ -30,8 +36,10 @@ class DeleteUserByIdInput(insightconnect_plugin_runtime.Input): } }, "required": [ + "email", "id" - ] + ], + "definitions": {} } """) @@ -40,109 +48,19 @@ def __init__(self): class DeleteUserByIdOutput(insightconnect_plugin_runtime.Output): - schema = json.loads(""" + schema = json.loads(r""" { "type": "object", "title": "Variables", "properties": { "success": { - "type": "boolean", + "type": "string", "title": "Success", - "description": "True if deleted", + "description": "A message to show if the user was deleted as expected", "order": 1 - }, - "user": { - "$ref": "#/definitions/user", - "title": "User", - "description": "User", - "order": 2 } }, - "definitions": { - "user": { - "type": "object", - "title": "user", - "properties": { - "avatar_url": { - "type": "string", - "title": "Avatar Url", - "description": "Avatar URL", - "order": 9 - }, - "color": { - "type": "string", - "title": "Color", - "description": "Color", - "order": 6 - }, - "description": { - "type": "string", - "title": "Description", - "description": "Description", - "order": 7 - }, - "email": { - "type": "string", - "title": "Email", - "description": "Email", - "order": 4 - }, - "id": { - "type": "string", - "title": "Id", - "description": "ID", - "order": 1 - }, - "job_title": { - "type": "string", - "title": "Job Title", - "description": "Job Title", - "order": 8 - }, - "name": { - "type": "string", - "title": "Name", - "description": "Name", - "order": 3 - }, - "role": { - "type": "string", - "title": "Role", - "description": "Role", - "enum": [ - "admin", - "limited_user", - "owner", - "read_only_user", - "user" - ], - "order": 11 - }, - "self": { - "type": "string", - "title": "Self", - "description": "URL to view object", - "order": 2 - }, - "summary": { - "type": "string", - "title": "Summary", - "description": "Summary", - "order": 5 - }, - "time_zone": { - "type": "string", - "title": "Time Zone", - "description": "Time Zone, e.g. America/Lima", - "order": 10 - } - }, - "required": [ - "email", - "name" - ] - } - } + "definitions": {} } """) diff --git a/plugins/pagerduty/komand_pagerduty/actions/get_on_call/__init__.py b/plugins/pagerduty/komand_pagerduty/actions/get_on_call/__init__.py index f5df66ac27..db5ea0558a 100755 --- a/plugins/pagerduty/komand_pagerduty/actions/get_on_call/__init__.py +++ b/plugins/pagerduty/komand_pagerduty/actions/get_on_call/__init__.py @@ -1,2 +1,2 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT +# GENERATED BY INSIGHT-PLUGIN - DO NOT EDIT from .action import GetOnCall diff --git a/plugins/pagerduty/komand_pagerduty/actions/get_on_call/action.py b/plugins/pagerduty/komand_pagerduty/actions/get_on_call/action.py index e9bd0f70e2..86839bcd7b 100755 --- a/plugins/pagerduty/komand_pagerduty/actions/get_on_call/action.py +++ b/plugins/pagerduty/komand_pagerduty/actions/get_on_call/action.py @@ -3,7 +3,7 @@ # Custom imports below from insightconnect_plugin_runtime.exceptions import PluginException -import asyncio +from komand_pagerduty.util.util import normalize_user class GetOnCall(insightconnect_plugin_runtime.Action): @@ -16,14 +16,9 @@ def __init__(self): ) def run(self, params={}): - schedule_id = params.get(Input.SCHEDULE_ID, None) - user_ids = [] - for oncall_object in self.connection.api.get_on_calls(schedule_id).get("oncalls", []): - try: - user_ids.append(oncall_object["user"]["id"]) - except KeyError as e: - self.logger.warning(f"User ID not available: {str(e)}") - continue + schedule_id = params.get(Input.SCHEDULE_ID) + + user_ids = self.get_user_ids(schedule_id=schedule_id) if not user_ids and schedule_id: self.logger.warning( @@ -31,19 +26,35 @@ def run(self, params={}): "Please make sure that the schedule used is correct." ) - users = asyncio.run(self.async_get_users(user_ids)) - return {Output.USERS: insightconnect_plugin_runtime.helper.clean(users)} - - async def async_get_users(self, user_ids: [str]) -> list: - connection = self.connection.async_connection - async with connection.get_async_session() as async_session: - tasks: [asyncio.Future] = [] - for user_id in user_ids: - url = f"https://api.pagerduty.com/users/{user_id}" - tasks.append( - asyncio.ensure_future(connection.async_request(session=async_session, url=url, method="get")) - ) - user_objects = await asyncio.gather(*tasks) - users = [u.get("user") for u in user_objects] - - return users + list_of_users = self.get_list_of_users_from_ids(user_ids=user_ids) + + return {Output.USERS: list_of_users} + + def get_user_ids(self, schedule_id: str): + user_ids = [] + for oncall_object in self.connection.api.get_on_calls(schedule_id).get("schedule", {}).get("users", []): + try: + if oncall_object.get("deleted_at", None): + self.logger.info(oncall_object) + self.logger.warning( + f"The following user {oncall_object.get('id')} is part of the schedule but has been deleted" + ) + else: + user_ids.append(oncall_object["id"]) + except KeyError as error: + self.logger.warning(f"User ID not available: {str(error)}") + continue + return user_ids + + def get_list_of_users_from_ids(self, user_ids: list): + list_of_users = [] + for user_id in user_ids: + try: + user_info = self.connection.api.get_user_by_id(user_id).get("user", {}) + except Exception: + self.logger.warning(f"No information was found for the user - {user_id}") + continue + + if user_info: + list_of_users.append(normalize_user(user_info)) + return list_of_users diff --git a/plugins/pagerduty/komand_pagerduty/actions/get_on_call/schema.py b/plugins/pagerduty/komand_pagerduty/actions/get_on_call/schema.py index 82b2d6f36a..6a960cce7e 100755 --- a/plugins/pagerduty/komand_pagerduty/actions/get_on_call/schema.py +++ b/plugins/pagerduty/komand_pagerduty/actions/get_on_call/schema.py @@ -1,4 +1,4 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT +# GENERATED BY INSIGHT-PLUGIN - DO NOT EDIT import insightconnect_plugin_runtime import json @@ -9,14 +9,14 @@ class Component: class Input: SCHEDULE_ID = "schedule_id" - + class Output: USERS = "users" - + class GetOnCallInput(insightconnect_plugin_runtime.Input): - schema = json.loads(""" + schema = json.loads(r""" { "type": "object", "title": "Variables", @@ -27,7 +27,11 @@ class GetOnCallInput(insightconnect_plugin_runtime.Input): "description": "Schedule ID", "order": 1 } - } + }, + "required": [ + "schedule_id" + ], + "definitions": {} } """) @@ -36,7 +40,7 @@ def __init__(self): class GetOnCallOutput(insightconnect_plugin_runtime.Output): - schema = json.loads(""" + schema = json.loads(r""" { "type": "object", "title": "Variables", @@ -59,51 +63,58 @@ class GetOnCallOutput(insightconnect_plugin_runtime.Output): "type": "object", "title": "user", "properties": { - "avatar_url": { + "id": { "type": "string", - "title": "Avatar Url", - "description": "Avatar URL", - "order": 9 + "description": "ID", + "order": 1 }, - "color": { + "self": { "type": "string", - "title": "Color", - "description": "Color", - "order": 6 + "description": "URL to view user", + "order": 2 }, - "description": { + "name": { "type": "string", - "title": "Description", - "description": "Description", - "order": 7 + "description": "Name", + "order": 3 }, "email": { "type": "string", - "title": "Email", "description": "Email", "order": 4 }, - "id": { + "summary": { "type": "string", - "title": "Id", - "description": "ID", - "order": 1 + "description": "Summary", + "order": 5 + }, + "color": { + "type": "string", + "description": "Color", + "order": 6 + }, + "description": { + "type": "string", + "description": "Description", + "order": 7 }, "job_title": { "type": "string", - "title": "Job Title", "description": "Job Title", "order": 8 }, - "name": { + "avatar_url": { "type": "string", - "title": "Name", - "description": "Name", - "order": 3 + "description": "Avatar URL", + "order": 9 + }, + "time_zone": { + "type": "string", + "description": "Time Zone, e.g. America/Lima", + "order": 10 }, "role": { "type": "string", - "title": "Role", "description": "Role", "enum": [ "admin", @@ -113,24 +124,6 @@ class GetOnCallOutput(insightconnect_plugin_runtime.Output): "user" ], "order": 11 - }, - "self": { - "type": "string", - "title": "Self", - "description": "URL to view object", - "order": 2 - }, - "summary": { - "type": "string", - "title": "Summary", - "description": "Summary", - "order": 5 - }, - "time_zone": { - "type": "string", - "title": "Time Zone", - "description": "Time Zone, e.g. America/Lima", - "order": 10 } }, "required": [ diff --git a/plugins/pagerduty/komand_pagerduty/actions/get_user_by_email/__init__.py b/plugins/pagerduty/komand_pagerduty/actions/get_user_by_email/__init__.py old mode 100755 new mode 100644 index eb0a75a46d..3660c8103e --- a/plugins/pagerduty/komand_pagerduty/actions/get_user_by_email/__init__.py +++ b/plugins/pagerduty/komand_pagerduty/actions/get_user_by_email/__init__.py @@ -1,2 +1,2 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT +# GENERATED BY INSIGHT-PLUGIN - DO NOT EDIT from .action import GetUserByEmail diff --git a/plugins/pagerduty/komand_pagerduty/actions/get_user_by_email/action.py b/plugins/pagerduty/komand_pagerduty/actions/get_user_by_email/action.py old mode 100755 new mode 100644 index 9a4480a928..7d7f4c1220 --- a/plugins/pagerduty/komand_pagerduty/actions/get_user_by_email/action.py +++ b/plugins/pagerduty/komand_pagerduty/actions/get_user_by_email/action.py @@ -1,35 +1,28 @@ import insightconnect_plugin_runtime -from .schema import GetUserByEmailInput, GetUserByEmailOutput +from insightconnect_plugin_runtime.exceptions import PluginException +from .schema import GetUserByEmailInput, GetUserByEmailOutput, Input, Output, Component # Custom imports below -import pypd -from komand_pagerduty.util.util import empty_user, normalize_user +from komand_pagerduty.util.util import normalize_user class GetUserByEmail(insightconnect_plugin_runtime.Action): def __init__(self): super(self.__class__, self).__init__( name="get_user_by_email", - description="Get a User By Email", + description=Component.DESCRIPTION, input=GetUserByEmailInput(), output=GetUserByEmailOutput(), ) def run(self, params={}): - """Get a user by email""" + user_email = params.get(Input.USER_EMAIL) - if not params["email"]: - raise Exception("Email required") + response = self.connection.api.get_user_by_email(user_email=user_email) - user = pypd.User.find_one(email=params["email"]) - if user: - user = normalize_user(user.json) - else: - user = None + for user in response.get("users", []): + if user.get("email", "") == user_email: + normalized_user = normalize_user(user) + return {Output.USER: normalized_user} - self.logger.debug("Returned: %s", user) - return {"found": bool(user), "user": user or empty_user} - - def test(self): - """Test action""" - return {"found": False, "user": empty_user} + raise PluginException(cause=f"No user found for email {user_email}") diff --git a/plugins/pagerduty/komand_pagerduty/actions/get_user_by_email/schema.py b/plugins/pagerduty/komand_pagerduty/actions/get_user_by_email/schema.py old mode 100755 new mode 100644 index cbbbec7330..b7b0a02f95 --- a/plugins/pagerduty/komand_pagerduty/actions/get_user_by_email/schema.py +++ b/plugins/pagerduty/komand_pagerduty/actions/get_user_by_email/schema.py @@ -1,37 +1,37 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT +# GENERATED BY INSIGHT-PLUGIN - DO NOT EDIT import insightconnect_plugin_runtime import json class Component: - DESCRIPTION = "Get a User by Email" + DESCRIPTION = "Get a User from using their email address" class Input: - EMAIL = "email" - + USER_EMAIL = "user_email" + class Output: - FOUND = "found" USER = "user" - + class GetUserByEmailInput(insightconnect_plugin_runtime.Input): - schema = json.loads(""" + schema = json.loads(r""" { "type": "object", "title": "Variables", "properties": { - "email": { + "user_email": { "type": "string", - "title": "Email", - "description": "Email", + "title": "User Email", + "description": "User email address", "order": 1 } }, "required": [ - "email" - ] + "user_email" + ], + "definitions": {} } """) @@ -40,22 +40,16 @@ def __init__(self): class GetUserByEmailOutput(insightconnect_plugin_runtime.Output): - schema = json.loads(""" + schema = json.loads(r""" { "type": "object", "title": "Variables", "properties": { - "found": { - "type": "boolean", - "title": "Found", - "description": "True if found", - "order": 1 - }, "user": { "$ref": "#/definitions/user", "title": "User", "description": "User", - "order": 2 + "order": 1 } }, "definitions": { @@ -63,51 +57,58 @@ class GetUserByEmailOutput(insightconnect_plugin_runtime.Output): "type": "object", "title": "user", "properties": { - "avatar_url": { + "id": { "type": "string", - "title": "Avatar Url", - "description": "Avatar URL", - "order": 9 + "description": "ID", + "order": 1 }, - "color": { + "self": { "type": "string", - "title": "Color", - "description": "Color", - "order": 6 + "description": "URL to view user", + "order": 2 }, - "description": { + "name": { "type": "string", - "title": "Description", - "description": "Description", - "order": 7 + "description": "Name", + "order": 3 }, "email": { "type": "string", - "title": "Email", "description": "Email", "order": 4 }, - "id": { + "summary": { "type": "string", - "title": "Id", - "description": "ID", - "order": 1 + "description": "Summary", + "order": 5 + }, + "color": { + "type": "string", + "description": "Color", + "order": 6 + }, + "description": { + "type": "string", + "description": "Description", + "order": 7 }, "job_title": { "type": "string", - "title": "Job Title", "description": "Job Title", "order": 8 }, - "name": { + "avatar_url": { "type": "string", - "title": "Name", - "description": "Name", - "order": 3 + "description": "Avatar URL", + "order": 9 + }, + "time_zone": { + "type": "string", + "description": "Time Zone, e.g. America/Lima", + "order": 10 }, "role": { "type": "string", - "title": "Role", "description": "Role", "enum": [ "admin", @@ -117,24 +118,6 @@ class GetUserByEmailOutput(insightconnect_plugin_runtime.Output): "user" ], "order": 11 - }, - "self": { - "type": "string", - "title": "Self", - "description": "URL to view object", - "order": 2 - }, - "summary": { - "type": "string", - "title": "Summary", - "description": "Summary", - "order": 5 - }, - "time_zone": { - "type": "string", - "title": "Time Zone", - "description": "Time Zone, e.g. America/Lima", - "order": 10 } }, "required": [ diff --git a/plugins/pagerduty/komand_pagerduty/actions/get_user_by_id/__init__.py b/plugins/pagerduty/komand_pagerduty/actions/get_user_by_id/__init__.py index 63e00d062b..7e6a88cfef 100755 --- a/plugins/pagerduty/komand_pagerduty/actions/get_user_by_id/__init__.py +++ b/plugins/pagerduty/komand_pagerduty/actions/get_user_by_id/__init__.py @@ -1,2 +1,2 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT +# GENERATED BY INSIGHT-PLUGIN - DO NOT EDIT from .action import GetUserById diff --git a/plugins/pagerduty/komand_pagerduty/actions/get_user_by_id/action.py b/plugins/pagerduty/komand_pagerduty/actions/get_user_by_id/action.py index b1e8956a1d..6a620148c0 100755 --- a/plugins/pagerduty/komand_pagerduty/actions/get_user_by_id/action.py +++ b/plugins/pagerduty/komand_pagerduty/actions/get_user_by_id/action.py @@ -1,9 +1,9 @@ import insightconnect_plugin_runtime -from .schema import GetUserByIdInput, GetUserByIdOutput +from insightconnect_plugin_runtime.exceptions import PluginException +from .schema import GetUserByIdInput, GetUserByIdOutput, Input, Output, Component # Custom imports below -import pypd -from komand_pagerduty.util.util import empty_user, normalize_user +from komand_pagerduty.util.util import normalize_user class GetUserById(insightconnect_plugin_runtime.Action): @@ -16,20 +16,10 @@ def __init__(self): ) def run(self, params={}): - """Get a user by ID""" + user_id = params.get(Input.ID) - if not params["id"]: - raise Exception("id required") + response = self.connection.api.get_user_by_id(user_id=user_id) - user = pypd.User.find_one(id=params["id"]) - if user: - user = normalize_user(user.json) - else: - user = None - - self.logger.debug("Returned: %s", user) - return {"found": not not user, "user": user or empty_user} - - def test(self): - """Test action""" - return {"found": False, "user": empty_user} + if response.get("user"): + normalized_user = normalize_user(response.get("user")) + return {Output.USER: normalized_user} diff --git a/plugins/pagerduty/komand_pagerduty/actions/get_user_by_id/schema.py b/plugins/pagerduty/komand_pagerduty/actions/get_user_by_id/schema.py index 86b3eb65c4..6b5b35d347 100755 --- a/plugins/pagerduty/komand_pagerduty/actions/get_user_by_id/schema.py +++ b/plugins/pagerduty/komand_pagerduty/actions/get_user_by_id/schema.py @@ -1,4 +1,4 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT +# GENERATED BY INSIGHT-PLUGIN - DO NOT EDIT import insightconnect_plugin_runtime import json @@ -9,15 +9,14 @@ class Component: class Input: ID = "id" - + class Output: - FOUND = "found" USER = "user" - + class GetUserByIdInput(insightconnect_plugin_runtime.Input): - schema = json.loads(""" + schema = json.loads(r""" { "type": "object", "title": "Variables", @@ -31,7 +30,8 @@ class GetUserByIdInput(insightconnect_plugin_runtime.Input): }, "required": [ "id" - ] + ], + "definitions": {} } """) @@ -40,22 +40,16 @@ def __init__(self): class GetUserByIdOutput(insightconnect_plugin_runtime.Output): - schema = json.loads(""" + schema = json.loads(r""" { "type": "object", "title": "Variables", "properties": { - "found": { - "type": "boolean", - "title": "Found", - "description": "True if found", - "order": 1 - }, "user": { "$ref": "#/definitions/user", "title": "User", "description": "User", - "order": 2 + "order": 1 } }, "definitions": { @@ -63,51 +57,58 @@ class GetUserByIdOutput(insightconnect_plugin_runtime.Output): "type": "object", "title": "user", "properties": { - "avatar_url": { + "id": { "type": "string", - "title": "Avatar Url", - "description": "Avatar URL", - "order": 9 + "description": "ID", + "order": 1 }, - "color": { + "self": { "type": "string", - "title": "Color", - "description": "Color", - "order": 6 + "description": "URL to view user", + "order": 2 }, - "description": { + "name": { "type": "string", - "title": "Description", - "description": "Description", - "order": 7 + "description": "Name", + "order": 3 }, "email": { "type": "string", - "title": "Email", "description": "Email", "order": 4 }, - "id": { + "summary": { "type": "string", - "title": "Id", - "description": "ID", - "order": 1 + "description": "Summary", + "order": 5 + }, + "color": { + "type": "string", + "description": "Color", + "order": 6 + }, + "description": { + "type": "string", + "description": "Description", + "order": 7 }, "job_title": { "type": "string", - "title": "Job Title", "description": "Job Title", "order": 8 }, - "name": { + "avatar_url": { "type": "string", - "title": "Name", - "description": "Name", - "order": 3 + "description": "Avatar URL", + "order": 9 + }, + "time_zone": { + "type": "string", + "description": "Time Zone, e.g. America/Lima", + "order": 10 }, "role": { "type": "string", - "title": "Role", "description": "Role", "enum": [ "admin", @@ -117,24 +118,6 @@ class GetUserByIdOutput(insightconnect_plugin_runtime.Output): "user" ], "order": 11 - }, - "self": { - "type": "string", - "title": "Self", - "description": "URL to view object", - "order": 2 - }, - "summary": { - "type": "string", - "title": "Summary", - "description": "Summary", - "order": 5 - }, - "time_zone": { - "type": "string", - "title": "Time Zone", - "description": "Time Zone, e.g. America/Lima", - "order": 10 } }, "required": [ diff --git a/plugins/pagerduty/komand_pagerduty/actions/send_acknowledge_event/__init__.py b/plugins/pagerduty/komand_pagerduty/actions/send_acknowledge_event/__init__.py index 522cb4fd46..74103345fd 100755 --- a/plugins/pagerduty/komand_pagerduty/actions/send_acknowledge_event/__init__.py +++ b/plugins/pagerduty/komand_pagerduty/actions/send_acknowledge_event/__init__.py @@ -1,2 +1,2 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT +# GENERATED BY INSIGHT-PLUGIN - DO NOT EDIT from .action import SendAcknowledgeEvent diff --git a/plugins/pagerduty/komand_pagerduty/actions/send_acknowledge_event/action.py b/plugins/pagerduty/komand_pagerduty/actions/send_acknowledge_event/action.py index c3f3ce9bf4..3e815bccab 100755 --- a/plugins/pagerduty/komand_pagerduty/actions/send_acknowledge_event/action.py +++ b/plugins/pagerduty/komand_pagerduty/actions/send_acknowledge_event/action.py @@ -1,8 +1,8 @@ import insightconnect_plugin_runtime -from .schema import SendAcknowledgeEventInput, SendAcknowledgeEventOutput +from insightconnect_plugin_runtime.exceptions import PluginException +from .schema import SendAcknowledgeEventInput, SendAcknowledgeEventOutput, Input, Output, Component # Custom imports below -import pypd class SendAcknowledgeEvent(insightconnect_plugin_runtime.Action): @@ -15,25 +15,12 @@ def __init__(self): ) def run(self, params={}): - """Send acknowledge""" + email = params.get(Input.EMAIL) + incident_id = params.get(Input.INCIDENT_ID) - self.logger.info("Acknowledging: %s", params) - ev = pypd.Event.create( - data={ - "event_type": "acknowledge", - "service_key": params["service_key"], - "incident_key": params["incident_key"], - "description": params.get("description") or "", - "details": params.get("details") or {}, - } + response = self.connection.api.acknowledge_event( + email=email, + incident_id=incident_id, ) - return ev - - def test(self): - """Test action""" - return { - "incident_key": "aebdf1be9793454e86c0f0079820f32f", - "status": "success", - "message": "Event processed", - } + return {Output.INCIDENT: response.get("incident")} diff --git a/plugins/pagerduty/komand_pagerduty/actions/send_acknowledge_event/schema.py b/plugins/pagerduty/komand_pagerduty/actions/send_acknowledge_event/schema.py index f2a5e40f1e..7ed271cd82 100755 --- a/plugins/pagerduty/komand_pagerduty/actions/send_acknowledge_event/schema.py +++ b/plugins/pagerduty/komand_pagerduty/actions/send_acknowledge_event/schema.py @@ -1,4 +1,4 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT +# GENERATED BY INSIGHT-PLUGIN - DO NOT EDIT import insightconnect_plugin_runtime import json @@ -8,53 +8,38 @@ class Component: class Input: - DESCRIPTION = "description" - DETAILS = "details" - INCIDENT_KEY = "incident_key" - SERVICE_KEY = "service_key" - + EMAIL = "email" + INCIDENT_ID = "incident_id" + class Output: - INCIDENT_KEY = "incident_key" - MESSAGE = "message" - STATUS = "status" - + INCIDENT = "incident" + class SendAcknowledgeEventInput(insightconnect_plugin_runtime.Input): - schema = json.loads(""" + schema = json.loads(r""" { "type": "object", "title": "Variables", "properties": { - "description": { + "email": { "type": "string", - "title": "Description", - "description": "Text that will appear in the incident's log associated with this event", - "order": 3 - }, - "details": { - "type": "object", - "title": "Details", - "description": "An arbitrary JSON object containing any data you'd like included in the incident log", - "order": 4 + "title": "Email", + "description": "The email address of a valid user associated with the account making the request", + "order": 1 }, - "incident_key": { + "incident_id": { "type": "string", - "title": "Incident Key", - "description": "Incident Key", + "title": "Incident ID", + "description": "The ID of the incident", "order": 2 - }, - "service_key": { - "type": "string", - "title": "Service Key", - "description": "Service Key (aka Integration Key)", - "order": 1 } }, "required": [ - "incident_key", - "service_key" - ] + "email", + "incident_id" + ], + "definitions": {} } """) @@ -63,29 +48,150 @@ def __init__(self): class SendAcknowledgeEventOutput(insightconnect_plugin_runtime.Output): - schema = json.loads(""" + schema = json.loads(r""" { "type": "object", "title": "Variables", "properties": { - "incident_key": { - "type": "string", - "title": "Incident Key", - "description": "Incident Key", - "order": 3 - }, - "message": { - "type": "string", - "title": "Message", - "description": "Message", - "order": 2 - }, - "status": { - "type": "string", - "title": "Status", - "description": "Status", + "incident": { + "$ref": "#/definitions/incident_output", + "title": "Incident", + "description": "The incident object that was acknowledged", "order": 1 } + }, + "definitions": { + "incident_output": { + "type": "object", + "title": "incident_output", + "properties": { + "id": { + "type": "string", + "description": "The id of the incident", + "order": 1 + }, + "type": { + "type": "string", + "description": "A string that determines the schema of the object", + "order": 2 + }, + "summary": { + "type": "string", + "description": "A short-form, server-generated string that provides succinct, important information about an object suitable for primary labeling of an entity in a client. In many cases, this will be identical to name, though it is not intended to be an identifier", + "order": 3 + }, + "self": { + "type": "string", + "description": "The API show URL at which the object is accessible", + "order": 4 + }, + "html_url": { + "type": "string", + "description": "A URL at which the entity is uniquely displayed in the Web app", + "order": 5 + }, + "incident_number": { + "description": "The number of the incident. This is unique across your account.", + "order": 6 + }, + "title": { + "type": "string", + "description": "A succinct description of the nature, symptoms, cause, or effect of the incident", + "order": 7 + }, + "created_at": { + "type": "string", + "description": "The time the incident was first triggered", + "order": 8 + }, + "updated_at": { + "type": "string", + "description": "The time the incident was last modified", + "order": 9 + }, + "status": { + "type": "string", + "description": "The current status of the incident", + "order": 10 + }, + "incident_key": { + "type": "string", + "description": "The incident's de-duplication key", + "order": 11 + }, + "service": { + "type": "object", + "description": "The service the incident is on. If the include[]=services query parameter is provided, the full service definition will be returned", + "order": 12 + }, + "assignments": { + "description": "Which accounts the incident will be assigned to", + "order": 13 + }, + "assigned_via": { + "type": "string", + "description": "How the current incident assignments were decided. Note that direct_assignment incidents will not escalate up the attached escalation_policy", + "order": 14 + }, + "last_status_change_at": { + "type": "string", + "description": "The time the status of the incident last changed. If the incident is not currently acknowledged or resolved, this will be the incident's updated_at", + "order": 15 + }, + "first_trigger_log_entry": { + "type": "object", + "description": "The first log entry on the incident. The log entry will be of type TriggerLogEntry and will represent information about how the incident was triggered. If the include[]=first_trigger_log_entries query parameter is provided, the full log entry definition will be returned", + "order": 16 + }, + "alert_counts": { + "type": "object", + "description": "The counts of alerts grouped into this incident", + "order": 17 + }, + "is_mergeable": { + "type": "boolean", + "description": "Whether the incident is mergeable. Only incidents that have alerts, or that are manually created can be merged", + "order": 18 + }, + "escalation_policy": { + "type": "object", + "description": "The escalation policy attached to the service that the incident is on. If the include[]=escalation_policies query parameter is provided, the full escalation policy definition will be returned", + "order": 19 + }, + "teams": { + "description": "Teams that the alert is assigned to", + "order": 20 + }, + "pending_actions": { + "description": "The list of pending_actions on the incident. A pending_action object contains a type of action which can be escalate, unacknowledge, resolve or urgency_change. A pending_action object contains at, the time at which the action will take place. An urgency_change pending_action will contain to, the urgency that the incident will change to", + "order": 21 + }, + "acknowledgements": { + "description": "List of all acknowledgements for this incident. This list will be empty if the Incident.status is resolved or triggered. If the include[]=acknowledgers query parameter is provided, the full user or service definitions will be returned for each acknowledgement entry", + "order": 22 + }, + "last_status_change_by": { + "type": "object", + "description": "The agent (user, service or integration) that created or modified the Incident Log Entry", + "order": 23 + }, + "priority": { + "type": "object", + "description": "The priority of the object", + "order": 24 + }, + "conference_bridge": { + "type": "object", + "description": "The conference bridge information attached to the incident. Only returned if the include[]=conference_bridge query parameter is provided", + "order": 25 + }, + "urgency": { + "type": "string", + "description": "The current urgency of the incident", + "order": 26 + } + } + } } } """) diff --git a/plugins/pagerduty/komand_pagerduty/actions/send_resolve_event/__init__.py b/plugins/pagerduty/komand_pagerduty/actions/send_resolve_event/__init__.py index a700eb8d43..78beacf529 100755 --- a/plugins/pagerduty/komand_pagerduty/actions/send_resolve_event/__init__.py +++ b/plugins/pagerduty/komand_pagerduty/actions/send_resolve_event/__init__.py @@ -1,2 +1,2 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT +# GENERATED BY INSIGHT-PLUGIN - DO NOT EDIT from .action import SendResolveEvent diff --git a/plugins/pagerduty/komand_pagerduty/actions/send_resolve_event/action.py b/plugins/pagerduty/komand_pagerduty/actions/send_resolve_event/action.py index f7718e97df..d5f1be6cee 100755 --- a/plugins/pagerduty/komand_pagerduty/actions/send_resolve_event/action.py +++ b/plugins/pagerduty/komand_pagerduty/actions/send_resolve_event/action.py @@ -1,8 +1,8 @@ import insightconnect_plugin_runtime -from .schema import SendResolveEventInput, SendResolveEventOutput +from insightconnect_plugin_runtime.exceptions import PluginException +from .schema import SendResolveEventInput, SendResolveEventOutput, Input, Output, Component # Custom imports below -import pypd class SendResolveEvent(insightconnect_plugin_runtime.Action): @@ -15,20 +15,12 @@ def __init__(self): ) def run(self, params={}): - """Resolve event""" + email = params.get(Input.EMAIL) + incident_id = params.get(Input.INCIDENT_ID) - ev = pypd.Event.create( - data={ - "service_key": params["service_key"], - "event_type": "resolve", - "incident_key": params["incident_key"], - "description": params.get("description"), - "details": params.get("details"), - } + response = self.connection.api.resolve_event( + email=email, + incident_id=incident_id, ) - return ev - - def test(self): - """Test action""" - return {} + return {Output.INCIDENT: response.get("incident")} diff --git a/plugins/pagerduty/komand_pagerduty/actions/send_resolve_event/schema.py b/plugins/pagerduty/komand_pagerduty/actions/send_resolve_event/schema.py index 4c87bbb92d..74802f18f0 100755 --- a/plugins/pagerduty/komand_pagerduty/actions/send_resolve_event/schema.py +++ b/plugins/pagerduty/komand_pagerduty/actions/send_resolve_event/schema.py @@ -1,4 +1,4 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT +# GENERATED BY INSIGHT-PLUGIN - DO NOT EDIT import insightconnect_plugin_runtime import json @@ -8,53 +8,39 @@ class Component: class Input: - DESCRIPTION = "description" - DETAILS = "details" - INCIDENT_KEY = "incident_key" - SERVICE_KEY = "service_key" - + EMAIL = "email" + INCIDENT_ID = "incident_id" + RESOLVE_MESSAGE = "resolve_message" + class Output: - INCIDENT_KEY = "incident_key" - MESSAGE = "message" - STATUS = "status" - + INCIDENT = "incident" + class SendResolveEventInput(insightconnect_plugin_runtime.Input): - schema = json.loads(""" + schema = json.loads(r""" { "type": "object", "title": "Variables", "properties": { - "description": { + "email": { "type": "string", - "title": "Description", - "description": "Text that will appear in the incident's log associated with this event", - "order": 3 - }, - "details": { - "type": "object", - "title": "Details", - "description": "An arbitrary JSON object containing any data you'd like included in the incident log", - "order": 4 + "title": "Email", + "description": "The email address of a valid user associated with the account making the request", + "order": 1 }, - "incident_key": { + "incident_id": { "type": "string", - "title": "Incident Key", - "description": "Incident Key", + "title": "Incident ID", + "description": "The ID of the incident", "order": 2 - }, - "service_key": { - "type": "string", - "title": "Service Key", - "description": "Service Key (aka Integration Key)", - "order": 1 } }, "required": [ - "incident_key", - "service_key" - ] + "email", + "incident_id" + ], + "definitions": {} } """) @@ -63,29 +49,150 @@ def __init__(self): class SendResolveEventOutput(insightconnect_plugin_runtime.Output): - schema = json.loads(""" + schema = json.loads(r""" { "type": "object", "title": "Variables", "properties": { - "incident_key": { - "type": "string", - "title": "Incident Key", - "description": "Incident Key", - "order": 3 - }, - "message": { - "type": "string", - "title": "Message", - "description": "Message", - "order": 2 - }, - "status": { - "type": "string", - "title": "Status", - "description": "Status", + "incident": { + "$ref": "#/definitions/incident_output", + "title": "Incident", + "description": "The incident object that was resolved", "order": 1 } + }, + "definitions": { + "incident_output": { + "type": "object", + "title": "incident_output", + "properties": { + "id": { + "type": "string", + "description": "The id of the incident", + "order": 1 + }, + "type": { + "type": "string", + "description": "A string that determines the schema of the object", + "order": 2 + }, + "summary": { + "type": "string", + "description": "A short-form, server-generated string that provides succinct, important information about an object suitable for primary labeling of an entity in a client. In many cases, this will be identical to name, though it is not intended to be an identifier", + "order": 3 + }, + "self": { + "type": "string", + "description": "The API show URL at which the object is accessible", + "order": 4 + }, + "html_url": { + "type": "string", + "description": "A URL at which the entity is uniquely displayed in the Web app", + "order": 5 + }, + "incident_number": { + "description": "The number of the incident. This is unique across your account.", + "order": 6 + }, + "title": { + "type": "string", + "description": "A succinct description of the nature, symptoms, cause, or effect of the incident", + "order": 7 + }, + "created_at": { + "type": "string", + "description": "The time the incident was first triggered", + "order": 8 + }, + "updated_at": { + "type": "string", + "description": "The time the incident was last modified", + "order": 9 + }, + "status": { + "type": "string", + "description": "The current status of the incident", + "order": 10 + }, + "incident_key": { + "type": "string", + "description": "The incident's de-duplication key", + "order": 11 + }, + "service": { + "type": "object", + "description": "The service the incident is on. If the include[]=services query parameter is provided, the full service definition will be returned", + "order": 12 + }, + "assignments": { + "description": "Which accounts the incident will be assigned to", + "order": 13 + }, + "assigned_via": { + "type": "string", + "description": "How the current incident assignments were decided. Note that direct_assignment incidents will not escalate up the attached escalation_policy", + "order": 14 + }, + "last_status_change_at": { + "type": "string", + "description": "The time the status of the incident last changed. If the incident is not currently acknowledged or resolved, this will be the incident's updated_at", + "order": 15 + }, + "first_trigger_log_entry": { + "type": "object", + "description": "The first log entry on the incident. The log entry will be of type TriggerLogEntry and will represent information about how the incident was triggered. If the include[]=first_trigger_log_entries query parameter is provided, the full log entry definition will be returned", + "order": 16 + }, + "alert_counts": { + "type": "object", + "description": "The counts of alerts grouped into this incident", + "order": 17 + }, + "is_mergeable": { + "type": "boolean", + "description": "Whether the incident is mergeable. Only incidents that have alerts, or that are manually created can be merged", + "order": 18 + }, + "escalation_policy": { + "type": "object", + "description": "The escalation policy attached to the service that the incident is on. If the include[]=escalation_policies query parameter is provided, the full escalation policy definition will be returned", + "order": 19 + }, + "teams": { + "description": "Teams that the alert is assigned to", + "order": 20 + }, + "pending_actions": { + "description": "The list of pending_actions on the incident. A pending_action object contains a type of action which can be escalate, unacknowledge, resolve or urgency_change. A pending_action object contains at, the time at which the action will take place. An urgency_change pending_action will contain to, the urgency that the incident will change to", + "order": 21 + }, + "acknowledgements": { + "description": "List of all acknowledgements for this incident. This list will be empty if the Incident.status is resolved or triggered. If the include[]=acknowledgers query parameter is provided, the full user or service definitions will be returned for each acknowledgement entry", + "order": 22 + }, + "last_status_change_by": { + "type": "object", + "description": "The agent (user, service or integration) that created or modified the Incident Log Entry", + "order": 23 + }, + "priority": { + "type": "object", + "description": "The priority of the object", + "order": 24 + }, + "conference_bridge": { + "type": "object", + "description": "The conference bridge information attached to the incident. Only returned if the include[]=conference_bridge query parameter is provided", + "order": 25 + }, + "urgency": { + "type": "string", + "description": "The current urgency of the incident", + "order": 26 + } + } + } } } """) diff --git a/plugins/pagerduty/komand_pagerduty/actions/send_trigger_event/__init__.py b/plugins/pagerduty/komand_pagerduty/actions/send_trigger_event/__init__.py index 685b8d2fdf..07465aebb6 100755 --- a/plugins/pagerduty/komand_pagerduty/actions/send_trigger_event/__init__.py +++ b/plugins/pagerduty/komand_pagerduty/actions/send_trigger_event/__init__.py @@ -1,2 +1,2 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT +# GENERATED BY INSIGHT-PLUGIN - DO NOT EDIT from .action import SendTriggerEvent diff --git a/plugins/pagerduty/komand_pagerduty/actions/send_trigger_event/action.py b/plugins/pagerduty/komand_pagerduty/actions/send_trigger_event/action.py old mode 100755 new mode 100644 index 56825b3606..0e47713dc1 --- a/plugins/pagerduty/komand_pagerduty/actions/send_trigger_event/action.py +++ b/plugins/pagerduty/komand_pagerduty/actions/send_trigger_event/action.py @@ -1,8 +1,8 @@ import insightconnect_plugin_runtime -from .schema import SendTriggerEventInput, SendTriggerEventOutput +from insightconnect_plugin_runtime.exceptions import PluginException +from .schema import SendTriggerEventInput, SendTriggerEventOutput, Input, Output, Component # Custom import below -import pypd class SendTriggerEvent(insightconnect_plugin_runtime.Action): @@ -15,25 +15,37 @@ def __init__(self): ) def run(self, params={}): - """Trigger event""" - ev = pypd.Event.create( - data={ - "service_key": params["service_key"], - "event_type": "trigger", - "description": params["description"], - "contexts": params.get("contexts"), - "details": params.get("details"), - "client": params.get("client"), - "client_url": params.get("client_url"), - } - ) + # required + email = params.get(Input.EMAIL) + title = params.get(Input.TITLE) + service = params.get(Input.SERVICE, {}) + + # optional - return ev + escalation_policy = params.get(Input.ESCALATION_POLICY, {}) + assignments = params.get(Input.ASSIGNMENTS, []) - def test(self): - """Test event""" - return { - "incident_key": "aebdf1be9793454e86c0f0079820f32f", - "status": "success", - "message": "Event processed", + dict_of_optional_fields = { + "urgency": params.get(Input.URGENCY, ""), + "incident_key": params.get(Input.INCIDENT_KEY, ""), + "priority": params.get(Input.PRIORITY, {}), + "escalation_policy": escalation_policy, + "conference_bridge": params.get(Input.CONFERENCE_BRIDGE, {}), + "body": params.get(Input.BODY, {}), + "assignments": assignments, } + + if escalation_policy and assignments: + self.logger.warning( + "Invalid input only one of 'escalation_policy' or 'assignments' can be used at one time" + ) + raise PluginException( + cause="Invalid paramaters", + assistance="Invalid input only one of 'escalation_policy' or 'assignments' can be used at one time", + ) + + response = self.connection.api.trigger_event( + email=email, title=title, service=service, dict_of_optional_fields=dict_of_optional_fields + ) + + return {Output.INCIDENT: response.get("incident")} diff --git a/plugins/pagerduty/komand_pagerduty/actions/send_trigger_event/schema.py b/plugins/pagerduty/komand_pagerduty/actions/send_trigger_event/schema.py index 0eb29d09a9..03403fd21d 100755 --- a/plugins/pagerduty/komand_pagerduty/actions/send_trigger_event/schema.py +++ b/plugins/pagerduty/komand_pagerduty/actions/send_trigger_event/schema.py @@ -1,4 +1,4 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT +# GENERATED BY INSIGHT-PLUGIN - DO NOT EDIT import insightconnect_plugin_runtime import json @@ -8,70 +8,222 @@ class Component: class Input: - CLIENT = "client" - CLIENT_URL = "client_url" - CONTEXTS = "contexts" - DESCRIPTION = "description" - DETAILS = "details" - SERVICE_KEY = "service_key" - + ASSIGNMENTS = "assignments" + BODY = "body" + CONFERENCE_BRIDGE = "conference_bridge" + EMAIL = "email" + ESCALATION_POLICY = "escalation_policy" + INCIDENT_KEY = "incident_key" + PRIORITY = "priority" + SERVICE = "service" + TITLE = "title" + URGENCY = "urgency" + class Output: - INCIDENT_KEY = "incident_key" - MESSAGE = "message" - STATUS = "status" - + INCIDENT = "incident" + class SendTriggerEventInput(insightconnect_plugin_runtime.Input): - schema = json.loads(""" + schema = json.loads(r""" { "type": "object", "title": "Variables", "properties": { - "client": { - "type": "string", - "title": "Client", - "description": "The name of the monitoring client that is triggering this event", - "order": 4 - }, - "client_url": { - "type": "string", - "title": "Client URL", - "description": "The URL of the monitoring client that is triggering this event", - "order": 5 - }, - "contexts": { + "assignments": { "type": "array", - "title": "Contexts", - "description": "Additional context objects", + "title": "Assignments", + "description": "Assign the incident to these assignees. Cannot be specified if an escalation policy is given", "items": { - "type": "object" + "$ref": "#/definitions/assignee" }, + "order": 8 + }, + "body": { + "$ref": "#/definitions/body_input", + "title": "Body", + "description": "Details to be added to the incident body", "order": 6 }, - "description": { + "conference_bridge": { + "$ref": "#/definitions/conference_bridge_input", + "title": "Conference Bridge", + "description": "The conference bridge information attached to the incident. Only returned if the include[]=conference_bridge query parameter is provided", + "order": 10 + }, + "email": { "type": "string", - "title": "Description", - "description": "Text that will appear in the incident's log associated with this event", - "order": 2 + "title": "Email", + "description": "The email address of a valid user associated with the account making the request", + "order": 1 }, - "details": { - "type": "object", - "title": "Details", - "description": "An arbitrary JSON object containing any data you'd like included in the incident log", + "escalation_policy": { + "$ref": "#/definitions/escalation_policy_input", + "title": "Escalation Policy", + "description": "Assign the incident to this escalation policy. Cannot be specified if Assignments given", + "order": 9 + }, + "incident_key": { + "type": "string", + "title": "Incident Key", + "description": "A string which identifies the incident. Sending subsequent requests referencing the same service and with the same incident_key will result in those requests being rejected if an open incident matches that incident_key", + "order": 7 + }, + "priority": { + "$ref": "#/definitions/priority_input", + "title": "Priority", + "description": "The priority that the incident is to be set to", + "order": 4 + }, + "service": { + "$ref": "#/definitions/service_input", + "title": "Service", + "description": "The service that the incident is related to", "order": 3 }, - "service_key": { + "title": { "type": "string", - "title": "Service Key", - "description": "Service Key (aka Integration Key)", - "order": 1 + "title": "Title", + "description": "A description of the nature, symptoms, cause, or effect of the incident", + "order": 2 + }, + "urgency": { + "type": "string", + "title": "Urgency", + "description": "The urgency that the incident is to be set to", + "order": 5 } }, "required": [ - "description", - "service_key" - ] + "email", + "title", + "service" + ], + "definitions": { + "service_input": { + "type": "object", + "title": "service_input", + "properties": { + "id": { + "type": "string", + "description": "The id of the service that the incident is related to", + "order": 1 + }, + "type": { + "type": "string", + "description": "The type of the service that the incident is related to", + "order": 2 + } + }, + "required": [ + "id", + "type" + ] + }, + "priority_input": { + "type": "object", + "title": "priority_input", + "properties": { + "id": { + "type": "string", + "description": "The id of the priority that the incident is to be set to", + "order": 1 + }, + "type": { + "type": "string", + "description": "The type of the priority that the incident is to be set to", + "order": 2 + } + }, + "required": [ + "id", + "type" + ] + }, + "body_input": { + "type": "object", + "title": "body_input", + "properties": { + "details": { + "type": "string", + "description": "The id of the priority that the incident is to be set to", + "order": 1 + }, + "type": { + "type": "string", + "description": "The type of the body is to be added to", + "order": 2 + } + }, + "required": [ + "details", + "type" + ] + }, + "assignee": { + "type": "object", + "title": "assignee", + "properties": { + "id": { + "type": "string", + "description": "The id of the user that the new incident will be assigned to", + "order": 1 + }, + "type": { + "type": "string", + "description": "A string that determines the schema of the object.", + "order": 2 + } + } + }, + "escalation_policy_input": { + "type": "object", + "title": "escalation_policy_input", + "properties": { + "id": { + "type": "string", + "description": "The id of the escalation policy that the new incident will be assigned to", + "order": 1 + }, + "type": { + "type": "string", + "description": "A string that determines the schema of the object.", + "order": 2 + }, + "summary": { + "type": "string", + "description": "A short-form, server-generated string that provides succinct, important information about an object", + "order": 3 + }, + "self": { + "type": "string", + "description": "The API show URL at which the object is accessible", + "order": 4 + }, + "html_url": { + "type": "string", + "description": "A URL at which the entity is uniquely displayed in the Web app", + "order": 5 + } + } + }, + "conference_bridge_input": { + "type": "object", + "title": "conference_bridge_input", + "properties": { + "conference_number": { + "type": "string", + "description": "The phone number of the conference call for the conference bridge. Phone numbers should be formatted like +1 415-555-1212,,,,1234#, where a comma (,) represents a one-second wait and pound (#) completes access code input", + "order": 1 + }, + "conference_url": { + "type": "string", + "description": "A URL for the conference bridge. This could be a link to a web conference or Slack channel", + "order": 2 + } + } + } + } } """) @@ -80,29 +232,150 @@ def __init__(self): class SendTriggerEventOutput(insightconnect_plugin_runtime.Output): - schema = json.loads(""" + schema = json.loads(r""" { "type": "object", "title": "Variables", "properties": { - "incident_key": { - "type": "string", - "title": "Incident Key", - "description": "Incident Key", - "order": 3 - }, - "message": { - "type": "string", - "title": "Message", - "description": "Message", - "order": 2 - }, - "status": { - "type": "string", - "title": "Status", - "description": "Status", + "incident": { + "$ref": "#/definitions/incident_output", + "title": "Incident", + "description": "The incident object that was created", "order": 1 } + }, + "definitions": { + "incident_output": { + "type": "object", + "title": "incident_output", + "properties": { + "id": { + "type": "string", + "description": "The id of the incident", + "order": 1 + }, + "type": { + "type": "string", + "description": "A string that determines the schema of the object", + "order": 2 + }, + "summary": { + "type": "string", + "description": "A short-form, server-generated string that provides succinct, important information about an object suitable for primary labeling of an entity in a client. In many cases, this will be identical to name, though it is not intended to be an identifier", + "order": 3 + }, + "self": { + "type": "string", + "description": "The API show URL at which the object is accessible", + "order": 4 + }, + "html_url": { + "type": "string", + "description": "A URL at which the entity is uniquely displayed in the Web app", + "order": 5 + }, + "incident_number": { + "description": "The number of the incident. This is unique across your account.", + "order": 6 + }, + "title": { + "type": "string", + "description": "A succinct description of the nature, symptoms, cause, or effect of the incident", + "order": 7 + }, + "created_at": { + "type": "string", + "description": "The time the incident was first triggered", + "order": 8 + }, + "updated_at": { + "type": "string", + "description": "The time the incident was last modified", + "order": 9 + }, + "status": { + "type": "string", + "description": "The current status of the incident", + "order": 10 + }, + "incident_key": { + "type": "string", + "description": "The incident's de-duplication key", + "order": 11 + }, + "service": { + "type": "object", + "description": "The service the incident is on. If the include[]=services query parameter is provided, the full service definition will be returned", + "order": 12 + }, + "assignments": { + "description": "Which accounts the incident will be assigned to", + "order": 13 + }, + "assigned_via": { + "type": "string", + "description": "How the current incident assignments were decided. Note that direct_assignment incidents will not escalate up the attached escalation_policy", + "order": 14 + }, + "last_status_change_at": { + "type": "string", + "description": "The time the status of the incident last changed. If the incident is not currently acknowledged or resolved, this will be the incident's updated_at", + "order": 15 + }, + "first_trigger_log_entry": { + "type": "object", + "description": "The first log entry on the incident. The log entry will be of type TriggerLogEntry and will represent information about how the incident was triggered. If the include[]=first_trigger_log_entries query parameter is provided, the full log entry definition will be returned", + "order": 16 + }, + "alert_counts": { + "type": "object", + "description": "The counts of alerts grouped into this incident", + "order": 17 + }, + "is_mergeable": { + "type": "boolean", + "description": "Whether the incident is mergeable. Only incidents that have alerts, or that are manually created can be merged", + "order": 18 + }, + "escalation_policy": { + "type": "object", + "description": "The escalation policy attached to the service that the incident is on. If the include[]=escalation_policies query parameter is provided, the full escalation policy definition will be returned", + "order": 19 + }, + "teams": { + "description": "Teams that the alert is assigned to", + "order": 20 + }, + "pending_actions": { + "description": "The list of pending_actions on the incident. A pending_action object contains a type of action which can be escalate, unacknowledge, resolve or urgency_change. A pending_action object contains at, the time at which the action will take place. An urgency_change pending_action will contain to, the urgency that the incident will change to", + "order": 21 + }, + "acknowledgements": { + "description": "List of all acknowledgements for this incident. This list will be empty if the Incident.status is resolved or triggered. If the include[]=acknowledgers query parameter is provided, the full user or service definitions will be returned for each acknowledgement entry", + "order": 22 + }, + "last_status_change_by": { + "type": "object", + "description": "The agent (user, service or integration) that created or modified the Incident Log Entry", + "order": 23 + }, + "priority": { + "type": "object", + "description": "The priority of the object", + "order": 24 + }, + "conference_bridge": { + "type": "object", + "description": "The conference bridge information attached to the incident. Only returned if the include[]=conference_bridge query parameter is provided", + "order": 25 + }, + "urgency": { + "type": "string", + "description": "The current urgency of the incident", + "order": 26 + } + } + } } } """) diff --git a/plugins/pagerduty/komand_pagerduty/connection/__init__.py b/plugins/pagerduty/komand_pagerduty/connection/__init__.py index a515dcf6b0..c78d3356be 100755 --- a/plugins/pagerduty/komand_pagerduty/connection/__init__.py +++ b/plugins/pagerduty/komand_pagerduty/connection/__init__.py @@ -1,2 +1,2 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT +# GENERATED BY INSIGHT-PLUGIN - DO NOT EDIT from .connection import Connection diff --git a/plugins/pagerduty/komand_pagerduty/connection/connection.py b/plugins/pagerduty/komand_pagerduty/connection/connection.py index ed09eaa7f1..d6a35b904d 100755 --- a/plugins/pagerduty/komand_pagerduty/connection/connection.py +++ b/plugins/pagerduty/komand_pagerduty/connection/connection.py @@ -1,12 +1,9 @@ import insightconnect_plugin_runtime -from .schema import ConnectionSchema +from .schema import ConnectionSchema, Input # Custom imports below -import pypd -import requests -from komand_pagerduty.util.async_requests import AsyncRequests -from insightconnect_plugin_runtime.exceptions import ConnectionTestException from komand_pagerduty.util.api import PagerDutyAPI +from insightconnect_plugin_runtime.exceptions import PluginException, ConnectionTestException class Connection(insightconnect_plugin_runtime.Connection): @@ -19,26 +16,12 @@ def connect(self, params={}): Connect to PagerDuty """ - key = params.get("api_key").get("secretKey") - pypd.api_key = key - pypd.Incident.find(maximum=1) - + key = params.get(Input.API_KEY, {}).get("secretKey") self.api = PagerDutyAPI(api_key=key, logger=self.logger) - self.api_connection = requests.Session() - headers = {"Authorization": f"Token token={key}"} - self.api_connection.headers = headers - - self.async_connection = AsyncRequests(api_key=key) - def test(self): - response = self.api_connection.get("https://api.pagerduty.com/users") try: - response.raise_for_status() - except Exception as e: - raise ConnectionTestException( - cause="Connection Test Failed", - assistance="Please check your API key. " "See the following for more information.", - data=str(e), - ) - return {"success": True} + self.api.list_users() + return {"success": True} + except PluginException as error: + raise ConnectionTestException(cause=error.cause, assistance=error.assistance, data=error.data) diff --git a/plugins/pagerduty/komand_pagerduty/connection/schema.py b/plugins/pagerduty/komand_pagerduty/connection/schema.py index 7fa81861d8..757f495670 100755 --- a/plugins/pagerduty/komand_pagerduty/connection/schema.py +++ b/plugins/pagerduty/komand_pagerduty/connection/schema.py @@ -1,14 +1,14 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT +# GENERATED BY INSIGHT-PLUGIN - DO NOT EDIT import insightconnect_plugin_runtime import json class Input: API_KEY = "api_key" - + class ConnectionSchema(insightconnect_plugin_runtime.Input): - schema = json.loads(""" + schema = json.loads(r""" { "type": "object", "title": "Variables", @@ -29,18 +29,18 @@ class ConnectionSchema(insightconnect_plugin_runtime.Input): "type": "object", "title": "Credential: Secret Key", "description": "A shared secret key", + "required": [ + "secretKey" + ], "properties": { "secretKey": { "type": "string", "title": "Secret Key", - "displayType": "password", "description": "The shared secret key", - "format": "password" + "format": "password", + "displayType": "password" } - }, - "required": [ - "secretKey" - ] + } } } } diff --git a/plugins/pagerduty/komand_pagerduty/tasks/__init__.py b/plugins/pagerduty/komand_pagerduty/tasks/__init__.py new file mode 100644 index 0000000000..7020c9a4ad --- /dev/null +++ b/plugins/pagerduty/komand_pagerduty/tasks/__init__.py @@ -0,0 +1,2 @@ +# GENERATED BY INSIGHT-PLUGIN - DO NOT EDIT + diff --git a/plugins/pagerduty/komand_pagerduty/triggers/__init__.py b/plugins/pagerduty/komand_pagerduty/triggers/__init__.py index bace8db897..7020c9a4ad 100755 --- a/plugins/pagerduty/komand_pagerduty/triggers/__init__.py +++ b/plugins/pagerduty/komand_pagerduty/triggers/__init__.py @@ -1 +1,2 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT +# GENERATED BY INSIGHT-PLUGIN - DO NOT EDIT + diff --git a/plugins/pagerduty/komand_pagerduty/util/api.py b/plugins/pagerduty/komand_pagerduty/util/api.py index 1b68db159a..9f035caadf 100644 --- a/plugins/pagerduty/komand_pagerduty/util/api.py +++ b/plugins/pagerduty/komand_pagerduty/util/api.py @@ -1,51 +1,215 @@ from insightconnect_plugin_runtime.helper import clean from insightconnect_plugin_runtime.exceptions import PluginException, ConnectionTestException from logging import Logger +from typing import Union import requests import json class PagerDutyAPI: def __init__(self, api_key: str, logger: Logger): - self.headers = {"Authorization": f"Token token={api_key}", "Content-Type": "application/json"} + self.headers = { + "Authorization": f"Token token={api_key}", + "Content-Type": "application/json", + "Accept": "application/json", + } self.session = requests.session() self.logger = logger - def get_on_calls(self, schedule_id: str = None) -> dict: - params = {"limit": 100} - if schedule_id: - params = {"schedule_ids[]": schedule_id} - return self.send_request("GET", "/oncalls", params) + def get_on_calls(self, schedule_id: str) -> dict: + """ + Formats the request to fetch the on-call users for a given schedule + + :param str schedule_id: The id of the schedule that the user info will be fetched for + :return dict: The Schedule object that is returend from the pagerduty api + """ + + return self.send_request("GET", f"/schedules/{schedule_id}/") + + def resolve_event(self, email: str, incident_id: str) -> dict: + """ + Formats the request to call for an incident to be resolved + + :param str email: The email address of the user that is resolving the event + :param str incident_id: The id of the incident to be resolved + :return dict: The full incident object with its updated values will be returend + """ + data = {"incident": {"type": "incident", "status": "resolved"}} + return self.send_request( + method="PUT", path=f"/incidents/{incident_id}/", data=json.dumps(data), from_email=email + ) + + def acknowledge_event(self, email: str, incident_id: str) -> dict: + """ + Formats the request to call for an incident to be acknowledged + + :param str email: The email address of the user that is acknowledging the event + :param str incident_id: The id of the incident to be acknowledged + :return dict: The full incident object with its updated values will be returend + """ + data = {"incident": {"type": "incident", "status": "acknowledged"}} + return self.send_request( + method="PUT", path=f"/incidents/{incident_id}/", data=json.dumps(data), from_email=email + ) + + def trigger_event( + self, + email: str, + title: str, + service: dict, + dict_of_optional_fields: dict, + ) -> dict: + """ + Formats the request to allow the user to trigger an incident + + :param str email: The email of the user triggering the event + :param str title: The title of the description + :param dict service: The service id and the type that will be incident will be associated to + :param dict dict_of_optional_fields: Optional fields that can also be added to an incident, these can include: + [urgency, incident_key, priority, escalation_policy, conference_bridge, body, assignments] + :return dict: This will return the full object of the newly created incident + """ + payload = {"incident": {"type": "incident", "title": title, "service": service}} + + for key, value in dict_of_optional_fields.items(): + if value: + payload["incident"][key] = value + + return self.send_request(method="POST", path="/incidents/", payload=payload, from_email=email) + + def create_user( + self, + from_email: str, + new_users_email: str, + name: str, + dict_of_optional_fields: dict, + ) -> dict: + """ + Formats the request to all for a new user to be created + + :param str from_email: The email for the account that is creating the new user + :param str new_users_email: The email for the new account + :param str name: The name for the new account + :param dict dict_of_optional_fields: Optional fields that can also be used when creating a new user, these include: + [time_zone, color, role, description, job_title, license] + :return dict: The newly cerated user object + """ + payload = {"user": {"name": name, "email": new_users_email}} + + for key, value in dict_of_optional_fields.items(): + if value: + payload["user"][key] = value + + return self.send_request(method="POST", path="/users/", payload=payload, from_email=from_email) + + def delete_user_by_id(self, email: str, user_id: str) -> bool: + """ + Formats the request to allow for a user to be deleted + + :param str email: The email of the user that is deleting the account + :param str user_id: The id of the user that is to be deleted + :return bool: True if the user has been deleted + """ + return self.send_request(method="DELETE", path=f"/users/{user_id}/", from_email=email) + + def get_user_by_id(self, user_id: str) -> dict: + """ + formats the request to allow for the information of a user to be fetched + + :param str user_id: The id of the user to get information on + :return dict: The information on the user + """ + return self.send_request(method="GET", path=f"/users/{user_id}/") + + def get_user_by_email(self, user_email: str) -> dict: + """ + formats the request to allow for the information of a user to be fetched + + :param str user_email: The email address of the user to get information on + :return dict: The information on the user + """ + params = {"query": user_email} + return self.send_request(method="GET", path="/users/", params=params) + + def list_users(self) -> dict: + """ + Formats the request to get a list of all of the users in pagerduty + + + :return dict: This will return a list of user objects + """ + return self.send_request(method="GET", path="/users/") + + def send_request( + self, + method: str, + path: str, + params: dict = None, + payload: dict = None, + headers: dict = None, + data: dict = None, + from_email: str = "", + ) -> Union[dict, bool]: + """ + A wrapper with error handling for making requests to the pager duty api + + :param str method: The type of request that will be made + :param str path: The path that will be appended to the base url + :param dict params: Any paramaters that will be added to the request, defaults to None + :param dict payload: Any data that will be added to the json section of the request, defaults to None + :param dict headers: Any additional headers that will be added to the request, defaults to None + :param dict data: Any data that will be added to the data section of the request, defaults to None + :raises PluginException: If there is an error connecting to the pager duty api or else if there is no valid data returned + :return Union[dict, bool]: + dict: The response of the request in json format + bool: If the delete request is called then there will be no data returned from the api, so we return True + """ + + # in the case that the from email is added, we need to update a new headers var and not self.headers + if not headers: + headers = {} + headers.update(self.headers) + + if from_email: + headers.update({"From": f"{from_email}"}) - def send_request(self, method: str, path: str, params: dict = None, payload: dict = None) -> dict: try: response = self.session.request( method.upper(), "https://api.pagerduty.com" + path, params=params, json=payload, - headers=self.headers, + headers=headers, + data=data, ) - if response.status_code == 401: - raise PluginException(preset=PluginException.Preset.USERNAME_PASSWORD, data=response.text) - if response.status_code == 403: - raise PluginException(preset=PluginException.Preset.API_KEY, data=response.text) - if response.status_code == 404: - raise PluginException(preset=PluginException.Preset.NOT_FOUND, data=response.text) - if 400 <= response.status_code < 500: - raise PluginException( - preset=PluginException.Preset.UNKNOWN, - data=response.text, - ) - if response.status_code >= 500: - raise PluginException(preset=PluginException.Preset.SERVER_ERROR, data=response.text) - + if response.status_code == 204: + return True if 200 <= response.status_code < 300: return clean(json.loads(response.content)) - raise PluginException(preset=PluginException.Preset.UNKNOWN, data=response.text) - except json.decoder.JSONDecodeError as e: - raise PluginException(preset=PluginException.Preset.INVALID_JSON, data=e) - except requests.exceptions.HTTPError as e: - raise PluginException(preset=PluginException.Preset.UNKNOWN, data=e) + self._check_status_code(response) + except requests.exceptions.HTTPError as error: + raise PluginException(preset=PluginException.Preset.UNKNOWN, data=error) + + def _check_status_code(self, response: dict): + """ + This will check the status code of the response and the appropriate error message based on the status code will be raised as a PluginError + + :param dict response: The response object to be checked + :raises PluginException: PluginException: The PluginException error will be raised and based on the status code the error messaged will be set, this is based on a set of predefined messages in the insightconnect_plugin_runtime.exceptions class + """ + if response.status_code == 401: + raise PluginException(preset=PluginException.Preset.UNAUTHORIZED, data=response.text) + if response.status_code == 403: + raise PluginException(preset=PluginException.Preset.API_KEY, data=response.text) + if response.status_code == 404: + raise PluginException(preset=PluginException.Preset.NOT_FOUND, data=response.text) + if 400 <= response.status_code < 500: + raise PluginException( + preset=PluginException.Preset.UNKNOWN, + data=response.text, + ) + if response.status_code >= 500: + raise PluginException(preset=PluginException.Preset.SERVER_ERROR, data=response.text) + raise PluginException(preset=PluginException.Preset.UNKNOWN, data=response.text) diff --git a/plugins/pagerduty/komand_pagerduty/util/async_requests.py b/plugins/pagerduty/komand_pagerduty/util/async_requests.py deleted file mode 100644 index 3c8e3b2b94..0000000000 --- a/plugins/pagerduty/komand_pagerduty/util/async_requests.py +++ /dev/null @@ -1,64 +0,0 @@ -import aiohttp -import json -from insightconnect_plugin_runtime.exceptions import PluginException - - -class AsyncRequests: - def __init__(self, api_key: str): - self.api_key = api_key - - def get_async_session(self): - """ - Create and return a new aiohttp ClientSession - :return: aiohttp ClientSession - """ - - headers = {"Authorization": f"Token token={self.api_key}"} - return aiohttp.ClientSession(connector=aiohttp.TCPConnector(ssl=True), headers=headers) - - async def async_request( - self, session, url: str, method: str = "get", params: dict = None, body: dict = None - ) -> dict: - """ - Sends an asynchronous request to PagerDuty - :param session: asynchronous session - :param url: url endpoint - :param method: http method for API request - :param params: URL parameters - :param body: request body - :return: JSON response body - """ - - extras = {"json": body, "params": params} - response = await session.request(url=url, method=method, **extras) - text = await response.text() - status = response.status - self.status_code_handling(text, status) - return await response.json() - - @staticmethod - def status_code_handling(response_text, status_code): - _ERRORS = { - 400: "Caller provided invalid arguments. Please review the response for error details. " - "Retrying with the same arguments will not work.", - 401: "Supplied credentials were incorrect. Ensure API key is correct.", - 403: "You do not have authorization to view the resources.", - 404: "The requested resource was not found.", - 429: "Too many requests have been made, the rate limit has been reached.", - 000: "Unexpected response from PagerDuty. Please contact support for assistance.", - } - if status_code != 200: - assistance = _ERRORS.get(status_code, _ERRORS[000]) - try: - response_json = json.loads(response_text) - except (KeyError, json.decoder.JSONDecodeError): - raise PluginException( - cause=f"Malformed JSON received along with a status code of {status_code}", - assistance=f"{assistance}", - data=response_text, - ) - raise PluginException( - cause=f"PagerDuty returned a response code of {status_code}", - assistance=assistance, - data=response_json, - ) diff --git a/plugins/pagerduty/plugin.spec.yaml b/plugins/pagerduty/plugin.spec.yaml index 66d4674bbc..268ab1bee9 100644 --- a/plugins/pagerduty/plugin.spec.yaml +++ b/plugins/pagerduty/plugin.spec.yaml @@ -4,9 +4,11 @@ products: [insightconnect] name: pagerduty title: PagerDuty description: Leverage PagerDuty for incident management and response -version: 2.2.0 +version: 3.0.0 +connection_version: 3 vendor: rapid7 support: community +supported_versions: ["2023-10-12"] status: [] resources: source_url: https://github.com/rapid7/insightconnect-plugins/tree/master/plugins/pagerduty @@ -17,48 +19,63 @@ tags: - incident management hub_tags: use_cases: [alerting_and_notifications] - keywords: [incident response, incident] + keywords: [incident_response, incidents] features: [] +sdk: + type: full + version: 5 + user: nobody connection: api_key: title: API Key type: credential_secret_key description: API Key required: true + example: stRbCzL92kpAfwCkSiA9 types: user: id: description: ID type: string + example: ABCD123 self: - description: URL to view object + description: URL to view user type: string + example: "https://api.pagerduty.com/users/ABCD123" name: description: Name type: string required: true + example: test user email: description: Email type: string required: true + example: user1@example.com summary: description: Summary type: string + example: test summary color: description: Color type: string + example: purple description: description: Description type: string + example: test description job_title: description: Job Title type: string + example: engineer avatar_url: description: Avatar URL type: string + example: "https://secure.gravatar.com/avatar/abcABC123456abcABC123456abcABC123456.png?d=mm&r=PG" time_zone: description: Time Zone, e.g. America/Lima type: string + example: "Europe/London" role: description: Role type: string @@ -68,6 +85,183 @@ types: - owner - read_only_user - user + incident_output: + id: + description: The id of the incident + type: string + example: ABC1234 + type: + description: A string that determines the schema of the object + type: string + example: incident + summary: + description: A short-form, server-generated string that provides succinct, important information about an object suitable for primary labelling of an entity in a client + type: string + example: "[#1234] The server is on fire." + self: + description: The API show URL at which the object is accessible + type: string + example: https://api.pagerduty.com/incidents/ABC1234 + html_url: + description: A URL at which the entity is uniquely displayed in the Web app + type: string + example: https://subdomain.pagerduty.com/incidents/ABC1234 + incident_number: + description: The number of the incident. This is unique across your account. + type: integar + example: 1234 + title: + description: A succinct description of the nature, symptoms, cause, or effect of the incident + type: string + example: The server is on fire. + created_at: + description: The time the incident was first triggered + type: string + example: "2015-10-06T21:30:42Z" + updated_at: + description: The time the incident was last modified + type: string + example: "2015-10-08T21:30:42Z" + status: + description: The current status of the incident + type: string + example: resolved + incident_key: + description: The incident's de-duplication key + type: string + example: abcABC123456abcABC123456abcABC123456 + service: + description: The service the incident is on. If the include[]=services query parameter is provided, the full service definition will be returned + type: object + example: {"id": "ABC1234","type": "service_reference","summary": "My Mail Service","self": "https://api.pagerduty.com/services/ABC1234","html_url": "https://subdomain.pagerduty.com/service-directory/ABC1234"} + assignments: + description: Which accounts the incident will be assigned to + type: array + example: [{"at": "2015-11-10T00:31:52Z","assignee": {"id": "ABC1234","type": "user_reference","summary": "Test User","self": "https://api.pagerduty.com/users/ABC1234","html_url": "https://subdomain.pagerduty.com/users/ABC1234"}}] + assigned_via: + description: How the current incident assignments were decided. Note that direct_assignment incidents will not escalate up the attached escalation_policy + type: string + example: escalation_policy + last_status_change_at: + description: The time the status of the incident last changed. If the incident is not currently acknowledged or resolved, this will be the incident's updated_at + type: string + example: "2015-10-06T21:38:23Z" + first_trigger_log_entry: + description: The first log entry on the incident. The log entry will be of type TriggerLogEntry and will represent information about how the incident was triggered. If the include[]=first_trigger_log_entries query parameter is provided, the full log entry definition will be returned + type: object + example: {"id": "ABCDEFGH123456","type": "trigger_log_entry_reference","summary": "Triggered through the API","self": "https://api.pagerduty.com/log_entries/ABCDEFGH123456?incident_id=ABC1234","html_url": "https://subdomain.pagerduty.com/incidents/ABC1234/log_entries/ABCDEFGH123456"} + alert_counts: + description: The counts of alerts grouped into this incident + type: object + example: {"all": 0,"resolved": 0,"triggered": 0} + is_mergeable: + description: Whether the incident is mergeable. Only incidents that have alerts, or that are manually created can be merged + type: boolean + example: true + escalation_policy: + description: The escalation policy attached to the service that the incident is on. If the include[]=escalation_policies query parameter is provided, the full escalation policy definition will be returned + type: object + example: {"id": "ABC1234","type": "escalation_policy_reference","summary": "Another Escalation Policy","self": "https://api.pagerduty.com/escalation_policies/ABC1234","html_url": "https://subdomain.pagerduty.com/escalation_policies/ABC1234"} + teams: + description: Teams that the alert is assigned to + type: array + example: [{"id": "ABC1234","type": "team_reference","summary": "Engineering","self": "https://api.pagerduty.com/teams/ABC1234","html_url": "https://subdomain.pagerduty.com/teams/ABC1234"}] + pending_actions: + description: The list of pending_actions on the incident. A pending_action object contains a type of action which can be escalate, unacknowledge, resolve or urgency_change. A pending_action object contains at, the time at which the action will take place. An urgency_change pending_action will contain to, the urgency that the incident will change to + type: array + example: [{"type": "unacknowledge","at": "2015-11-10T01:02:52Z"},{"type": "resolve","at": "2015-11-10T04:31:52Z"}] + acknowledgements: + description: List of all acknowledgements for this incident. This list will be empty if the Incident.status is resolved or triggered. If the include[]=acknowledgers query parameter is provided, the full user or service definitions will be returned for each acknowledgement entry + type: array + example: [{"at": "2015-11-10T00:32:52Z","acknowledger": {"id": "ABC1234","type": "user_reference","summary": "Test User","self": "https://api.pagerduty.com/users/ABC1234","html_url": "https://subdomain.pagerduty.com/users/ABC1234"}}] + last_status_change_by: + description: The agent (user, service or integration) that created or modified the Incident Log Entry + type: object + example: {"id": "ABC1234","type": "user_reference","summary": "Test User","self": "https://api.pagerduty.com/users/ABC1234","html_url": "https://subdomain.pagerduty.com/users/ABC1234"} + priority: + description: The priority of the object + type: object + example: {"id": "ABC1234","type": "priority_reference","summary": "P2","self": "https://api.pagerduty.com/priorities/ABC1234"} + conference_bridge: + description: The conference bridge information attached to the incident. Only returned if the include[]=conference_bridge query parameter is provided + type: object + example: {"conference_number":"555-123-4567", "conference_url":"https://example.com/123-456-789"} + urgency: + description: The current urgency of the incident + type: string + example: high + service_input: + id: + description: The id of the service that the incident is related to + type: string + example: PWIXJZS + required: true + type: + description: The type of the service that the incident is related to + type: string + example: service_reference + required: true + priority_input: + id: + description: The id of the priority that the incident is to be set to + type: string + example: ABC1234 + required: true + type: + description: The type of the priority that the incident is to be set to + type: string + example: priority_reference + required: true + body_input: + details: + description: The id of the priority that the incident is to be set to + type: string + example: A disk is getting full on this machine. You should investigate what is causing the disk to fill + required: true + type: + description: The type of the body is to be added to + type: string + example: incident_body + required: true + assignee: + id: + description: The id of the user that the new incident will be assigned to + type: string + example: ABC1234 + type: + description: A string that determines the schema of the object. + type: string + example: user_reference + escalation_policy_input: + id: + description: The id of the escalation policy that the new incident will be assigned to + type: string + example: ABC1234 + type: + description: A string that determines the schema of the object. + type: string + example: escalation_policy_reference + summary: + description: A short-form, server-generated string that provides succinct, important information about an object + type: string + example: Another Escalation Policy + self: + description: The API show URL at which the object is accessible + type: string + example: https://api.pagerduty.com/escalation_policies/ABC1234 + html_url: + description: A URL at which the entity is uniquely displayed in the Web app + type: string + example: https://subdomain.pagerduty.com/escalation_policies/ABC1234 + conference_bridge_input: + conference_number: + description: The phone number of the conference call for the conference bridge. Phone numbers should be formatted like +1 415-555-1212,,,,1234#, where a comma (,) represents a one-second wait and pound (#) completes access code input + type: string + example: 555-123-4567 + conference_url: + description: A URL for the conference bridge. This could be a link to a web conference or Slack channel + type: string + example: https://example.com/123-456-789 actions: get_on_call: title: Get On-Call Users @@ -77,54 +271,49 @@ actions: title: Schedule ID description: Schedule ID type: string - required: false - example: P9E0DZT + required: true + example: ABC1234 output: users: title: Users description: List of on-call users type: "[]user" required: true - get_user_by_email: - title: Get User by Email - description: Get a User by Email + example: [{"avatar_url": "https://secure.gravatar.com/avatar/abcABC123456abcABC123456abcABC123456.png?d=mm&r=PG","billed": true,"color": "purple","contact_methods": [{"html_url": null,"id": "ABC1234","self": "https://api.pagerduty.com/users/ABCD123/contact_methods/ABC1234","summary": "Default","type": "email_contact_method_reference"}],"coordinated_incidents": [],"description": "","email": "user1@example.com","html_url": "https://api.pagerduty.com/users/ABCD123","id": "ABCD123","invitation_sent": false,"job_title": "","name": "Test account","notification_rules": [{"html_url": null,"id": "ABC1234","self": "https://api.pagerduty.com/users/ABCD123/notification_rules/ABC1234","summary": "0 minutes: channel ABC1234","type": "assignment_notification_rule_reference"},{"html_url": null,"id": "ABC1234","self": "https://api.pagerduty.com/users/ABCD123/notification_rules/ABC1234","summary": "0 minutes: channel ABC1234","type": "assignment_notification_rule_reference"}],"role": "owner","self": "https://api.pagerduty.com/users/ABCD123","summary": "test summary","teams": [{"html_url": "https://api.pagerduty.com/teams/ABC1234","id": "ABC1234","self": "https://api.pagerduty.com/teams/ABC1234","summary": "Engineering","type": "team_reference"}],"time_zone": "Europe/London","type": "user"}] + get_user_by_id: + title: Get User by ID + description: Get a User by ID input: - email: - title: Email - description: Email + id: + title: User ID + description: User ID type: string required: true + example: ABC1234 output: - found: - title: Found - type: boolean - description: True if found - required: false user: title: User description: User type: user required: false - get_user_by_id: - title: Get User by ID - description: Get a User by ID + example: {"avatar_url": "https://secure.gravatar.com/avatar/abcABC123456abcABC123456abcABC123456.png?d=mm&r=PG","billed": true,"color": "purple","contact_methods": [{"html_url": null,"id": "ABC1234","self": "https://api.pagerduty.com/users/ABCD123/contact_methods/ABC1234","summary": "Default","type": "email_contact_method_reference"}],"coordinated_incidents": [],"description": "","email": "user1@example.com","html_url": "https://api.pagerduty.com/users/ABCD123","id": "ABCD123","invitation_sent": false,"job_title": "","name": "Test account","notification_rules": [{"html_url": null,"id": "ABC1234","self": "https://api.pagerduty.com/users/ABCD123/notification_rules/ABC1234","summary": "0 minutes: channel ABC1234","type": "assignment_notification_rule_reference"},{"html_url": null,"id": "ABC1234","self": "https://api.pagerduty.com/users/ABCD123/notification_rules/ABC1234","summary": "0 minutes: channel ABC1234","type": "assignment_notification_rule_reference"}],"role": "owner","self": "https://api.pagerduty.com/users/ABCD123","summary": "test summary","teams": [{"html_url": "https://api.pagerduty.com/teams/ABC1234","id": "ABC1234","self": "https://api.pagerduty.com/teams/ABC1234","summary": "Engineering","type": "team_reference"}],"time_zone": "Europe/London","type": "user"} + get_user_by_email: + title: Get User by Their Email Address + description: Get a User from using their email address input: - id: - title: User ID - description: User ID + user_email: + title: User Email + description: User email address type: string required: true + example: user@example.com output: - found: - title: Found - type: boolean - description: True if found - required: false user: title: User description: User type: user required: false + example: {"avatar_url": "https://secure.gravatar.com/avatar/abcABC123456abcABC123456abcABC123456.png?d=mm&r=PG","billed": true,"color": "purple","contact_methods": [{"html_url": null,"id": "ABC1234","self": "https://api.pagerduty.com/users/ABCD123/contact_methods/ABC1234","summary": "Default","type": "email_contact_method_reference"}],"coordinated_incidents": [],"description": "","email": "user1@example.com","html_url": "https://api.pagerduty.com/users/ABCD123","id": "ABCD123","invitation_sent": false,"job_title": "","name": "Test account","notification_rules": [{"html_url": null,"id": "ABC1234","self": "https://api.pagerduty.com/users/ABCD123/notification_rules/ABC1234","summary": "0 minutes: channel ABC1234","type": "assignment_notification_rule_reference"},{"html_url": null,"id": "ABC1234","self": "https://api.pagerduty.com/users/ABCD123/notification_rules/ABC1234","summary": "0 minutes: channel ABC1234","type": "assignment_notification_rule_reference"}],"role": "owner","self": "https://api.pagerduty.com/users/ABCD123","summary": "test summary","teams": [{"html_url": "https://api.pagerduty.com/teams/ABC1234","id": "ABC1234","self": "https://api.pagerduty.com/teams/ABC1234","summary": "Engineering","type": "team_reference"}],"time_zone": "Europe/London","type": "user"} create_user: title: Create User description: Create a User @@ -134,11 +323,13 @@ actions: description: Name type: string required: true + example: test user email: - title: Email - description: Email + title: Email for New Account + description: The email address for the new account to be created type: string required: true + example: user1@example.com role: title: Role description: Role @@ -150,22 +341,50 @@ actions: - read_only_user - user required: false + example: user from_email: - title: Email - description: Email of creating user + title: Email of the Creating User + description: The email address of user that is creating the account type: string required: true - output: - success: - title: Success - type: boolean - description: True if created + example: user2@example.com + time_zone: + title: Time Zone + description: Time Zone, e.g. America/Lima + type: string required: false + example: "Europe/London" + color: + title: Color + description: The schedule color + type: string + required: false + example: green + user_description: + title: Description + description: The description of the new user + type: string + required: false + example: test description of the new use + job_title: + title: Job Title + description: The description of the new user + type: string + required: false + example: job title + license: + title: License + description: The license of the new user + type: object + required: false + example: {"id":"PTDVERC", "type":"license_reference"} + output: user: title: User description: User type: user required: false + example: {"avatar_url": "https://secure.gravatar.com/avatar/abcABC123456abcABC123456abcABC123456.png?d=mm&r=PG","billed": true,"color": "purple","contact_methods": [{"html_url": null,"id": "ABC1234","self": "https://api.pagerduty.com/users/ABCD123/contact_methods/ABC1234","summary": "Default","type": "email_contact_method_reference"}],"coordinated_incidents": [],"description": "","email": user1@example.com,"html_url": "https://api.pagerduty.com/users/ABCD123","id": "ABCD123","invitation_sent": false,"job_title": "","name": "test user","notification_rules": [{"html_url": null,"id": "ABC1234","self": "https://api.pagerduty.com/users/ABCD123/notification_rules/ABC1234","summary": "0 minutes: channel ABC1234","type": "assignment_notification_rule_reference"},{"html_url": null,"id": "ABC1234","self": "https://api.pagerduty.com/users/ABCD123/notification_rules/ABC1234","summary": "0 minutes: channel ABC1234","type": "assignment_notification_rule_reference"}],"role": "owner","self": "https://api.pagerduty.com/users/ABCD123","summary": "test summary","teams": [{"html_url": "https://api.pagerduty.com/teams/ABC1234","id": "ABC1234","self": "https://api.pagerduty.com/teams/ABC1234","summary": "Engineering","type": "team_reference"}],"time_zone": "Europe/London","type": "user"} delete_user_by_id: title: Delete User by ID description: Delete a User by ID @@ -175,150 +394,134 @@ actions: description: User ID type: string required: true + example: ABCD123 + email: + title: Email + type: string + description: The email address of a valid user associated with the account making the delete request + required: true + example: user1@example.com output: success: title: Success - type: boolean - description: True if deleted - required: false - user: - title: User - description: User - type: user + type: string + description: A message to show if the user was deleted as expected required: false + example: The user ABCD123 has been deleted send_trigger_event: title: Send Trigger Event description: Trigger an incident input: - service_key: - title: Service Key + email: + title: Email type: string - description: Service Key (aka Integration Key) + description: The email address of a valid user associated with the account making the request required: true - description: - title: Description + example: user1@example.com + title: + title: Title type: string + description: A description of the nature, symptoms, cause, or effect of the incident required: true - description: Text that will appear in the incident's log associated with this - event - details: - title: Details - description: An arbitrary JSON object containing any data you'd like included - in the incident log - type: object - required: false - client: - title: Client - type: string - description: The name of the monitoring client that is triggering this event - required: false - client_url: - title: Client URL - type: string - description: The URL of the monitoring client that is triggering this event - required: false - contexts: - title: Contexts - description: Additional context objects - type: '[]object' + example: The server is on fire. + service: + title: Service + type: service_input + description: The service that the incident is related to + required: true + example: {"id": "ABC1234","type": "service_reference"} + priority: + title: Priority + type: priority_input + description: The priority that the incident is to be set to required: false - output: - status: - title: Status - description: Status + example: {"id": "ABC1234","type": "priority_reference"} + urgency: + title: Urgency type: string + description: The urgency that the incident is to be set to required: false - message: - title: Message - description: Message - type: string + example: high + body: + title: Body + type: body_input + description: Details to be added to the incident body required: false + example: {"details": "A disk is getting full on this machine. You should investigate what is causing the disk to fill.", "type": "incident_body"} incident_key: title: Incident Key - description: Incident Key type: string + description: A string which identifies the incident. Sending subsequent requests referencing the same service and with the same incident_key will result in those requests being rejected if an open incident matches that incident_key + required: false + example: abcABC123456abcABC123456abcABC123456 + assignments: + title: Assignments + type: "[]assignee" + description: Assign the incident to these assignees. Cannot be specified if an escalation policy is given + required: false + example: [{'assignee': {'id': 'ABC1234', 'type': 'user_reference'}}] + escalation_policy: + title: Escalation Policy + type: escalation_policy_input + description: Assign the incident to this escalation policy. Cannot be specified if Assignments given + required: false + example: {'html_url': 'https://subdomain.pagerduty.com/escalation_policies/ABC1234', 'id': 'ABC1234', 'self': 'https://api.pagerduty.com/escalation_policies/ABC1234', 'summary': 'Another Escalation Policy', 'type': 'escalation_policy_reference'} + conference_bridge: + title: Conference Bridge + type: conference_bridge_input + description: The conference bridge information attached to the incident. Only returned if the include[]=conference_bridge query parameter is provided required: false + example: {'conference_number': '555-123-4567', 'conference_url': 'https://example.com/123-456-789'} + output: + incident: + title: Incident + description: The incident object that was created + type: incident_output + required: False + example: {'incident': {'acknowledgements': [{'acknowledger': {'html_url': 'https://subdomain.pagerduty.com/users/ABC1234', 'id': 'ABC1234', 'self': 'https://api.pagerduty.com/users/ABC1234', 'summary': 'Test User', 'type': 'user_reference'}, 'at': '2015-11-10T00:32:52Z'}], 'alert_counts': {'all': 0, 'resolved': 0, 'triggered': 0}, 'assigned_via': 'escalation_policy', 'assignments': [{'assignee': {'html_url': 'https://subdomain.pagerduty.com/users/ABC1234', 'id': 'ABC1234', 'self': 'https://api.pagerduty.com/users/ABC1234', 'summary': 'Test User', 'type': 'user_reference'}, 'at': '2015-11-10T00:31:52Z'}], 'conference_bridge': {'conference_number': '555-123-4567', 'conference_url': 'https://example.com/123-456-789'}, 'created_at': '2015-10-06T21:30:42Z', 'escalation_policy': {'html_url': 'https://subdomain.pagerduty.com/escalation_policies/ABC1234', 'id': 'ABC1234', 'self': 'https://api.pagerduty.com/escalation_policies/ABC1234', 'summary': 'Another Escalation Policy', 'type': 'escalation_policy_reference'}, 'first_trigger_log_entry': {'html_url': 'https://subdomain.pagerduty.com/incidents/ABC1234/log_entries/ABCDEFGH123456', 'id': 'ABCDEFGH123456', 'self': 'https://api.pagerduty.com/log_entries/ABCDEFGH123456?incident_id=ABC1234', 'summary': 'Triggered through the API', 'type': 'trigger_log_entry_reference'}, 'html_url': 'https://subdomain.pagerduty.com/incidents/ABC1234', 'id': 'ABC1234', 'incident_key': 'abcABC123456abcABC123456abcABC123456', 'incident_number': 1234, 'is_mergeable': true, 'last_status_change_at': '2015-10-06T21:38:23Z', 'last_status_change_by': {'html_url': 'https://subdomain.pagerduty.com/users/ABC1234', 'id': 'ABC1234', 'self': 'https://api.pagerduty.com/users/ABC1234', 'summary': 'Test User', 'type': 'user_reference'}, 'pending_actions': [{'at': '2015-11-10T01:02:52Z', 'type': 'unacknowledge'}, {'at': '2015-11-10T04:31:52Z', 'type': 'resolve'}], 'priority': {'id': 'ABC1234', 'self': 'https://api.pagerduty.com/priorities/ABC1234', 'summary': 'P2', 'type': 'priority_reference'}, 'self': 'https://api.pagerduty.com/incidents/ABC1234', 'service': {'html_url': 'https://subdomain.pagerduty.com/service-directory/ABC1234', 'id': 'ABC1234', 'self': 'https://api.pagerduty.com/services/ABC1234', 'summary': 'My Mail Service', 'type': 'service_reference'}, 'status': 'resolved', 'summary': '[#1234] The server is on fire.', 'teams': [{'html_url': 'https://subdomain.pagerduty.com/teams/ABC1234', 'id': 'ABC1234', 'self': 'https://api.pagerduty.com/teams/ABC1234', 'summary': 'Engineering', 'type': 'team_reference'}], 'title': 'The server is on fire.', 'type': 'incident', 'updated_at': '2015-10-08T21:30:42Z', 'urgency': 'high'}} send_acknowledge_event: title: Send Acknowledge Event description: Acknowledge an incident input: - service_key: - title: Service Key + email: + title: Email type: string - description: Service Key (aka Integration Key) + description: The email address of a valid user associated with the account making the request required: true - incident_key: - title: Incident Key + example: user1@example.com + incident_id: + title: Incident ID type: string - description: Incident Key + description: The ID of the incident required: true - description: - title: Description - type: string - description: Text that will appear in the incident's log associated with this - event - required: false - details: - title: Details - description: An arbitrary JSON object containing any data you'd like included - in the incident log - type: object - required: false + example: Q1GXLD8EXPKU32 output: - status: - title: Status - description: Status - type: string - required: false - message: - title: Message - description: Message - type: string - required: false - incident_key: - title: Incident Key - description: Incident Key - type: string - required: false + incident: + title: Incident + description: The incident object that was acknowledged + type: incident_output + required: False + example: {'incident': {'acknowledgements': [{'acknowledger': {'html_url': 'https://subdomain.pagerduty.com/users/ABC1234', 'id': 'ABC1234', 'self': 'https://api.pagerduty.com/users/ABC1234', 'summary': 'Test User', 'type': 'user_reference'}, 'at': '2015-11-10T00:32:52Z'}], 'alert_counts': {'all': 0, 'resolved': 0, 'triggered': 0}, 'assigned_via': 'escalation_policy', 'assignments': [{'assignee': {'html_url': 'https://subdomain.pagerduty.com/users/ABC1234', 'id': 'ABC1234', 'self': 'https://api.pagerduty.com/users/ABC1234', 'summary': 'Test User', 'type': 'user_reference'}, 'at': '2015-11-10T00:31:52Z'}], 'conference_bridge': {'conference_number': '555-123-4567', 'conference_url': 'https://example.com/123-456-789'}, 'created_at': '2015-10-06T21:30:42Z', 'escalation_policy': {'html_url': 'https://subdomain.pagerduty.com/escalation_policies/ABC1234', 'id': 'ABC1234', 'self': 'https://api.pagerduty.com/escalation_policies/ABC1234', 'summary': 'Another Escalation Policy', 'type': 'escalation_policy_reference'}, 'first_trigger_log_entry': {'html_url': 'https://subdomain.pagerduty.com/incidents/ABC1234/log_entries/ABCDEFGH123456', 'id': 'ABCDEFGH123456', 'self': 'https://api.pagerduty.com/log_entries/ABCDEFGH123456?incident_id=ABC1234', 'summary': 'Triggered through the API', 'type': 'trigger_log_entry_reference'}, 'html_url': 'https://subdomain.pagerduty.com/incidents/ABC1234', 'id': 'ABC1234', 'incident_key': 'abcABC123456abcABC123456abcABC123456', 'incident_number': 1234, 'is_mergeable': true, 'last_status_change_at': '2015-10-06T21:38:23Z', 'last_status_change_by': {'html_url': 'https://subdomain.pagerduty.com/users/ABC1234', 'id': 'ABC1234', 'self': 'https://api.pagerduty.com/users/ABC1234', 'summary': 'Test User', 'type': 'user_reference'}, 'pending_actions': [{'at': '2015-11-10T01:02:52Z', 'type': 'unacknowledge'}, {'at': '2015-11-10T04:31:52Z', 'type': 'resolve'}], 'priority': {'id': 'ABC1234', 'self': 'https://api.pagerduty.com/priorities/ABC1234', 'summary': 'P2', 'type': 'priority_reference'}, 'self': 'https://api.pagerduty.com/incidents/ABC1234', 'service': {'html_url': 'https://subdomain.pagerduty.com/service-directory/ABC1234', 'id': 'ABC1234', 'self': 'https://api.pagerduty.com/services/ABC1234', 'summary': 'My Mail Service', 'type': 'service_reference'}, 'status': 'resolved', 'summary': '[#1234] The server is on fire.', 'teams': [{'html_url': 'https://subdomain.pagerduty.com/teams/ABC1234', 'id': 'ABC1234', 'self': 'https://api.pagerduty.com/teams/ABC1234', 'summary': 'Engineering', 'type': 'team_reference'}], 'title': 'The server is on fire.', 'type': 'incident', 'updated_at': '2015-10-08T21:30:42Z', 'urgency': 'high'}} send_resolve_event: title: Send Resolve Event description: Resolve an incident input: - service_key: - title: Service Key + email: + title: Email type: string - description: Service Key (aka Integration Key) + description: The email address of a valid user associated with the account making the request required: true - incident_key: - title: Incident Key + example: user1@example.com + incident_id: + title: Incident ID type: string - description: Incident Key + description: The ID of the incident required: true - description: - title: Description - type: string - description: Text that will appear in the incident's log associated with this - event - required: false - details: - title: Details - description: An arbitrary JSON object containing any data you'd like included - in the incident log - type: object - required: false + example: Q1GXLD8EXPKU32 output: - status: - title: Status - description: Status - type: string - required: false - message: - title: Message - description: Message - type: string - required: false - incident_key: - title: Incident Key - description: Incident Key - type: string + incident: + title: Incident + description: The incident object that was resolved + type: incident_output required: false + example: {'incident': {'acknowledgements': [{'acknowledger': {'html_url': 'https://subdomain.pagerduty.com/users/ABC1234', 'id': 'ABC1234', 'self': 'https://api.pagerduty.com/users/ABC1234', 'summary': 'Test User', 'type': 'user_reference'}, 'at': '2015-11-10T00:32:52Z'}], 'alert_counts': {'all': 0, 'resolved': 0, 'triggered': 0}, 'assigned_via': 'escalation_policy', 'assignments': [{'assignee': {'html_url': 'https://subdomain.pagerduty.com/users/ABC1234', 'id': 'ABC1234', 'self': 'https://api.pagerduty.com/users/ABC1234', 'summary': 'Test User', 'type': 'user_reference'}, 'at': '2015-11-10T00:31:52Z'}], 'conference_bridge': {'conference_number': '555-123-4567', 'conference_url': 'https://example.com/123-456-789'}, 'created_at': '2015-10-06T21:30:42Z', 'escalation_policy': {'html_url': 'https://subdomain.pagerduty.com/escalation_policies/ABC1234', 'id': 'ABC1234', 'self': 'https://api.pagerduty.com/escalation_policies/ABC1234', 'summary': 'Another Escalation Policy', 'type': 'escalation_policy_reference'}, 'first_trigger_log_entry': {'html_url': 'https://subdomain.pagerduty.com/incidents/ABC1234/log_entries/ABCDEFGH123456', 'id': 'ABCDEFGH123456', 'self': 'https://api.pagerduty.com/log_entries/ABCDEFGH123456?incident_id=ABC1234', 'summary': 'Triggered through the API', 'type': 'trigger_log_entry_reference'}, 'html_url': 'https://subdomain.pagerduty.com/incidents/ABC1234', 'id': 'ABC1234', 'incident_key': 'abcABC123456abcABC123456abcABC123456', 'incident_number': 1234, 'is_mergeable': true, 'last_status_change_at': '2015-10-06T21:38:23Z', 'last_status_change_by': {'html_url': 'https://subdomain.pagerduty.com/users/ABC1234', 'id': 'ABC1234', 'self': 'https://api.pagerduty.com/users/ABC1234', 'summary': 'Test User', 'type': 'user_reference'}, 'pending_actions': [{'at': '2015-11-10T01:02:52Z', 'type': 'unacknowledge'}, {'at': '2015-11-10T04:31:52Z', 'type': 'resolve'}], 'priority': {'id': 'ABC1234', 'self': 'https://api.pagerduty.com/priorities/ABC1234', 'summary': 'P2', 'type': 'priority_reference'}, 'self': 'https://api.pagerduty.com/incidents/ABC1234', 'service': {'html_url': 'https://subdomain.pagerduty.com/service-directory/ABC1234', 'id': 'ABC1234', 'self': 'https://api.pagerduty.com/services/ABC1234', 'summary': 'My Mail Service', 'type': 'service_reference'}, 'status': 'resolved', 'summary': '[#1234] The server is on fire.', 'teams': [{'html_url': 'https://subdomain.pagerduty.com/teams/ABC1234', 'id': 'ABC1234', 'self': 'https://api.pagerduty.com/teams/ABC1234', 'summary': 'Engineering', 'type': 'team_reference'}], 'title': 'The server is on fire.', 'type': 'incident', 'updated_at': '2015-10-08T21:30:42Z', 'urgency': 'high'}} \ No newline at end of file diff --git a/plugins/pagerduty/requirements.txt b/plugins/pagerduty/requirements.txt index 5c891af69a..adbecb2141 100755 --- a/plugins/pagerduty/requirements.txt +++ b/plugins/pagerduty/requirements.txt @@ -1,5 +1,4 @@ # List third-party dependencies here, separated by newlines. # All dependencies must be version-pinned, eg. requests==1.2.0 # See: https://pip.pypa.io/en/stable/user_guide/#requirements-files -pypd==1.1.0 -aiohttp==3.6.3 +parameterized==0.8.1 \ No newline at end of file diff --git a/plugins/pagerduty/setup.py b/plugins/pagerduty/setup.py index 686b2d2795..2fcce898bc 100644 --- a/plugins/pagerduty/setup.py +++ b/plugins/pagerduty/setup.py @@ -1,9 +1,9 @@ -# GENERATED BY KOMAND SDK - DO NOT EDIT +# GENERATED BY INSIGHT-PLUGIN - DO NOT EDIT from setuptools import setup, find_packages setup(name="pagerduty-rapid7-plugin", - version="2.2.0", + version="3.0.0", description="Leverage PagerDuty for incident management and response", author="rapid7", author_email="", diff --git a/plugins/pagerduty/unit_test/__init__.py b/plugins/pagerduty/unit_test/__init__.py new file mode 100644 index 0000000000..797e426edf --- /dev/null +++ b/plugins/pagerduty/unit_test/__init__.py @@ -0,0 +1 @@ +# GENERATED BY INSIGHT-PLUGIN - DO NOT EDIT diff --git a/plugins/pagerduty/unit_test/expected/create_user_additional_fields.json.exp b/plugins/pagerduty/unit_test/expected/create_user_additional_fields.json.exp new file mode 100644 index 0000000000..1ae1d97871 --- /dev/null +++ b/plugins/pagerduty/unit_test/expected/create_user_additional_fields.json.exp @@ -0,0 +1,43 @@ +{ + "user": { + "avatar_url": "https://secure.gravatar.com/avatar/87dfa473571de452cf8741716cd028e2.png?d=mm&r=PG", + "billed": true, + "color": "purple", + "contact_methods": [ + { + "id": "PUA7UDS", + "self": "https://api.pagerduty.com/users/PFJIAVM/contact_methods/PUA7UDS", + "summary": "Default", + "type": "email_contact_method_reference" + } + ], + "coordinated_incidents": [], + "description": "this is a test desc", + "email": "test_23@test.com", + "html_url": "https://dev-rapid7.pagerduty.com/users/PFJIAVM", + "id": "PFJIAVM", + "invitation_sent": true, + "job_title": "engineer", + "name": "Test additional fields", + "notification_rules": [ + { + "id": "P38RX1Z", + "self": "https://api.pagerduty.com/users/PFJIAVM/notification_rules/P38RX1Z", + "summary": "0 minutes: channel PUA7UDS", + "type": "assignment_notification_rule_reference" + }, + { + "id": "P6HCXDM", + "self": "https://api.pagerduty.com/users/PFJIAVM/notification_rules/P6HCXDM", + "summary": "0 minutes: channel PUA7UDS", + "type": "assignment_notification_rule_reference" + } + ], + "role": "admin", + "self": "https://api.pagerduty.com/users/PFJIAVM", + "summary": "Test User", + "teams": [], + "time_zone": "Europe/London", + "type": "user" + } +} \ No newline at end of file diff --git a/plugins/pagerduty/unit_test/expected/create_user_minimum_fields.json.exp b/plugins/pagerduty/unit_test/expected/create_user_minimum_fields.json.exp new file mode 100644 index 0000000000..c542aab5bb --- /dev/null +++ b/plugins/pagerduty/unit_test/expected/create_user_minimum_fields.json.exp @@ -0,0 +1,43 @@ +{ + "user": { + "avatar_url": "https://secure.gravatar.com/avatar/663a7dbec91b9dabba93f906648dd514.png?d=mm&r=PG", + "billed": true, + "color": "green", + "contact_methods": [ + { + "id": "P050K1G", + "self": "https://api.pagerduty.com/users/PTVOCBV/contact_methods/P050K1G", + "summary": "Default", + "type": "email_contact_method_reference" + } + ], + "coordinated_incidents": [], + "description": "", + "email": "test_3@test.com", + "html_url": "https://dev-rapid7.pagerduty.com/users/PTVOCBV", + "id": "PTVOCBV", + "invitation_sent": true, + "job_title": "", + "name": "Test minimum fields", + "notification_rules": [ + { + "id": "PZ9BJ0K", + "self": "https://api.pagerduty.com/users/PTVOCBV/notification_rules/PZ9BJ0K", + "summary": "0 minutes: channel P050K1G", + "type": "assignment_notification_rule_reference" + }, + { + "id": "PCIMJDN", + "self": "https://api.pagerduty.com/users/PTVOCBV/notification_rules/PCIMJDN", + "summary": "0 minutes: channel P050K1G", + "type": "assignment_notification_rule_reference" + } + ], + "role": "admin", + "self": "https://api.pagerduty.com/users/PTVOCBV", + "summary": "Test minimum fields", + "teams": [], + "time_zone": "Europe/London", + "type": "user" + } +} \ No newline at end of file diff --git a/plugins/pagerduty/unit_test/expected/get_user_by_email_valid.json.exp b/plugins/pagerduty/unit_test/expected/get_user_by_email_valid.json.exp new file mode 100644 index 0000000000..0b27c3fa76 --- /dev/null +++ b/plugins/pagerduty/unit_test/expected/get_user_by_email_valid.json.exp @@ -0,0 +1,43 @@ +{ + "user" : { + "avatar_url": "https://secure.gravatar.com/avatar/663a7dbec91b9dabba93f906648dd514.png?d=mm&r=PG", + "billed": true, + "color": "green", + "contact_methods": [ + { + "id": "P050K1G", + "self": "https://api.pagerduty.com/users/PTVOCBV/contact_methods/P050K1G", + "summary": "Default", + "type": "email_contact_method_reference" + } + ], + "coordinated_incidents": [], + "email": "valid_email", + "html_url": "https://dev-rapid7.pagerduty.com/users/PTVOCBV", + "id": "valid_id", + "invitation_sent": true, + "name": "get_user_valid", + "notification_rules": [ + { + "id": "PZ9BJ0K", + "self": "https://api.pagerduty.com/users/PTVOCBV/notification_rules/PZ9BJ0K", + "summary": "0 minutes: channel P050K1G", + "type": "assignment_notification_rule_reference" + }, + { + "id": "PCIMJDN", + "self": "https://api.pagerduty.com/users/PTVOCBV/notification_rules/PCIMJDN", + "summary": "0 minutes: channel P050K1G", + "type": "assignment_notification_rule_reference" + } + ], + "role": "admin", + "self": "https://api.pagerduty.com/users/PTVOCBV", + "summary": "get_user_valid", + "teams": [], + "time_zone": "Europe/London", + "type": "user", + "description" : "", + "job_title": "" + } +} \ No newline at end of file diff --git a/plugins/pagerduty/unit_test/expected/get_user_valid.json.exp b/plugins/pagerduty/unit_test/expected/get_user_valid.json.exp new file mode 100644 index 0000000000..bd1fb68054 --- /dev/null +++ b/plugins/pagerduty/unit_test/expected/get_user_valid.json.exp @@ -0,0 +1,43 @@ +{ + "user": { + "avatar_url": "https://secure.gravatar.com/avatar/663a7dbec91b9dabba93f906648dd514.png?d=mm&r=PG", + "billed": true, + "color": "green", + "contact_methods": [ + { + "id": "P050K1G", + "self": "https://api.pagerduty.com/users/PTVOCBV/contact_methods/P050K1G", + "summary": "Default", + "type": "email_contact_method_reference" + } + ], + "coordinated_incidents": [], + "description": "", + "email": "test_3@test.com", + "html_url": "https://dev-rapid7.pagerduty.com/users/PTVOCBV", + "id": "valid_id", + "invitation_sent": true, + "job_title": "", + "name": "get_user_valid", + "notification_rules": [ + { + "id": "PZ9BJ0K", + "self": "https://api.pagerduty.com/users/PTVOCBV/notification_rules/PZ9BJ0K", + "summary": "0 minutes: channel P050K1G", + "type": "assignment_notification_rule_reference" + }, + { + "id": "PCIMJDN", + "self": "https://api.pagerduty.com/users/PTVOCBV/notification_rules/PCIMJDN", + "summary": "0 minutes: channel P050K1G", + "type": "assignment_notification_rule_reference" + } + ], + "role": "admin", + "self": "https://api.pagerduty.com/users/PTVOCBV", + "summary": "get_user_valid", + "teams": [], + "time_zone": "Europe/London", + "type": "user" + } +} \ No newline at end of file diff --git a/plugins/pagerduty/unit_test/expected/test_acknowledge_valid.json.exp b/plugins/pagerduty/unit_test/expected/test_acknowledge_valid.json.exp new file mode 100644 index 0000000000..df6009ad9b --- /dev/null +++ b/plugins/pagerduty/unit_test/expected/test_acknowledge_valid.json.exp @@ -0,0 +1,91 @@ +{ + "incident": { + "acknowledgements": [ + { + "acknowledger": { + "html_url": "https://dev-rapid7.pagerduty.com/users/PYGDZB8", + "id": "PYGDZB8", + "self": "https://api.pagerduty.com/users/PYGDZB8", + "summary": "test user", + "type": "user_reference" + }, + "at": "2023-10-13T14:55:07Z" + } + ], + "alert_counts": { + "all": 0, + "resolved": 0, + "triggered": 0 + }, + "assigned_via": "escalation_policy", + "assignments": [ + { + "assignee": { + "html_url": "https://dev-rapid7.pagerduty.com/users/PYGDZB8", + "id": "PYGDZB8", + "self": "https://api.pagerduty.com/users/PYGDZB8", + "summary": "test user", + "type": "user_reference" + }, + "at": "2023-10-13T14:54:58Z" + } + ], + "created_at": "2023-10-13T14:54:58Z", + "description": "test ack", + "escalation_policy": { + "html_url": "https://dev-rapid7.pagerduty.com/escalation_policies/PJINSTN", + "id": "PJINSTN", + "self": "https://api.pagerduty.com/escalation_policies/PJINSTN", + "summary": "Test Service-ep", + "type": "escalation_policy_reference" + }, + "first_trigger_log_entry": { + "html_url": "https://dev-rapid7.pagerduty.com/incidents/Q1R042KMH6D067/log_entries/R87EKJ59GRGLRWK7RPE9YWXQ9Y", + "id": "R87EKJ59GRGLRWK7RPE9YWXQ9Y", + "self": "https://api.pagerduty.com/log_entries/R87EKJ59GRGLRWK7RPE9YWXQ9Y", + "summary": "Triggered through the website.", + "type": "trigger_log_entry_reference" + }, + "html_url": "https://dev-rapid7.pagerduty.com/incidents/Q1R042KMH6D067", + "id": "Q1R042KMH6D067", + "impacted_services": [ + { + "html_url": "https://dev-rapid7.pagerduty.com/service-directory/PF8TUEU", + "id": "PF8TUEU", + "self": "https://api.pagerduty.com/services/PF8TUEU", + "summary": "Test Service", + "type": "service_reference" + } + ], + "incident_key": "0594f9d98f3747179b052ba708d3e1d1", + "incident_number": 18, + "incidents_responders": [], + "is_mergeable": true, + "last_status_change_at": "2023-10-13T14:55:07Z", + "last_status_change_by": { + "html_url": "https://dev-rapid7.pagerduty.com/users/PYGDZB8", + "id": "PYGDZB8", + "self": "https://api.pagerduty.com/users/PYGDZB8", + "summary": "test user", + "type": "user_reference" + }, + "pending_actions": [], + "responder_requests": [], + "self": "https://api.pagerduty.com/incidents/Q1R042KMH6D067", + "service": { + "html_url": "https://dev-rapid7.pagerduty.com/service-directory/PF8TUEU", + "id": "PF8TUEU", + "self": "https://api.pagerduty.com/services/PF8TUEU", + "summary": "Test Service", + "type": "service_reference" + }, + "status": "acknowledged", + "subscriber_requests": [], + "summary": "[#18] test ack", + "teams": [], + "title": "test ack", + "type": "incident", + "updated_at": "2023-10-13T14:55:07Z", + "urgency": "high" + } +} \ No newline at end of file diff --git a/plugins/pagerduty/unit_test/expected/test_deleted_user.json.exp b/plugins/pagerduty/unit_test/expected/test_deleted_user.json.exp new file mode 100644 index 0000000000..16f2b180dc --- /dev/null +++ b/plugins/pagerduty/unit_test/expected/test_deleted_user.json.exp @@ -0,0 +1,53 @@ +{ + "users": [ + { + "avatar_url": "https://secure.gravatar.com/avatar/c67b6c8ed606dec999bb064ada88cf5c.png?d=mm&r=PG", + "billed": true, + "color": "purple", + "contact_methods": [ + { + "id": "P9CU341", + "self": "https://api.pagerduty.com/users/PYGDZB8/contact_methods/P9CU341", + "summary": "Default", + "type": "email_contact_method_reference" + } + ], + "coordinated_incidents": [], + "description": "", + "email": "test@example.com", + "html_url": "https://dev-rapid7.pagerduty.com/users/PYGDZB8", + "id": "PYGDZB8", + "invitation_sent": false, + "job_title": "", + "name": "test_account_with_id", + "notification_rules": [ + { + "id": "POMMNCV", + "self": "https://api.pagerduty.com/users/PYGDZB8/notification_rules/POMMNCV", + "summary": "0 minutes: channel P9CU341", + "type": "assignment_notification_rule_reference" + }, + { + "id": "PSZNORI", + "self": "https://api.pagerduty.com/users/PYGDZB8/notification_rules/PSZNORI", + "summary": "0 minutes: channel P9CU341", + "type": "assignment_notification_rule_reference" + } + ], + "role": "owner", + "self": "https://api.pagerduty.com/users/PYGDZB8", + "summary": "test_account_with_id", + "teams": [ + { + "html_url": "https://dev-rapid7.pagerduty.com/teams/PLBLK3G", + "id": "PLBLK3G", + "self": "https://api.pagerduty.com/teams/PLBLK3G", + "summary": "Engineering", + "type": "team_reference" + } + ], + "time_zone": "Europe/London", + "type": "user" + } + ] +} \ No newline at end of file diff --git a/plugins/pagerduty/unit_test/expected/test_resolve_valid.json.exp b/plugins/pagerduty/unit_test/expected/test_resolve_valid.json.exp new file mode 100644 index 0000000000..09d5da3dfc --- /dev/null +++ b/plugins/pagerduty/unit_test/expected/test_resolve_valid.json.exp @@ -0,0 +1,83 @@ +{ + "incident": { + "acknowledgements": [], + "alert_counts": { + "all": 0, + "resolved": 0, + "triggered": 0 + }, + "assigned_via": "escalation_policy", + "assignments": [], + "created_at": "2023-10-13T10:53:01Z", + "description": "The server is on fire.", + "escalation_policy": { + "html_url": "https://dev-rapid7.pagerduty.com/escalation_policies/PKEYM28", + "id": "PKEYM28", + "self": "https://api.pagerduty.com/escalation_policies/PKEYM28", + "summary": "Default", + "type": "escalation_policy_reference" + }, + "first_trigger_log_entry": { + "html_url": "https://dev-rapid7.pagerduty.com/incidents/Q0G4WBB4K4ILLM/log_entries/R8TRH580Z2TG8C3O5QZA15ID7X", + "id": "R8TRH580Z2TG8C3O5QZA15ID7X", + "self": "https://api.pagerduty.com/log_entries/R8TRH580Z2TG8C3O5QZA15ID7X", + "summary": "Triggered through the website.", + "type": "trigger_log_entry_reference" + }, + "html_url": "https://dev-rapid7.pagerduty.com/incidents/Q0G4WBB4K4ILLM", + "id": "Q0G4WBB4K4ILLM", + "impacted_services": [ + { + "html_url": "https://dev-rapid7.pagerduty.com/service-directory/PLPY09O", + "id": "PLPY09O", + "self": "https://api.pagerduty.com/services/PLPY09O", + "summary": "new test service", + "type": "service_reference" + } + ], + "incident_key": "baf7cf21b1da41b4b0221008339ff361", + "incident_number": 14, + "incidents_responders": [], + "is_mergeable": true, + "last_status_change_at": "2023-10-13T10:53:30Z", + "last_status_change_by": { + "html_url": "https://dev-rapid7.pagerduty.com/users/PYGDZB8", + "id": "PYGDZB8", + "self": "https://api.pagerduty.com/users/PYGDZB8", + "summary": "test user", + "type": "user_reference" + }, + "pending_actions": [], + "priority": { + "account_id": "P9IAY3D", + "color": "a8171c", + "created_at": "2023-09-20T11:32:06Z", + "id": "PR0EVG8", + "name": "P1", + "order": 500000000, + "schema_version": 0, + "self": "https://api.pagerduty.com/priorities/PR0EVG8", + "summary": "P1", + "type": "priority", + "updated_at": "2023-09-20T11:32:06Z" + }, + "resolved_at": "2023-10-13T10:53:30Z", + "responder_requests": [], + "self": "https://api.pagerduty.com/incidents/Q0G4WBB4K4ILLM", + "service": { + "html_url": "https://dev-rapid7.pagerduty.com/service-directory/PLPY09O", + "id": "PLPY09O", + "self": "https://api.pagerduty.com/services/PLPY09O", + "summary": "new test service", + "type": "service_reference" + }, + "status": "resolved", + "subscriber_requests": [], + "summary": "[#14] The server is on fire.", + "teams": [], + "title": "The server is on fire.", + "type": "incident", + "updated_at": "2023-10-13T10:53:30Z", + "urgency": "high" + } +} \ No newline at end of file diff --git a/plugins/pagerduty/unit_test/expected/test_user_missing_id.json.exp b/plugins/pagerduty/unit_test/expected/test_user_missing_id.json.exp new file mode 100644 index 0000000000..16f2b180dc --- /dev/null +++ b/plugins/pagerduty/unit_test/expected/test_user_missing_id.json.exp @@ -0,0 +1,53 @@ +{ + "users": [ + { + "avatar_url": "https://secure.gravatar.com/avatar/c67b6c8ed606dec999bb064ada88cf5c.png?d=mm&r=PG", + "billed": true, + "color": "purple", + "contact_methods": [ + { + "id": "P9CU341", + "self": "https://api.pagerduty.com/users/PYGDZB8/contact_methods/P9CU341", + "summary": "Default", + "type": "email_contact_method_reference" + } + ], + "coordinated_incidents": [], + "description": "", + "email": "test@example.com", + "html_url": "https://dev-rapid7.pagerduty.com/users/PYGDZB8", + "id": "PYGDZB8", + "invitation_sent": false, + "job_title": "", + "name": "test_account_with_id", + "notification_rules": [ + { + "id": "POMMNCV", + "self": "https://api.pagerduty.com/users/PYGDZB8/notification_rules/POMMNCV", + "summary": "0 minutes: channel P9CU341", + "type": "assignment_notification_rule_reference" + }, + { + "id": "PSZNORI", + "self": "https://api.pagerduty.com/users/PYGDZB8/notification_rules/PSZNORI", + "summary": "0 minutes: channel P9CU341", + "type": "assignment_notification_rule_reference" + } + ], + "role": "owner", + "self": "https://api.pagerduty.com/users/PYGDZB8", + "summary": "test_account_with_id", + "teams": [ + { + "html_url": "https://dev-rapid7.pagerduty.com/teams/PLBLK3G", + "id": "PLBLK3G", + "self": "https://api.pagerduty.com/teams/PLBLK3G", + "summary": "Engineering", + "type": "team_reference" + } + ], + "time_zone": "Europe/London", + "type": "user" + } + ] +} \ No newline at end of file diff --git a/plugins/pagerduty/unit_test/expected/test_valid_on_call.json.exp b/plugins/pagerduty/unit_test/expected/test_valid_on_call.json.exp new file mode 100644 index 0000000000..16f2b180dc --- /dev/null +++ b/plugins/pagerduty/unit_test/expected/test_valid_on_call.json.exp @@ -0,0 +1,53 @@ +{ + "users": [ + { + "avatar_url": "https://secure.gravatar.com/avatar/c67b6c8ed606dec999bb064ada88cf5c.png?d=mm&r=PG", + "billed": true, + "color": "purple", + "contact_methods": [ + { + "id": "P9CU341", + "self": "https://api.pagerduty.com/users/PYGDZB8/contact_methods/P9CU341", + "summary": "Default", + "type": "email_contact_method_reference" + } + ], + "coordinated_incidents": [], + "description": "", + "email": "test@example.com", + "html_url": "https://dev-rapid7.pagerduty.com/users/PYGDZB8", + "id": "PYGDZB8", + "invitation_sent": false, + "job_title": "", + "name": "test_account_with_id", + "notification_rules": [ + { + "id": "POMMNCV", + "self": "https://api.pagerduty.com/users/PYGDZB8/notification_rules/POMMNCV", + "summary": "0 minutes: channel P9CU341", + "type": "assignment_notification_rule_reference" + }, + { + "id": "PSZNORI", + "self": "https://api.pagerduty.com/users/PYGDZB8/notification_rules/PSZNORI", + "summary": "0 minutes: channel P9CU341", + "type": "assignment_notification_rule_reference" + } + ], + "role": "owner", + "self": "https://api.pagerduty.com/users/PYGDZB8", + "summary": "test_account_with_id", + "teams": [ + { + "html_url": "https://dev-rapid7.pagerduty.com/teams/PLBLK3G", + "id": "PLBLK3G", + "self": "https://api.pagerduty.com/teams/PLBLK3G", + "summary": "Engineering", + "type": "team_reference" + } + ], + "time_zone": "Europe/London", + "type": "user" + } + ] +} \ No newline at end of file diff --git a/plugins/pagerduty/unit_test/expected/trigger_event_additional_fields_assignments.json.exp b/plugins/pagerduty/unit_test/expected/trigger_event_additional_fields_assignments.json.exp new file mode 100644 index 0000000000..6c269dbd53 --- /dev/null +++ b/plugins/pagerduty/unit_test/expected/trigger_event_additional_fields_assignments.json.exp @@ -0,0 +1,96 @@ +{ + "incident": { + "acknowledgements": [], + "alert_counts": { + "all": 0, + "resolved": 0, + "triggered": 0 + }, + "assigned_via": "direct_assignment", + "assignments": [ + { + "assignee": { + "html_url": "https://dev-rapid7.pagerduty.com/users/PFJIAVM", + "id": "PFJIAVM", + "self": "https://api.pagerduty.com/users/PFJIAVM", + "summary": "Test User", + "type": "user_reference" + }, + "at": "2023-10-13T16:10:00Z" + } + ], + "body": { + "details": "A disk is getting full on this machine. You should investigate what is causing the disk to fill, and ensure that there is an automated process in place for ensuring data is rotated (eg. logs should have logrotate around them). If data is expected to stay on this disk forever, you should start planning to scale up to a larger disk." + }, + "created_at": "2023-10-13T16:10:00Z", + "description": "test additional fields assignments", + "escalation_policy": { + "html_url": "https://dev-rapid7.pagerduty.com/escalation_policies/P3LATBS", + "id": "P3LATBS", + "self": "https://api.pagerduty.com/escalation_policies/P3LATBS", + "summary": "new test service-ep", + "type": "escalation_policy_reference" + }, + "first_trigger_log_entry": { + "html_url": "https://dev-rapid7.pagerduty.com/incidents/Q0Y3S4INEWMXN2/log_entries/ROE454ML7MN357NRCOM7243QES", + "id": "ROE454ML7MN357NRCOM7243QES", + "self": "https://api.pagerduty.com/log_entries/ROE454ML7MN357NRCOM7243QES", + "summary": "Triggered through the website.", + "type": "trigger_log_entry_reference" + }, + "html_url": "https://dev-rapid7.pagerduty.com/incidents/Q0Y3S4INEWMXN2", + "id": "Q0Y3S4INEWMXN2", + "impacted_services": [ + { + "html_url": "https://dev-rapid7.pagerduty.com/service-directory/PLPY09O", + "id": "PLPY09O", + "self": "https://api.pagerduty.com/services/PLPY09O", + "summary": "new test service", + "type": "service_reference" + } + ], + "incident_key": "e7dfa7ed254447a2b28e9bfef69b6709", + "incident_number": 22, + "incidents_responders": [], + "is_mergeable": true, + "last_status_change_at": "2023-10-13T16:10:00Z", + "last_status_change_by": { + "html_url": "https://dev-rapid7.pagerduty.com/service-directory/PLPY09O", + "id": "PLPY09O", + "self": "https://api.pagerduty.com/services/PLPY09O", + "summary": "new test service", + "type": "service_reference" + }, + "pending_actions": [], + "priority": { + "account_id": "P9IAY3D", + "color": "a8171c", + "created_at": "2023-09-20T11:32:06Z", + "id": "PR0EVG8", + "name": "P1", + "order": 500000000, + "schema_version": 0, + "self": "https://api.pagerduty.com/priorities/PR0EVG8", + "summary": "P1", + "type": "priority", + "updated_at": "2023-09-20T11:32:06Z" + }, + "responder_requests": [], + "self": "https://api.pagerduty.com/incidents/Q0Y3S4INEWMXN2", + "service": { + "html_url": "https://dev-rapid7.pagerduty.com/service-directory/PLPY09O", + "id": "PLPY09O", + "self": "https://api.pagerduty.com/services/PLPY09O", + "summary": "new test service", + "type": "service_reference" + }, + "status": "triggered", + "subscriber_requests": [], + "summary": "[#22] test additional fields assignments", + "teams": [], + "title": "test additional fields assignments", + "type": "incident", + "updated_at": "2023-10-13T16:10:00Z", + "urgency": "high" + } +} \ No newline at end of file diff --git a/plugins/pagerduty/unit_test/expected/trigger_event_additional_fields_escalation.json.exp b/plugins/pagerduty/unit_test/expected/trigger_event_additional_fields_escalation.json.exp new file mode 100644 index 0000000000..1484985fe9 --- /dev/null +++ b/plugins/pagerduty/unit_test/expected/trigger_event_additional_fields_escalation.json.exp @@ -0,0 +1,96 @@ +{ + "incident": { + "acknowledgements": [], + "alert_counts": { + "all": 0, + "resolved": 0, + "triggered": 0 + }, + "assigned_via": "escalation_policy", + "assignments": [ + { + "assignee": { + "html_url": "https://dev-rapid7.pagerduty.com/users/PYGDZB8", + "id": "PYGDZB8", + "self": "https://api.pagerduty.com/users/PYGDZB8", + "summary": "test@example.com", + "type": "user_reference" + }, + "at": "2023-10-13T15:59:39Z" + } + ], + "body": { + "details": "A disk is getting full on this machine. You should investigate what is causing the disk to fill, and ensure that there is an automated process in place for ensuring data is rotated (eg. logs should have logrotate around them). If data is expected to stay on this disk forever, you should start planning to scale up to a larger disk." + }, + "created_at": "2023-10-13T15:59:39Z", + "description": "test additional fields escalation", + "escalation_policy": { + "html_url": "https://dev-rapid7.pagerduty.com/escalation_policies/PKEYM28", + "id": "PKEYM28", + "self": "https://api.pagerduty.com/escalation_policies/PKEYM28", + "summary": "Default", + "type": "escalation_policy_reference" + }, + "first_trigger_log_entry": { + "html_url": "https://dev-rapid7.pagerduty.com/incidents/Q223HZVB2YUWJN/log_entries/R98U7JZHT15GCY383DCJ9GOX31", + "id": "R98U7JZHT15GCY383DCJ9GOX31", + "self": "https://api.pagerduty.com/log_entries/R98U7JZHT15GCY383DCJ9GOX31", + "summary": "Triggered through the website.", + "type": "trigger_log_entry_reference" + }, + "html_url": "https://dev-rapid7.pagerduty.com/incidents/Q223HZVB2YUWJN", + "id": "Q223HZVB2YUWJN", + "impacted_services": [ + { + "html_url": "https://dev-rapid7.pagerduty.com/service-directory/PLPY09O", + "id": "PLPY09O", + "self": "https://api.pagerduty.com/services/PLPY09O", + "summary": "new test service", + "type": "service_reference" + } + ], + "incident_key": "091aeb1d22454504b96a0357a40921ac", + "incident_number": 21, + "incidents_responders": [], + "is_mergeable": true, + "last_status_change_at": "2023-10-13T15:59:39Z", + "last_status_change_by": { + "html_url": "https://dev-rapid7.pagerduty.com/service-directory/PLPY09O", + "id": "PLPY09O", + "self": "https://api.pagerduty.com/services/PLPY09O", + "summary": "new test service", + "type": "service_reference" + }, + "pending_actions": [], + "priority": { + "account_id": "P9IAY3D", + "color": "a8171c", + "created_at": "2023-09-20T11:32:06Z", + "id": "PR0EVG8", + "name": "P1", + "order": 500000000, + "schema_version": 0, + "self": "https://api.pagerduty.com/priorities/PR0EVG8", + "summary": "P1", + "type": "priority", + "updated_at": "2023-09-20T11:32:06Z" + }, + "responder_requests": [], + "self": "https://api.pagerduty.com/incidents/Q223HZVB2YUWJN", + "service": { + "html_url": "https://dev-rapid7.pagerduty.com/service-directory/PLPY09O", + "id": "PLPY09O", + "self": "https://api.pagerduty.com/services/PLPY09O", + "summary": "new test service", + "type": "service_reference" + }, + "status": "triggered", + "subscriber_requests": [], + "summary": "[#21] test additional fields escalation", + "teams": [], + "title": "test additional fields escalation", + "type": "incident", + "updated_at": "2023-10-13T15:59:39Z", + "urgency": "high" + } +} \ No newline at end of file diff --git a/plugins/pagerduty/unit_test/expected/trigger_event_minimum_fields.json.exp b/plugins/pagerduty/unit_test/expected/trigger_event_minimum_fields.json.exp new file mode 100644 index 0000000000..f5f4eb1563 --- /dev/null +++ b/plugins/pagerduty/unit_test/expected/trigger_event_minimum_fields.json.exp @@ -0,0 +1,80 @@ +{ + "incident": { + "acknowledgements": [], + "alert_counts": { + "all": 0, + "resolved": 0, + "triggered": 0 + }, + "assigned_via": "escalation_policy", + "assignments": [ + { + "assignee": { + "html_url": "https://dev-rapid7.pagerduty.com/users/PYGDZB8", + "id": "PYGDZB8", + "self": "https://api.pagerduty.com/users/PYGDZB8", + "summary": "test user", + "type": "user_reference" + }, + "at": "2023-10-13T15:48:15Z" + } + ], + "created_at": "2023-10-13T15:48:15Z", + "description": "The server is on fire.", + "escalation_policy": { + "html_url": "https://dev-rapid7.pagerduty.com/escalation_policies/P3LATBS", + "id": "P3LATBS", + "self": "https://api.pagerduty.com/escalation_policies/P3LATBS", + "summary": "new test service-ep", + "type": "escalation_policy_reference" + }, + "first_trigger_log_entry": { + "html_url": "https://dev-rapid7.pagerduty.com/incidents/Q23JJ69D97VICC/log_entries/RQ3CR2OXPZRLM40BRHTF7DRV2U", + "id": "RQ3CR2OXPZRLM40BRHTF7DRV2U", + "self": "https://api.pagerduty.com/log_entries/RQ3CR2OXPZRLM40BRHTF7DRV2U", + "summary": "Triggered through the website.", + "type": "trigger_log_entry_reference" + }, + "html_url": "https://dev-rapid7.pagerduty.com/incidents/Q23JJ69D97VICC", + "id": "Q23JJ69D97VICC", + "impacted_services": [ + { + "html_url": "https://dev-rapid7.pagerduty.com/service-directory/PLPY09O", + "id": "PLPY09O", + "self": "https://api.pagerduty.com/services/PLPY09O", + "summary": "new test service", + "type": "service_reference" + } + ], + "incident_key": "4524dbecd65a42adb857550a4bc0dd23", + "incident_number": 19, + "incidents_responders": [], + "is_mergeable": true, + "last_status_change_at": "2023-10-13T15:48:15Z", + "last_status_change_by": { + "html_url": "https://dev-rapid7.pagerduty.com/service-directory/PLPY09O", + "id": "PLPY09O", + "self": "https://api.pagerduty.com/services/PLPY09O", + "summary": "new test service", + "type": "service_reference" + }, + "pending_actions": [], + "responder_requests": [], + "self": "https://api.pagerduty.com/incidents/Q23JJ69D97VICC", + "service": { + "html_url": "https://dev-rapid7.pagerduty.com/service-directory/PLPY09O", + "id": "PLPY09O", + "self": "https://api.pagerduty.com/services/PLPY09O", + "summary": "new test service", + "type": "service_reference" + }, + "status": "triggered", + "subscriber_requests": [], + "summary": "[#19] test minimum fields", + "teams": [], + "title": "test minimum fields", + "type": "incident", + "updated_at": "2023-10-13T15:48:15Z", + "urgency": "high" + } +} \ No newline at end of file diff --git a/plugins/pagerduty/unit_test/inputs/create_user_additional_fields.json.inp b/plugins/pagerduty/unit_test/inputs/create_user_additional_fields.json.inp new file mode 100644 index 0000000000..2467ad1f0a --- /dev/null +++ b/plugins/pagerduty/unit_test/inputs/create_user_additional_fields.json.inp @@ -0,0 +1,10 @@ +{ + "email": "test_23@test.com", + "from_email": "test_2@test.com", + "name": "Test additional fields", + "role": "admin", + "time_zone": "Europe/London", + "color": "purple", + "description": "this is a test desc", + "job_title": "engineer" +} \ No newline at end of file diff --git a/plugins/pagerduty/unit_test/inputs/create_user_api_error_fields.json.inp b/plugins/pagerduty/unit_test/inputs/create_user_api_error_fields.json.inp new file mode 100644 index 0000000000..3ee492083d --- /dev/null +++ b/plugins/pagerduty/unit_test/inputs/create_user_api_error_fields.json.inp @@ -0,0 +1,6 @@ +{ + "email": "test_3@test.com", + "from_email": "test_2@test.com", + "name": "Test api error", + "role": "admin" +} \ No newline at end of file diff --git a/plugins/pagerduty/unit_test/inputs/create_user_minimum_fields.json.inp b/plugins/pagerduty/unit_test/inputs/create_user_minimum_fields.json.inp new file mode 100644 index 0000000000..57c924b23d --- /dev/null +++ b/plugins/pagerduty/unit_test/inputs/create_user_minimum_fields.json.inp @@ -0,0 +1,6 @@ +{ + "email": "test_3@test.com", + "from_email": "test_2@test.com", + "name": "Test minimum fields", + "role": "admin" +} \ No newline at end of file diff --git a/plugins/pagerduty/unit_test/inputs/send_trigger_both_esc_asg_invalid.json.inp b/plugins/pagerduty/unit_test/inputs/send_trigger_both_esc_asg_invalid.json.inp new file mode 100644 index 0000000000..e0ef5226d9 --- /dev/null +++ b/plugins/pagerduty/unit_test/inputs/send_trigger_both_esc_asg_invalid.json.inp @@ -0,0 +1,30 @@ +{ + "email": "test@example.com", + "title": "The server is on fire.", + "service": { + "id": "PLPY09O", + "type": "service_reference" + }, + "priority": { + "id": "PR0EVG8", + "type": "priority" + }, + "urgency": "high", + "incident_key": "baf7cf21b1da41b4b0221008339ff361", + "body": { + "type": "incident_body", + "details": "A disk is getting full on this machine. You should investigate what is causing the disk to fill, and ensure that there is an automated process in place for ensuring data is rotated (eg. logs should have logrotate around them). If data is expected to stay on this disk forever, you should start planning to scale up to a larger disk." + }, + "escalation_policy": { + "id": "PKEYM28", + "type": "escalation_policy_reference" + }, + "assignments": [ + { + "assignee": { + "id": "P9FKCQ7", + "type": "user_reference" + } + } + ] +} \ No newline at end of file diff --git a/plugins/pagerduty/unit_test/inputs/trigger_event_additional_fields_assignments.json.inp b/plugins/pagerduty/unit_test/inputs/trigger_event_additional_fields_assignments.json.inp new file mode 100644 index 0000000000..8b501010a0 --- /dev/null +++ b/plugins/pagerduty/unit_test/inputs/trigger_event_additional_fields_assignments.json.inp @@ -0,0 +1,25 @@ +{ + "email": "test@example.com", + "title": "test additional fields assignments", + "service": { + "id": "PLPY09O", + "type": "service_reference" + }, + "priority": { + "id": "PR0EVG8", + "type": "priority" + }, + "urgency": "high", + "body": { + "type": "incident_body", + "details": "A disk is getting full on this machine. You should investigate what is causing the disk to fill, and ensure that there is an automated process in place for ensuring data is rotated (eg. logs should have logrotate around them). If data is expected to stay on this disk forever, you should start planning to scale up to a larger disk." + }, + "assignments": [ + { + "assignee": { + "id": "PFJIAVM", + "type": "user_reference" + } + } + ] +} \ No newline at end of file diff --git a/plugins/pagerduty/unit_test/inputs/trigger_event_additional_fields_escalation.json.inp b/plugins/pagerduty/unit_test/inputs/trigger_event_additional_fields_escalation.json.inp new file mode 100644 index 0000000000..6ca00b02c0 --- /dev/null +++ b/plugins/pagerduty/unit_test/inputs/trigger_event_additional_fields_escalation.json.inp @@ -0,0 +1,22 @@ +{ + "email": "test@example.com", + "title": "test additional fields escalation", + "service": { + "id": "PLPY09O", + "type": "service_reference" + }, + "priority": { + "id": "PR0EVG8", + "type": "priority" + }, + "urgency": "high", + "incident_key": "baf7cf21b1da41b4b0221008339ff361", + "body": { + "type": "incident_body", + "details": "A disk is getting full on this machine. You should investigate what is causing the disk to fill, and ensure that there is an automated process in place for ensuring data is rotated (eg. logs should have logrotate around them). If data is expected to stay on this disk forever, you should start planning to scale up to a larger disk." + }, + "escalation_policy": { + "id": "PKEYM28", + "type": "escalation_policy_reference" + } +} \ No newline at end of file diff --git a/plugins/pagerduty/unit_test/inputs/trigger_event_minimum_fields.json.inp b/plugins/pagerduty/unit_test/inputs/trigger_event_minimum_fields.json.inp new file mode 100644 index 0000000000..6b425e89f6 --- /dev/null +++ b/plugins/pagerduty/unit_test/inputs/trigger_event_minimum_fields.json.inp @@ -0,0 +1,8 @@ +{ + "email": "test@example.com", + "title": "test minimum fields", + "service": { + "id": "PLPY09O", + "type": "service_reference" + } +} \ No newline at end of file diff --git a/plugins/pagerduty/unit_test/responses/create_user_additional_fields.json.resp b/plugins/pagerduty/unit_test/responses/create_user_additional_fields.json.resp new file mode 100644 index 0000000000..1ae1d97871 --- /dev/null +++ b/plugins/pagerduty/unit_test/responses/create_user_additional_fields.json.resp @@ -0,0 +1,43 @@ +{ + "user": { + "avatar_url": "https://secure.gravatar.com/avatar/87dfa473571de452cf8741716cd028e2.png?d=mm&r=PG", + "billed": true, + "color": "purple", + "contact_methods": [ + { + "id": "PUA7UDS", + "self": "https://api.pagerduty.com/users/PFJIAVM/contact_methods/PUA7UDS", + "summary": "Default", + "type": "email_contact_method_reference" + } + ], + "coordinated_incidents": [], + "description": "this is a test desc", + "email": "test_23@test.com", + "html_url": "https://dev-rapid7.pagerduty.com/users/PFJIAVM", + "id": "PFJIAVM", + "invitation_sent": true, + "job_title": "engineer", + "name": "Test additional fields", + "notification_rules": [ + { + "id": "P38RX1Z", + "self": "https://api.pagerduty.com/users/PFJIAVM/notification_rules/P38RX1Z", + "summary": "0 minutes: channel PUA7UDS", + "type": "assignment_notification_rule_reference" + }, + { + "id": "P6HCXDM", + "self": "https://api.pagerduty.com/users/PFJIAVM/notification_rules/P6HCXDM", + "summary": "0 minutes: channel PUA7UDS", + "type": "assignment_notification_rule_reference" + } + ], + "role": "admin", + "self": "https://api.pagerduty.com/users/PFJIAVM", + "summary": "Test User", + "teams": [], + "time_zone": "Europe/London", + "type": "user" + } +} \ No newline at end of file diff --git a/plugins/pagerduty/unit_test/responses/create_user_minimum_fields.json.resp b/plugins/pagerduty/unit_test/responses/create_user_minimum_fields.json.resp new file mode 100644 index 0000000000..0098789307 --- /dev/null +++ b/plugins/pagerduty/unit_test/responses/create_user_minimum_fields.json.resp @@ -0,0 +1,41 @@ +{ + "user": { + "avatar_url": "https://secure.gravatar.com/avatar/663a7dbec91b9dabba93f906648dd514.png?d=mm&r=PG", + "billed": true, + "color": "green", + "contact_methods": [ + { + "id": "P050K1G", + "self": "https://api.pagerduty.com/users/PTVOCBV/contact_methods/P050K1G", + "summary": "Default", + "type": "email_contact_method_reference" + } + ], + "coordinated_incidents": [], + "email": "test_3@test.com", + "html_url": "https://dev-rapid7.pagerduty.com/users/PTVOCBV", + "id": "PTVOCBV", + "invitation_sent": true, + "name": "Test minimum fields", + "notification_rules": [ + { + "id": "PZ9BJ0K", + "self": "https://api.pagerduty.com/users/PTVOCBV/notification_rules/PZ9BJ0K", + "summary": "0 minutes: channel P050K1G", + "type": "assignment_notification_rule_reference" + }, + { + "id": "PCIMJDN", + "self": "https://api.pagerduty.com/users/PTVOCBV/notification_rules/PCIMJDN", + "summary": "0 minutes: channel P050K1G", + "type": "assignment_notification_rule_reference" + } + ], + "role": "admin", + "self": "https://api.pagerduty.com/users/PTVOCBV", + "summary": "Test minimum fields", + "teams": [], + "time_zone": "Europe/London", + "type": "user" + } +} \ No newline at end of file diff --git a/plugins/pagerduty/unit_test/responses/get_user_by_email_not_found.json.resp b/plugins/pagerduty/unit_test/responses/get_user_by_email_not_found.json.resp new file mode 100644 index 0000000000..c7c6addc0d --- /dev/null +++ b/plugins/pagerduty/unit_test/responses/get_user_by_email_not_found.json.resp @@ -0,0 +1,7 @@ +{ + "users": [], + "query": "invalid_email", + "limit": 25, + "offset": 0, + "more": false +} \ No newline at end of file diff --git a/plugins/pagerduty/unit_test/responses/get_user_by_email_valid.json.resp b/plugins/pagerduty/unit_test/responses/get_user_by_email_valid.json.resp new file mode 100644 index 0000000000..cb085d5aee --- /dev/null +++ b/plugins/pagerduty/unit_test/responses/get_user_by_email_valid.json.resp @@ -0,0 +1,47 @@ +{ + "users": [ + { + "avatar_url": "https://secure.gravatar.com/avatar/663a7dbec91b9dabba93f906648dd514.png?d=mm&r=PG", + "billed": true, + "color": "green", + "contact_methods": [ + { + "id": "P050K1G", + "self": "https://api.pagerduty.com/users/PTVOCBV/contact_methods/P050K1G", + "summary": "Default", + "type": "email_contact_method_reference" + } + ], + "coordinated_incidents": [], + "email": "valid_email", + "html_url": "https://dev-rapid7.pagerduty.com/users/PTVOCBV", + "id": "valid_id", + "invitation_sent": true, + "name": "get_user_valid", + "notification_rules": [ + { + "id": "PZ9BJ0K", + "self": "https://api.pagerduty.com/users/PTVOCBV/notification_rules/PZ9BJ0K", + "summary": "0 minutes: channel P050K1G", + "type": "assignment_notification_rule_reference" + }, + { + "id": "PCIMJDN", + "self": "https://api.pagerduty.com/users/PTVOCBV/notification_rules/PCIMJDN", + "summary": "0 minutes: channel P050K1G", + "type": "assignment_notification_rule_reference" + } + ], + "role": "admin", + "self": "https://api.pagerduty.com/users/PTVOCBV", + "summary": "get_user_valid", + "teams": [], + "time_zone": "Europe/London", + "type": "user" + } + ], + "query": "valid_email", + "limit": 25, + "offset": 0, + "more": false +} \ No newline at end of file diff --git a/plugins/pagerduty/unit_test/responses/get_user_valid.json.resp b/plugins/pagerduty/unit_test/responses/get_user_valid.json.resp new file mode 100644 index 0000000000..739fb0f991 --- /dev/null +++ b/plugins/pagerduty/unit_test/responses/get_user_valid.json.resp @@ -0,0 +1,41 @@ +{ + "user": { + "avatar_url": "https://secure.gravatar.com/avatar/663a7dbec91b9dabba93f906648dd514.png?d=mm&r=PG", + "billed": true, + "color": "green", + "contact_methods": [ + { + "id": "P050K1G", + "self": "https://api.pagerduty.com/users/PTVOCBV/contact_methods/P050K1G", + "summary": "Default", + "type": "email_contact_method_reference" + } + ], + "coordinated_incidents": [], + "email": "test_3@test.com", + "html_url": "https://dev-rapid7.pagerduty.com/users/PTVOCBV", + "id": "valid_id", + "invitation_sent": true, + "name": "get_user_valid", + "notification_rules": [ + { + "id": "PZ9BJ0K", + "self": "https://api.pagerduty.com/users/PTVOCBV/notification_rules/PZ9BJ0K", + "summary": "0 minutes: channel P050K1G", + "type": "assignment_notification_rule_reference" + }, + { + "id": "PCIMJDN", + "self": "https://api.pagerduty.com/users/PTVOCBV/notification_rules/PCIMJDN", + "summary": "0 minutes: channel P050K1G", + "type": "assignment_notification_rule_reference" + } + ], + "role": "admin", + "self": "https://api.pagerduty.com/users/PTVOCBV", + "summary": "get_user_valid", + "teams": [], + "time_zone": "Europe/London", + "type": "user" + } +} \ No newline at end of file diff --git a/plugins/pagerduty/unit_test/responses/test_acknowledge_valid.json.resp b/plugins/pagerduty/unit_test/responses/test_acknowledge_valid.json.resp new file mode 100644 index 0000000000..df6009ad9b --- /dev/null +++ b/plugins/pagerduty/unit_test/responses/test_acknowledge_valid.json.resp @@ -0,0 +1,91 @@ +{ + "incident": { + "acknowledgements": [ + { + "acknowledger": { + "html_url": "https://dev-rapid7.pagerduty.com/users/PYGDZB8", + "id": "PYGDZB8", + "self": "https://api.pagerduty.com/users/PYGDZB8", + "summary": "test user", + "type": "user_reference" + }, + "at": "2023-10-13T14:55:07Z" + } + ], + "alert_counts": { + "all": 0, + "resolved": 0, + "triggered": 0 + }, + "assigned_via": "escalation_policy", + "assignments": [ + { + "assignee": { + "html_url": "https://dev-rapid7.pagerduty.com/users/PYGDZB8", + "id": "PYGDZB8", + "self": "https://api.pagerduty.com/users/PYGDZB8", + "summary": "test user", + "type": "user_reference" + }, + "at": "2023-10-13T14:54:58Z" + } + ], + "created_at": "2023-10-13T14:54:58Z", + "description": "test ack", + "escalation_policy": { + "html_url": "https://dev-rapid7.pagerduty.com/escalation_policies/PJINSTN", + "id": "PJINSTN", + "self": "https://api.pagerduty.com/escalation_policies/PJINSTN", + "summary": "Test Service-ep", + "type": "escalation_policy_reference" + }, + "first_trigger_log_entry": { + "html_url": "https://dev-rapid7.pagerduty.com/incidents/Q1R042KMH6D067/log_entries/R87EKJ59GRGLRWK7RPE9YWXQ9Y", + "id": "R87EKJ59GRGLRWK7RPE9YWXQ9Y", + "self": "https://api.pagerduty.com/log_entries/R87EKJ59GRGLRWK7RPE9YWXQ9Y", + "summary": "Triggered through the website.", + "type": "trigger_log_entry_reference" + }, + "html_url": "https://dev-rapid7.pagerduty.com/incidents/Q1R042KMH6D067", + "id": "Q1R042KMH6D067", + "impacted_services": [ + { + "html_url": "https://dev-rapid7.pagerduty.com/service-directory/PF8TUEU", + "id": "PF8TUEU", + "self": "https://api.pagerduty.com/services/PF8TUEU", + "summary": "Test Service", + "type": "service_reference" + } + ], + "incident_key": "0594f9d98f3747179b052ba708d3e1d1", + "incident_number": 18, + "incidents_responders": [], + "is_mergeable": true, + "last_status_change_at": "2023-10-13T14:55:07Z", + "last_status_change_by": { + "html_url": "https://dev-rapid7.pagerduty.com/users/PYGDZB8", + "id": "PYGDZB8", + "self": "https://api.pagerduty.com/users/PYGDZB8", + "summary": "test user", + "type": "user_reference" + }, + "pending_actions": [], + "responder_requests": [], + "self": "https://api.pagerduty.com/incidents/Q1R042KMH6D067", + "service": { + "html_url": "https://dev-rapid7.pagerduty.com/service-directory/PF8TUEU", + "id": "PF8TUEU", + "self": "https://api.pagerduty.com/services/PF8TUEU", + "summary": "Test Service", + "type": "service_reference" + }, + "status": "acknowledged", + "subscriber_requests": [], + "summary": "[#18] test ack", + "teams": [], + "title": "test ack", + "type": "incident", + "updated_at": "2023-10-13T14:55:07Z", + "urgency": "high" + } +} \ No newline at end of file diff --git a/plugins/pagerduty/unit_test/responses/test_cannot_find_user.json.resp b/plugins/pagerduty/unit_test/responses/test_cannot_find_user.json.resp new file mode 100644 index 0000000000..34a5293ac9 --- /dev/null +++ b/plugins/pagerduty/unit_test/responses/test_cannot_find_user.json.resp @@ -0,0 +1,55 @@ +{ + "schedule": { + "users": [ + { + "avatar_url": "https://secure.gravatar.com/avatar/c67b6c8ed606dec999bb064ada88cf5c.png?d=mm&r=PG", + "billed": true, + "color": "purple", + "contact_methods": [ + { + "id": "P9CU341", + "self": "https://api.pagerduty.com/users/PYGDZB8/contact_methods/P9CU341", + "summary": "Default", + "type": "email_contact_method_reference" + } + ], + "coordinated_incidents": [], + "description": "", + "email": "test@example.com", + "html_url": "https://dev-rapid7.pagerduty.com/users/PYGDZB8", + "id": "PYGDZB9", + "invitation_sent": false, + "job_title": "", + "name": "test_account_with_id", + "notification_rules": [ + { + "id": "POMMNCV", + "self": "https://api.pagerduty.com/users/PYGDZB8/notification_rules/POMMNCV", + "summary": "0 minutes: channel P9CU341", + "type": "assignment_notification_rule_reference" + }, + { + "id": "PSZNORI", + "self": "https://api.pagerduty.com/users/PYGDZB8/notification_rules/PSZNORI", + "summary": "0 minutes: channel P9CU341", + "type": "assignment_notification_rule_reference" + } + ], + "role": "owner", + "self": "https://api.pagerduty.com/users/PYGDZB8", + "summary": "test_account_with_id", + "teams": [ + { + "html_url": "https://dev-rapid7.pagerduty.com/teams/PLBLK3G", + "id": "PLBLK3G", + "self": "https://api.pagerduty.com/teams/PLBLK3G", + "summary": "Engineering", + "type": "team_reference" + } + ], + "time_zone": "Europe/London", + "type": "user" + } + ] + } +} \ No newline at end of file diff --git a/plugins/pagerduty/unit_test/responses/test_deleted_user.json.resp b/plugins/pagerduty/unit_test/responses/test_deleted_user.json.resp new file mode 100644 index 0000000000..fde55e0d1b --- /dev/null +++ b/plugins/pagerduty/unit_test/responses/test_deleted_user.json.resp @@ -0,0 +1,62 @@ +{ + "schedule": { + "users": [ + { + "avatar_url": "https://secure.gravatar.com/avatar/c67b6c8ed606dec999bb064ada88cf5c.png?d=mm&r=PG", + "billed": true, + "color": "purple", + "contact_methods": [ + { + "id": "P9CU341", + "self": "https://api.pagerduty.com/users/PYGDZB8/contact_methods/P9CU341", + "summary": "Default", + "type": "email_contact_method_reference" + } + ], + "coordinated_incidents": [], + "description": "", + "email": "test@example.com", + "html_url": "https://dev-rapid7.pagerduty.com/users/PYGDZB8", + "id": "PYGDZB8", + "invitation_sent": false, + "job_title": "", + "name": "test_account_with_id", + "notification_rules": [ + { + "id": "POMMNCV", + "self": "https://api.pagerduty.com/users/PYGDZB8/notification_rules/POMMNCV", + "summary": "0 minutes: channel P9CU341", + "type": "assignment_notification_rule_reference" + }, + { + "id": "PSZNORI", + "self": "https://api.pagerduty.com/users/PYGDZB8/notification_rules/PSZNORI", + "summary": "0 minutes: channel P9CU341", + "type": "assignment_notification_rule_reference" + } + ], + "role": "owner", + "self": "https://api.pagerduty.com/users/PYGDZB8", + "summary": "test_account_with_id", + "teams": [ + { + "html_url": "https://dev-rapid7.pagerduty.com/teams/PLBLK3G", + "id": "PLBLK3G", + "self": "https://api.pagerduty.com/teams/PLBLK3G", + "summary": "Engineering", + "type": "team_reference" + } + ], + "time_zone": "Europe/London", + "type": "user" + }, + { + "id": "P9FKCQ7", + "type": "user_reference", + "summary": "test from icon", + "html_url": "https://dev-rapid7.pagerduty.com/users/P9FKCQ7", + "deleted_at": "2023-10-12T18:24:30+01:00" + } + ] + } +} \ No newline at end of file diff --git a/plugins/pagerduty/unit_test/responses/test_get_on_call_no_users.json.resp b/plugins/pagerduty/unit_test/responses/test_get_on_call_no_users.json.resp new file mode 100644 index 0000000000..ce164e07f5 --- /dev/null +++ b/plugins/pagerduty/unit_test/responses/test_get_on_call_no_users.json.resp @@ -0,0 +1,3 @@ +{ + "schedules" : {} +} \ No newline at end of file diff --git a/plugins/pagerduty/unit_test/responses/test_resolve_valid.json.resp b/plugins/pagerduty/unit_test/responses/test_resolve_valid.json.resp new file mode 100644 index 0000000000..09d5da3dfc --- /dev/null +++ b/plugins/pagerduty/unit_test/responses/test_resolve_valid.json.resp @@ -0,0 +1,83 @@ +{ + "incident": { + "acknowledgements": [], + "alert_counts": { + "all": 0, + "resolved": 0, + "triggered": 0 + }, + "assigned_via": "escalation_policy", + "assignments": [], + "created_at": "2023-10-13T10:53:01Z", + "description": "The server is on fire.", + "escalation_policy": { + "html_url": "https://dev-rapid7.pagerduty.com/escalation_policies/PKEYM28", + "id": "PKEYM28", + "self": "https://api.pagerduty.com/escalation_policies/PKEYM28", + "summary": "Default", + "type": "escalation_policy_reference" + }, + "first_trigger_log_entry": { + "html_url": "https://dev-rapid7.pagerduty.com/incidents/Q0G4WBB4K4ILLM/log_entries/R8TRH580Z2TG8C3O5QZA15ID7X", + "id": "R8TRH580Z2TG8C3O5QZA15ID7X", + "self": "https://api.pagerduty.com/log_entries/R8TRH580Z2TG8C3O5QZA15ID7X", + "summary": "Triggered through the website.", + "type": "trigger_log_entry_reference" + }, + "html_url": "https://dev-rapid7.pagerduty.com/incidents/Q0G4WBB4K4ILLM", + "id": "Q0G4WBB4K4ILLM", + "impacted_services": [ + { + "html_url": "https://dev-rapid7.pagerduty.com/service-directory/PLPY09O", + "id": "PLPY09O", + "self": "https://api.pagerduty.com/services/PLPY09O", + "summary": "new test service", + "type": "service_reference" + } + ], + "incident_key": "baf7cf21b1da41b4b0221008339ff361", + "incident_number": 14, + "incidents_responders": [], + "is_mergeable": true, + "last_status_change_at": "2023-10-13T10:53:30Z", + "last_status_change_by": { + "html_url": "https://dev-rapid7.pagerduty.com/users/PYGDZB8", + "id": "PYGDZB8", + "self": "https://api.pagerduty.com/users/PYGDZB8", + "summary": "test user", + "type": "user_reference" + }, + "pending_actions": [], + "priority": { + "account_id": "P9IAY3D", + "color": "a8171c", + "created_at": "2023-09-20T11:32:06Z", + "id": "PR0EVG8", + "name": "P1", + "order": 500000000, + "schema_version": 0, + "self": "https://api.pagerduty.com/priorities/PR0EVG8", + "summary": "P1", + "type": "priority", + "updated_at": "2023-09-20T11:32:06Z" + }, + "resolved_at": "2023-10-13T10:53:30Z", + "responder_requests": [], + "self": "https://api.pagerduty.com/incidents/Q0G4WBB4K4ILLM", + "service": { + "html_url": "https://dev-rapid7.pagerduty.com/service-directory/PLPY09O", + "id": "PLPY09O", + "self": "https://api.pagerduty.com/services/PLPY09O", + "summary": "new test service", + "type": "service_reference" + }, + "status": "resolved", + "subscriber_requests": [], + "summary": "[#14] The server is on fire.", + "teams": [], + "title": "The server is on fire.", + "type": "incident", + "updated_at": "2023-10-13T10:53:30Z", + "urgency": "high" + } +} \ No newline at end of file diff --git a/plugins/pagerduty/unit_test/responses/test_user_missing_id.json.resp b/plugins/pagerduty/unit_test/responses/test_user_missing_id.json.resp new file mode 100644 index 0000000000..61e1497f74 --- /dev/null +++ b/plugins/pagerduty/unit_test/responses/test_user_missing_id.json.resp @@ -0,0 +1,103 @@ +{ + "schedule": { + "users": [ + { + "avatar_url": "https://secure.gravatar.com/avatar/c67b6c8ed606dec999bb064ada88cf5c.png?d=mm&r=PG", + "billed": true, + "color": "purple", + "contact_methods": [ + { + "id": "P9CU341", + "self": "https://api.pagerduty.com/users/PYGDZB8/contact_methods/P9CU341", + "summary": "Default", + "type": "email_contact_method_reference" + } + ], + "coordinated_incidents": [], + "description": "", + "email": "test@example.com", + "html_url": "https://dev-rapid7.pagerduty.com/users/PYGDZB8", + "id": "PYGDZB8", + "invitation_sent": false, + "job_title": "", + "name": "test_account_with_id", + "notification_rules": [ + { + "id": "POMMNCV", + "self": "https://api.pagerduty.com/users/PYGDZB8/notification_rules/POMMNCV", + "summary": "0 minutes: channel P9CU341", + "type": "assignment_notification_rule_reference" + }, + { + "id": "PSZNORI", + "self": "https://api.pagerduty.com/users/PYGDZB8/notification_rules/PSZNORI", + "summary": "0 minutes: channel P9CU341", + "type": "assignment_notification_rule_reference" + } + ], + "role": "owner", + "self": "https://api.pagerduty.com/users/PYGDZB8", + "summary": "test_account_with_id", + "teams": [ + { + "html_url": "https://dev-rapid7.pagerduty.com/teams/PLBLK3G", + "id": "PLBLK3G", + "self": "https://api.pagerduty.com/teams/PLBLK3G", + "summary": "Engineering", + "type": "team_reference" + } + ], + "time_zone": "Europe/London", + "type": "user" + }, + { + "avatar_url": "https://secure.gravatar.com/avatar/c67b6c8ed606dec999bb064ada88cf5c.png?d=mm&r=PG", + "billed": true, + "color": "purple", + "contact_methods": [ + { + "id": "P9CU341", + "self": "https://api.pagerduty.com/users/PYGDZB8/contact_methods/P9CU341", + "summary": "Default", + "type": "email_contact_method_reference" + } + ], + "coordinated_incidents": [], + "description": "", + "email": "test@example.com", + "html_url": "https://dev-rapid7.pagerduty.com/users/PYGDZB8", + "invitation_sent": false, + "job_title": "", + "name": "test_account_without_id", + "notification_rules": [ + { + "id": "POMMNCV", + "self": "https://api.pagerduty.com/users/PYGDZB8/notification_rules/POMMNCV", + "summary": "0 minutes: channel P9CU341", + "type": "assignment_notification_rule_reference" + }, + { + "id": "PSZNORI", + "self": "https://api.pagerduty.com/users/PYGDZB8/notification_rules/PSZNORI", + "summary": "0 minutes: channel P9CU341", + "type": "assignment_notification_rule_reference" + } + ], + "role": "owner", + "self": "https://api.pagerduty.com/users/PYGDZB8", + "summary": "test_account_with_id", + "teams": [ + { + "html_url": "https://dev-rapid7.pagerduty.com/teams/PLBLK3G", + "id": "PLBLK3G", + "self": "https://api.pagerduty.com/teams/PLBLK3G", + "summary": "Engineering", + "type": "team_reference" + } + ], + "time_zone": "Europe/London", + "type": "user" + } + ] + } +} \ No newline at end of file diff --git a/plugins/pagerduty/unit_test/responses/test_valid_on_call.json.resp b/plugins/pagerduty/unit_test/responses/test_valid_on_call.json.resp new file mode 100644 index 0000000000..cc4cb15621 --- /dev/null +++ b/plugins/pagerduty/unit_test/responses/test_valid_on_call.json.resp @@ -0,0 +1,55 @@ +{ + "schedule": { + "users": [ + { + "avatar_url": "https://secure.gravatar.com/avatar/c67b6c8ed606dec999bb064ada88cf5c.png?d=mm&r=PG", + "billed": true, + "color": "purple", + "contact_methods": [ + { + "id": "P9CU341", + "self": "https://api.pagerduty.com/users/PYGDZB8/contact_methods/P9CU341", + "summary": "Default", + "type": "email_contact_method_reference" + } + ], + "coordinated_incidents": [], + "description": "", + "email": "test@example.com", + "html_url": "https://dev-rapid7.pagerduty.com/users/PYGDZB8", + "id": "PYGDZB8", + "invitation_sent": false, + "job_title": "", + "name": "test_account_with_id", + "notification_rules": [ + { + "id": "POMMNCV", + "self": "https://api.pagerduty.com/users/PYGDZB8/notification_rules/POMMNCV", + "summary": "0 minutes: channel P9CU341", + "type": "assignment_notification_rule_reference" + }, + { + "id": "PSZNORI", + "self": "https://api.pagerduty.com/users/PYGDZB8/notification_rules/PSZNORI", + "summary": "0 minutes: channel P9CU341", + "type": "assignment_notification_rule_reference" + } + ], + "role": "owner", + "self": "https://api.pagerduty.com/users/PYGDZB8", + "summary": "test_account_with_id", + "teams": [ + { + "html_url": "https://dev-rapid7.pagerduty.com/teams/PLBLK3G", + "id": "PLBLK3G", + "self": "https://api.pagerduty.com/teams/PLBLK3G", + "summary": "Engineering", + "type": "team_reference" + } + ], + "time_zone": "Europe/London", + "type": "user" + } + ] + } +} \ No newline at end of file diff --git a/plugins/pagerduty/unit_test/responses/trigger_event_additional_fields_assignments.json.resp b/plugins/pagerduty/unit_test/responses/trigger_event_additional_fields_assignments.json.resp new file mode 100644 index 0000000000..f3a228d959 --- /dev/null +++ b/plugins/pagerduty/unit_test/responses/trigger_event_additional_fields_assignments.json.resp @@ -0,0 +1,96 @@ +{ + "incident": { + "acknowledgements": [], + "alert_counts": { + "all": 0, + "resolved": 0, + "triggered": 0 + }, + "assigned_via": "direct_assignment", + "assignments": [ + { + "assignee": { + "html_url": "https://dev-rapid7.pagerduty.com/users/PFJIAVM", + "id": "PFJIAVM", + "self": "https://api.pagerduty.com/users/PFJIAVM", + "summary": "Test User", + "type": "user_reference" + }, + "at": "2023-10-13T16:10:00Z" + } + ], + "body": { + "details": "A disk is getting full on this machine. You should investigate what is causing the disk to fill, and ensure that there is an automated process in place for ensuring data is rotated (eg. logs should have logrotate around them). If data is expected to stay on this disk forever, you should start planning to scale up to a larger disk." + }, + "created_at": "2023-10-13T16:10:00Z", + "description": "test additional fields assignments", + "escalation_policy": { + "html_url": "https://dev-rapid7.pagerduty.com/escalation_policies/P3LATBS", + "id": "P3LATBS", + "self": "https://api.pagerduty.com/escalation_policies/P3LATBS", + "summary": "new test service-ep", + "type": "escalation_policy_reference" + }, + "first_trigger_log_entry": { + "html_url": "https://dev-rapid7.pagerduty.com/incidents/Q0Y3S4INEWMXN2/log_entries/ROE454ML7MN357NRCOM7243QES", + "id": "ROE454ML7MN357NRCOM7243QES", + "self": "https://api.pagerduty.com/log_entries/ROE454ML7MN357NRCOM7243QES", + "summary": "Triggered through the website.", + "type": "trigger_log_entry_reference" + }, + "html_url": "https://dev-rapid7.pagerduty.com/incidents/Q0Y3S4INEWMXN2", + "id": "Q0Y3S4INEWMXN2", + "impacted_services": [ + { + "html_url": "https://dev-rapid7.pagerduty.com/service-directory/PLPY09O", + "id": "PLPY09O", + "self": "https://api.pagerduty.com/services/PLPY09O", + "summary": "new test service", + "type": "service_reference" + } + ], + "incident_key": "e7dfa7ed254447a2b28e9bfef69b6709", + "incident_number": 22, + "incidents_responders": [], + "is_mergeable": true, + "last_status_change_at": "2023-10-13T16:10:00Z", + "last_status_change_by": { + "html_url": "https://dev-rapid7.pagerduty.com/service-directory/PLPY09O", + "id": "PLPY09O", + "self": "https://api.pagerduty.com/services/PLPY09O", + "summary": "new test service", + "type": "service_reference" + }, + "pending_actions": [], + "priority": { + "account_id": "P9IAY3D", + "color": "a8171c", + "created_at": "2023-09-20T11:32:06Z", + "id": "PR0EVG8", + "name": "P1", + "order": 500000000, + "schema_version": 0, + "self": "https://api.pagerduty.com/priorities/PR0EVG8", + "summary": "P1", + "type": "priority", + "updated_at": "2023-09-20T11:32:06Z" + }, + "responder_requests": [], + "self": "https://api.pagerduty.com/incidents/Q0Y3S4INEWMXN2", + "service": { + "html_url": "https://dev-rapid7.pagerduty.com/service-directory/PLPY09O", + "id": "PLPY09O", + "self": "https://api.pagerduty.com/services/PLPY09O", + "summary": "new test service", + "type": "service_reference" + }, + "status": "triggered", + "subscriber_requests": [], + "summary": "[#22] test additional fields assignments", + "teams": [], + "title": "test additional fields assignments", + "type": "incident", + "updated_at": "2023-10-13T16:10:00Z", + "urgency": "high" + } +} \ No newline at end of file diff --git a/plugins/pagerduty/unit_test/responses/trigger_event_additional_fields_escalation.json.resp b/plugins/pagerduty/unit_test/responses/trigger_event_additional_fields_escalation.json.resp new file mode 100644 index 0000000000..1484985fe9 --- /dev/null +++ b/plugins/pagerduty/unit_test/responses/trigger_event_additional_fields_escalation.json.resp @@ -0,0 +1,96 @@ +{ + "incident": { + "acknowledgements": [], + "alert_counts": { + "all": 0, + "resolved": 0, + "triggered": 0 + }, + "assigned_via": "escalation_policy", + "assignments": [ + { + "assignee": { + "html_url": "https://dev-rapid7.pagerduty.com/users/PYGDZB8", + "id": "PYGDZB8", + "self": "https://api.pagerduty.com/users/PYGDZB8", + "summary": "test@example.com", + "type": "user_reference" + }, + "at": "2023-10-13T15:59:39Z" + } + ], + "body": { + "details": "A disk is getting full on this machine. You should investigate what is causing the disk to fill, and ensure that there is an automated process in place for ensuring data is rotated (eg. logs should have logrotate around them). If data is expected to stay on this disk forever, you should start planning to scale up to a larger disk." + }, + "created_at": "2023-10-13T15:59:39Z", + "description": "test additional fields escalation", + "escalation_policy": { + "html_url": "https://dev-rapid7.pagerduty.com/escalation_policies/PKEYM28", + "id": "PKEYM28", + "self": "https://api.pagerduty.com/escalation_policies/PKEYM28", + "summary": "Default", + "type": "escalation_policy_reference" + }, + "first_trigger_log_entry": { + "html_url": "https://dev-rapid7.pagerduty.com/incidents/Q223HZVB2YUWJN/log_entries/R98U7JZHT15GCY383DCJ9GOX31", + "id": "R98U7JZHT15GCY383DCJ9GOX31", + "self": "https://api.pagerduty.com/log_entries/R98U7JZHT15GCY383DCJ9GOX31", + "summary": "Triggered through the website.", + "type": "trigger_log_entry_reference" + }, + "html_url": "https://dev-rapid7.pagerduty.com/incidents/Q223HZVB2YUWJN", + "id": "Q223HZVB2YUWJN", + "impacted_services": [ + { + "html_url": "https://dev-rapid7.pagerduty.com/service-directory/PLPY09O", + "id": "PLPY09O", + "self": "https://api.pagerduty.com/services/PLPY09O", + "summary": "new test service", + "type": "service_reference" + } + ], + "incident_key": "091aeb1d22454504b96a0357a40921ac", + "incident_number": 21, + "incidents_responders": [], + "is_mergeable": true, + "last_status_change_at": "2023-10-13T15:59:39Z", + "last_status_change_by": { + "html_url": "https://dev-rapid7.pagerduty.com/service-directory/PLPY09O", + "id": "PLPY09O", + "self": "https://api.pagerduty.com/services/PLPY09O", + "summary": "new test service", + "type": "service_reference" + }, + "pending_actions": [], + "priority": { + "account_id": "P9IAY3D", + "color": "a8171c", + "created_at": "2023-09-20T11:32:06Z", + "id": "PR0EVG8", + "name": "P1", + "order": 500000000, + "schema_version": 0, + "self": "https://api.pagerduty.com/priorities/PR0EVG8", + "summary": "P1", + "type": "priority", + "updated_at": "2023-09-20T11:32:06Z" + }, + "responder_requests": [], + "self": "https://api.pagerduty.com/incidents/Q223HZVB2YUWJN", + "service": { + "html_url": "https://dev-rapid7.pagerduty.com/service-directory/PLPY09O", + "id": "PLPY09O", + "self": "https://api.pagerduty.com/services/PLPY09O", + "summary": "new test service", + "type": "service_reference" + }, + "status": "triggered", + "subscriber_requests": [], + "summary": "[#21] test additional fields escalation", + "teams": [], + "title": "test additional fields escalation", + "type": "incident", + "updated_at": "2023-10-13T15:59:39Z", + "urgency": "high" + } +} \ No newline at end of file diff --git a/plugins/pagerduty/unit_test/responses/trigger_event_minimum_fields.json.resp b/plugins/pagerduty/unit_test/responses/trigger_event_minimum_fields.json.resp new file mode 100644 index 0000000000..f5f4eb1563 --- /dev/null +++ b/plugins/pagerduty/unit_test/responses/trigger_event_minimum_fields.json.resp @@ -0,0 +1,80 @@ +{ + "incident": { + "acknowledgements": [], + "alert_counts": { + "all": 0, + "resolved": 0, + "triggered": 0 + }, + "assigned_via": "escalation_policy", + "assignments": [ + { + "assignee": { + "html_url": "https://dev-rapid7.pagerduty.com/users/PYGDZB8", + "id": "PYGDZB8", + "self": "https://api.pagerduty.com/users/PYGDZB8", + "summary": "test user", + "type": "user_reference" + }, + "at": "2023-10-13T15:48:15Z" + } + ], + "created_at": "2023-10-13T15:48:15Z", + "description": "The server is on fire.", + "escalation_policy": { + "html_url": "https://dev-rapid7.pagerduty.com/escalation_policies/P3LATBS", + "id": "P3LATBS", + "self": "https://api.pagerduty.com/escalation_policies/P3LATBS", + "summary": "new test service-ep", + "type": "escalation_policy_reference" + }, + "first_trigger_log_entry": { + "html_url": "https://dev-rapid7.pagerduty.com/incidents/Q23JJ69D97VICC/log_entries/RQ3CR2OXPZRLM40BRHTF7DRV2U", + "id": "RQ3CR2OXPZRLM40BRHTF7DRV2U", + "self": "https://api.pagerduty.com/log_entries/RQ3CR2OXPZRLM40BRHTF7DRV2U", + "summary": "Triggered through the website.", + "type": "trigger_log_entry_reference" + }, + "html_url": "https://dev-rapid7.pagerduty.com/incidents/Q23JJ69D97VICC", + "id": "Q23JJ69D97VICC", + "impacted_services": [ + { + "html_url": "https://dev-rapid7.pagerduty.com/service-directory/PLPY09O", + "id": "PLPY09O", + "self": "https://api.pagerduty.com/services/PLPY09O", + "summary": "new test service", + "type": "service_reference" + } + ], + "incident_key": "4524dbecd65a42adb857550a4bc0dd23", + "incident_number": 19, + "incidents_responders": [], + "is_mergeable": true, + "last_status_change_at": "2023-10-13T15:48:15Z", + "last_status_change_by": { + "html_url": "https://dev-rapid7.pagerduty.com/service-directory/PLPY09O", + "id": "PLPY09O", + "self": "https://api.pagerduty.com/services/PLPY09O", + "summary": "new test service", + "type": "service_reference" + }, + "pending_actions": [], + "responder_requests": [], + "self": "https://api.pagerduty.com/incidents/Q23JJ69D97VICC", + "service": { + "html_url": "https://dev-rapid7.pagerduty.com/service-directory/PLPY09O", + "id": "PLPY09O", + "self": "https://api.pagerduty.com/services/PLPY09O", + "summary": "new test service", + "type": "service_reference" + }, + "status": "triggered", + "subscriber_requests": [], + "summary": "[#19] test minimum fields", + "teams": [], + "title": "test minimum fields", + "type": "incident", + "updated_at": "2023-10-13T15:48:15Z", + "urgency": "high" + } +} \ No newline at end of file diff --git a/plugins/pagerduty/unit_test/responses/valid_get_on_call_user.json.resp b/plugins/pagerduty/unit_test/responses/valid_get_on_call_user.json.resp new file mode 100644 index 0000000000..4763a69d4a --- /dev/null +++ b/plugins/pagerduty/unit_test/responses/valid_get_on_call_user.json.resp @@ -0,0 +1,51 @@ +{ + "user":{ + "avatar_url": "https://secure.gravatar.com/avatar/c67b6c8ed606dec999bb064ada88cf5c.png?d=mm&r=PG", + "billed": true, + "color": "purple", + "contact_methods": [ + { + "id": "P9CU341", + "self": "https://api.pagerduty.com/users/PYGDZB8/contact_methods/P9CU341", + "summary": "Default", + "type": "email_contact_method_reference" + } + ], + "coordinated_incidents": [], + "description": "", + "email": "test@example.com", + "html_url": "https://dev-rapid7.pagerduty.com/users/PYGDZB8", + "id": "PYGDZB8", + "invitation_sent": false, + "job_title": "", + "name": "test_account_with_id", + "notification_rules": [ + { + "id": "POMMNCV", + "self": "https://api.pagerduty.com/users/PYGDZB8/notification_rules/POMMNCV", + "summary": "0 minutes: channel P9CU341", + "type": "assignment_notification_rule_reference" + }, + { + "id": "PSZNORI", + "self": "https://api.pagerduty.com/users/PYGDZB8/notification_rules/PSZNORI", + "summary": "0 minutes: channel P9CU341", + "type": "assignment_notification_rule_reference" + } + ], + "role": "owner", + "self": "https://api.pagerduty.com/users/PYGDZB8", + "summary": "test_account_with_id", + "teams": [ + { + "html_url": "https://dev-rapid7.pagerduty.com/teams/PLBLK3G", + "id": "PLBLK3G", + "self": "https://api.pagerduty.com/teams/PLBLK3G", + "summary": "Engineering", + "type": "team_reference" + } + ], + "time_zone": "Europe/London", + "type": "user" + } +} \ No newline at end of file diff --git a/plugins/pagerduty/unit_test/test_create_user.py b/plugins/pagerduty/unit_test/test_create_user.py index 475612ec69..d695224ea8 100644 --- a/plugins/pagerduty/unit_test/test_create_user.py +++ b/plugins/pagerduty/unit_test/test_create_user.py @@ -4,69 +4,51 @@ sys.path.append(os.path.abspath("../")) from unittest import TestCase -from komand_pagerduty.connection.connection import Connection from komand_pagerduty.actions.create_user import CreateUser -import json -import logging +from unittest.mock import patch, MagicMock +from parameterized import parameterized +from util import Util +from insightconnect_plugin_runtime.exceptions import PluginException +@patch("requests.Session.request", side_effect=Util.mock_request) class TestCreateUser(TestCase): - def test_integration_create_user(self): - """ - TODO: Implement assertions at the end of this test case - - This is an integration test that will connect to the services your plugin uses. It should be used - as the basis for tests below that can run independent of a "live" connection. - - This test assumes a normal plugin structure with a /tests directory. In that /tests directory should - be json samples that contain all the data needed to run this test. To generate samples run: - - icon-plugin generate samples - - """ - - log = logging.getLogger("Test") - test_conn = Connection() - test_action = CreateUser() - - test_conn.logger = log - test_action.logger = log - - try: - with open("../tests/create_user.json") as file: - test_json = json.loads(file.read()).get("body") - connection_params = test_json.get("connection") - action_params = test_json.get("input") - except Exception as e: - message = """ - Could not find or read sample tests from /tests directory - - An exception here likely means you didn't fill out your samples correctly in the /tests directory - Please use 'icon-plugin generate samples', and fill out the resulting test files in the /tests directory - """ - self.fail(message) - - test_conn.connect(connection_params) - test_action.connection = test_conn - results = test_action.run(action_params) - - # TODO: Remove this line - self.fail("Unimplemented test case") - - # TODO: The following assert should be updated to look for data from your action - # For example: self.assertEquals({"success": True}, results) - self.assertEquals({}, results) - - def test_create_user(self): - """ - TODO: Implement test cases here - - Here you can mock the connection with data returned from the above integration test. - For information on mocking and unit testing please go here: - - https://docs.google.com/document/d/1PifePDG1-mBcmNYE8dULwGxJimiRBrax5BIDG_0TFQI/edit?usp=sharing - - You can either create a formal Mock for this, or you can create a fake connection class to pass to your - action for testing. - """ - self.fail("Unimplemented Test Case") + @classmethod + def setUpClass(cls) -> None: + cls.action = Util.default_connector(CreateUser()) + + @parameterized.expand( + [ + [ + "minimum_valid", + Util.read_file_to_dict("inputs/create_user_minimum_fields.json.inp"), + Util.read_file_to_dict("expected/create_user_minimum_fields.json.exp"), + ], + [ + "additional_fields_valid", + Util.read_file_to_dict("inputs/create_user_additional_fields.json.inp"), + Util.read_file_to_dict("expected/create_user_additional_fields.json.exp"), + ], + ] + ) + def test_create_user_valid(self, _mock_request: MagicMock, _test_name: str, input_params: dict, expected: dict): + actual = self.action.run(input_params) + self.assertEqual(actual, expected) + + @parameterized.expand( + [ + [ + "api_error_invalid", + Util.read_file_to_dict("inputs/create_user_api_error_fields.json.inp"), + "Server error occurred", + "Verify your plugin connection inputs are correct and not malformed and try again. If the issue persists, please contact support.", + ] + ] + ) + def test_api_error_invalid( + self, _mock_request: MagicMock, _test_name: str, input_params: dict, cause: str, assistance: str + ): + with self.assertRaises(PluginException) as error: + self.action.run(input_params) + self.assertEqual(error.exception.cause, cause) + self.assertEqual(error.exception.assistance, assistance) diff --git a/plugins/pagerduty/unit_test/test_delete_user_by_id.py b/plugins/pagerduty/unit_test/test_delete_user_by_id.py index 2b499d1ce6..a29d80053a 100644 --- a/plugins/pagerduty/unit_test/test_delete_user_by_id.py +++ b/plugins/pagerduty/unit_test/test_delete_user_by_id.py @@ -4,69 +4,49 @@ sys.path.append(os.path.abspath("../")) from unittest import TestCase -from komand_pagerduty.connection.connection import Connection from komand_pagerduty.actions.delete_user_by_id import DeleteUserById -import json -import logging +from unittest.mock import patch, MagicMock +from parameterized import parameterized +from util import Util +from insightconnect_plugin_runtime.exceptions import PluginException +@patch("requests.Session.request", side_effect=Util.mock_request) class TestDeleteUserById(TestCase): - def test_integration_delete_user_by_id(self): - """ - TODO: Implement assertions at the end of this test case - - This is an integration test that will connect to the services your plugin uses. It should be used - as the basis for tests below that can run independent of a "live" connection. - - This test assumes a normal plugin structure with a /tests directory. In that /tests directory should - be json samples that contain all the data needed to run this test. To generate samples run: - - icon-plugin generate samples - - """ - - log = logging.getLogger("Test") - test_conn = Connection() - test_action = DeleteUserById() - - test_conn.logger = log - test_action.logger = log - - try: - with open("../tests/delete_user_by_id.json") as file: - test_json = json.loads(file.read()).get("body") - connection_params = test_json.get("connection") - action_params = test_json.get("input") - except Exception as e: - message = """ - Could not find or read sample tests from /tests directory - - An exception here likely means you didn't fill out your samples correctly in the /tests directory - Please use 'icon-plugin generate samples', and fill out the resulting test files in the /tests directory - """ - self.fail(message) - - test_conn.connect(connection_params) - test_action.connection = test_conn - results = test_action.run(action_params) - - # TODO: Remove this line - self.fail("Unimplemented test case") - - # TODO: The following assert should be updated to look for data from your action - # For example: self.assertEquals({"success": True}, results) - self.assertEquals({}, results) - - def test_delete_user_by_id(self): - """ - TODO: Implement test cases here - - Here you can mock the connection with data returned from the above integration test. - For information on mocking and unit testing please go here: - - https://docs.google.com/document/d/1PifePDG1-mBcmNYE8dULwGxJimiRBrax5BIDG_0TFQI/edit?usp=sharing - - You can either create a formal Mock for this, or you can create a fake connection class to pass to your - action for testing. - """ - self.fail("Unimplemented Test Case") + @classmethod + def setUpClass(cls) -> None: + cls.action = Util.default_connector(DeleteUserById()) + + @parameterized.expand( + [ + [ + "delete_valid", + {"id": "valid_id", "email": "test@test.com"}, + {"success": "The user valid_id has been deleted"}, + ] + ] + ) + def test_delete_user_by_id_valid( + self, _mock_request: MagicMock, _test_name: str, input_params: dict, expected: dict + ): + actual = self.action.run(input_params) + self.assertEqual(actual, expected) + + @parameterized.expand( + [ + [ + "delete_invalid", + {"id": "invalid_id", "email": "test@test.com"}, + "Invalid or unreachable endpoint provided.", + "Verify the URLs or endpoints in your configuration are correct.", + ] + ] + ) + def test_delete_user_by_id_invalid( + self, _mock_request: MagicMock, _test_name: str, input_params: dict, cause: str, assistance: str + ): + with self.assertRaises(PluginException) as error: + self.action.run(input_params) + + self.assertEqual(error.exception.cause, cause) + self.assertEqual(error.exception.assistance, assistance) diff --git a/plugins/pagerduty/unit_test/test_get_on_call.py b/plugins/pagerduty/unit_test/test_get_on_call.py index 4edd9ed471..0e460d37e0 100644 --- a/plugins/pagerduty/unit_test/test_get_on_call.py +++ b/plugins/pagerduty/unit_test/test_get_on_call.py @@ -4,38 +4,87 @@ sys.path.append(os.path.abspath("../")) from unittest import TestCase -from komand_pagerduty.connection.connection import Connection from komand_pagerduty.actions.get_on_call import GetOnCall -import json -import logging +from unittest.mock import patch, MagicMock, call +from parameterized import parameterized +from util import Util +from insightconnect_plugin_runtime.exceptions import PluginException +@patch("requests.Session.request", side_effect=Util.mock_request) class TestGetOnCall(TestCase): - def test_integration_get_on_call(self): - log = logging.getLogger("Test") - test_conn = Connection() - test_action = GetOnCall() - - test_conn.logger = log - test_action.logger = log - - try: - with open("../tests/get_on_call.json") as file: - test_json = json.loads(file.read()).get("body") - connection_params = test_json.get("connection") - action_params = test_json.get("input") - except Exception as e: - message = """ - Could not find or read sample tests from /tests directory - - An exception here likely means you didn't fill out your samples correctly in the /tests directory - Please use 'icon-plugin generate samples', and fill out the resulting test files in the /tests directory - """ - self.fail(message) - - test_conn.connect(connection_params) - test_action.connection = test_conn - results = test_action.run(action_params) - - self.assertIsNotNone(results) - self.assertTrue("users" in results.keys()) + @classmethod + def setUpClass(cls) -> None: + cls.action = Util.default_connector(GetOnCall()) + + @parameterized.expand([["no_uers_from_schedule_invalid", {"schedule_id": "no_users"}, {"users": []}]]) + def test_no_uers_from_schedule_invalid( + self, _mock_request: MagicMock, _test_name: str, input_params: dict, expected: dict + ): + actual = self.action.run(input_params) + self.assertEqual(actual, expected) + + @parameterized.expand( + [ + [ + "no_user_id_from_user_invalid", + {"schedule_id": "user_missing_id"}, + Util.read_file_to_dict("expected/test_user_missing_id.json.exp"), + ] + ] + ) + @patch("logging.Logger.warning") + def test_no_user_id_from_user_invalid( + self, _test_name: str, input_params: dict, expected: dict, mocked_warn: MagicMock, _mock_request: MagicMock + ): + actual = self.action.run(input_params) + self.assertEqual(actual, expected) + + self.assertTrue(mocked_warn.called) + log_call = call("User ID not available: 'id'") + self.assertIn(log_call, mocked_warn.call_args_list) + + @parameterized.expand( + [ + [ + "test_a_deleted_user_invalid", + {"schedule_id": "user_has_been_deleted"}, + Util.read_file_to_dict("expected/test_deleted_user.json.exp"), + ] + ] + ) + @patch("logging.Logger.warning") + def test_no_user_id_from_user_invalid( + self, _test_name: str, input_params: dict, expected: dict, mocked_warn: MagicMock, _mock_request: MagicMock + ): + actual = self.action.run(input_params) + self.assertEqual(actual, expected) + + self.assertTrue(mocked_warn.called) + log_call = call("The following user P9FKCQ7 is part of the schedule but has been deleted") + self.assertIn(log_call, mocked_warn.call_args_list) + + @parameterized.expand([["test_cannot_find_user_invalid", {"schedule_id": "test_cannot_find_user"}, {"users": []}]]) + @patch("logging.Logger.warning") + def test_no_user_id_from_user_invalid( + self, _test_name: str, input_params: dict, expected: dict, mocked_warn: MagicMock, _mock_request: MagicMock + ): + actual = self.action.run(input_params) + self.assertEqual(actual, expected) + + self.assertTrue(mocked_warn.called) + log_call = call("No information was found for the user - PYGDZB9") + self.assertIn(log_call, mocked_warn.call_args_list) + + @parameterized.expand( + [ + [ + "test_valid_on_call", + {"schedule_id": "test_valid_on_call"}, + Util.read_file_to_dict("expected/test_valid_on_call.json.exp"), + ] + ] + ) + def test_valid_on_call(self, _mock_request: MagicMock, _test_name: str, input_params: dict, expected: dict): + actual = self.action.run(input_params) + self.assertEqual(actual, expected) diff --git a/plugins/pagerduty/unit_test/test_get_user_by_email.py b/plugins/pagerduty/unit_test/test_get_user_by_email.py index f0a45e0e99..b35e4569ad 100644 --- a/plugins/pagerduty/unit_test/test_get_user_by_email.py +++ b/plugins/pagerduty/unit_test/test_get_user_by_email.py @@ -4,69 +4,38 @@ sys.path.append(os.path.abspath("../")) from unittest import TestCase -from komand_pagerduty.connection.connection import Connection from komand_pagerduty.actions.get_user_by_email import GetUserByEmail -import json -import logging +from unittest.mock import patch, MagicMock +from parameterized import parameterized +from util import Util +from insightconnect_plugin_runtime.exceptions import PluginException +@patch("requests.Session.request", side_effect=Util.mock_request) class TestGetUserByEmail(TestCase): - def test_integration_get_user_by_email(self): - """ - TODO: Implement assertions at the end of this test case - - This is an integration test that will connect to the services your plugin uses. It should be used - as the basis for tests below that can run independent of a "live" connection. - - This test assumes a normal plugin structure with a /tests directory. In that /tests directory should - be json samples that contain all the data needed to run this test. To generate samples run: - - icon-plugin generate samples - - """ - - log = logging.getLogger("Test") - test_conn = Connection() - test_action = GetUserByEmail() - - test_conn.logger = log - test_action.logger = log - - try: - with open("../tests/get_user_by_email.json") as file: - test_json = json.loads(file.read()).get("body") - connection_params = test_json.get("connection") - action_params = test_json.get("input") - except Exception as e: - message = """ - Could not find or read sample tests from /tests directory - - An exception here likely means you didn't fill out your samples correctly in the /tests directory - Please use 'icon-plugin generate samples', and fill out the resulting test files in the /tests directory - """ - self.fail(message) - - test_conn.connect(connection_params) - test_action.connection = test_conn - results = test_action.run(action_params) - - # TODO: Remove this line - self.fail("Unimplemented test case") - - # TODO: The following assert should be updated to look for data from your action - # For example: self.assertEquals({"success": True}, results) - self.assertEquals({}, results) - - def test_get_user_by_email(self): - """ - TODO: Implement test cases here - - Here you can mock the connection with data returned from the above integration test. - For information on mocking and unit testing please go here: - - https://docs.google.com/document/d/1PifePDG1-mBcmNYE8dULwGxJimiRBrax5BIDG_0TFQI/edit?usp=sharing - - You can either create a formal Mock for this, or you can create a fake connection class to pass to your - action for testing. - """ - self.fail("Unimplemented Test Case") + @classmethod + def setUpClass(cls) -> None: + cls.action = Util.default_connector(GetUserByEmail()) + + @parameterized.expand( + [ + [ + "get_user_valid", + {"user_email": "valid_email"}, + Util.read_file_to_dict("expected/get_user_by_email_valid.json.exp"), + ] + ] + ) + def test_get_user_by_email_valid( + self, _mock_request: MagicMock, _test_name: str, input_params: dict, expected: dict + ): + actual = self.action.run(input_params) + self.assertEqual(actual, expected) + + @parameterized.expand( + [["no_users_found", {"user_email": "invalid_email"}, "No user found for email invalid_email"]] + ) + def test_get_user_by_email_invalid(self, _mock_request: MagicMock, _test_name: str, input_params: dict, cause: str): + with self.assertRaises(PluginException) as error: + self.action.run(input_params) + self.assertEqual(error.exception.cause, cause) diff --git a/plugins/pagerduty/unit_test/test_get_user_by_id.py b/plugins/pagerduty/unit_test/test_get_user_by_id.py index cd87e04e7e..a7a1aac8c9 100644 --- a/plugins/pagerduty/unit_test/test_get_user_by_id.py +++ b/plugins/pagerduty/unit_test/test_get_user_by_id.py @@ -4,69 +4,47 @@ sys.path.append(os.path.abspath("../")) from unittest import TestCase -from komand_pagerduty.connection.connection import Connection + from komand_pagerduty.actions.get_user_by_id import GetUserById -import json -import logging +from unittest.mock import patch, MagicMock +from parameterized import parameterized +from util import Util +from insightconnect_plugin_runtime.exceptions import PluginException +@patch("requests.Session.request", side_effect=Util.mock_request) class TestGetUserById(TestCase): - def test_integration_get_user_by_id(self): - """ - TODO: Implement assertions at the end of this test case - - This is an integration test that will connect to the services your plugin uses. It should be used - as the basis for tests below that can run independent of a "live" connection. - - This test assumes a normal plugin structure with a /tests directory. In that /tests directory should - be json samples that contain all the data needed to run this test. To generate samples run: - - icon-plugin generate samples - - """ - - log = logging.getLogger("Test") - test_conn = Connection() - test_action = GetUserById() - - test_conn.logger = log - test_action.logger = log - - try: - with open("../tests/get_user_by_id.json") as file: - test_json = json.loads(file.read()).get("body") - connection_params = test_json.get("connection") - action_params = test_json.get("input") - except Exception as e: - message = """ - Could not find or read sample tests from /tests directory - - An exception here likely means you didn't fill out your samples correctly in the /tests directory - Please use 'icon-plugin generate samples', and fill out the resulting test files in the /tests directory - """ - self.fail(message) - - test_conn.connect(connection_params) - test_action.connection = test_conn - results = test_action.run(action_params) - - # TODO: Remove this line - self.fail("Unimplemented test case") - - # TODO: The following assert should be updated to look for data from your action - # For example: self.assertEquals({"success": True}, results) - self.assertEquals({}, results) - - def test_get_user_by_id(self): - """ - TODO: Implement test cases here - - Here you can mock the connection with data returned from the above integration test. - For information on mocking and unit testing please go here: - - https://docs.google.com/document/d/1PifePDG1-mBcmNYE8dULwGxJimiRBrax5BIDG_0TFQI/edit?usp=sharing - - You can either create a formal Mock for this, or you can create a fake connection class to pass to your - action for testing. - """ - self.fail("Unimplemented Test Case") + @classmethod + def setUpClass(cls) -> None: + cls.action = Util.default_connector(GetUserById()) + + @parameterized.expand( + [ + [ + "get_user_valid", + {"id": "valid_id"}, + Util.read_file_to_dict("expected/get_user_valid.json.exp"), + ] + ] + ) + def test_get_user_by_id(self, _mock_request: MagicMock, _test_name: str, input_params: dict, expected: dict): + actual = self.action.run(input_params) + self.assertEqual(actual, expected) + + @parameterized.expand( + [ + [ + "api_error_invalid", + {"id": "invalid_id"}, + "Invalid or unreachable endpoint provided.", + "Verify the URLs or endpoints in your configuration are correct.", + ] + ] + ) + def test_api_error_invalid( + self, _mock_request: MagicMock, _test_name: str, input_params: dict, cause: str, assistance: str + ): + with self.assertRaises(PluginException) as error: + self.action.run(input_params) + self.assertEqual(error.exception.cause, cause) + self.assertEqual(error.exception.assistance, assistance) diff --git a/plugins/pagerduty/unit_test/test_send_acknowledge_event.py b/plugins/pagerduty/unit_test/test_send_acknowledge_event.py index 83a2b4f76a..d3b8ba00db 100644 --- a/plugins/pagerduty/unit_test/test_send_acknowledge_event.py +++ b/plugins/pagerduty/unit_test/test_send_acknowledge_event.py @@ -4,69 +4,48 @@ sys.path.append(os.path.abspath("../")) from unittest import TestCase -from komand_pagerduty.connection.connection import Connection from komand_pagerduty.actions.send_acknowledge_event import SendAcknowledgeEvent -import json -import logging +from unittest.mock import patch, MagicMock +from parameterized import parameterized +from util import Util +from insightconnect_plugin_runtime.exceptions import PluginException +@patch("requests.Session.request", side_effect=Util.mock_request) class TestSendAcknowledgeEvent(TestCase): - def test_integration_send_acknowledge_event(self): - """ - TODO: Implement assertions at the end of this test case - - This is an integration test that will connect to the services your plugin uses. It should be used - as the basis for tests below that can run independent of a "live" connection. - - This test assumes a normal plugin structure with a /tests directory. In that /tests directory should - be json samples that contain all the data needed to run this test. To generate samples run: - - icon-plugin generate samples - - """ - - log = logging.getLogger("Test") - test_conn = Connection() - test_action = SendAcknowledgeEvent() - - test_conn.logger = log - test_action.logger = log - - try: - with open("../tests/send_acknowledge_event.json") as file: - test_json = json.loads(file.read()).get("body") - connection_params = test_json.get("connection") - action_params = test_json.get("input") - except Exception as e: - message = """ - Could not find or read sample tests from /tests directory - - An exception here likely means you didn't fill out your samples correctly in the /tests directory - Please use 'icon-plugin generate samples', and fill out the resulting test files in the /tests directory - """ - self.fail(message) - - test_conn.connect(connection_params) - test_action.connection = test_conn - results = test_action.run(action_params) - - # TODO: Remove this line - self.fail("Unimplemented test case") - - # TODO: The following assert should be updated to look for data from your action - # For example: self.assertEquals({"success": True}, results) - self.assertEquals({}, results) - - def test_send_acknowledge_event(self): - """ - TODO: Implement test cases here - - Here you can mock the connection with data returned from the above integration test. - For information on mocking and unit testing please go here: - - https://docs.google.com/document/d/1PifePDG1-mBcmNYE8dULwGxJimiRBrax5BIDG_0TFQI/edit?usp=sharing - - You can either create a formal Mock for this, or you can create a fake connection class to pass to your - action for testing. - """ - self.fail("Unimplemented Test Case") + @classmethod + def setUpClass(cls) -> None: + cls.action = Util.default_connector(SendAcknowledgeEvent()) + + @parameterized.expand( + [ + [ + "test_acknowledge_valid", + {"incident_id": "valid_id", "email": "test@example.com"}, + Util.read_file_to_dict("expected/test_acknowledge_valid.json.exp"), + ] + ] + ) + def test_send_acknowledge_event( + self, _mock_request: MagicMock, _test_name: str, input_params: dict, expected: dict + ): + actual = self.action.run(input_params) + self.assertEqual(actual, expected) + + @parameterized.expand( + [ + [ + "api_error_invalid", + {"incident_id": "invalid_id", "email": "test@example.com"}, + "Invalid or unreachable endpoint provided.", + "Verify the URLs or endpoints in your configuration are correct.", + ] + ] + ) + def test_api_error_invalid( + self, _mock_request: MagicMock, _test_name: str, input_params: dict, cause: str, assistance: str + ): + with self.assertRaises(PluginException) as error: + self.action.run(input_params) + self.assertEqual(error.exception.cause, cause) + self.assertEqual(error.exception.assistance, assistance) diff --git a/plugins/pagerduty/unit_test/test_send_resolve_event.py b/plugins/pagerduty/unit_test/test_send_resolve_event.py index 387a83fb26..1a3ea46094 100644 --- a/plugins/pagerduty/unit_test/test_send_resolve_event.py +++ b/plugins/pagerduty/unit_test/test_send_resolve_event.py @@ -4,69 +4,47 @@ sys.path.append(os.path.abspath("../")) from unittest import TestCase -from komand_pagerduty.connection.connection import Connection + from komand_pagerduty.actions.send_resolve_event import SendResolveEvent -import json -import logging +from unittest.mock import patch, MagicMock +from parameterized import parameterized +from util import Util +from insightconnect_plugin_runtime.exceptions import PluginException +@patch("requests.Session.request", side_effect=Util.mock_request) class TestSendResolveEvent(TestCase): - def test_integration_send_resolve_event(self): - """ - TODO: Implement assertions at the end of this test case - - This is an integration test that will connect to the services your plugin uses. It should be used - as the basis for tests below that can run independent of a "live" connection. - - This test assumes a normal plugin structure with a /tests directory. In that /tests directory should - be json samples that contain all the data needed to run this test. To generate samples run: - - icon-plugin generate samples - - """ - - log = logging.getLogger("Test") - test_conn = Connection() - test_action = SendResolveEvent() - - test_conn.logger = log - test_action.logger = log - - try: - with open("../tests/send_resolve_event.json") as file: - test_json = json.loads(file.read()).get("body") - connection_params = test_json.get("connection") - action_params = test_json.get("input") - except Exception as e: - message = """ - Could not find or read sample tests from /tests directory - - An exception here likely means you didn't fill out your samples correctly in the /tests directory - Please use 'icon-plugin generate samples', and fill out the resulting test files in the /tests directory - """ - self.fail(message) - - test_conn.connect(connection_params) - test_action.connection = test_conn - results = test_action.run(action_params) - - # TODO: Remove this line - self.fail("Unimplemented test case") - - # TODO: The following assert should be updated to look for data from your action - # For example: self.assertEquals({"success": True}, results) - self.assertEquals({}, results) - - def test_send_resolve_event(self): - """ - TODO: Implement test cases here - - Here you can mock the connection with data returned from the above integration test. - For information on mocking and unit testing please go here: - - https://docs.google.com/document/d/1PifePDG1-mBcmNYE8dULwGxJimiRBrax5BIDG_0TFQI/edit?usp=sharing - - You can either create a formal Mock for this, or you can create a fake connection class to pass to your - action for testing. - """ - self.fail("Unimplemented Test Case") + @classmethod + def setUpClass(cls) -> None: + cls.action = Util.default_connector(SendResolveEvent()) + + @parameterized.expand( + [ + [ + "test_resolve_valid", + {"incident_id": "valid_id", "email": "test@example.com"}, + Util.read_file_to_dict("expected/test_resolve_valid.json.exp"), + ] + ] + ) + def test_send_resolve_event(self, _mock_request: MagicMock, _test_name: str, input_params: dict, expected: dict): + actual = self.action.run(input_params) + self.assertEqual(actual, expected) + + @parameterized.expand( + [ + [ + "api_error_invalid", + {"incident_id": "invalid_id", "email": "test@example.com"}, + "Invalid or unreachable endpoint provided.", + "Verify the URLs or endpoints in your configuration are correct.", + ] + ] + ) + def test_api_error_invalid( + self, _mock_request: MagicMock, _test_name: str, input_params: dict, cause: str, assistance: str + ): + with self.assertRaises(PluginException) as error: + self.action.run(input_params) + self.assertEqual(error.exception.cause, cause) + self.assertEqual(error.exception.assistance, assistance) diff --git a/plugins/pagerduty/unit_test/test_send_trigger_event.py b/plugins/pagerduty/unit_test/test_send_trigger_event.py index 49a512fe4d..048e79ce95 100644 --- a/plugins/pagerduty/unit_test/test_send_trigger_event.py +++ b/plugins/pagerduty/unit_test/test_send_trigger_event.py @@ -4,69 +4,57 @@ sys.path.append(os.path.abspath("../")) from unittest import TestCase -from komand_pagerduty.connection.connection import Connection + from komand_pagerduty.actions.send_trigger_event import SendTriggerEvent -import json -import logging +from unittest.mock import patch, MagicMock +from parameterized import parameterized +from util import Util +from insightconnect_plugin_runtime.exceptions import PluginException +@patch("requests.Session.request", side_effect=Util.mock_request) class TestSendTriggerEvent(TestCase): - def test_integration_send_trigger_event(self): - """ - TODO: Implement assertions at the end of this test case - - This is an integration test that will connect to the services your plugin uses. It should be used - as the basis for tests below that can run independent of a "live" connection. - - This test assumes a normal plugin structure with a /tests directory. In that /tests directory should - be json samples that contain all the data needed to run this test. To generate samples run: - - icon-plugin generate samples - - """ - - log = logging.getLogger("Test") - test_conn = Connection() - test_action = SendTriggerEvent() - - test_conn.logger = log - test_action.logger = log - - try: - with open("../tests/send_trigger_event.json") as file: - test_json = json.loads(file.read()).get("body") - connection_params = test_json.get("connection") - action_params = test_json.get("input") - except Exception as e: - message = """ - Could not find or read sample tests from /tests directory - - An exception here likely means you didn't fill out your samples correctly in the /tests directory - Please use 'icon-plugin generate samples', and fill out the resulting test files in the /tests directory - """ - self.fail(message) - - test_conn.connect(connection_params) - test_action.connection = test_conn - results = test_action.run(action_params) - - # TODO: Remove this line - self.fail("Unimplemented test case") - - # TODO: The following assert should be updated to look for data from your action - # For example: self.assertEquals({"success": True}, results) - self.assertEquals({}, results) - - def test_send_trigger_event(self): - """ - TODO: Implement test cases here - - Here you can mock the connection with data returned from the above integration test. - For information on mocking and unit testing please go here: - - https://docs.google.com/document/d/1PifePDG1-mBcmNYE8dULwGxJimiRBrax5BIDG_0TFQI/edit?usp=sharing - - You can either create a formal Mock for this, or you can create a fake connection class to pass to your - action for testing. - """ - self.fail("Unimplemented Test Case") + @classmethod + def setUpClass(cls) -> None: + cls.action = Util.default_connector(SendTriggerEvent()) + + @parameterized.expand( + [ + [ + "minimum_valid", + Util.read_file_to_dict("inputs/trigger_event_minimum_fields.json.inp"), + Util.read_file_to_dict("expected/trigger_event_minimum_fields.json.exp"), + ], + [ + "additional_fields_escalation_valid", + Util.read_file_to_dict("inputs/trigger_event_additional_fields_escalation.json.inp"), + Util.read_file_to_dict("expected/trigger_event_additional_fields_escalation.json.exp"), + ], + [ + "additional_fields_assignments_valid", + Util.read_file_to_dict("inputs/trigger_event_additional_fields_assignments.json.inp"), + Util.read_file_to_dict("expected/trigger_event_additional_fields_assignments.json.exp"), + ], + ] + ) + def test_send_trigger_event(self, _mock_request: MagicMock, _test_name: str, input_params: dict, expected: dict): + actual = self.action.run(input_params) + self.assertEqual(actual, expected) + + @parameterized.expand( + [ + [ + "both_escalation_policy_and_assignments_invalid", + Util.read_file_to_dict("inputs/send_trigger_both_esc_asg_invalid.json.inp"), + "Invalid paramaters", + "Invalid input only one of 'escalation_policy' or 'assignments' can be used at one time", + ] + ] + ) + def test_missing_params_invalid( + self, _mock_request: MagicMock, _test_name: str, input_params: dict, cause: str, assistance: str + ): + with self.assertRaises(PluginException) as error: + self.action.run(input_params) + self.assertEqual(error.exception.cause, cause) + self.assertEqual(error.exception.assistance, assistance) diff --git a/plugins/pagerduty/unit_test/util.py b/plugins/pagerduty/unit_test/util.py new file mode 100644 index 0000000000..e7b6da6fa1 --- /dev/null +++ b/plugins/pagerduty/unit_test/util.py @@ -0,0 +1,124 @@ +import json +import logging +import sys +import os + +sys.path.append(os.path.abspath("../")) + +import insightconnect_plugin_runtime +from komand_pagerduty.connection.connection import Connection +from komand_pagerduty.connection.schema import Input + + +class Util: + @staticmethod + def default_connector(action: insightconnect_plugin_runtime.Action, params: dict = None): + default_connection = Connection() + default_connection.logger = logging.getLogger("connection logger") + if not params: + params = { + Input.API_KEY: {"secretKey": "example-secret-key"}, + } + default_connection.connect(params) + action.connection = default_connection + action.logger = logging.getLogger("action logger") + return action + + @staticmethod + def read_file_to_string(filename: str) -> str: + with open( + os.path.join(os.path.dirname(os.path.realpath(__file__)), filename), "r", encoding="utf-8" + ) as file_reader: + return file_reader.read() + + @staticmethod + def read_file_to_dict(filename: str) -> dict: + return json.loads(Util.read_file_to_string(filename)) + + @staticmethod + def mock_request(*args, **kwargs): + class MockResponse: + def __init__(self, status_code: int, filename: str = None): + self.status_code = status_code + self.text = "" + self.content = b"" + if filename: + self.text = Util.read_file_to_string(f"responses/{filename}") + self.content = Util.read_file_to_string(f"responses/{filename}") + + def json(self): + return json.loads(self.text) + + params = kwargs.get("params", {}) + data = kwargs.get("data", {}) + payload = kwargs.get("json", {}) + url = args[1] + method = args[0] + + if data: + data = json.loads(data) + print(f"{data = }") + + if url == "https://api.pagerduty.com/users/": + if method == "POST": + name = payload.get("user", {}).get("name") + if name == "Test minimum fields": + return MockResponse(200, "create_user_minimum_fields.json.resp") + elif name == "Test additional fields": + return MockResponse(200, "create_user_additional_fields.json.resp") + elif name == "Test api error": + return MockResponse(500) + else: + raise NotImplementedError("Not implemented", kwargs) + elif method == "GET": + query = params.get("query", {}) + if query == "valid_email": + return MockResponse(200, "get_user_by_email_valid.json.resp") + elif query == "invalid_email": + return MockResponse(200, "get_user_by_email_not_found.json.resp") + + elif url == "https://api.pagerduty.com/users/valid_id/": + if method == "DELETE": + return MockResponse(204, "") + elif method == "GET": + return MockResponse(200, "get_user_valid.json.resp") + + elif url == "https://api.pagerduty.com/users/invalid_id/": + return MockResponse(404) + + elif url == "https://api.pagerduty.com/incidents/valid_id/" and method == "PUT": + incident_status = data.get("incident", {}).get("status") + if incident_status == "resolved": + return MockResponse(200, "test_resolve_valid.json.resp") + elif incident_status == "acknowledged": + return MockResponse(200, "test_acknowledge_valid.json.resp") + + elif url == "https://api.pagerduty.com/incidents/invalid_id/" and method == "PUT": + return MockResponse(404) + + elif url == "https://api.pagerduty.com/incidents/" and method == "POST": + title = payload.get("incident", {}).get("title", "") + if title == "test minimum fields": + return MockResponse(200, "trigger_event_minimum_fields.json.resp") + elif title == "test additional fields escalation": + return MockResponse(200, "trigger_event_additional_fields_escalation.json.resp") + elif title == "test additional fields assignments": + return MockResponse(200, "trigger_event_additional_fields_assignments.json.resp") + + elif url == "https://api.pagerduty.com/schedules/no_users/": + return MockResponse(200, "test_get_on_call_no_users.json.resp") + elif url == "https://api.pagerduty.com/schedules/user_missing_id/": + return MockResponse(200, "test_user_missing_id.json.resp") + elif url == "https://api.pagerduty.com/schedules/user_has_been_deleted/": + return MockResponse(200, "test_deleted_user.json.resp") + elif url == "https://api.pagerduty.com/schedules/test_valid_on_call/": + return MockResponse(200, "test_valid_on_call.json.resp") + elif url == "https://api.pagerduty.com/schedules/test_cannot_find_user/": + return MockResponse(200, "test_cannot_find_user.json.resp") + + elif url == "https://api.pagerduty.com/users/PYGDZB8/": + return MockResponse(200, "valid_get_on_call_user.json.resp") + elif url == "https://api.pagerduty.com/users/PYGDZB9/": + return MockResponse(404) + + raise NotImplementedError("Not implemented", kwargs)