Skip to content

Commit

Permalink
added workflows, parameters, and a read-me for the two PM Cloud event…
Browse files Browse the repository at this point in the history
… feeds

Signed-off-by: Jarod Amos <[email protected]>
  • Loading branch information
jamos-bt committed Oct 4, 2023
1 parent 2244818 commit ac9cb7d
Show file tree
Hide file tree
Showing 5 changed files with 391 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<WorkflowParameterValues xmlns="http://qradar.ibm.com/UniversalCloudRESTAPI/WorkflowParameterValues/V1">

<!-- PM Cloud Services Hostname : Be sure to include the '-services' portion of the hostname (ex: if you access the web site at 'mysite.example.com' then the value to enter here would be 'mysite-services.example.com') -->
<Value name="hostname" value="" />
<!-- Client ID -->
<Value name="client_id" value="" />
<!-- Client Secret -->
<Value name="client_secret" value="" />
<!-- Page Size : Audit activity is retrieved from your PM Cloud site in chunks of data (pages). The page size determines how many records are retrieved by any single request. (default: 200 - max: 200) -->
<Value name="page_size" value="200" />

</WorkflowParameterValues>
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Workflow
name="BeyondTrust PM Cloud - Activity Audits"
description="Retrieves activity audit data from a PM Cloud site via standard REST API calls"
version="23.1"
xmlns="http://qradar.ibm.com/UniversalCloudRESTAPI/Workflow/V1">

<Parameters>
<Parameter name="hostname"
label="PM Cloud Services Hostname"
description="Be sure to include the '-services' portion of the hostname (ex: if you access the web site at 'mysite.example.com' then the value to enter here would be 'mysite-services.example.com')"
required="true" />
<Parameter name="client_id"
label="Client ID"
required="true" />
<Parameter name="client_secret"
label="Client Secret"
required="true"
secret="true" />
<Parameter name="page_size"
label="Page Size"
description="Audit activity is retrieved from your PM Cloud site in chunks of data (pages). The page size determines how many records are retrieved by any single request. (default: 200 - max: 200)"
required="true"
default="200" />
</Parameters>

<Actions>

<!-- Initialize the last ingested date (current time minus 1 hour) -->
<Initialize path="/last_ingested_date" value="${time() - 3600000}" />
<!-- Prepare the start and end date filter, based on the current last ingested date -->
<FormatDate pattern="yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" time="${/last_ingested_date}" timeZone="UTC" savePath="/start_date" />
<!-- Prepare the end date filter, which is the current time. -->
<FormatDate pattern="yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" timeZone="UTC" savePath="/end_date" />
<Log type="INFO" message="Preparing to attempt activity audit ingestion from ${/hostname} starting at ${/start_date} through ${/end_date}" />

<!--
//////////////////////
// Get Access Token //
//////////////////////
-->
<Log type="DEBUG" message="Preparing to attempt authentication call to ${/hostname}" />
<CallEndpoint url="https://${/hostname}/oauth/connect/token" method="POST" savePath="/auth_token_response" >
<RequestHeader name="Accept" value="*/*" />
<!-- <BasicAuthentication username="${/client_id}" password="${/client_secret}" /> -->
<RequestHeader name="Authorization" value="Basic ${base64_encode('${/client_id}:${/client_secret}')}"/>
<UrlEncodedFormRequestBody>
<Parameter name="grant_type" value="client_credentials" />
</UrlEncodedFormRequestBody>
</CallEndpoint>

<!-- Handle Errors -->
<If condition="/auth_token_response/status_code = 429">
<Set path="/temp_message" value="(HTTP 429) API rate limit hit. The polling process for this interval will exit and another attempt will be made on the next interval" />
<Log type="WARN" message="${/temp_message}" />
<Abort reason="${/temp_message}" />
</If>
<ElseIf condition="/auth_token_response/status_code != 200">
<Set path="/temp_message" value="Authentication attempt failed: ${/auth_token_response/body}" />
<Log type="ERROR" message="${/temp_message}" />
<Abort reason="${/temp_message}" />
</ElseIf>

<!-- Extract the Access Token -->
<Log type="DEBUG" message="Successfully authenticated" />
<Set path="/access_token" value="${/auth_token_response/body/access_token}" />


<!--
////////////////////
// Request Events //
////////////////////
-->

<Set path="/page_number" value="1" />
<Set path="/total_ingested_count" value="0" />

<!-- Fetch all events, one page at a time -->
<DoWhile condition="/events_response/body/pageCount >= /page_number">

<Log type="DEBUG" message="Retrieving activity audit records from ${/hostname} starting at ${/start_date} through ${/end_date} (Page: ${/page_number} - Page Size: ${/page_size})" />

<!-- Fetch the current page -->
<CallEndpoint url="https://${/hostname}/management-api/v1/ActivityAudits/Details" method="GET" savePath="/events_response" >
<BearerAuthentication token="${/access_token}" />
<QueryParameter name="Filter.Created.Dates" value="${/start_date}" />
<QueryParameter name="Filter.Created.Dates" value="${/end_date}" />
<QueryParameter name="Filter.Created.SelectionMode" value="Range" />
<QueryParameter name="Pagination.PageSize" value="${/page_size}" />
<QueryParameter name="Pagination.PageNumber" value="${/page_number}" />
</CallEndpoint>

<!-- Handle Errors -->
<If condition="/events_response/status_code = 429">
<Set path="/temp_message" value="(HTTP 429) API rate limit hit. The polling process for this interval will exit and another attempt will be made on the next interval" />
<Log type="WARN" message="${/temp_message}" />
<Abort reason="${/temp_message}" />
</If>
<ElseIf condition="/events_response/status_code != 200">
<Set path="/temp_message" value="Activity audits ingestion failed: ${/events_response/status_code} ${/events_response/status_message}" />
<Log type="ERROR" message="${/temp_message}" />
<Abort reason="${/temp_message}" />
</ElseIf>

<Log type="DEBUG" message="Found a total of ${/events_response/body/totalRecordCount} activity audit record(s) spanning ${/events_response/body/pageCount} page(s) - current page is ${/page_number}" />

<!-- Update the last ingested date -->
<ForEach item="/event" items="/events_response/body/data">
<!-- Post Event -->
<PostEvent path="/event" source="${/hostname}"/>
<Set path="/total_ingested_count" value="${/total_ingested_count + 1}" />

<!-- Save the date as the last ingested date -->
<Set path="/event_created" value="${/event/created}" />
<ParseDate pattern="yyyy-MM-dd'T'HH:mm:ss[.SSSSSSS][.SSSSSS][.SSSSS][.SSSS][.SSS][.SS][.S]" date="${/event_created}" timeZone="UTC" savePath="/event_timestamp" />
<If condition="/event_timestamp > /last_ingested_date">
<Set path="/last_ingested_date" value="${/event_timestamp + 1}" />
</If>
<Log type="DEBUG" message="Event ingested datetime is (${/event_timestamp}) for activity audit data ID: ${/event/id}" />
</ForEach>

<!-- Move to the next page -->
<Set path="/page_number" value="${/page_number + 1}" />

</DoWhile>

<Log type="INFO" message="Ingested ${/total_ingested_count} activity audits from ${/hostname} starting at ${/start_date} through ${/end_date}" />

</Actions>

<Tests>
<DNSResolutionTest host="${/hostname}" />
<TCPConnectionTest host="${/hostname}" />
<SSLHandshakeTest host="${/hostname}" />
<HTTPConnectionThroughProxyTest url="https://${/hostname}/bogus-path" expectedResponseStatus="404" />
</Tests>

</Workflow>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<WorkflowParameterValues xmlns="http://qradar.ibm.com/UniversalCloudRESTAPI/WorkflowParameterValues/V1">

<!-- PM Cloud Services Hostname : Be sure to include the '-services' portion of the hostname (ex: if you access the web site at 'mysite.example.com' then the value to enter here would be 'mysite-services.example.com') -->
<Value name="hostname" value="" />
<!-- Client ID -->
<Value name="client_id" value="" />
<!-- Client Secret -->
<Value name="client_secret" value="" />
<!-- Batch Size : Client events are retrieved through your PM Cloud site in chunks of data (batches). The batch size determines how many records are retrieved by any single request. (default: 1000 - max: 1000) -->
<Value name="batch_size" value="1000" />

</WorkflowParameterValues>
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Workflow
name="BeyondTrust PM Cloud - Client Events"
description="Retrieves client event data from a PM Cloud site via standard REST API calls"
version="23.1"
xmlns="http://qradar.ibm.com/UniversalCloudRESTAPI/Workflow/V1">

<Parameters>
<Parameter name="hostname"
label="PM Cloud Services Hostname"
description="Be sure to include the '-services' portion of the hostname (ex: if you access the web site at 'mysite.example.com' then the value to enter here would be 'mysite-services.example.com')"
required="true" />
<Parameter name="client_id"
label="Client ID"
required="true" />
<Parameter name="client_secret"
label="Client Secret"
required="true"
secret="true" />
<Parameter name="batch_size"
label="Batch Size"
description="Client events are retrieved through your PM Cloud site in chunks of data (batches). The batch size determines how many records are retrieved by any single request. (default: 1000 - max: 1000)"
required="true"
default="1000" />
</Parameters>

<Actions>

<!-- Initialize the last ingested date (current time minus 1 hour) -->
<Initialize path="/last_ingested_date" value="${time() - 3600000}" />
<!-- Prepare the start date filter, based on the current last ingested date -->
<FormatDate pattern="yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" time="${/last_ingested_date}" timeZone="UTC" savePath="/start_date" />
<Log type="INFO" message="Preparing to attempt client event ingestion from ${/hostname} starting at ${/start_date}" />

<!--
//////////////////////
// Get Access Token //
//////////////////////
-->
<Log type="DEBUG" message="Preparing to attempt authentication call to ${/hostname}" />
<CallEndpoint url="https://${/hostname}/oauth/connect/token" method="POST" savePath="/auth_token_response" >
<RequestHeader name="Accept" value="*/*" />
<!-- <BasicAuthentication username="${/client_id}" password="${/client_secret}" /> -->
<RequestHeader name="Authorization" value="Basic ${base64_encode('${/client_id}:${/client_secret}')}"/>
<UrlEncodedFormRequestBody>
<Parameter name="grant_type" value="client_credentials" />
</UrlEncodedFormRequestBody>
</CallEndpoint>

<!-- Handle Errors -->
<If condition="/auth_token_response/status_code = 429">
<Set path="/temp_message" value="(HTTP 429) API rate limit hit. The polling process for this interval will exit and another attempt will be made on the next interval" />
<Log type="WARN" message="${/temp_message}" />
<Abort reason="${/temp_message}" />
</If>
<ElseIf condition="/auth_token_response/status_code != 200">
<Set path="/temp_message" value="Authentication attempt failed: ${/auth_token_response/body}" />
<Log type="ERROR" message="${/temp_message}" />
<Abort reason="${/temp_message}" />
</ElseIf>

<!-- Extract the Access Token -->
<Log type="DEBUG" message="Successfully authenticated" />
<Set path="/access_token" value="${/auth_token_response/body/access_token}" />


<!--
////////////////////
// Request Events //
////////////////////
-->

<Set path="/total_ingested_count" value="0" />

<!-- Fetch all events, one batch at a time ... If the number of events returned in this batch is smaller than the batch size, it must be the last batch -->
<DoWhile condition="/events_response/body/totalRecordsReturned >= /batch_size">

<Log type="DEBUG" message="Retrieving client events from ${/hostname} starting at ${/start_date} (Batch Size: ${/batch_size})" />

<!-- Fetch the current batch -->
<CallEndpoint url="https://${/hostname}/management-api/v1/Events/FromStartDate" method="GET" savePath="/events_response" >
<BearerAuthentication token="${/access_token}" />
<QueryParameter name="StartDate" value="${/start_date}" />
<QueryParameter name="RecordSize" value="${/batch_size}" />
</CallEndpoint>

<!-- Handle Errors -->
<If condition="/events_response/status_code = 429">
<Set path="/temp_message" value="(HTTP 429) API rate limit hit. The polling process for this interval will exit and another attempt will be made on the next interval" />
<Log type="WARN" message="${/temp_message}" />
<Abort reason="${/temp_message}" />
</If>
<ElseIf condition="/events_response/status_code != 200">
<Set path="/temp_message" value="Client events ingestion failed: ${/events_response/status_code} ${/events_response/status_message}" />
<Log type="ERROR" message="${/temp_message}" />
<Abort reason="${/temp_message}" />
</ElseIf>

<Log type="DEBUG" message="Found a total of ${/events_response/body/totalRecordsReturned} client event(s) in this batch (Batch Size: ${/batch_size})" />

<!-- Update the last ingested date and start date so the next call picks up where this left off -->
<ForEach item="/event" items="/events_response/body/events">
<!-- Post Event -->
<PostEvent path="/event" source="${/hostname}"/>
<Set path="/total_ingested_count" value="${/total_ingested_count + 1}" />

<!-- Save the date as the last ingested date -->
<Set path="/event_created" value="${/event/event/ingested}" />
<ParseDate pattern="yyyy-MM-dd'T'HH:mm:ss[.SSSSSSS][.SSSSSS][.SSSSS][.SSSS][.SSS][.SS][.S]'+00:00'" date="${/event_created}" timeZone="UTC" savePath="/event_timestamp" />
<If condition="/event_timestamp > /last_ingested_date">
<Set path="/last_ingested_date" value="${/event_timestamp + 1}" />
<FormatDate pattern="yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" time="${/last_ingested_date}" timeZone="UTC" savePath="/start_date" />
</If>
<Log type="DEBUG" message="Event ingested datetime is (${/event_timestamp}) for client event ID: ${/event/id}" />
</ForEach>

</DoWhile>

<Log type="INFO" message="Ingested ${/total_ingested_count} client events from ${/hostname} starting at ${/start_date}" />

</Actions>

<Tests>
<DNSResolutionTest host="${/hostname}" />
<TCPConnectionTest host="${/hostname}" />
<SSLHandshakeTest host="${/hostname}" />
<HTTPConnectionThroughProxyTest url="https://${/hostname}/bogus-path" expectedResponseStatus="404" />
</Tests>

</Workflow>
Loading

0 comments on commit ac9cb7d

Please sign in to comment.