From 611fe2ff627060843a990622f80fda668e36b174 Mon Sep 17 00:00:00 2001 From: SeaBlooms Date: Tue, 22 Oct 2024 19:01:37 -0600 Subject: [PATCH 01/20] update examples with new methods --- examples/examples.py | 83 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 65 insertions(+), 18 deletions(-) diff --git a/examples/examples.py b/examples/examples.py index ed468f0..d380d28 100644 --- a/examples/examples.py +++ b/examples/examples.py @@ -2,6 +2,7 @@ import random import time import os +from datetime import datetime account = os.environ.get("JUPITERONE_ACCOUNT") token = os.environ.get("JUPITERONE_TOKEN") @@ -118,11 +119,20 @@ integration_instance_id = "" # start_sync_job -start_sync_job_r = j1.start_sync_job(instance_id=integration_instance_id) +# sync_mode can be "DIFF", "CREATE_OR_UPDATE", or "PATCH" +start_sync_job_r = j1.start_sync_job(instance_id=integration_instance_id, + sync_mode='CREATE_OR_UPDATE', + source='integration-external') print("start_sync_job()") print(start_sync_job_r) # upload_entities_batch_json +rand_val_range = [x / 10.0 for x in range(0, 100)] +rand_val = random.choice(rand_val_range) + +now_dt = datetime.now() +epoch_now = round(datetime.strptime(str(now_dt), "%Y-%m-%d %H:%M:%S.%f").timestamp()) + entity_payload = [ { "_key": "1", @@ -131,20 +141,18 @@ "displayName": "pythonclient1", "propertyName": "value", "relationshipProperty": "source", + "value": rand_val, + "bulkUploadedOn": epoch_now }, { "_key": "2", "_type": "pythonclient", "_class": "API", "displayName": "pythonclient2", - "propertyName": "value" - }, - { - "_key": "3", - "_type": "pythonclient", - "_class": "API", - "displayName": "pythonclient3", - "propertyName": "value" + "propertyName": "value", + "relationshipProperty": "source", + "value": rand_val, + "bulkUploadedOn": epoch_now } ] @@ -188,22 +196,21 @@ "_type": "pythonclient", "_class": "API", "displayName": "pythonclient4", - "propertyName": "value", - "relationshipProperty": "source", + "enrichProp": "value1" }, { "_key": "5", "_type": "pythonclient", "_class": "API", "displayName": "pythonclient5", - "propertyName": "value" + "enrichProp": "value2" }, { "_key": "6", "_type": "pythonclient", "_class": "API", "displayName": "pythonclient6", - "propertyName": "value" + "enrichProp": "value3" } ], "relationships": [ @@ -278,12 +285,52 @@ print("get_smartclass_details()") print(get_smartclass_details_r) -# list_configured_alert_rules -list_configured_alert_rules_r = j1.list_configured_alert_rules() -print("list_configured_alert_rules()") -print(list_configured_alert_rules_r) - # generate_j1ql generate_j1ql_r = j1.generate_j1ql(natural_language_prompt="show me all Users containing 'jupiterone' in their email address") print("generate_j1ql()") print(generate_j1ql_r) + +# list_alert_rules +list_alert_rules_r = j1.list_alert_rules() +print("list_configured_alert_rules()") +print(list_alert_rules_r) +print(len(list_alert_rules_r['questionInstances'])) + +# create_alert_rule +webhook_token = "" + +webhook_action_config = { + "type": "WEBHOOK", + "endpoint": "https://webhook.domain.here/endpoint", + "headers": { + "Authorization": "Bearer {}".format(webhook_token), + }, + "method": "POST", + "body": { + "queryData": "{{queries.query0.data}}" + } +} + +tag_entities_action_config = { + "type": "TAG_ENTITIES", + "entities": "{{queries.query0.data}}", + "tags": [ + { + "name": "tagKey", + "value": "tagValue" + } + ] +} + +create_alert_rule_r = j1.create_alert_rule(name="create_alert_rule", + description="create_alert_rule-description", + tags=['tag1', 'tag2'], + polling_interval="DISABLED", + severity="INFO", + j1ql="find jupiterone_user") +print("create_alert_rule()") +print(create_alert_rule_r) + +delete_alert_rule_r = j1.delete_alert_rule(rule_id="") +print("delete_alert_rule()") +print(delete_alert_rule_r) From b01d73d017b2658a0b5a35566855cec10cd3e5ba Mon Sep 17 00:00:00 2001 From: SeaBlooms Date: Tue, 22 Oct 2024 20:50:33 -0600 Subject: [PATCH 02/20] add pagination for alert rules --- jupiterone/client.py | 42 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/jupiterone/client.py b/jupiterone/client.py index 3d39cda..014d218 100644 --- a/jupiterone/client.py +++ b/jupiterone/client.py @@ -48,7 +48,6 @@ def retry_on_429(exc): """Used to trigger retry on rate limit""" return isinstance(exc, JupiterOneApiRetryError) - class JupiterOneClient: """Python client class for the JupiterOne GraphQL API""" @@ -712,14 +711,45 @@ def generate_j1ql(self, natural_language_prompt: str = None): return response['data']['j1qlFromNaturalLanguage'] def list_alert_rules(self): - """List defined Alert Rules configured in J1 account + """List all defined Alert Rules configured in J1 account """ - response = self._execute_query(LIST_RULE_INSTANCES) + results = [] + + data = { + "query": LIST_RULE_INSTANCES, + "flags": { + "variableResultSize": True + } + } + + r = requests.post(url=self.graphql_url, headers=self.headers, json=data, verify=True).json() + results.extend(r['data']['listRuleInstances']['questionInstances']) + + while r['data']['listRuleInstances']['pageInfo']['hasNextPage'] == True: + + cursor = r['data']['listRuleInstances']['pageInfo']['endCursor'] + + # cursor query until reached last page + data = { + "query": LIST_RULE_INSTANCES, + "variables": { + "cursor": cursor + }, + "flags":{ + "variableResultSize": True + } + } + + r = requests.post(url=self.graphql_url, headers=self.headers, json=data, verify=True).json() + results.extend(r['data']['listRuleInstances']['questionInstances']) + + else: + return results - return response['data']['listRuleInstances'] + return results - 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): + 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_config: Dict = None): """Create Alert Rule Configuration in J1 account """ @@ -795,4 +825,4 @@ def delete_alert_rule(self, rule_id: str = None): response = self._execute_query(DELETE_RULE_INSTANCE, variables=variables) - return response['data']['deleteRuleInstance'] \ No newline at end of file + return response['data']['deleteRuleInstance'] From c7474111c6a2f086d5c2f50799d60c789cebaa89 Mon Sep 17 00:00:00 2001 From: SeaBlooms Date: Tue, 22 Oct 2024 20:53:55 -0600 Subject: [PATCH 03/20] fixes --- examples/examples.py | 2 +- jupiterone/client.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/examples.py b/examples/examples.py index d380d28..7804fac 100644 --- a/examples/examples.py +++ b/examples/examples.py @@ -294,7 +294,7 @@ list_alert_rules_r = j1.list_alert_rules() print("list_configured_alert_rules()") print(list_alert_rules_r) -print(len(list_alert_rules_r['questionInstances'])) +print(len(list_alert_rules_r)) # create_alert_rule webhook_token = "" diff --git a/jupiterone/client.py b/jupiterone/client.py index 014d218..34d85b0 100644 --- a/jupiterone/client.py +++ b/jupiterone/client.py @@ -730,7 +730,7 @@ def list_alert_rules(self): cursor = r['data']['listRuleInstances']['pageInfo']['endCursor'] - # cursor query until reached last page + # cursor query until last page fetched data = { "query": LIST_RULE_INSTANCES, "variables": { From b899c925aa0d753d0d2aaa7bd28cb987d481e2ee Mon Sep 17 00:00:00 2001 From: SeaBlooms Date: Tue, 22 Oct 2024 20:57:53 -0600 Subject: [PATCH 04/20] remove else after while --- jupiterone/client.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/jupiterone/client.py b/jupiterone/client.py index 34d85b0..92bbb95 100644 --- a/jupiterone/client.py +++ b/jupiterone/client.py @@ -744,12 +744,9 @@ def list_alert_rules(self): r = requests.post(url=self.graphql_url, headers=self.headers, json=data, verify=True).json() results.extend(r['data']['listRuleInstances']['questionInstances']) - else: - return results - return results - 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_config: Dict = None): + 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): """Create Alert Rule Configuration in J1 account """ @@ -826,3 +823,4 @@ def delete_alert_rule(self, rule_id: str = None): response = self._execute_query(DELETE_RULE_INSTANCE, variables=variables) return response['data']['deleteRuleInstance'] + \ No newline at end of file From 2aedeca634cf17597c9422890ff6f305958770e9 Mon Sep 17 00:00:00 2001 From: SeaBlooms Date: Tue, 22 Oct 2024 21:18:29 -0600 Subject: [PATCH 05/20] add get_alert_rule_details --- examples/examples.py | 5 +++++ jupiterone/client.py | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/examples/examples.py b/examples/examples.py index 7804fac..51479c4 100644 --- a/examples/examples.py +++ b/examples/examples.py @@ -296,6 +296,11 @@ print(list_alert_rules_r) print(len(list_alert_rules_r)) +# get_alert_rule_details +get_alert_rule_details_r = j1.get_alert_rule_details(alert_rule_id="") +print("get_alert_rule_details()") +print(get_alert_rule_details_r) + # create_alert_rule webhook_token = "" diff --git a/jupiterone/client.py b/jupiterone/client.py index 92bbb95..9d7d939 100644 --- a/jupiterone/client.py +++ b/jupiterone/client.py @@ -746,6 +746,48 @@ def list_alert_rules(self): return results + def get_alert_rule_details(self, alert_rule_id: str = None): + """Get details of a single defined Alert Rule configured in J1 account + + """ + results = [] + + data = { + "query": LIST_RULE_INSTANCES, + "flags": { + "variableResultSize": True + } + } + + r = requests.post(url=self.graphql_url, headers=self.headers, json=data, verify=True).json() + results.extend(r['data']['listRuleInstances']['questionInstances']) + + while r['data']['listRuleInstances']['pageInfo']['hasNextPage'] == True: + + cursor = r['data']['listRuleInstances']['pageInfo']['endCursor'] + + # cursor query until last page fetched + data = { + "query": LIST_RULE_INSTANCES, + "variables": { + "cursor": cursor + }, + "flags":{ + "variableResultSize": True + } + } + + r = requests.post(url=self.graphql_url, headers=self.headers, json=data, verify=True).json() + results.extend(r['data']['listRuleInstances']['questionInstances']) + + # pick result out of list of results by 'id' key + for item in results: + if item["id"] == alert_rule_id: + result = item + break + + return result + 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): """Create Alert Rule Configuration in J1 account From 6534c9477a34702957a42a63bf73bef2773f4edc Mon Sep 17 00:00:00 2001 From: SeaBlooms Date: Tue, 22 Oct 2024 21:31:26 -0600 Subject: [PATCH 06/20] fix fetch logic --- jupiterone/client.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/jupiterone/client.py b/jupiterone/client.py index 9d7d939..5d13a75 100644 --- a/jupiterone/client.py +++ b/jupiterone/client.py @@ -781,12 +781,12 @@ def get_alert_rule_details(self, alert_rule_id: str = None): results.extend(r['data']['listRuleInstances']['questionInstances']) # pick result out of list of results by 'id' key - for item in results: - if item["id"] == alert_rule_id: - result = item - break + item = next((item for item in results if item['id'] == alert_rule_id), None) - return result + if item: + return item + else: + return 'Alert Rule not found for provided ID in configured J1 Account' 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): """Create Alert Rule Configuration in J1 account From 5a1b68f358d743e969e8904bc1d6a92cd546b20f Mon Sep 17 00:00:00 2001 From: SeaBlooms Date: Tue, 22 Oct 2024 22:48:39 -0600 Subject: [PATCH 07/20] add update_alert_rule --- examples/examples.py | 12 ++++++++- jupiterone/client.py | 64 ++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 73 insertions(+), 3 deletions(-) diff --git a/examples/examples.py b/examples/examples.py index 51479c4..3952288 100644 --- a/examples/examples.py +++ b/examples/examples.py @@ -302,6 +302,7 @@ print(get_alert_rule_details_r) # create_alert_rule +# polling_interval can be DISABLED, THIRTY_MINUTES, ONE_HOUR, FOUR_HOURS, EIGHT_HOURS, TWELVE_HOURS, ONE_DAY, and ONE_WEEK webhook_token = "" webhook_action_config = { @@ -327,7 +328,7 @@ ] } -create_alert_rule_r = j1.create_alert_rule(name="create_alert_rule", +create_alert_rule_r = j1.create_alert_rule(name="create_alert_rule-name", description="create_alert_rule-description", tags=['tag1', 'tag2'], polling_interval="DISABLED", @@ -339,3 +340,12 @@ delete_alert_rule_r = j1.delete_alert_rule(rule_id="") print("delete_alert_rule()") print(delete_alert_rule_r) + +# update_alert_rule +update_alert_rule_r = j1.update_alert_rule(rule_id="", + j1ql="find jupiterone_user as i return i._key", + polling_interval="ONE_WEEK", + tags=['new_tag1', 'new_tag2']) +print("update_alert_rule()") +print(json.dumps(update_alert_rule_r, indent=1)) + diff --git a/jupiterone/client.py b/jupiterone/client.py index 5d13a75..d74561a 100644 --- a/jupiterone/client.py +++ b/jupiterone/client.py @@ -40,7 +40,8 @@ J1QL_FROM_NATURAL_LANGUAGE, LIST_RULE_INSTANCES, CREATE_RULE_INSTANCE, - DELETE_RULE_INSTANCE + DELETE_RULE_INSTANCE, + UPDATE_RULE_INSTANCE ) @@ -865,4 +866,63 @@ def delete_alert_rule(self, rule_id: str = None): response = self._execute_query(DELETE_RULE_INSTANCE, variables=variables) return response['data']['deleteRuleInstance'] - \ No newline at end of file + + def update_alert_rule(self, rule_id: str = None, j1ql: str = None, polling_interval: str = None, tags: List[str] = None): + """Update Alert Rule Configuration in J1 account + + """ + # fetch existing alert rule + alert_rule_config = self.get_alert_rule_details(rule_id) + + # increment rule config version + rule_version = alert_rule_config['version'] + 1 + + # fetch current operations config + operations = alert_rule_config['operations'] + del operations[0]['__typename'] + + # update J1QL query if provided + if j1ql is not None: + question_config = alert_rule_config['question'] + # remove problematic fields + del question_config['__typename'] + del question_config['queries'][0]['__typename'] + + # update query string + question_config['queries'][0]['query'] = j1ql + else: + question_config = alert_rule_config['question'] + # remove problematic fields + del question_config['__typename'] + del question_config['queries'][0]['__typename'] + + # update polling_interval if provided + if polling_interval is not None: + interval_config = alert_rule_config['pollingInterval'] + interval_config = polling_interval + else: + interval_config = alert_rule_config['pollingInterval'] + + # update tags list if provided + if tags is not None: + tags_config = alert_rule_config['tags'] + tags_config = tags + else: + tags_config = alert_rule_config['tags'] + + variables = { + "instance": { + "id": rule_id, + "version": rule_version, + "specVersion": alert_rule_config['specVersion'], + "name": alert_rule_config['name'], + "question": question_config, + "operations": operations, + "pollingInterval": interval_config, + "tags": tags_config + } + } + + response = self._execute_query(UPDATE_RULE_INSTANCE, variables=variables) + + return response['data']['updateInlineQuestionRuleInstance'] From e482255946ca7e8785899cfd3f7ff25000866cf4 Mon Sep 17 00:00:00 2001 From: SeaBlooms Date: Tue, 22 Oct 2024 22:49:53 -0600 Subject: [PATCH 08/20] Update constants.py --- jupiterone/constants.py | 59 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/jupiterone/constants.py b/jupiterone/constants.py index 71fda66..ee0806e 100644 --- a/jupiterone/constants.py +++ b/jupiterone/constants.py @@ -473,4 +473,63 @@ __typename } } +""" + +UPDATE_RULE_INSTANCE = """ + mutation updateQuestionRuleInstance($instance: UpdateInlineQuestionRuleInstanceInput!) { + updateInlineQuestionRuleInstance(instance: $instance) { + ...RuleInstanceFields + __typename + } + } + + fragment RuleInstanceFields on QuestionRuleInstance { + id + accountId + name + description + version + lastEvaluationStartOn + lastEvaluationEndOn + evaluationStep + specVersion + notifyOnFailure + triggerActionsOnNewEntitiesOnly + ignorePreviousResults + pollingInterval + templates + outputs + labels { + labelName + labelValue + __typename + } + question { + queries { + query + name + includeDeleted + __typename + } + __typename + } + questionId + latest + deleted + type + operations { + when + actions + __typename + } + latestAlertId + latestAlertIsActive + state { + actions + __typename + } + tags + remediationSteps + __typename + } """ \ No newline at end of file From 1c5ef24d58edccde46305a2816063850c79aa0ab Mon Sep 17 00:00:00 2001 From: SeaBlooms Date: Tue, 22 Oct 2024 23:02:43 -0600 Subject: [PATCH 09/20] Update README.md --- README.md | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 65 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index b0daa05..464bc70 100644 --- a/README.md +++ b/README.md @@ -300,14 +300,76 @@ j1.evaluate_smartclass(smartclass_id='') j1.get_smartclass_details(smartclass_id='') ``` +##### Generate J1QL from Natural Language Prompt + +```python +j1.generate_j1ql(natural_language_prompt='') +``` + ##### List Alert Rules ```python -j1.list_configured_alert_rules() +j1.list_alert_rules() ``` -##### Generate J1QL from Natural Language Prompt +##### Get Alert Rule Details ```python -j1.generate_j1ql(natural_language_prompt='') +j1.get_alert_rule_details(alert_rule_id='') ``` + +##### Create Alert Rule + +```python +# polling_interval can be DISABLED, THIRTY_MINUTES, ONE_HOUR, FOUR_HOURS, EIGHT_HOURS, TWELVE_HOURS, ONE_DAY, and ONE_WEEK + +j1.create_alert_rule(name="create_alert_rule-name", + description="create_alert_rule-description", + tags=['tag1', 'tag2'], + polling_interval="DISABLED", + severity="INFO", + j1ql="find jupiterone_user") +``` + +##### Create Alert Rule with Action Config + +```python + +webhook_action_config = { + "type": "WEBHOOK", + "endpoint": "https://webhook.domain.here/endpoint", + "headers": { + "Authorization": "Bearer ", + }, + "method": "POST", + "body": { + "queryData": "{{queries.query0.data}}" + } +} + +j1.create_alert_rule(name="create_alert_rule-name", + description="create_alert_rule-description", + tags=['tag1', 'tag2'], + polling_interval="DISABLED", + severity="INFO", + j1ql="find jupiterone_user", + action_configs=webhook_action_config) + +``` + +##### Delete Alert Rule + +```python + +j1.delete_alert_rule(rule_id=' Date: Tue, 22 Oct 2024 23:15:10 -0600 Subject: [PATCH 10/20] add tag_op to update rule --- README.md | 11 +++++++++++ jupiterone/client.py | 11 +++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 464bc70..5625183 100644 --- a/README.md +++ b/README.md @@ -368,8 +368,19 @@ j1.delete_alert_rule(rule_id=' Date: Tue, 22 Oct 2024 23:24:49 -0600 Subject: [PATCH 11/20] Update client.py --- jupiterone/client.py | 1 - 1 file changed, 1 deletion(-) diff --git a/jupiterone/client.py b/jupiterone/client.py index d0d6528..d3c61d7 100644 --- a/jupiterone/client.py +++ b/jupiterone/client.py @@ -906,7 +906,6 @@ def update_alert_rule(self, rule_id: str = None, j1ql: str = None, polling_inter if tags is not None: if tag_op == "OVERWRITE": - tags_config = alert_rule_config['tags'] tags_config = tags elif tag_op == "APPEND": tags_config = alert_rule_config['tags'] + tags From 9271056c459d0c3346ea82fdf1c8e2b56afd89f2 Mon Sep 17 00:00:00 2001 From: SeaBlooms Date: Tue, 22 Oct 2024 23:27:50 -0600 Subject: [PATCH 12/20] Update client.py --- jupiterone/client.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/jupiterone/client.py b/jupiterone/client.py index d3c61d7..563219d 100644 --- a/jupiterone/client.py +++ b/jupiterone/client.py @@ -909,6 +909,8 @@ def update_alert_rule(self, rule_id: str = None, j1ql: str = None, polling_inter tags_config = tags elif tag_op == "APPEND": tags_config = alert_rule_config['tags'] + tags + else: + tags_config = alert_rule_config['tags'] else: tags_config = alert_rule_config['tags'] From 519b8bb50f083c1ad4798ab1ccdbf2a60adc3385 Mon Sep 17 00:00:00 2001 From: SeaBlooms Date: Tue, 22 Oct 2024 23:38:10 -0600 Subject: [PATCH 13/20] add evaluate_alert_rule and cleanup --- README.md | 10 +++++++++- examples/examples.py | 9 ++++++++- jupiterone/client.py | 18 +++++++++++++++--- jupiterone/constants.py | 9 +++++++++ 4 files changed, 41 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 5625183..fb7db25 100644 --- a/README.md +++ b/README.md @@ -315,7 +315,7 @@ j1.list_alert_rules() ##### Get Alert Rule Details ```python -j1.get_alert_rule_details(alert_rule_id='') +j1.get_alert_rule_details(rule_id='') ``` ##### Create Alert Rule @@ -383,4 +383,12 @@ j1.update_alert_rule(rule_id='") +get_alert_rule_details_r = j1.get_alert_rule_details(rule_id="") print("get_alert_rule_details()") print(get_alert_rule_details_r) @@ -337,6 +337,7 @@ print("create_alert_rule()") print(create_alert_rule_r) +# delete_alert_rule delete_alert_rule_r = j1.delete_alert_rule(rule_id="") print("delete_alert_rule()") print(delete_alert_rule_r) @@ -349,3 +350,9 @@ print("update_alert_rule()") print(json.dumps(update_alert_rule_r, indent=1)) +# evaluate_alert_rule +evaluate_alert_rule_r = j1.evaluate_alert_rule(rule_id="") +print("evaluate_alert_rule()") +print(json.dumps(evaluate_alert_rule_r, indent=1)) + + diff --git a/jupiterone/client.py b/jupiterone/client.py index 563219d..07fa3b5 100644 --- a/jupiterone/client.py +++ b/jupiterone/client.py @@ -41,7 +41,8 @@ LIST_RULE_INSTANCES, CREATE_RULE_INSTANCE, DELETE_RULE_INSTANCE, - UPDATE_RULE_INSTANCE + UPDATE_RULE_INSTANCE, + EVALUATE_RULE_INSTANCE ) @@ -747,7 +748,7 @@ def list_alert_rules(self): return results - def get_alert_rule_details(self, alert_rule_id: str = None): + def get_alert_rule_details(self, rule_id: str = None): """Get details of a single defined Alert Rule configured in J1 account """ @@ -782,7 +783,7 @@ def get_alert_rule_details(self, alert_rule_id: str = None): results.extend(r['data']['listRuleInstances']['questionInstances']) # pick result out of list of results by 'id' key - item = next((item for item in results if item['id'] == alert_rule_id), None) + item = next((item for item in results if item['id'] == rule_id), None) if item: return item @@ -930,3 +931,14 @@ def update_alert_rule(self, rule_id: str = None, j1ql: str = None, polling_inter response = self._execute_query(UPDATE_RULE_INSTANCE, variables=variables) return response['data']['updateInlineQuestionRuleInstance'] + + def evaluate_alert_rule(self, rule_id: str = None): + """Run an Evaluation for a defined Alert Rule configured in J1 account + + """ + variables = { + "id": rule_id + } + + response = self._execute_query(EVALUATE_RULE_INSTANCE, variables=variables) + return response \ No newline at end of file diff --git a/jupiterone/constants.py b/jupiterone/constants.py index ee0806e..110419a 100644 --- a/jupiterone/constants.py +++ b/jupiterone/constants.py @@ -532,4 +532,13 @@ remediationSteps __typename } +""" + +EVALUATE_RULE_INSTANCE = """ + mutation evaluateRuleInstance($id: ID!) { + evaluateRuleInstance(id: $id) { + id + __typename + } + } """ \ No newline at end of file From 25b2bd5bd9aea6f13d150d453d688da272d49c0d Mon Sep 17 00:00:00 2001 From: SeaBlooms Date: Tue, 22 Oct 2024 23:44:31 -0600 Subject: [PATCH 14/20] Update client.py --- jupiterone/client.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/jupiterone/client.py b/jupiterone/client.py index 07fa3b5..a92c5ae 100644 --- a/jupiterone/client.py +++ b/jupiterone/client.py @@ -850,8 +850,6 @@ def create_alert_rule(self, name: str = None, description: str = None, tags: Lis if action_configs: variables['instance']['operations'][0]['actions'].append(action_configs) - print(variables) - response = self._execute_query(CREATE_RULE_INSTANCE, variables=variables) return response['data']['createInlineQuestionRuleInstance'] From e25211748c616e7d84b34802fed973e420b9a120 Mon Sep 17 00:00:00 2001 From: SeaBlooms Date: Tue, 22 Oct 2024 23:47:15 -0600 Subject: [PATCH 15/20] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index fb7db25..613206e 100644 --- a/README.md +++ b/README.md @@ -321,7 +321,8 @@ j1.get_alert_rule_details(rule_id='') ##### Create Alert Rule ```python -# polling_interval can be DISABLED, THIRTY_MINUTES, ONE_HOUR, FOUR_HOURS, EIGHT_HOURS, TWELVE_HOURS, ONE_DAY, and ONE_WEEK +# polling_interval can be DISABLED, THIRTY_MINUTES, ONE_HOUR, FOUR_HOURS, EIGHT_HOURS, TWELVE_HOURS, ONE_DAY, or ONE_WEEK +# severity can be INFO, LOW, MEDIUM, HIGH, or CRITICAL j1.create_alert_rule(name="create_alert_rule-name", description="create_alert_rule-description", From 149df57b2ed2681658feae3e3241702dd517cd93 Mon Sep 17 00:00:00 2001 From: SeaBlooms Date: Wed, 23 Oct 2024 09:42:39 -0600 Subject: [PATCH 16/20] fix typo --- README.md | 2 +- examples/examples copy.py | 369 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 370 insertions(+), 1 deletion(-) create mode 100644 examples/examples copy.py diff --git a/README.md b/README.md index 613206e..385de23 100644 --- a/README.md +++ b/README.md @@ -99,7 +99,7 @@ j1.update_entity( #### Delete an entity: ```python -j1.delete_entity(entit_id='') +j1.delete_entity(entity_id='') ``` ##### Create a relationship diff --git a/examples/examples copy.py b/examples/examples copy.py new file mode 100644 index 0000000..1340b35 --- /dev/null +++ b/examples/examples copy.py @@ -0,0 +1,369 @@ +from jupiterone.client import JupiterOneClient +import random +import time +import os +from datetime import datetime +import json + +account = os.environ.get("JUPITERONE_ACCOUNT") +token = os.environ.get("JUPITERONE_TOKEN") +url = "https://graphql.us.jupiterone.io" + +j1 = JupiterOneClient(account=account, token=token, url=url) + +# # query_v1 +# q = 'FIND User WITH _type = "jupiterone_user" as i return i.*' +# query_r = j1.query_v1(q) +# print("query_v1()") +# print(query_r) +# +# # create_entity +# num1 = random.randrange(1, 999, 1) +# +# # create_entity +# properties = { +# 'displayName': 'test{}'.format(num1), +# 'customProperty': 'customVal', +# 'tag.Production': 'false', +# 'owner': 'user.name@jupiterone.com' +# } +# +# create_r = j1.create_entity( +# entity_key='jupiterone-api-client-python:{}'.format(num1), +# entity_type='python_client_create_entity', +# entity_class='Record', +# properties=properties, +# timestamp=int(time.time()) * 1000 # Optional, defaults to current datetime +# ) +# print("create_entity()") +# print(create_r) +# +# properties = { +# 'customProperty': 'customValUpdated' +# } +# +# # update_entity +# update_r = j1.update_entity( +# entity_id='{}'.format(create_r['entity']['_id']), +# properties=properties +# ) +# print("update_entity()") +# print(update_r) +# +# # create_entity_2 +# num2 = random.randrange(1, 999, 1) +# +# properties = { +# 'displayName': 'test{}'.format(num2), +# 'customProperty': 'customVal', +# 'tag.Production': 'false', +# 'owner': 'user.name@jupiterone.com' +# } +# +# create_r_2 = j1.create_entity( +# entity_key='jupiterone-api-client-python:{}'.format(num2), +# entity_type='python_client_create_entity', +# entity_class='Record', +# properties=properties, +# timestamp=int(time.time()) * 1000 # Optional, defaults to current datetime +# ) +# print("create_entity()") +# print(create_r_2) +# +# # create_relationship +# create_relationship_r = j1.create_relationship( +# relationship_key='{}:{}'.format(create_r['entity']['_id'], create_r_2['entity']['_id']), +# relationship_type='jupiterone-api-client-python:create_relationship', +# relationship_class='HAS', +# from_entity_id=create_r['entity']['_id'], +# to_entity_id=create_r_2['entity']['_id'], +# ) +# print("create_relationship()") +# print(create_relationship_r) +# +# # delete_relationship +# delete_relationship_r = j1.delete_relationship(relationship_id=create_relationship_r['relationship']['_id']) +# print("delete_relationship()") +# print(delete_relationship_r) +# +# # delete_entity +# delete_entity_r1 = j1.delete_entity(entity_id=create_r['entity']['_id']) +# print("delete_entity()") +# print(delete_entity_r1) +# +# delete_entity_r2 = j1.delete_entity(entity_id=create_r_2['entity']['_id']) +# print("delete_entity()") +# print(delete_entity_r2) +# +# # cursor_query +# q = "FIND Person" +# cursor_query_r = j1._cursor_query(q) +# print("cursor_query()") +# print(cursor_query_r) +# +# # fetch_all_entity_properties +# fetch_all_entity_properties_r = j1.fetch_all_entity_properties() +# print("fetch_all_entity_properties()") +# print(fetch_all_entity_properties_r) +# +# # fetch_all_entity_tags +# fetch_all_entity_tags_r = j1.fetch_all_entity_tags() +# print("fetch_all_entity_tags()") +# print(fetch_all_entity_tags_r) +# +# # create_integration_instance +# create_integration_instance_r = j1.create_integration_instance(instance_name="pythonclient-customintegration", +# instance_description="dev-testing") +# print("create_integration_instance()") +# print(create_integration_instance_r) +# +# integration_instance_id = "" +# # +# # start_sync_job +# start_sync_job_r = j1.start_sync_job(instance_id=integration_instance_id, +# sync_mode='PATCH', +# source='integration-external') +# print("start_sync_job()") +# print(start_sync_job_r) +# +# # upload_entities_batch_json +# rand_score_range = [x / 10.0 for x in range(0, 100)] +# rand_score = random.choice(rand_score_range) +# +# now_dt = datetime.now() +# epoch_now = round(datetime.strptime(str(now_dt), "%Y-%m-%d %H:%M:%S.%f").timestamp()) +# +# entity_payload = [ +# { +# "_key": "jupiterone_user:0014433b-e14e-49f8-967f-86b54a27b90d", +# "enrichVal": rand_score, +# "lastEnrichedOn": epoch_now +# }, +# { +# "_key": "jupiterone_user:28a5ab70-6ec3-49fc-bf37-df04c36bc6e1", +# "enrichVal": rand_score, +# "lastEnrichedOn": epoch_now +# } +# ] +# +# # update_entities_batch_json +# upload_entities_batch_json_r = j1.upload_entities_batch_json(instance_job_id=start_sync_job_r['job']['id'], +# entities_list=entity_payload) +# print("upload_entities_batch_json()") +# print(upload_entities_batch_json_r) +# +# # upload_relationships_batch_json +# relationships_payload = [ +# { +# "_key": "1:2", +# "_class": "EXTENDS", +# "_type": "pythonclient_extends_pythonclient", +# "_fromEntityKey": "1", +# "_toEntityKey": "2", +# "relationshipProperty": "value" +# }, +# { +# "_key": "2:3", +# "_class": "EXTENDS", +# "_type": "pythonclient_extends_pythonclient", +# "_fromEntityKey": "2", +# "_toEntityKey": "3", +# "relationshipProperty": "value" +# } +# ] +# +# # update_relationships_batch_json +# upload_relationships_batch_json_r = j1.upload_relationships_batch_json(instance_job_id=start_sync_job_r['job']['id'], +# relationships_list=relationships_payload) +# print("upload_relationships_batch_json()") +# print(upload_relationships_batch_json_r) +# +# # upload_entities_batch_json +# combined_payload = { +# "entities": [ +# { +# "_key": "4", +# "_type": "pythonclient", +# "_class": "API", +# "displayName": "pythonclient4", +# "enrichProp": "value1" +# }, +# { +# "_key": "5", +# "_type": "pythonclient", +# "_class": "API", +# "displayName": "pythonclient5", +# "enrichProp": "value2" +# }, +# { +# "_key": "6", +# "_type": "pythonclient", +# "_class": "API", +# "displayName": "pythonclient6", +# "enrichProp": "value3" +# } +# ], +# "relationships": [ +# { +# "_key": "4:5", +# "_class": "EXTENDS", +# "_type": "pythonclient_extends_pythonclient", +# "_fromEntityKey": "4", +# "_toEntityKey": "5", +# "relationshipProperty": "value" +# }, +# { +# "_key": "5:6", +# "_class": "EXTENDS", +# "_type": "pythonclient_extends_pythonclient", +# "_fromEntityKey": "5", +# "_toEntityKey": "6", +# "relationshipProperty": "value" +# } +# ] +# } +# +# # upload_combined_batch_json +# upload_combined_batch_json_r = j1.upload_combined_batch_json(instance_job_id=start_sync_job_r['job']['id'], +# combined_payload=combined_payload) +# print("upload_combined_batch_json()") +# print(upload_combined_batch_json_r) +# +# # finalize_sync_job +# finalize_sync_job_r = j1.finalize_sync_job(instance_job_id=start_sync_job_r['job']['id']) +# print("finalize_sync_job()") +# print(finalize_sync_job_r) +# +# # fetch_integration_jobs +# fetch_integration_jobs_r = j1.fetch_integration_jobs(instance_id=integration_instance_id) +# print("fetch_integration_jobs()") +# print(fetch_integration_jobs_r) +# +# while j1.fetch_integration_jobs(instance_id=integration_instance_id)['jobs'][0]['status'] == "IN_PROGRESS": +# +# fetch_integration_jobs_r = j1.fetch_integration_jobs(instance_id=integration_instance_id) +# +# print("fetch_integration_jobs()") +# print(fetch_integration_jobs_r) +# # +# # query_v1 +# q = 'FIND User WITH _type = "jupiterone_user" as i return i.*' +# query_r = j1.query_v1(q) +# print("query_v1()") +# print(query_r) +# print(len(query_r['data'])) +# +# +# # fetch_integration_job_events +# fetch_integration_job_events_r = j1.fetch_integration_job_events(instance_id=integration_instance_id, +# instance_job_id=fetch_integration_jobs_r['jobs'][0]['id']) +# print("fetch_integration_job_events()") +# print(fetch_integration_job_events_r) +# +# # create_smartclass +# create_smartclass_r = j1.create_smartclass(smartclass_name="SmartClass1", +# smartclass_description="Created via create_smartclass() method") +# print("create_smartclass()") +# print(create_smartclass_r) +# +# # create_smartclass_query +# create_smartclass_query_r = j1.create_smartclass_query(smartclass_id=create_smartclass_r['id'], +# query="FIND (Device|Host) with osType ~= \'Windows\'", +# query_description="all windows devices and hosts") +# print("create_smartclass_query()") +# print(create_smartclass_query_r) +# +# # evaluate_smartclass +# evaluate_smartclass_r = j1.evaluate_smartclass(smartclass_id=create_smartclass_query_r['smartClassId']) +# print("evaluate_smartclass()") +# print(evaluate_smartclass_r) +# +# # get_smartclass_details +# get_smartclass_details_r = j1.get_smartclass_details(smartclass_id=create_smartclass_query_r['smartClassId']) +# print("get_smartclass_details()") +# print(get_smartclass_details_r) +# +# # generate_j1ql +# generate_j1ql_r = j1.generate_j1ql(natural_language_prompt="show me all Users containing 'jupiterone' in their email address") +# print("generate_j1ql()") +# print(generate_j1ql_r) + +# # list_alert_rules +# list_configured_alert_rules_r = j1.list_alert_rules() +# # print("list_configured_alert_rules()") +# print(json.dumps(list_configured_alert_rules_r, indent=1)) +# print(len(list_configured_alert_rules_r)) + +# update_alert_rule +# update_alert_rule_r = j1.update_alert_rule(rule_id="36f2a661-b47d-4c1a-97a6-7c2905a45c80", +# j1ql="Find DataStore LIMIT 123", +# polling_interval="DISABLED", +# tags=['newnewnew', 'naananana'], +# tag_op="OVERWRITE") + +# update_alert_rule_r = j1.update_alert_rule(rule_id="35091853-9e3a-4cef-86db-58a0f40343cb", +# tags=['newTag1', 'newTag1'], +# tag_op="OVERWRITE") + +# update_alert_rule_r = j1.update_alert_rule(rule_id="36f2a661-b47d-4c1a-97a6-7c2905a45c80", +# tags=['additionalTag1', 'additionalTag2'], +# tag_op="APPEND") + +# update_alert_rule_r = j1.update_alert_rule(rule_id="36f2a661-b47d-4c1a-97a6-7c2905a45c80", +# j1ql="Find Internet") + +# print("update_alert_rule()") +# print(json.dumps(update_alert_rule_r, indent=1)) + +evaluate_alert_rule_r = j1.evaluate_alert_rule(rule_id="36f2a661-b47d-4c1a-97a6-7c2905a45c80") +print("evaluate_alert_rule()") +print(json.dumps(evaluate_alert_rule_r, indent=1)) + + +# for i in list_configured_alert_rules_r: +# print(i['id']) + +# # create_alert_rule +# webhook_token = "" +# +# webhook_action_config = { +# "type": "WEBHOOK", +# "endpoint": "https://webhook.receiver.endpoint", +# "headers": { +# "Authorization": "Bearer {}".format(webhook_token), +# }, +# "method": "POST", +# "body": { +# "queryData": "{{queries.query0.data}}" +# } +# } +# +# tag_entities_action_config = { +# "type": "TAG_ENTITIES", +# "entities": "{{queries.query0.data}}", +# "tags": [ +# { +# "name": "tagKey", +# "value": "tagValue" +# } +# ] +# } +# + +# for i in range(250): +# +# print(i) +# i = str(i) + "-batch2" +# +# create_alert_rule_r = j1.create_alert_rule(name=f"{i}-10-22-24-name", +# description=f"{i}-10-22-24-description", +# tags=['tag1', 'tag2'], +# polling_interval="DISABLED", +# severity="INFO", +# j1ql=f"find jupiterone_user") +# print("create_alert_rule()") +# print(create_alert_rule_r) +# +# delete_alert_rule_r = j1.delete_alert_rule(rule_id="78fa4bd1-b413-46d7-bffe-336051c2055d") +# print("delete_alert_rule()") +# print(delete_alert_rule_r) From f9fcf59138bdbb170403ec4e31ed1c2680652f8f Mon Sep 17 00:00:00 2001 From: SeaBlooms Date: Wed, 23 Oct 2024 09:46:55 -0600 Subject: [PATCH 17/20] Revert "fix typo" This reverts commit 149df57b2ed2681658feae3e3241702dd517cd93. --- README.md | 2 +- examples/examples copy.py | 369 -------------------------------------- 2 files changed, 1 insertion(+), 370 deletions(-) delete mode 100644 examples/examples copy.py diff --git a/README.md b/README.md index 385de23..613206e 100644 --- a/README.md +++ b/README.md @@ -99,7 +99,7 @@ j1.update_entity( #### Delete an entity: ```python -j1.delete_entity(entity_id='') +j1.delete_entity(entit_id='') ``` ##### Create a relationship diff --git a/examples/examples copy.py b/examples/examples copy.py deleted file mode 100644 index 1340b35..0000000 --- a/examples/examples copy.py +++ /dev/null @@ -1,369 +0,0 @@ -from jupiterone.client import JupiterOneClient -import random -import time -import os -from datetime import datetime -import json - -account = os.environ.get("JUPITERONE_ACCOUNT") -token = os.environ.get("JUPITERONE_TOKEN") -url = "https://graphql.us.jupiterone.io" - -j1 = JupiterOneClient(account=account, token=token, url=url) - -# # query_v1 -# q = 'FIND User WITH _type = "jupiterone_user" as i return i.*' -# query_r = j1.query_v1(q) -# print("query_v1()") -# print(query_r) -# -# # create_entity -# num1 = random.randrange(1, 999, 1) -# -# # create_entity -# properties = { -# 'displayName': 'test{}'.format(num1), -# 'customProperty': 'customVal', -# 'tag.Production': 'false', -# 'owner': 'user.name@jupiterone.com' -# } -# -# create_r = j1.create_entity( -# entity_key='jupiterone-api-client-python:{}'.format(num1), -# entity_type='python_client_create_entity', -# entity_class='Record', -# properties=properties, -# timestamp=int(time.time()) * 1000 # Optional, defaults to current datetime -# ) -# print("create_entity()") -# print(create_r) -# -# properties = { -# 'customProperty': 'customValUpdated' -# } -# -# # update_entity -# update_r = j1.update_entity( -# entity_id='{}'.format(create_r['entity']['_id']), -# properties=properties -# ) -# print("update_entity()") -# print(update_r) -# -# # create_entity_2 -# num2 = random.randrange(1, 999, 1) -# -# properties = { -# 'displayName': 'test{}'.format(num2), -# 'customProperty': 'customVal', -# 'tag.Production': 'false', -# 'owner': 'user.name@jupiterone.com' -# } -# -# create_r_2 = j1.create_entity( -# entity_key='jupiterone-api-client-python:{}'.format(num2), -# entity_type='python_client_create_entity', -# entity_class='Record', -# properties=properties, -# timestamp=int(time.time()) * 1000 # Optional, defaults to current datetime -# ) -# print("create_entity()") -# print(create_r_2) -# -# # create_relationship -# create_relationship_r = j1.create_relationship( -# relationship_key='{}:{}'.format(create_r['entity']['_id'], create_r_2['entity']['_id']), -# relationship_type='jupiterone-api-client-python:create_relationship', -# relationship_class='HAS', -# from_entity_id=create_r['entity']['_id'], -# to_entity_id=create_r_2['entity']['_id'], -# ) -# print("create_relationship()") -# print(create_relationship_r) -# -# # delete_relationship -# delete_relationship_r = j1.delete_relationship(relationship_id=create_relationship_r['relationship']['_id']) -# print("delete_relationship()") -# print(delete_relationship_r) -# -# # delete_entity -# delete_entity_r1 = j1.delete_entity(entity_id=create_r['entity']['_id']) -# print("delete_entity()") -# print(delete_entity_r1) -# -# delete_entity_r2 = j1.delete_entity(entity_id=create_r_2['entity']['_id']) -# print("delete_entity()") -# print(delete_entity_r2) -# -# # cursor_query -# q = "FIND Person" -# cursor_query_r = j1._cursor_query(q) -# print("cursor_query()") -# print(cursor_query_r) -# -# # fetch_all_entity_properties -# fetch_all_entity_properties_r = j1.fetch_all_entity_properties() -# print("fetch_all_entity_properties()") -# print(fetch_all_entity_properties_r) -# -# # fetch_all_entity_tags -# fetch_all_entity_tags_r = j1.fetch_all_entity_tags() -# print("fetch_all_entity_tags()") -# print(fetch_all_entity_tags_r) -# -# # create_integration_instance -# create_integration_instance_r = j1.create_integration_instance(instance_name="pythonclient-customintegration", -# instance_description="dev-testing") -# print("create_integration_instance()") -# print(create_integration_instance_r) -# -# integration_instance_id = "" -# # -# # start_sync_job -# start_sync_job_r = j1.start_sync_job(instance_id=integration_instance_id, -# sync_mode='PATCH', -# source='integration-external') -# print("start_sync_job()") -# print(start_sync_job_r) -# -# # upload_entities_batch_json -# rand_score_range = [x / 10.0 for x in range(0, 100)] -# rand_score = random.choice(rand_score_range) -# -# now_dt = datetime.now() -# epoch_now = round(datetime.strptime(str(now_dt), "%Y-%m-%d %H:%M:%S.%f").timestamp()) -# -# entity_payload = [ -# { -# "_key": "jupiterone_user:0014433b-e14e-49f8-967f-86b54a27b90d", -# "enrichVal": rand_score, -# "lastEnrichedOn": epoch_now -# }, -# { -# "_key": "jupiterone_user:28a5ab70-6ec3-49fc-bf37-df04c36bc6e1", -# "enrichVal": rand_score, -# "lastEnrichedOn": epoch_now -# } -# ] -# -# # update_entities_batch_json -# upload_entities_batch_json_r = j1.upload_entities_batch_json(instance_job_id=start_sync_job_r['job']['id'], -# entities_list=entity_payload) -# print("upload_entities_batch_json()") -# print(upload_entities_batch_json_r) -# -# # upload_relationships_batch_json -# relationships_payload = [ -# { -# "_key": "1:2", -# "_class": "EXTENDS", -# "_type": "pythonclient_extends_pythonclient", -# "_fromEntityKey": "1", -# "_toEntityKey": "2", -# "relationshipProperty": "value" -# }, -# { -# "_key": "2:3", -# "_class": "EXTENDS", -# "_type": "pythonclient_extends_pythonclient", -# "_fromEntityKey": "2", -# "_toEntityKey": "3", -# "relationshipProperty": "value" -# } -# ] -# -# # update_relationships_batch_json -# upload_relationships_batch_json_r = j1.upload_relationships_batch_json(instance_job_id=start_sync_job_r['job']['id'], -# relationships_list=relationships_payload) -# print("upload_relationships_batch_json()") -# print(upload_relationships_batch_json_r) -# -# # upload_entities_batch_json -# combined_payload = { -# "entities": [ -# { -# "_key": "4", -# "_type": "pythonclient", -# "_class": "API", -# "displayName": "pythonclient4", -# "enrichProp": "value1" -# }, -# { -# "_key": "5", -# "_type": "pythonclient", -# "_class": "API", -# "displayName": "pythonclient5", -# "enrichProp": "value2" -# }, -# { -# "_key": "6", -# "_type": "pythonclient", -# "_class": "API", -# "displayName": "pythonclient6", -# "enrichProp": "value3" -# } -# ], -# "relationships": [ -# { -# "_key": "4:5", -# "_class": "EXTENDS", -# "_type": "pythonclient_extends_pythonclient", -# "_fromEntityKey": "4", -# "_toEntityKey": "5", -# "relationshipProperty": "value" -# }, -# { -# "_key": "5:6", -# "_class": "EXTENDS", -# "_type": "pythonclient_extends_pythonclient", -# "_fromEntityKey": "5", -# "_toEntityKey": "6", -# "relationshipProperty": "value" -# } -# ] -# } -# -# # upload_combined_batch_json -# upload_combined_batch_json_r = j1.upload_combined_batch_json(instance_job_id=start_sync_job_r['job']['id'], -# combined_payload=combined_payload) -# print("upload_combined_batch_json()") -# print(upload_combined_batch_json_r) -# -# # finalize_sync_job -# finalize_sync_job_r = j1.finalize_sync_job(instance_job_id=start_sync_job_r['job']['id']) -# print("finalize_sync_job()") -# print(finalize_sync_job_r) -# -# # fetch_integration_jobs -# fetch_integration_jobs_r = j1.fetch_integration_jobs(instance_id=integration_instance_id) -# print("fetch_integration_jobs()") -# print(fetch_integration_jobs_r) -# -# while j1.fetch_integration_jobs(instance_id=integration_instance_id)['jobs'][0]['status'] == "IN_PROGRESS": -# -# fetch_integration_jobs_r = j1.fetch_integration_jobs(instance_id=integration_instance_id) -# -# print("fetch_integration_jobs()") -# print(fetch_integration_jobs_r) -# # -# # query_v1 -# q = 'FIND User WITH _type = "jupiterone_user" as i return i.*' -# query_r = j1.query_v1(q) -# print("query_v1()") -# print(query_r) -# print(len(query_r['data'])) -# -# -# # fetch_integration_job_events -# fetch_integration_job_events_r = j1.fetch_integration_job_events(instance_id=integration_instance_id, -# instance_job_id=fetch_integration_jobs_r['jobs'][0]['id']) -# print("fetch_integration_job_events()") -# print(fetch_integration_job_events_r) -# -# # create_smartclass -# create_smartclass_r = j1.create_smartclass(smartclass_name="SmartClass1", -# smartclass_description="Created via create_smartclass() method") -# print("create_smartclass()") -# print(create_smartclass_r) -# -# # create_smartclass_query -# create_smartclass_query_r = j1.create_smartclass_query(smartclass_id=create_smartclass_r['id'], -# query="FIND (Device|Host) with osType ~= \'Windows\'", -# query_description="all windows devices and hosts") -# print("create_smartclass_query()") -# print(create_smartclass_query_r) -# -# # evaluate_smartclass -# evaluate_smartclass_r = j1.evaluate_smartclass(smartclass_id=create_smartclass_query_r['smartClassId']) -# print("evaluate_smartclass()") -# print(evaluate_smartclass_r) -# -# # get_smartclass_details -# get_smartclass_details_r = j1.get_smartclass_details(smartclass_id=create_smartclass_query_r['smartClassId']) -# print("get_smartclass_details()") -# print(get_smartclass_details_r) -# -# # generate_j1ql -# generate_j1ql_r = j1.generate_j1ql(natural_language_prompt="show me all Users containing 'jupiterone' in their email address") -# print("generate_j1ql()") -# print(generate_j1ql_r) - -# # list_alert_rules -# list_configured_alert_rules_r = j1.list_alert_rules() -# # print("list_configured_alert_rules()") -# print(json.dumps(list_configured_alert_rules_r, indent=1)) -# print(len(list_configured_alert_rules_r)) - -# update_alert_rule -# update_alert_rule_r = j1.update_alert_rule(rule_id="36f2a661-b47d-4c1a-97a6-7c2905a45c80", -# j1ql="Find DataStore LIMIT 123", -# polling_interval="DISABLED", -# tags=['newnewnew', 'naananana'], -# tag_op="OVERWRITE") - -# update_alert_rule_r = j1.update_alert_rule(rule_id="35091853-9e3a-4cef-86db-58a0f40343cb", -# tags=['newTag1', 'newTag1'], -# tag_op="OVERWRITE") - -# update_alert_rule_r = j1.update_alert_rule(rule_id="36f2a661-b47d-4c1a-97a6-7c2905a45c80", -# tags=['additionalTag1', 'additionalTag2'], -# tag_op="APPEND") - -# update_alert_rule_r = j1.update_alert_rule(rule_id="36f2a661-b47d-4c1a-97a6-7c2905a45c80", -# j1ql="Find Internet") - -# print("update_alert_rule()") -# print(json.dumps(update_alert_rule_r, indent=1)) - -evaluate_alert_rule_r = j1.evaluate_alert_rule(rule_id="36f2a661-b47d-4c1a-97a6-7c2905a45c80") -print("evaluate_alert_rule()") -print(json.dumps(evaluate_alert_rule_r, indent=1)) - - -# for i in list_configured_alert_rules_r: -# print(i['id']) - -# # create_alert_rule -# webhook_token = "" -# -# webhook_action_config = { -# "type": "WEBHOOK", -# "endpoint": "https://webhook.receiver.endpoint", -# "headers": { -# "Authorization": "Bearer {}".format(webhook_token), -# }, -# "method": "POST", -# "body": { -# "queryData": "{{queries.query0.data}}" -# } -# } -# -# tag_entities_action_config = { -# "type": "TAG_ENTITIES", -# "entities": "{{queries.query0.data}}", -# "tags": [ -# { -# "name": "tagKey", -# "value": "tagValue" -# } -# ] -# } -# - -# for i in range(250): -# -# print(i) -# i = str(i) + "-batch2" -# -# create_alert_rule_r = j1.create_alert_rule(name=f"{i}-10-22-24-name", -# description=f"{i}-10-22-24-description", -# tags=['tag1', 'tag2'], -# polling_interval="DISABLED", -# severity="INFO", -# j1ql=f"find jupiterone_user") -# print("create_alert_rule()") -# print(create_alert_rule_r) -# -# delete_alert_rule_r = j1.delete_alert_rule(rule_id="78fa4bd1-b413-46d7-bffe-336051c2055d") -# print("delete_alert_rule()") -# print(delete_alert_rule_r) From 1c75a7ad5e8f1f1b3012f3920129750c306059f2 Mon Sep 17 00:00:00 2001 From: SeaBlooms Date: Wed, 23 Oct 2024 09:48:10 -0600 Subject: [PATCH 18/20] fix typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 613206e..385de23 100644 --- a/README.md +++ b/README.md @@ -99,7 +99,7 @@ j1.update_entity( #### Delete an entity: ```python -j1.delete_entity(entit_id='') +j1.delete_entity(entity_id='') ``` ##### Create a relationship From 24f8f67071449144549ab6932d9e41da1c8f5c15 Mon Sep 17 00:00:00 2001 From: SeaBlooms Date: Wed, 23 Oct 2024 10:54:59 -0600 Subject: [PATCH 19/20] add fetch_entity_raw_data() --- examples/examples.py | 5 +++++ jupiterone/client.py | 16 +++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/examples/examples.py b/examples/examples.py index a4afe00..fa8b295 100644 --- a/examples/examples.py +++ b/examples/examples.py @@ -110,6 +110,11 @@ print("fetch_all_entity_tags()") print(fetch_all_entity_tags_r) +# fetch_entity_raw_data +fetch_entity_raw_data_r = j1.fetch_entity_raw_data(entity_id="") +print("fetch_entity_raw_data()") +print(json.dumps(fetch_entity_raw_data_r, indent=1)) + # create_integration_instance create_integration_instance_r = j1.create_integration_instance(instance_name="pythonclient-customintegration", instance_description="dev-testing") diff --git a/jupiterone/client.py b/jupiterone/client.py index a92c5ae..8757a26 100644 --- a/jupiterone/client.py +++ b/jupiterone/client.py @@ -33,6 +33,7 @@ INTEGRATION_JOB_VALUES, INTEGRATION_INSTANCE_EVENT_VALUES, ALL_PROPERTIES, + GET_ENTITY_RAW_DATA, CREATE_SMARTCLASS, CREATE_SMARTCLASS_QUERY, EVALUATE_SMARTCLASS, @@ -500,6 +501,19 @@ def fetch_all_entity_tags(self): return return_list + def fetch_entity_raw_data(self, entity_id: str = None): + """Fetch the contents of raw data for a given entity in a J1 Account. + + """ + variables = { + "entityId": entity_id, + "source": "integration-managed" + } + + response = self._execute_query(query=GET_ENTITY_RAW_DATA, variables=variables) + + return response + def start_sync_job(self, instance_id: str = None, sync_mode: str = None, source: str = None,): """Start a synchronization job. @@ -939,4 +953,4 @@ def evaluate_alert_rule(self, rule_id: str = None): } response = self._execute_query(EVALUATE_RULE_INSTANCE, variables=variables) - return response \ No newline at end of file + return response From 2f92c09c2e9e60b8e0097dbee80cd554edc16a7c Mon Sep 17 00:00:00 2001 From: SeaBlooms Date: Wed, 23 Oct 2024 13:07:56 -0600 Subject: [PATCH 20/20] update epoch_now --- examples/examples.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/examples/examples.py b/examples/examples.py index fa8b295..f75562f 100644 --- a/examples/examples.py +++ b/examples/examples.py @@ -2,7 +2,6 @@ import random import time import os -from datetime import datetime account = os.environ.get("JUPITERONE_ACCOUNT") token = os.environ.get("JUPITERONE_TOKEN") @@ -135,8 +134,7 @@ rand_val_range = [x / 10.0 for x in range(0, 100)] rand_val = random.choice(rand_val_range) -now_dt = datetime.now() -epoch_now = round(datetime.strptime(str(now_dt), "%Y-%m-%d %H:%M:%S.%f").timestamp()) +epoch_now = round(time.time() * 1000) entity_payload = [ {