Skip to content

Commit

Permalink
[OpsGenie v3] Get Team Routing Rules (demisto#28620)
Browse files Browse the repository at this point in the history
* [OpsGenie v3] Get Team Routing Rules (demisto#28496)

* master

* reverting crowdstrike.py

* get-routing-rules

* added release notes

* quick fix

* Opsgenie

* fixing release note issues

* bumped version

* details

* argument

* ran demisto-sdk format on the files

* added docs for the command

* required True

* team_id required

* flake8

* improved docs for details

* removed _dev

* flake8g

* Update Packs/OpsGenie/Integrations/OpsGenieV3/OpsGenieV3.yml

Co-authored-by: Menachem Weinfeld <90556466+mmhw@users.noreply.github.com>

* Update Packs/OpsGenie/Integrations/OpsGenieV3/OpsGenieV3.py

Co-authored-by: Menachem Weinfeld <90556466+mmhw@users.noreply.github.com>

* get routing rules

* added outputs

* outputs

* ran precommit

* fixed ISC001 Implicitly concatenated string literals on one line

* Update the README file

* Update Packs/OpsGenie/Integrations/OpsGenieV3/OpsGenieV3.yml

Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com>

* Update Packs/OpsGenie/Integrations/OpsGenieV3/OpsGenieV3.yml

Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com>

* Update Packs/OpsGenie/Integrations/OpsGenieV3/OpsGenieV3.yml

Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com>

* Update Packs/OpsGenie/Integrations/OpsGenieV3/README.md

Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com>

* Update Packs/OpsGenie/Integrations/OpsGenieV3/README.md

Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com>

* Update Packs/OpsGenie/Integrations/OpsGenieV3/README.md

Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com>

* Update Packs/OpsGenie/ReleaseNotes/2_0_17.md

Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com>

* Update Packs/OpsGenie/ReleaseNotes/2_0_17.md

Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com>

* Change output prefix "OpsGenie.Team.RoutingRules" -> "OpsGenie.TeamRoutingRule"

* Fix the README file

* Add isArray: true

---------

Co-authored-by: Menachem Weinfeld <90556466+mmhw@users.noreply.github.com>
Co-authored-by: Menachem Weinfeld <mmhw770@gmail.com>
Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com>

* Fix the test playbook

* Skip the TPB

---------

Co-authored-by: Enes Özdemir <49711791+ennozdd@users.noreply.github.com>
Co-authored-by: Menachem Weinfeld <90556466+mmhw@users.noreply.github.com>
Co-authored-by: Menachem Weinfeld <mmhw770@gmail.com>
Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com>
  • Loading branch information
5 people authored and xsoar-bot committed Oct 5, 2023
1 parent c81c7d1 commit 967eeb8
Show file tree
Hide file tree
Showing 8 changed files with 146 additions and 26 deletions.
33 changes: 27 additions & 6 deletions Packs/OpsGenie/Integrations/OpsGenieV3/OpsGenieV3.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from CommonServerPython import * # noqa: F401
from requests import Response
import urllib3
from typing import Callable, Tuple
from collections.abc import Callable
from CommonServerUserPython import * # noqa

# Disable insecure warnings
Expand Down Expand Up @@ -77,6 +77,10 @@ def responders_to_json(responders: List, responder_key: str, one_is_dict: bool =

def create_alert(self, args: dict):
args['responders'] = argToList(args.get('responders'))
if args.get('details') and not isinstance(args.get('details'), dict):
args['details'] = {key_value.split('=')[0]: key_value.split('=')[1]
for key_value in argToList(args.get('details'))}

args.update(Client.responders_to_json(args.get('responders', []), "responders"))
return self._http_request(method='POST',
url_suffix=f"/v2/{ALERTS_SUFFIX}",
Expand Down Expand Up @@ -211,7 +215,7 @@ def list_schedule_overrides(self, args: dict):
)

def get_on_call(self, args: dict):
return self._http_request(method='GET', url_suffix=f"/v2/{SCHEDULE_SUFFIX}/" f"{args.get('schedule')}/on-calls",
return self._http_request(method='GET', url_suffix=f"/v2/{SCHEDULE_SUFFIX}/{args.get('schedule')}/on-calls",
params={"scheduleIdentifierType": args.get('scheduleIdentifierType')})

def create_incident(self, args: dict):
Expand Down Expand Up @@ -244,12 +248,12 @@ def build_query(args: dict) -> str:
priority = argToList(args.get("priority", [ALL_TYPE]))
if ALL_TYPE not in priority:
query += ' AND ' if query else ''
priority_parsed = ' OR '.join([p for p in priority])
priority_parsed = ' OR '.join(list(priority))
query += f'priority: ({priority_parsed})'
tags = argToList(args.get("tags", []))
if tags:
query += ' AND ' if query else ''
tag_parsed = ' OR '.join([t for t in tags])
tag_parsed = ' OR '.join(list(tags))
query += f'tag: ({tag_parsed})'
return query

Expand Down Expand Up @@ -315,6 +319,11 @@ def get_team(self, args: dict):
url_suffix=f"/v2/{TEAMS_SUFFIX}/{args.get('team_id')}"
)

def get_team_routing_rules(self, args: dict):
return self._http_request(method='GET',
url_suffix=f"/v2/{TEAMS_SUFFIX}/{args.get('team_id')}/routing-rules"
)

def list_teams(self):
return self._http_request(method='GET',
url_suffix=f"/v2/{TEAMS_SUFFIX}"
Expand Down Expand Up @@ -867,6 +876,17 @@ def get_teams(client: Client, args: Dict[str, Any]) -> CommandResults:
)


def get_team_routing_rules(client: Client, args: Dict[str, Any]) -> CommandResults:
result = client.get_team_routing_rules(args)
data = result.get("data")
return CommandResults(
outputs_prefix="OpsGenie.TeamRoutingRule",
outputs=data,
readable_output=tableToMarkdown("OpsGenie Team Routing Rules", data),
raw_response=result
)


def _parse_fetch_time(fetch_time: str):
fetch_time_date = dateparser.parse(date_string=f"{fetch_time} UTC")
assert fetch_time_date is not None, f'could not parse {fetch_time} UTC'
Expand Down Expand Up @@ -900,7 +920,7 @@ def fetch_incidents_by_type(client: Client,
time_query = f'createdAt>{timestamp_last_run} AND createdAt<={timestamp_now}'
params['query'] = f'{query} AND {time_query}' if query else f'{time_query}'
params['limit'] = limit
params['is_fetch_query'] = True if query else False
params['is_fetch_query'] = bool(query)
params['status'] = status
params["priority"] = priority
params["tags"] = tags
Expand Down Expand Up @@ -928,7 +948,7 @@ def _get_utc_now():

def fetch_incidents_command(client: Client,
params: Dict[str, Any],
last_run: Optional[Dict] = None) -> Tuple[List[Dict[str, Any]], Dict]:
last_run: Optional[Dict] = None) -> tuple[List[Dict[str, Any]], Dict]:
"""Uses to fetch incidents into Demisto
Documentation: https://github.com/demisto/content/tree/master/docs/fetching_incidents
Expand Down Expand Up @@ -1031,6 +1051,7 @@ def main() -> None:
'opsgenie-add-tag-incident': add_tag_incident,
'opsgenie-remove-tag-incident': remove_tag_incident,
'opsgenie-get-teams': get_teams,
'opsgenie-get-team-routing-rules': get_team_routing_rules,
'opsgenie-get-request': get_request_command
}
command = demisto.command()
Expand Down
55 changes: 41 additions & 14 deletions Packs/OpsGenie/Integrations/OpsGenieV3/OpsGenieV3.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,18 @@ configuration:
hiddenusername: true
- display: Fetch incidents
name: isFetch
type: 8
required: false
type: 8
- defaultvalue: 3 days
display: First fetch timestamp (<number> <time unit>, e.g., 12 hours, 7 days)
name: first_fetch
type: 0
required: false
type: 0
- defaultvalue: '20'
name: max_fetch
display: Max Fetch
type: 0
required: false
type: 0
- additionalinfo: Fetch only events with selected event types.
defaultvalue: All
display: Event types
Expand All @@ -35,22 +35,23 @@ configuration:
- All
- Alerts
- Incidents
type: 16
required: false
type: 16
- display: Status
name: status
additionalinfo: Fetch only events with selected status. If query is used, this parameter will be overridden.
defaultvalue: Open
required: false
options:
- All
- Open
- Closed
type: 15
required: false
- display: Priority
additionalinfo: Fetch only events with selected priority. If query is used, this parameter will be overridden.
name: priority
defaultvalue: All
required: false
options:
- All
- P1
Expand All @@ -59,29 +60,28 @@ configuration:
- P4
- P5
type: 16
required: false
- display: Tags
additionalinfo: Fetch only events with selected tags. If query is used, this parameter will be overridden.
name: tags
type: 0
required: false
type: 0
- display: Query
additionalinfo: Query parameters will be used as URL encoded values for “query” key. i.e. 'https://api.opsgenie.com/v2/alerts?query=status%3Aopenor%20acknowledged%3Atrue&limit=10&sort=createdAt'
name: query
type: 0
required: false
type: 0
- display: Incident type
name: incidentType
type: 13
required: false
type: 13
- display: Trust any certificate (not secure)
name: insecure
type: 8
required: false
type: 8
- display: Use system proxy settings
name: proxy
type: 8
required: false
type: 8
description: Integration with Atlassian OpsGenie. OpsGenie is a cloud-based service that enables operations teams to manage alerts generated by monitoring tools to ensure the right people are notified, and the problems are addressed in a timely manner.
display: OpsGenie v3
name: OpsGenieV3
Expand Down Expand Up @@ -116,6 +116,10 @@ script:
name: source
- description: Additional alert note.
name: note
- name: details
description: Comma-separated key=value pairs to use as custom properties of the alert. JSON format is also supported when used within an automation. Examples; details="account=pa,hostname=computer01".
type: keyValue
isArray: true
description: Create an alert in Opsgenie.
name: opsgenie-create-alert
polling: true
Expand Down Expand Up @@ -147,7 +151,6 @@ script:
- contextPath: OpsGenie.Alert.success
description: Whether the request was successful.
type: Boolean

- arguments:
- description: The ID of the alert from Opsgenie.
name: alert-id
Expand Down Expand Up @@ -1258,8 +1261,32 @@ script:
- contextPath: OpsGenie.Incident.success
description: Whether the request was successful.
type: Boolean

dockerimage: demisto/python3:3.10.12.63474
- name: opsgenie-get-team-routing-rules
description: Lists team routing rules.
arguments:
- name: team_id
description: The ID of the team from Opsgenie.
required: true
outputs:
- contextPath: OpsGenie.TeamRoutingRule.name
description: Name of the routing rule.
- contextPath: OpsGenie.TeamRoutingRule.order
description: Order of the routing rule.
- contextPath: OpsGenie.TeamRoutingRule.id
description: ID of the routing rule.
- contextPath: OpsGenie.TeamRoutingRule.timezone
description: Timezone of the routing rule.
- contextPath: OpsGenie.TeamRoutingRule.teamId
description: Team ID of the routing rule.
- contextPath: OpsGenie.TeamRoutingRule.customerId
description: Customer ID of the routing rule.
- contextPath: OpsGenie.TeamRoutingRule.notify.id
description: Notify ID of the routing rule.
- contextPath: OpsGenie.TeamRoutingRule.notify.name
description: Notify name of the routing rule.
- contextPath: OpsGenie.TeamRoutingRule.notify.type
description: Notify type of the routing rule.
dockerimage: demisto/python3:3.10.12.66339
isfetch: true
script: '-'
type: python
Expand Down
11 changes: 9 additions & 2 deletions Packs/OpsGenie/Integrations/OpsGenieV3/OpsGenieV3_test.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import pytest
import io

from requests import Response

Expand All @@ -9,7 +8,7 @@


def util_load_json(path, wrap_in_response=False):
with io.open(path, mode='r', encoding='utf-8') as f:
with open(path, encoding='utf-8') as f:
jsonres = json.loads(f.read())
if wrap_in_response:
res = Response()
Expand Down Expand Up @@ -1024,3 +1023,11 @@ def test_invite_user(mocker):
mocker.patch.object(mock_client, 'invite_user', return_value=util_load_json('test_data/invite_user.json'))
res = OpsGenieV3.invite_user(mock_client, {'username': "test@example.com", 'fullName': 'Test Example', 'role': 'user'})
assert (res.raw_response == util_load_json('test_data/invite_user.json'))


def test_get_team_routing_rules(mocker):
mock_client = OpsGenieV3.Client(base_url="")
mocker.patch.object(mock_client, 'get_team_routing_rules',
return_value=util_load_json('test_data/get_team_routing_rules.json'))
res = OpsGenieV3.get_team_routing_rules(mock_client, {'team_id': " a6604a9f-b152-54c-b31-1b9741c109"})
assert (res.raw_response == util_load_json('test_data/get_team_routing_rules.json'))
31 changes: 30 additions & 1 deletion Packs/OpsGenie/Integrations/OpsGenieV3/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ Create an alert in Opsgenie.
| tags | Comma-separated list of tags to add. | Optional |
| priority | Incident priority. Possible values are: P1, P2, P3, P4, P5. Default is P3. | Optional |
| source | Display name of the request source. Defaults to IP address of the request sender. | Optional |
| note | Additional alert note. | Optional |
| note | Additional alert note. | Optional |
| details | Comma-separated key=value pairs to use as custom properties of the alert. JSON format is also supported when used within an automation. Examples; details="account=pa,hostname=computer01". | Optional |


#### Context Output
Expand Down Expand Up @@ -1839,3 +1840,31 @@ Removed the following commands in this version:
* *OpsGenieV2.CloseAlert.status* - replaced by *OpsGenie.ClosedAlert.status*.
* *OpsGenieV2.CloseAlert.success* - replaced by *OpsGenie.ClosedAlert.success*.

### opsgenie-get-team-routing-rules

***
Lists team routing rules.

#### Base Command

`opsgenie-get-team-routing-rules`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| team_id | The ID of the team from Opsgenie. | Required |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| OpsGenie.TeamRoutingRule.name | unknown | Name of the routing rule. |
| OpsGenie.TeamRoutingRule.order | unknown | Order of the routing rule. |
| OpsGenie.TeamRoutingRule.id | unknown | ID of the routing rule. |
| OpsGenie.TeamRoutingRule.timezone | unknown | Timezone of the routing rule. |
| OpsGenie.TeamRoutingRule.teamId | unknown | Team ID of the routing rule. |
| OpsGenie.TeamRoutingRule.customerId | unknown | Customer ID of the routing rule. |
| OpsGenie.TeamRoutingRule.notify.id | unknown | Notify ID of the routing rule. |
| OpsGenie.TeamRoutingRule.notify.name | unknown | Notify name of the routing rule. |
| OpsGenie.TeamRoutingRule.notify.type | unknown | Notify type of the routing rule. |
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"data": [
{
"description": "",
"id": "0234de-4870-44-82fd-f5aff14a684",
"name": "Demisto_EscalationHigh",
"ownerTeam": {
"id": "a6604a9f-b152-54c-b31-1b9741c109",
"name": "Demisto"
},
"rules": [
{
"condition": "if-not-closed",
"delay": {
"timeAmount": 360,
"timeUnit": "minutes"
},
"notifyType": "admins",
"recipient": {
"id": "a6606a9f-b132-444c-bba1-1b97c111c109",
"name": "Demisto",
"type": "team"
}
}
]
}
],
"requestId": "f5aede7c-247e-4f38-b50b-6c9848f49beb",
"took": 0.111
}
5 changes: 5 additions & 0 deletions Packs/OpsGenie/ReleaseNotes/2_0_17.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#### Integrations
##### OpsGenie v3

- Added a new command ***opsgenie-get-team-routing-rules***.
- Added a new argument **details** to the command ***opsgenie-create-alert***.
4 changes: 2 additions & 2 deletions Packs/OpsGenie/pack_metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "OpsGenie",
"description": "Get current on-call assignments, schedules, and users info",
"support": "xsoar",
"currentVersion": "2.0.16",
"currentVersion": "2.0.17",
"author": "Cortex XSOAR",
"url": "https://www.paloaltonetworks.com/cortex",
"email": "",
Expand All @@ -17,4 +17,4 @@
"xsoar",
"marketplacev2"
]
}
}
3 changes: 2 additions & 1 deletion Tests/conf.json
Original file line number Diff line number Diff line change
Expand Up @@ -5672,7 +5672,8 @@
"MSGraph_DeviceManagement_Test_dev": "Issue CIAC-7430",
"Microsoft Defender Advanced Threat Protection - Test dev": "Issue CIAC-7514",
"Microsoft Defender Advanced Threat Protection - Test self deployed": "Issue CIAC-7527",
"Microsoft Defender Advanced Threat Protection - Test": "Issue CIAC-7527"
"Microsoft Defender Advanced Threat Protection - Test": "Issue CIAC-7527",
"OpsGenieV3TestPlaybook": "Issue CIAC-7649"
},
"skipped_integrations": {
"CiscoWSAv2": "No instance - No license",
Expand Down

0 comments on commit 967eeb8

Please sign in to comment.