-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathworkflows.go
More file actions
258 lines (229 loc) · 10.7 KB
/
Copy pathworkflows.go
File metadata and controls
258 lines (229 loc) · 10.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
package vsax
import (
"context"
"fmt"
"iter"
"net/http"
"strconv"
)
// Workflow trigger types.
const (
TriggerTypeNotification = "Notification"
TriggerTypeAdHocScheduled = "Ad-hoc and Scheduled"
TriggerTypeExternalWebhook = "External Webhook"
)
// Workflow context types.
const (
WorkflowContextScope = "Scope"
WorkflowContextOrganization = "Organization"
WorkflowContextDevice = "Device"
WorkflowContextDeviceless = "Deviceless"
)
// Workflow execution statuses.
const (
WorkflowStatusPending = "Pending"
WorkflowStatusRunning = "Running"
WorkflowStatusSuccess = "Success"
WorkflowStatusFailed = "Failed"
WorkflowStatusCanceling = "Canceling"
WorkflowStatusCanceled = "Canceled"
)
// Workflow is a VSA X automation workflow (list/detail summary).
type Workflow struct {
ID int64 `json:"Id"`
Name string `json:"Name,omitempty"`
Description string `json:"Description,omitempty"`
IsEnabled bool `json:"IsEnabled"`
TriggerType string `json:"TriggerType,omitempty"`
TriggerSubType string `json:"TriggerSubType,omitempty"`
UpdatedAt Time `json:"UpdatedAt,omitzero"`
ContextType string `json:"ContextType,omitempty"`
ContextItemID string `json:"ContextItemId,omitempty"`
FolderPath string `json:"FolderPath,omitempty"`
}
// WorkflowDetails extends Workflow with trigger, actions, and folder info
// returned by GET /automation/workflows/{id}.
type WorkflowDetails struct {
Workflow
Trigger *WorkflowTrigger `json:"Trigger,omitempty"`
Actions []WorkflowStep `json:"Actions,omitempty"`
}
// WorkflowTrigger describes what starts a workflow.
type WorkflowTrigger struct {
TriggerType string `json:"TriggerType,omitempty"`
TriggerSubType string `json:"TriggerSubType,omitempty"`
Description string `json:"Description,omitempty"`
SkipOffline bool `json:"SkipOffline,omitempty"`
Schedule *WorkflowTriggerSchedule `json:"Schedule,omitempty"`
ID int64 `json:"Id,omitempty"`
DisplayName string `json:"DisplayName,omitempty"`
}
// WorkflowTriggerSchedule is the schedule for scheduled triggers.
type WorkflowTriggerSchedule struct {
StartDate Time `json:"StartDate,omitzero"`
Timezone string `json:"Timezone,omitempty"`
Frequency int `json:"Frequency,omitempty"`
FrequencyInterval string `json:"FrequencyInterval,omitempty"`
FrequencySubInterval string `json:"FrequencySubInterval,omitempty"`
DistributionPeriodInSeconds int `json:"DistributionPeriodInSeconds,omitempty"`
}
// WorkflowStep is a single node in a workflow's execution tree. Action steps
// carry ActionType + Parameters; condition steps carry Rules + Positive/
// NegativeOutcome branches.
type WorkflowStep struct {
ID int64 `json:"Id,omitempty"`
DisplayName string `json:"DisplayName,omitempty"`
StepType string `json:"StepType,omitempty"` // "Action" | "Condition"
ActionType string `json:"ActionType,omitempty"`
Parameters string `json:"Parameters,omitempty"` // JSON-encoded string
PositiveOutcome []WorkflowStep `json:"PositiveOutcome,omitempty"`
NegativeOutcome []WorkflowStep `json:"NegativeOutcome,omitempty"`
RuleAggregation string `json:"RuleAggregation,omitempty"`
Rules []WorkflowConditionRule `json:"Rules,omitempty"`
}
// WorkflowConditionRule is a rule evaluated by a condition step.
type WorkflowConditionRule struct {
PropertyID string `json:"PropertyId,omitempty"`
Operator string `json:"Operator,omitempty"`
Value string `json:"Value,omitempty"`
}
// VariableOverride overrides a named workflow variable at run time.
type VariableOverride struct {
Name string `json:"Name"`
Value string `json:"Value"`
}
// WorkflowExecution summarises one execution of a workflow.
type WorkflowExecution struct {
ID int64 `json:"Id"`
WorkflowID int64 `json:"WorkflowId"`
TargetType string `json:"TargetType,omitempty"` // "Device" | "Server"
TargetID string `json:"TargetId,omitempty"`
TriggerType string `json:"TriggerType,omitempty"`
TriggerID string `json:"TriggerId,omitempty"`
Status string `json:"Status,omitempty"`
CreatedAt Time `json:"CreatedAt,omitzero"`
CompletedAt Time `json:"CompletedAt,omitzero"`
ConstantVariableOverrides []VariableOverride `json:"ConstantVariableOverrides,omitempty"`
FolderPath string `json:"FolderPath,omitempty"`
}
// WorkflowExecutionDetails extends WorkflowExecution with per-step results.
type WorkflowExecutionDetails struct {
WorkflowExecution
ExecutionSteps []WorkflowExecutionStep `json:"ExecutionSteps,omitempty"`
}
// WorkflowExecutionStep is one step's result in an execution.
type WorkflowExecutionStep struct {
WorkflowStepID int64 `json:"WorkflowStepId"`
Status string `json:"Status,omitempty"`
CompletedAt Time `json:"CompletedAt,omitzero"`
UpdatedAt Time `json:"UpdatedAt,omitzero"`
Outcome *bool `json:"Outcome,omitempty"`
OutputItems []WorkflowExecutionOutputItem `json:"OutputItems,omitempty"`
}
// WorkflowExecutionOutputItem is one output from a workflow step.
type WorkflowExecutionOutputItem struct {
VariableID int64 `json:"VariableId,omitempty"`
VariableName string `json:"VariableName,omitempty"`
VariableDataType string `json:"VariableDataType,omitempty"`
VariableValue string `json:"VariableValue,omitempty"`
EmailSubject string `json:"EmailSubject,omitempty"`
EmailBody string `json:"EmailBody,omitempty"`
PsaTicketTitle string `json:"PsaTicketTitle,omitempty"`
PsaTicketNote string `json:"PsaTicketNote,omitempty"`
PsaTicketDescription string `json:"PsaTicketDescription,omitempty"`
IsPsaTicketNoteInternal bool `json:"IsPsaTicketNoteInternal,omitempty"`
PsaIntegrationID int64 `json:"PsaIntegrationId,omitempty"`
PsaTicketParameters []KeyValuePair `json:"PsaTicketParameters,omitempty"`
}
// KeyValuePair is a generic string key/value pair used by several endpoints.
type KeyValuePair struct {
Key string `json:"Key"`
Value string `json:"Value"`
}
// RunWorkflowRequest is the body for POST /automation/workflows/{id}/run.
//
// When DeviceIdentifiers is empty the workflow runs against the configured
// scope. ConstantVariableOverrides only applies to variables registered as
// a separate "Get Device Value > Constant Value" step.
type RunWorkflowRequest struct {
DeviceIdentifiers []string `json:"DeviceIdentifiers,omitempty"`
WebhookURL string `json:"WebhookUrl,omitempty"`
ConstantVariableOverrides []VariableOverride `json:"ConstantVariableOverrides,omitempty"`
}
// RunWorkflowResult is the response to POST /automation/workflows/{id}/run.
// NewExecutions are the executions created by this call; ExistingExecutions
// are runs already targeting the same devices (no new execution is created
// for those devices until those runs complete).
type RunWorkflowResult struct {
NewExecutions []WorkflowExecution `json:"NewExecutions,omitempty"`
ExistingExecutions []WorkflowExecution `json:"ExistingExecutions,omitempty"`
}
// CancelWorkflowExecutionsRequest cancels one or more workflow executions by ID.
type CancelWorkflowExecutionsRequest struct {
ExecutionIDs []int64 `json:"ExecutionIds"`
}
// WorkflowService provides access to workflow endpoints under /automation/workflows.
type WorkflowService struct {
client *Client
list listService[Workflow]
}
func newWorkflowService(c *Client) *WorkflowService {
return &WorkflowService{client: c, list: listService[Workflow]{client: c, path: "/automation/workflows"}}
}
// List retrieves one page of workflows.
func (s *WorkflowService) List(ctx context.Context, q *Query) (*PagedResult[Workflow], error) {
return s.list.List(ctx, q)
}
// All iterates all workflows across pages.
func (s *WorkflowService) All(ctx context.Context, q *Query) iter.Seq2[Workflow, error] {
return s.list.All(ctx, q)
}
// Get retrieves a single workflow by ID.
func (s *WorkflowService) Get(ctx context.Context, id int64) (*WorkflowDetails, error) {
env, err := s.client.do(ctx, http.MethodGet, "/automation/workflows/"+strconv.FormatInt(id, 10), nil)
if err != nil {
return nil, err
}
return decodeOne[WorkflowDetails](env)
}
// Run triggers execution of the workflow. body may be nil if the workflow
// needs no overrides.
func (s *WorkflowService) Run(ctx context.Context, workflowID int64, body *RunWorkflowRequest) (*RunWorkflowResult, error) {
var payload any
if body != nil {
payload = body
}
env, err := s.client.do(ctx, http.MethodPost, "/automation/workflows/"+strconv.FormatInt(workflowID, 10)+"/run", payload)
if err != nil {
return nil, err
}
return decodeOne[RunWorkflowResult](env)
}
// Executions lists workflow executions (across all workflows). Filter by
// WorkflowId via Query.Filter to scope to a single workflow.
func (s *WorkflowService) Executions(ctx context.Context, q *Query) (*PagedResult[WorkflowExecution], error) {
return listSub[WorkflowExecution](ctx, s.client, "/automation/workflows/executions", q)
}
// AllExecutions iterates all workflow executions across pages.
func (s *WorkflowService) AllExecutions(ctx context.Context, q *Query) iter.Seq2[WorkflowExecution, error] {
return allFromList(ctx, func() (*PagedResult[WorkflowExecution], error) {
return s.Executions(ctx, q)
})
}
// Execution returns the details of a single workflow execution.
func (s *WorkflowService) Execution(ctx context.Context, executionID int64) (*WorkflowExecutionDetails, error) {
env, err := s.client.do(ctx, http.MethodGet, "/automation/workflows/executions/"+strconv.FormatInt(executionID, 10), nil)
if err != nil {
return nil, err
}
return decodeOne[WorkflowExecutionDetails](env)
}
// CancelExecutions cancels the specified workflow executions.
func (s *WorkflowService) CancelExecutions(ctx context.Context, executionIDs ...int64) error {
if len(executionIDs) == 0 {
return fmt.Errorf("vsax: at least one execution id is required")
}
_, err := s.client.do(ctx, http.MethodPost, "/automation/workflows/executions/cancel",
CancelWorkflowExecutionsRequest{ExecutionIDs: executionIDs})
return err
}