Skip to content

Commit f051753

Browse files
committed
add list questions and update alert params
1 parent cc67098 commit f051753

File tree

2 files changed

+200
-6
lines changed

2 files changed

+200
-6
lines changed

jupiterone/client.py

Lines changed: 141 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@
4343
CREATE_RULE_INSTANCE,
4444
DELETE_RULE_INSTANCE,
4545
UPDATE_RULE_INSTANCE,
46-
EVALUATE_RULE_INSTANCE
46+
EVALUATE_RULE_INSTANCE,
47+
QUESTIONS,
4748
)
4849

4950

@@ -804,7 +805,14 @@ def get_alert_rule_details(self, rule_id: str = None):
804805
else:
805806
return 'Alert Rule not found for provided ID in configured J1 Account'
806807

807-
def create_alert_rule(self, name: str = None, description: str = None, tags: List[str] = None, polling_interval: str = None, severity: str = None, j1ql: str = None, action_configs: Dict = None):
808+
def create_alert_rule(self,
809+
name: str = None,
810+
description: str = None,
811+
tags: List[str] = None,
812+
polling_interval: str = None,
813+
severity: str = None,
814+
j1ql: str = None,
815+
action_configs: Dict = None):
808816
"""Create Alert Rule Configuration in J1 account
809817
810818
"""
@@ -864,6 +872,8 @@ def create_alert_rule(self, name: str = None, description: str = None, tags: Lis
864872
if action_configs:
865873
variables['instance']['operations'][0]['actions'].append(action_configs)
866874

875+
print(variables)
876+
867877
response = self._execute_query(CREATE_RULE_INSTANCE, variables=variables)
868878

869879
return response['data']['createInlineQuestionRuleInstance']
@@ -880,7 +890,17 @@ def delete_alert_rule(self, rule_id: str = None):
880890

881891
return response['data']['deleteRuleInstance']
882892

883-
def update_alert_rule(self, rule_id: str = None, j1ql: str = None, polling_interval: str = None, tags: List[str] = None, tag_op: str = None):
893+
def update_alert_rule(self,
894+
rule_id: str = None,
895+
name: str = None,
896+
description: str = None,
897+
j1ql: str = None,
898+
polling_interval: str = None,
899+
severity: str = None,
900+
tags: List[str] = None,
901+
tag_op: str = None,
902+
action_configs: List[dict] = None,
903+
action_configs_op: str = None):
884904
"""Update Alert Rule Configuration in J1 account
885905
886906
"""
@@ -894,14 +914,26 @@ def update_alert_rule(self, rule_id: str = None, j1ql: str = None, polling_inter
894914
operations = alert_rule_config['operations']
895915
del operations[0]['__typename']
896916

917+
# update name if provided
918+
if name is not None:
919+
alert_name = name
920+
else:
921+
alert_name = alert_rule_config['name']
922+
923+
# update description if provided
924+
if description is not None:
925+
alert_description = description
926+
else:
927+
alert_description = alert_rule_config['description']
928+
897929
# update J1QL query if provided
898930
if j1ql is not None:
899931
question_config = alert_rule_config['question']
900932
# remove problematic fields
901933
del question_config['__typename']
902934
del question_config['queries'][0]['__typename']
903935

904-
# update query string
936+
# update query string if provided
905937
question_config['queries'][0]['query'] = j1ql
906938
else:
907939
question_config = alert_rule_config['question']
@@ -915,9 +947,15 @@ def update_alert_rule(self, rule_id: str = None, j1ql: str = None, polling_inter
915947
else:
916948
interval_config = alert_rule_config['pollingInterval']
917949

950+
# update alert severity if provided
951+
if severity is not None:
952+
action_config = alert_rule_config['operations'][0]['actions']
953+
action_config[0]['targetValue'] = severity
954+
else:
955+
action_config = alert_rule_config['operations'][0]['actions']
956+
918957
# update tags list if provided
919958
if tags is not None:
920-
921959
if tag_op == "OVERWRITE":
922960
tags_config = tags
923961
elif tag_op == "APPEND":
@@ -927,12 +965,37 @@ def update_alert_rule(self, rule_id: str = None, j1ql: str = None, polling_inter
927965
else:
928966
tags_config = alert_rule_config['tags']
929967

968+
# update action_configs list if provided
969+
if action_configs is not None:
970+
971+
if action_configs_op == "OVERWRITE":
972+
973+
# maintain first item and build new list from input
974+
alert_action_configs = []
975+
base_action = alert_rule_config['operations'][0]['actions'][0]
976+
alert_action_configs.append(base_action)
977+
alert_action_configs.extend(action_configs)
978+
979+
# update actions field inside operations payload
980+
operations[0]['actions'] = alert_action_configs
981+
982+
elif action_configs_op == "APPEND":
983+
984+
# update actions field inside operations payload
985+
operations[0]['actions'].extend(action_configs)
986+
987+
else:
988+
pass
989+
else:
990+
pass
991+
930992
variables = {
931993
"instance": {
932994
"id": rule_id,
933995
"version": rule_version,
934996
"specVersion": alert_rule_config['specVersion'],
935-
"name": alert_rule_config['name'],
997+
"name": alert_name,
998+
"description": alert_description,
936999
"question": question_config,
9371000
"operations": operations,
9381001
"pollingInterval": interval_config,
@@ -954,3 +1017,75 @@ def evaluate_alert_rule(self, rule_id: str = None):
9541017

9551018
response = self._execute_query(EVALUATE_RULE_INSTANCE, variables=variables)
9561019
return response
1020+
1021+
def fetch_latest_evaluation_results(self):
1022+
"""Fetch latest Alert Rules configured in J1 account
1023+
1024+
"""
1025+
results = []
1026+
1027+
data = {
1028+
"query": LIST_RULE_INSTANCES,
1029+
"flags": {
1030+
"variableResultSize": True
1031+
}
1032+
}
1033+
1034+
r = requests.post(url=self.graphql_url, headers=self.headers, json=data, verify=True).json()
1035+
results.extend(r['data']['listRuleInstances']['questionInstances'])
1036+
1037+
while r['data']['listRuleInstances']['pageInfo']['hasNextPage'] == True:
1038+
1039+
cursor = r['data']['listRuleInstances']['pageInfo']['endCursor']
1040+
1041+
# cursor query until last page fetched
1042+
data = {
1043+
"query": LIST_RULE_INSTANCES,
1044+
"variables": {
1045+
"cursor": cursor
1046+
},
1047+
"flags":{
1048+
"variableResultSize": True
1049+
}
1050+
}
1051+
1052+
r = requests.post(url=self.graphql_url, headers=self.headers, json=data, verify=True).json()
1053+
results.extend(r['data']['listRuleInstances']['questionInstances'])
1054+
1055+
return results
1056+
1057+
def list_questions(self):
1058+
"""List all defined Questions configured in J1 account Questions Library
1059+
1060+
"""
1061+
results = []
1062+
1063+
data = {
1064+
"query": QUESTIONS,
1065+
"flags": {
1066+
"variableResultSize": True
1067+
}
1068+
}
1069+
1070+
r = requests.post(url=self.graphql_url, headers=self.headers, json=data, verify=True).json()
1071+
results.extend(r['data']['questions']['questions'])
1072+
1073+
while r['data']['questions']['pageInfo']['hasNextPage'] == True:
1074+
1075+
cursor = r['data']['questions']['pageInfo']['endCursor']
1076+
1077+
# cursor query until last page fetched
1078+
data = {
1079+
"query": QUESTIONS,
1080+
"variables": {
1081+
"cursor": cursor
1082+
},
1083+
"flags":{
1084+
"variableResultSize": True
1085+
}
1086+
}
1087+
1088+
r = requests.post(url=self.graphql_url, headers=self.headers, json=data, verify=True).json()
1089+
results.extend(r['data']['questions']['questions'])
1090+
1091+
return results

jupiterone/constants.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,4 +558,63 @@
558558
__typename
559559
}
560560
}
561+
"""
562+
563+
QUESTIONS = """
564+
query questions($searchQuery: String, $integrationDefinitionId: String, $tags: [String], $type: ListQuestionsType, $limit: Int, $cursor: String, $categories: [String]) {
565+
questions(
566+
searchQuery: $searchQuery
567+
integrationDefinitionId: $integrationDefinitionId
568+
tags: $tags
569+
type: $type
570+
limit: $limit
571+
cursor: $cursor
572+
categories: $categories
573+
) {
574+
questions {
575+
...QuestionFields
576+
__typename
577+
}
578+
totalHits
579+
pageInfo {
580+
endCursor
581+
hasNextPage
582+
__typename
583+
}
584+
__typename
585+
}
586+
}
587+
588+
fragment QuestionFields on Question {
589+
id
590+
sourceId
591+
title
592+
description
593+
tags
594+
lastUpdatedTimestamp
595+
queries {
596+
name
597+
query
598+
version
599+
resultsAre
600+
__typename
601+
}
602+
compliance {
603+
standard
604+
requirements
605+
controls
606+
__typename
607+
}
608+
variables {
609+
name
610+
required
611+
default
612+
__typename
613+
}
614+
accountId
615+
integrationDefinitionId
616+
showTrend
617+
pollingInterval
618+
__typename
619+
}
561620
"""

0 commit comments

Comments
 (0)