in Solutions/Team Cymru Scout/Data Connectors/TeamCymruScout/SharedCode/sentinel.py [0:0]
def post_data(self, body, log_type):
"""Build and send a request to the POST API.
Args:
body (str): Data to post into Sentinel log analytics workspace
log_type (str): Custom log table name in which data wil be added.
Returns:
status_code: Returns the response status code got while posting data to sentinel.
Raises:
SentinelIncorrectCredentialsException: When credentials are incorrect.
InvalidDataFormatException: When data format is incorrect.
TeamCymruScoutException: When custom exception is raised.
"""
__method_name = inspect.currentframe().f_code.co_name
method = "POST"
content_type = "application/json"
resource = "/api/logs"
rfc1123date = datetime.datetime.utcnow().strftime("%a, %d %b %Y %H:%M:%S GMT")
content_length = len(body)
try:
signature = self.build_signature(
rfc1123date,
content_length,
method,
content_type,
resource,
)
except Exception as err:
applogger.error(
"{}(method={}) : {} : Error occurred for build signature, Issue with Microsoft Sentinel Credentials".format(
self.logs_start_with,
__method_name,
err,
)
)
raise SentinelIncorrectCredentialsException("Error while generating signature for posting data into log analytics.")
uri = "https://" + consts.WORKSPACE_ID + ".ods.opinsights.azure.com" + resource + "?api-version=2016-04-01"
headers = {
"content-type": content_type,
"Authorization": signature,
"Log-Type": log_type,
"x-ms-date": rfc1123date,
}
retry_count = 0
while retry_count < consts.SENTINEL_RETRY_COUNT:
try:
response = requests.post(uri, data=body, headers=headers, timeout=consts.MAX_TIMEOUT_SENTINEL)
if response.status_code >= 200 and response.status_code <= 299:
applogger.debug(
"{}(method={}) : Status_code: {} Accepted: Data Posted Successfully"
" to Microsoft Sentinel.".format(
self.logs_start_with,
__method_name,
response.status_code,
)
)
return response.status_code
elif response.status_code == 400:
applogger.error(
"{}(method={}) : Error occurred: Response code: {} "
"Bad Request while posting data to log analytics.\nError: {}".format(
self.logs_start_with, __method_name, response.status_code, response.content
)
)
raise InvalidDataFormatException()
elif response.status_code == 403:
applogger.error(
"{}(method={}) : Error occurred for build signature: Issue with WorkspaceKey. "
"Kindly verify your WorkspaceKey.".format(
self.logs_start_with,
__method_name,
)
)
raise SentinelIncorrectCredentialsException()
elif response.status_code in _RETRY_STATUS_CODES:
applogger.error(
"{}(method={}) : Response code : {} {}. ".format(
self.logs_start_with, __method_name, response.status_code, _RETRY_STATUS_CODES[response.status_code]
)
)
time.sleep(consts.INGESTION_ERROR_SLEEP_TIME)
retry_count += 1
continue
raise TeamCymruScoutException(
"Response code: {} from posting data to log analytics.\nError: {}".format(response.status_code, response.content)
)
except InvalidDataFormatException:
raise InvalidDataFormatException()
except SentinelIncorrectCredentialsException:
applogger.error(
"{}(method={}) : Workspace Key is wrong, sleeping for {} seconds and retrying.".format(
self.logs_start_with,
__method_name,
consts.INGESTION_ERROR_SLEEP_TIME,
)
)
time.sleep(consts.INGESTION_ERROR_SLEEP_TIME)
retry_count += 1
continue
except requests.exceptions.ConnectionError as id_error:
try:
if isinstance(id_error.args[0].reason, NameResolutionError):
applogger.error(
"{}(method={}) : Either Workspace ID is wrong or Sentinel Workspace is unreachable: {}"
", Sleeping for {} seconds and retrying.".format(
self.logs_start_with,
__method_name,
id_error,
consts.INGESTION_ERROR_SLEEP_TIME,
)
)
time.sleep(consts.INGESTION_ERROR_SLEEP_TIME)
retry_count += 1
continue
except Exception as unknown_connect_error:
applogger.error(
"{}(method={}) : Unknown Error in ConnectionError, sleeping - {} seconds and retrying."
"Error - {}".format(
self.logs_start_with,
__method_name,
consts.INGESTION_ERROR_SLEEP_TIME,
unknown_connect_error,
)
)
time.sleep(consts.INGESTION_ERROR_SLEEP_TIME)
retry_count += 1
continue
applogger.error(
"{}(method={}) : Unknown Connection Error, sleeping - {} seconds and retrying."
"Error - {}".format(
self.logs_start_with,
__method_name,
consts.INGESTION_ERROR_SLEEP_TIME,
id_error,
)
)
time.sleep(consts.INGESTION_ERROR_SLEEP_TIME)
retry_count += 1
except requests.exceptions.Timeout as error:
applogger.error("{}(method={}) : Timeout Error: {}".format(self.logs_start_with, __method_name, error))
raise TeamCymruScoutException()
except TeamCymruScoutException as custom_err:
applogger.error(
"{}(method={}) : Error: {}, sleeping - {} seconds and retrying.".format(
self.logs_start_with,
__method_name,
custom_err,
consts.INGESTION_ERROR_SLEEP_TIME,
)
)
time.sleep(consts.INGESTION_ERROR_SLEEP_TIME)
retry_count += 1
except Exception as error:
applogger.error(
"{}(method={}) : Unknown Error: {}, sleeping - {} seconds and retrying.".format(
self.logs_start_with,
__method_name,
error,
consts.INGESTION_ERROR_SLEEP_TIME,
)
)
time.sleep(consts.INGESTION_ERROR_SLEEP_TIME)
retry_count += 1
if retry_count == consts.SENTINEL_RETRY_COUNT:
applogger.error(
"{}(method={}) : Maximum Retry count of {} exceeded, hence stopping execution.".format(
self.logs_start_with,
__method_name,
consts.SENTINEL_RETRY_COUNT,
)
)
raise TeamCymruScoutException()
return None