From c87f2c7c4af1558ce8420adb647c89f3110c11b6 Mon Sep 17 00:00:00 2001 From: Alex Dunker Date: Thu, 22 Oct 2026 17:31:39 -0500 Subject: [PATCH] feat(search): support workflowsummaries and workflowexecutions indices (#267) --- cmd/search/query.go | 2 +- internal/search/search.go | 50 ++++++++++++++++++++++++++++++++++ internal/search/types.go | 56 +++++++++++++++++++++++++++++++++------ 3 files changed, 99 insertions(+), 9 deletions(-) diff --git a/cmd/search/query.go b/cmd/search/query.go index ea0b8ac2..da57748b 100644 --- a/cmd/search/query.go +++ b/cmd/search/query.go @@ -57,7 +57,7 @@ func newQueryCmd() *cobra.Command { } cmd.Flags().StringVarP(&folderPath, "folderPath", "f", "search_results", "Folder path to save the search results to. If the directory doesn't exist, then it will be created. (defaults to the current working directory)") - cmd.Flags().StringArrayVar(&indices, "indices", []string{}, "Indices to perform the search query on (accessprofiles, accountactivities, entitlements, events, identities, roles)") + cmd.Flags().StringArrayVar(&indices, "indices", []string{}, "Indices to perform the search query on (accessprofiles, accountactivities, entitlements, events, identities, roles, workflowsummaries, workflowexecutions)") cmd.Flags().StringArrayVar(&sort, "sort", []string{}, "The sort value for the api call (displayName, +id...)") cmd.MarkFlagRequired("indices") diff --git a/internal/search/search.go b/internal/search/search.go index 08114c47..be52196a 100644 --- a/internal/search/search.go +++ b/internal/search/search.go @@ -26,6 +26,10 @@ func ParseIndices(indices string) (sailpointsdk.Index, error) { return sailpointsdk.INDEX_IDENTITIES, nil case "roles": return sailpointsdk.INDEX_ROLES, nil + case "workflowsummaries": + return sailpointsdk.Index("workflowsummaries"), nil + case "workflowexecutions": + return sailpointsdk.Index("workflowexecutions"), nil default: return "*", fmt.Errorf("index provided is invalid") } @@ -115,6 +119,22 @@ func PerformSearch(apiClient sailpoint.APIClient, search sailpointsdk.Search) (S return SearchResults, err } SearchResults.Roles = append(SearchResults.Roles, Role) + + case "workflowsummary": + var WorkflowSummary WorkflowSummary + err := mapstructure.Decode(entry, &WorkflowSummary) + if err != nil { + return SearchResults, err + } + SearchResults.WorkflowSummaries = append(SearchResults.WorkflowSummaries, WorkflowSummary) + + case "workflowexecution": + var WorkflowExecution WorkflowExecution + err := mapstructure.Decode(entry, &WorkflowExecution) + if err != nil { + return SearchResults, err + } + SearchResults.WorkflowExecutions = append(SearchResults.WorkflowExecutions, WorkflowExecution) } } @@ -187,6 +207,22 @@ func PerformSearchWithLimit(apiClient sailpoint.APIClient, search sailpointsdk.S return SearchResults, err } SearchResults.Roles = append(SearchResults.Roles, Role) + + case "workflowsummary": + var WorkflowSummary WorkflowSummary + err := mapstructure.Decode(entry, &WorkflowSummary) + if err != nil { + return SearchResults, err + } + SearchResults.WorkflowSummaries = append(SearchResults.WorkflowSummaries, WorkflowSummary) + + case "workflowexecution": + var WorkflowExecution WorkflowExecution + err := mapstructure.Decode(entry, &WorkflowExecution) + if err != nil { + return SearchResults, err + } + SearchResults.WorkflowExecutions = append(SearchResults.WorkflowExecutions, WorkflowExecution) } } @@ -236,6 +272,20 @@ func IterateIndices(SearchResults SearchResults, searchQuery string, folderPath return err } } + if len(SearchResults.WorkflowSummaries) > 0 { + fileName := "query=" + searchQuery + "&indices=WorkflowSummaries" + err := SaveResults(SearchResults.WorkflowSummaries, fileName, folderPath, outputTypes) + if err != nil { + return err + } + } + if len(SearchResults.WorkflowExecutions) > 0 { + fileName := "query=" + searchQuery + "&indices=WorkflowExecutions" + err := SaveResults(SearchResults.WorkflowExecutions, fileName, folderPath, outputTypes) + if err != nil { + return err + } + } return nil } diff --git a/internal/search/types.go b/internal/search/types.go index 69310b51..1380f445 100644 --- a/internal/search/types.go +++ b/internal/search/types.go @@ -1,12 +1,14 @@ package search type SearchResults struct { - AccountActivities []AccountActivity - AccessProfiles []AccessProfile - Entitlements []Entitlement - Events []Event - Identities []Identity - Roles []Role + AccountActivities []AccountActivity + AccessProfiles []AccessProfile + Entitlements []Entitlement + Events []Event + Identities []Identity + Roles []Role + WorkflowSummaries []WorkflowSummary + WorkflowExecutions []WorkflowExecution } type AccessProfile struct { @@ -84,8 +86,8 @@ type AccountActivity struct { ID string `json:"id,omitempty"` } `json:"source,omitempty"` AttributeRequests []struct { - Op string `json:"op,omitempty"` - Name string `json:"name,omitempty"` + Op string `json:"op,omitempty"` + Name string `json:"name,omitempty"` Value interface{} `json:"value,omitempty"` } `json:"attributeRequests,omitempty"` } `json:"originalRequests,omitempty"` @@ -288,3 +290,41 @@ type Role struct { AccessProfileCount int `json:"accessProfileCount"` Tags []string `json:"tags"` } + +type WorkflowSummary struct { + ID string `json:"id"` + WorkflowExecutionId string `json:"workflowExecutionId"` + EventId int `json:"eventId"` + WorkflowName string `json:"workflowName"` + WorkflowId string `json:"workflowId"` + Status string `json:"status"` + WorkflowTest bool `json:"workflowTest"` + RequestId string `json:"requestId"` + Created string `json:"created"` + Synced string `json:"synced"` + Type string `json:"type"` + Owner struct { + Name string `json:"name"` + ID string `json:"id"` + } `json:"owner"` + Attributes map[string]interface{} `json:"attributes"` +} + +type WorkflowExecution struct { + ID string `json:"id"` + WorkflowName string `json:"workflowName"` + WorkflowId string `json:"workflowId"` + Status string `json:"status"` + StartTime string `json:"startTime"` + CloseTime string `json:"closeTime"` + RequestId string `json:"requestId"` + WorkflowTest bool `json:"workflowTest"` + FailureType string `json:"failureType"` + FailureMessage string `json:"failureMessage"` + Synced string `json:"synced"` + Owner struct { + Name string `json:"name"` + ID string `json:"id"` + } `json:"owner"` + Trigger map[string]interface{} `json:"trigger"` +}