Skip to content

Commit

Permalink
feat: add script to add OMA webhook (#34)
Browse files Browse the repository at this point in the history
Also update store_policies to save policy names in db/account_id/alert_policies
omalaertquality also adds channel specified to policies listed in a file
  • Loading branch information
adiosspandit authored Oct 5, 2021
1 parent 4f0b2fd commit 3725134
Show file tree
Hide file tree
Showing 5 changed files with 142 additions and 0 deletions.
5 changes: 5 additions & 0 deletions library/clients/alertsclient.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import re
import library.clients.entityclient as ec
from library.clients.endpoints import Endpoints
import library.clients.gql as nerdGraph

logger = migrationlogger.get_logger(os.path.basename(__file__))

Expand Down Expand Up @@ -36,6 +37,10 @@ def setup_headers(api_key):
return {'Api-Key': api_key, 'Content-Type': 'application/json'}


def gql_headers(api_key):
return {'api-key': api_key, 'Content-Type': 'application/json'}


def get_all_alert_policies(api_key, region=Endpoints.REGION_US):
return utils.get_paginated_entities(api_key, Endpoints.of(region).ALERT_POLICIES_URL, POLICIES)

Expand Down
Empty file added library/template/__init__.py
Empty file.
43 changes: 43 additions & 0 deletions library/template/aqmwebhook.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"id": 123456,
"name": "REPLACE_WEBHOOK_NAME",
"type": "webhook",
"configuration": {
"payload_type": "application/json",
"headers": {
"X-Insert-Key": "REPLACE_INSERT_KEY"
},
"base_url": "REPLACE_BASE_URL",
"payload": {
"eventType": "nrAQMIncident",
"account_id": "$ACCOUNT_ID",
"account_name": "$ACCOUNT_NAME",
"closed_violations_count_critical": "$CLOSED_VIOLATIONS_COUNT_CRITICAL",
"closed_violations_count_warning": "$CLOSED_VIOLATIONS_COUNT_WARNING",
"condition_description": "$DESCRIPTION",
"condition_family_id": "$CONDITION_FAMILY_ID",
"condition_name": "$CONDITION_NAME",
"current_state": "$EVENT_STATE",
"details": "$EVENT_DETAILS",
"duration": "$DURATION",
"event_type": "$EVENT_TYPE",
"incident_acknowledge_url": "$INCIDENT_ACKNOWLEDGE_URL",
"incident_id": "$INCIDENT_ID",
"incident_url": "$INCIDENT_URL",
"metadata": "$METADATA",
"open_violations_count_critical": "$OPEN_VIOLATIONS_COUNT_CRITICAL",
"open_violations_count_warning": "$OPEN_VIOLATIONS_COUNT_WARNING",
"owner": "$EVENT_OWNER",
"policy_name": "$POLICY_NAME",
"policy_url": "$POLICY_URL",
"runbook_url": "$RUNBOOK_URL",
"severity": "$SEVERITY",
"targets": "$TARGETS",
"timestamp": "$TIMESTAMP",
"timestamp_utc_string": "$TIMESTAMP_UTC_STRING",
"violation_callback_url": "$VIOLATION_CALLBACK_URL",
"violation_chart_url": "$VIOLATION_CHART_URL",
"restangularEtag": "W/\"51a3b11f2876a8c8cf7f101bf9ac9928\""
}
}
}
84 changes: 84 additions & 0 deletions omalertquality.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import os
import json
import argparse
import library.utils as utils
import library.migrationlogger as m_logger
import library.clients.alertsclient as ac
import library.localstore as store

log = m_logger.get_logger(os.path.basename(__file__))


def configure_parser():
parser = argparse.ArgumentParser(description='Alert Quality Management Webhook operations')
parser.add_argument('--targetAccount', nargs=1, type=str, required=True, help='Account ID')
parser.add_argument('--targetApiKey', nargs=1, type=str, required=True, help='User API Key')
parser.add_argument('--targetRegion', type=str, nargs=1, required=False, help='targetRegion us(default) or eu')
parser.add_argument('--createChannel', type=str, nargs=1, required=False,
help='Pass channel name to create AQM Webhook Notification Channel')
parser.add_argument('--insertKey', type=str, nargs=1, required=False, help='Insights Insert API Key')
parser.add_argument('--addChannel', type=str, nargs=1, required=False, help='Add this Channel name to policies '
'listed in policyFile')
parser.add_argument('--policyFile', type=str, nargs=1, required=False, help='File containing alert policy names. '
'One per line. This can be generated '
'using store_policies')
return parser


def prepare_aqm_webhook_channel(account_id, insert_api_key, channel_name):
webhook_channel = store.load_json_from_file('library/template', 'aqmwebhook.json')
webhook_channel['name'] = channel_name
webhook_channel['configuration']['headers']['X-Insert-Key'] = insert_api_key
base_url = "https://insights-collector.newrelic.com/v1/accounts/" + str(account_id) + "/events"
webhook_channel['configuration']['base_url'] = base_url
return webhook_channel


def create_aqm_webhook(account_id, user_api_key, insert_api_key, channel_name, region):
aqm_channel = prepare_aqm_webhook_channel(account_id, insert_api_key, channel_name)
result = ac.create_channel(user_api_key, aqm_channel, region)
if 'errors' in result:
log.error(json.dumps(result))
else:
log.info(json.dumps(result))


def add_channel_to_policies(account_id, user_api_key, channel_name, policy_file, region):
log.info("Adding channel " + channel_name + " to policies in " + policy_file)
all_channels = ac.get_channels(user_api_key, region)
log.info(json.dumps(all_channels))
channel_id = -1
for channel in all_channels['channels']:
if channel['name'] == channel_name:
channel_id = channel['id']
if channel_id == -1:
utils.error_message_and_exit("Notification channel not found " + channel_name)
policy_names = store.load_names(policy_file)
for policy_name in policy_names:
result = ac.get_policy(user_api_key, policy_name, region)
if not result['policyFound']:
log.warn("Did not find policy skipping " + policy_name)
log.info("Found Policy adding channel to " + policy_name)
ac.put_channel_ids(user_api_key, result['policy']['id'], [channel_id], region)


def main():
parser = configure_parser()
args = parser.parse_args()
target_api_key = utils.ensure_target_api_key(args)
if not target_api_key:
utils.error_and_exit('target_api_key', 'ENV_TARGET_API_KEY')
region = utils.ensure_target_region(args)
if args.createChannel:
if not args.insertKey:
utils.error_message_and_exit("insertKey must be passed or creating channel")
create_aqm_webhook(args.targetAccount[0], target_api_key, args.insertKey[0], args.createChannel[0], region)
if args.addChannel:
if not args.policyFile:
utils.error_message_and_exit("policyFile not found. Pass policyFile listing policies to which channel "
"should be added")
add_channel_to_policies(args.targetAccount[0], target_api_key, args.addChannel[0], args.policyFile[0], region)


if __name__ == '__main__':
main()
10 changes: 10 additions & 0 deletions store_policies.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,16 @@ def store_alert_policies(src_account, src_api_key, src_region):
log.info('Starting store alert policies.')
policies = ac.get_all_alert_policies(src_api_key, src_region)
store.save_alert_policies(src_account, policies)
policy_file_name = str(src_account)+'_policies.csv'
policy_names_file = store.create_output_file(policy_file_name)
with policy_names_file.open('a') as policy_names_out:
for policy in policies['policies']:
policy_name = policy['name']
policy_name = store.sanitize(policy_name)
policy_names_out.write(policy_name + "\n")
policy_names_out.close()
log.info("Policy names stored in " + policy_file_name)
log.info("Policies JSON stored in " + "db/"+str(src_account)+"/alert_policies/alert_policies.json")
log.info('Finished store alert policies.')


Expand Down

0 comments on commit 3725134

Please sign in to comment.