Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Agent: Allow custom response properties in the action response #28575

Merged
merged 3 commits into from
Oct 21, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,50 @@ func (h *AppAction) Handle(ctx context.Context, a fleetapi.Action, acker store.F
action.StartedAt = readMapString(res, "started_at", startFormatted)
action.CompletedAt = readMapString(res, "completed_at", endFormatted)
action.Error = readMapString(res, "error", "")
appendActionResponse(action, action.InputType, res)
}

return acker.Ack(ctx, action)
}

var (
none = struct{}{}

// The set of action response fields are not included in the action_response property, because there are already set to top level fields
excludeActionResponseFields = map[string]struct{}{
"started_at": none,
"completed_at": none,
"error": none,
}
)

// appendActionResponse appends the action response property with all the action response values excluding the ones specified in excludeActionResponseFields
// "action_response": {
// "endpoint": {
// "acked": true
// }
// }
func appendActionResponse(action *fleetapi.ActionApp, inputType string, res map[string]interface{}) {
if len(res) == 0 {
return
}

m := make(map[string]interface{}, len(res))

for k, v := range res {
if _, ok := excludeActionResponseFields[k]; !ok {
m[k] = v
}
}

if len(m) > 0 {
mt := make(map[string]interface{}, 1)
mt[inputType] = m

action.Response = mt
}
}

func readMapString(m map[string]interface{}, key string, def string) string {
if m == nil {
return def
Expand Down
9 changes: 5 additions & 4 deletions x-pack/elastic-agent/pkg/fleetapi/ack_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,11 @@ type AckEvent struct {
Message string `json:"message,omitempty"` // : 'hello2',
Payload string `json:"payload,omitempty"` // : 'payload2',

ActionData json.RawMessage `json:"action_data,omitempty"` // copy of original action data
StartedAt string `json:"started_at,omitempty"` // time action started
CompletedAt string `json:"completed_at,omitempty"` // time action completed
Error string `json:"error,omitempty"` // optional action error
ActionData json.RawMessage `json:"action_data,omitempty"` // copy of original action data
ActionResponse map[string]interface{} `json:"action_response,omitempty"` // custom (per beat) response payload
StartedAt string `json:"started_at,omitempty"` // time action started
CompletedAt string `json:"completed_at,omitempty"` // time action completed
Error string `json:"error,omitempty"` // optional action error
}

// AckRequest consists of multiple actions acked to fleet ui.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ func constructEvent(action fleetapi.Action, agentID string) fleetapi.AckEvent {

if a, ok := action.(*fleetapi.ActionApp); ok {
ackev.ActionData = a.Data
ackev.ActionResponse = a.Response
ackev.StartedAt = a.StartedAt
ackev.CompletedAt = a.CompletedAt
ackev.Error = a.Error
Expand Down
18 changes: 10 additions & 8 deletions x-pack/elastic-agent/pkg/fleetapi/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,14 +208,15 @@ func (a *ActionSettings) String() string {

// ActionApp is the application action request.
type ActionApp struct {
ActionID string `json:"id" mapstructure:"id"`
ActionType string `json:"type" mapstructure:"type"`
InputType string `json:"input_type" mapstructure:"input_type"`
Timeout int64 `json:"timeout,omitempty" mapstructure:"timeout,omitempty"`
Data json.RawMessage `json:"data" mapstructure:"data"`
StartedAt string `json:"started_at,omitempty" mapstructure:"started_at,omitempty"`
CompletedAt string `json:"completed_at,omitempty" mapstructure:"completed_at,omitempty"`
Error string `json:"error,omitempty" mapstructure:"error,omitempty"`
ActionID string `json:"id" mapstructure:"id"`
ActionType string `json:"type" mapstructure:"type"`
InputType string `json:"input_type" mapstructure:"input_type"`
Timeout int64 `json:"timeout,omitempty" mapstructure:"timeout,omitempty"`
Data json.RawMessage `json:"data" mapstructure:"data"`
Response map[string]interface{} `json:"response" mapstructure:"response"`
StartedAt string `json:"started_at,omitempty" mapstructure:"started_at,omitempty"`
CompletedAt string `json:"completed_at,omitempty" mapstructure:"completed_at,omitempty"`
Error string `json:"error,omitempty" mapstructure:"error,omitempty"`
}

func (a *ActionApp) String() string {
Expand Down Expand Up @@ -287,6 +288,7 @@ func (a *Actions) UnmarshalJSON(data []byte) error {
InputType: response.InputType,
Timeout: response.Timeout,
Data: response.Data,
Response: response.Response,
}
case ActionTypeUnenroll:
action = &ActionUnenroll{
Expand Down