agent/contracts/model.go (219 lines of code) (raw):
// Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"). You may not
// use this file except in compliance with the License. A copy of the
// License is located at
//
// http://aws.amazon.com/apache2.0/
//
// or in the "license" file accompanying this file. This file is distributed
// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing
// permissions and limitations under the License.
// Package contracts contains all necessary interface and models
// necessary for communication and sharing within the agent.
package contracts
import "encoding/json"
// ResultStatus provides the granular status of a plugin.
// These are internal states maintained by agent during the execution of a command/config
type ResultStatus string
const (
// ResultStatusNotStarted represents NotStarted status
ResultStatusNotStarted ResultStatus = "NotStarted"
// ResultStatusInProgress represents InProgress status
ResultStatusInProgress ResultStatus = "InProgress"
// ResultStatusSuccess represents Success status
ResultStatusSuccess ResultStatus = "Success"
// ResultStatusSuccessAndReboot represents SuccessAndReboot status
ResultStatusSuccessAndReboot ResultStatus = "SuccessAndReboot"
// ResultStatusPassedAndReboot represents PassedAndReboot status
ResultStatusPassedAndReboot ResultStatus = "PassedAndReboot"
// ResultStatusFailed represents Failed status
ResultStatusFailed ResultStatus = "Failed"
// ResultStatusCancelled represents Cancelled status
ResultStatusCancelled ResultStatus = "Cancelled"
// ResultStatusTimedOut represents TimedOut status
ResultStatusTimedOut ResultStatus = "TimedOut"
// ResultStatusSkipped represents Skipped status
ResultStatusSkipped ResultStatus = "Skipped"
// ResultStatusTestFailure represents test failure
ResultStatusTestFailure ResultStatus = "TestFailure"
// ResultStatusTestPass represents test passing
ResultStatusTestPass ResultStatus = "TestPass"
)
const (
ExitWithSuccess int = 168
ExitWithFailure int = 169
)
const (
OnFailureModifier string = "onFailure"
OnSuccessModifier string = "onSuccess"
FinallyStepModifier string = "finallyStep"
)
const (
ModifierValueExit string = "exit"
ModifierValueSuccessAndExit string = "successAndExit"
ModifierValueTrue string = "true"
)
// IsSuccess checks whether the result is success or not
func (rs ResultStatus) IsSuccess() bool {
switch rs {
case ResultStatusSuccess, ResultStatusPassedAndReboot, ResultStatusSuccessAndReboot:
return true
default:
return false
}
}
// IsReboot checks whether the result is reboot or not
func (rs ResultStatus) IsReboot() bool {
switch rs {
case ResultStatusPassedAndReboot, ResultStatusSuccessAndReboot:
return true
default:
return false
}
}
// MergeResultStatus takes two ResultStatuses (presumably from sub-tasks) and decides what the overall task status should be
func MergeResultStatus(current ResultStatus, new ResultStatus) (merged ResultStatus) {
orderedResultStatus := [...]ResultStatus{
ResultStatusSkipped,
ResultStatusSuccess,
ResultStatusSuccessAndReboot,
ResultStatusPassedAndReboot,
ResultStatusNotStarted,
ResultStatusInProgress,
ResultStatusFailed,
ResultStatusCancelled,
ResultStatusTimedOut,
}
if current == "" {
return new
}
if new == "" {
return current
}
// Return the "greater" ResultStatus - the one with a higher index in OrderedResultStatus
// We assume both exist in the array and therefore the first one found is at the lower index (so return the other one)
for _, ResultStatus := range orderedResultStatus {
if ResultStatus == current {
return new
}
if ResultStatus == new {
return current
}
}
return new // Default to new ResultStatus if neither is found in the array
}
const (
/*
NOTE: Following constants are meant to be used for setting plugin status only
*/
// AssociationStatusPending represents Pending status
AssociationStatusPending = "Pending"
// AssociationStatusAssociated represents Associated status
AssociationStatusAssociated = "Associated"
// AssociationStatusInProgress represents InProgress status
AssociationStatusInProgress = "InProgress"
// AssociationStatusSuccess represents Success status
AssociationStatusSuccess = "Success"
// AssociationStatusFailed represents Failed status
AssociationStatusFailed = "Failed"
// AssociationStatusTimedOut represents TimedOut status
AssociationStatusTimedOut = "TimedOut"
)
const (
/*
NOTE: Following constants are meant to be used for setting error codes in plugin status only. If these are used
for setting plugin status -> the status will not be appropriately aggregated.
*/
// AssociationErrorCodeInvalidAssociation represents InvalidAssociation Error
AssociationErrorCodeInvalidAssociation = "InvalidAssoc"
// AssociationErrorCodeInvalidExpression represents InvalidExpression Error
AssociationErrorCodeInvalidExpression = "InvalidExpression"
// AssociationErrorCodeExecutionError represents Execution Error
AssociationErrorCodeExecutionError = "ExecutionError"
// AssociationErrorCodeListAssociationError represents ListAssociation Error
AssociationErrorCodeListAssociationError = "ListAssocError"
// AssociationErrorCodeSubmitAssociationError represents SubmitAssociation Error
AssociationErrorCodeSubmitAssociationError = "SubmitAssocError"
// AssociationErrorCodeStuckAtInProgressError represents association stuck in InProgress Error
AssociationErrorCodeStuckAtInProgressError = "StuckAtInProgress"
// AssociationErrorCodeNoError represents no error
AssociationErrorCodeNoError = ""
)
const (
// DocumentPendingMessages represents the summary message for pending association
AssociationPendingMessage string = "Association is pending"
// DocumentInProgressMessage represents the summary message for inprogress association
AssociationInProgressMessage string = "Executing association"
)
const (
// ParamTypeString represents the Param Type is String
ParamTypeString = "String"
// ParamTypeStringList represents the Param Type is StringList
ParamTypeStringList = "StringList"
// ParamTypeStringMap represents the param type is StringMap
ParamTypeStringMap = "StringMap"
)
type SSMConnectionChannel string
const (
MGS SSMConnectionChannel = "ssmmessages"
MDS SSMConnectionChannel = "ec2messages"
)
type ConnectionChannel struct {
SSMConnectionChannel SSMConnectionChannel
}
// A Parameter in the DocumentContent of an MDS message.
type Parameter struct {
DefaultVal interface{} `json:"default" yaml:"default"`
Description string `json:"description" yaml:"description"`
ParamType string `json:"type" yaml:"type"`
AllowedVal []string `json:"allowedValues" yaml:"allowedValues"`
AllowedPattern string `json:"allowedPattern" yaml:"allowedPattern"`
MinChars json.Number `json:"minChars,omitempty" yaml:"minChars,omitempty"`
MaxChars json.Number `json:"maxChars,omitempty" yaml:"maxChars,omitempty"`
MinItems json.Number `json:"minItems,omitempty" yaml:"minItems,omitempty"`
MaxItems json.Number `json:"maxItems,omitempty" yaml:"maxItems,omitempty"`
}
// PluginConfig stores plugin configuration
type PluginConfig struct {
Settings interface{} `json:"settings" yaml:"settings"`
Properties interface{} `json:"properties" yaml:"properties"`
Description string `json:"description" yaml:"description"`
}
// InstancePluginConfig stores plugin configuration
type InstancePluginConfig struct {
Action string `json:"action" yaml:"action"` // plugin name
Inputs interface{} `json:"inputs" yaml:"inputs"` // Properties
MaxAttempts int `json:"maxAttempts" yaml:"maxAttempts"`
Name string `json:"name" yaml:"name"` // unique identifier
OnFailure string `json:"onFailure" yaml:"onFailure"`
Settings interface{} `json:"settings" yaml:"settings"`
Timeout int `json:"timeoutSeconds" yaml:"timeoutSeconds"`
Preconditions map[string][]string `json:"precondition" yaml:"precondition"`
}
// DocumentContent object which represents ssm document content.
type DocumentContent struct {
SchemaVersion string `json:"schemaVersion" yaml:"schemaVersion"`
Description string `json:"description" yaml:"description"`
RuntimeConfig map[string]*PluginConfig `json:"runtimeConfig" yaml:"runtimeConfig"`
MainSteps []*InstancePluginConfig `json:"mainSteps" yaml:"mainSteps"`
Parameters map[string]*Parameter `json:"parameters" yaml:"parameters"`
// InvokedPlugin field is set when document is invoked from any other plugin.
// Currently, InvokedPlugin is set only in runDocument Plugin
InvokedPlugin string
}
// SessionInputs stores session configuration
type SessionInputs struct {
S3BucketName string `json:"s3BucketName" yaml:"s3BucketName"`
S3KeyPrefix string `json:"s3KeyPrefix" yaml:"s3KeyPrefix"`
S3EncryptionEnabled interface{} `json:"s3EncryptionEnabled" yaml:"s3EncryptionEnabled"`
CloudWatchLogGroupName string `json:"cloudWatchLogGroupName" yaml:"cloudWatchLogGroupName"`
CloudWatchStreamingEnabled bool `json:"cloudWatchStreamingEnabled" yaml:"cloudWatchStreamingEnabled"`
CloudWatchEncryptionEnabled interface{} `json:"cloudWatchEncryptionEnabled" yaml:"cloudWatchEncryptionEnabled"`
KmsKeyId string `json:"kmsKeyId" yaml:"kmsKeyId"`
RunAsEnabled interface{} `json:"runAsEnabled" yaml:"runAsEnabled"`
RunAsDefaultUser string `json:"runAsDefaultUser" yaml:"runAsDefaultUser"`
ShellProfile ShellProfileConfig `json:"shellProfile" yaml:"shellProfile"`
}
// ShellProfileConfig stores shell profile config
type ShellProfileConfig struct {
Windows string `json:"windows" yaml:"windows"`
Linux string `json:"linux" yaml:"linux"`
}
// SessionDocumentContent object which represents ssm session content.
type SessionDocumentContent struct {
SchemaVersion string `json:"schemaVersion" yaml:"schemaVersion"`
Description string `json:"description" yaml:"description"`
SessionType string `json:"sessionType" yaml:"sessionType"`
Inputs SessionInputs `json:"inputs" yaml:"inputs"`
Parameters map[string]*Parameter `json:"parameters" yaml:"parameters"`
Properties interface{} `json:"properties" yaml:"properties"`
}
// AdditionalInfo section in agent response
type AdditionalInfo struct {
Agent AgentInfo `json:"agent"`
DateTime string `json:"dateTime"`
RunID string `json:"runId"`
RuntimeStatusCounts map[string]int `json:"runtimeStatusCounts"`
AbleToOpenMGSConnection *bool `json:"ableToOpenMGSConnection,omitempty"`
}
// AgentInfo represents the agent response
type AgentInfo struct {
Lang string `json:"lang"`
Name string `json:"name"`
Os string `json:"os"`
OsVersion string `json:"osver"`
Version string `json:"ver"`
}
// PluginRuntimeStatus represents plugin runtime status section in agent response
type PluginRuntimeStatus struct {
Status ResultStatus `json:"status"`
Code int `json:"code"`
Name string `json:"name"`
Output string `json:"output"`
StartDateTime string `json:"startDateTime"`
EndDateTime string `json:"endDateTime"`
OutputS3BucketName string `json:"outputS3BucketName"`
OutputS3KeyPrefix string `json:"outputS3KeyPrefix"`
StepName string `json:"stepName"`
StandardOutput string `json:"standardOutput"`
StandardError string `json:"standardError"`
}
// AgentConfiguration is a struct that stores information about the agent and instance
type AgentConfiguration struct {
AgentInfo AgentInfo
InstanceID string
}
// DocumentResult is a struct that stores information about the result of the document
type DocumentResult struct {
DocumentName string
DocumentVersion string
MessageID string
AssociationID string
PluginResults map[string]*PluginResult
Status ResultStatus
LastPlugin string
NPlugins int
UpstreamServiceName UpstreamServiceName
ResultType ResultType
RelatedDocumentType DocumentType
}
// ResultType represents document Result types
type ResultType string
const (
// RunCommandResult represents result sent by document worker which ran runCommand documents
RunCommandResult ResultType = "RunCommandResult"
// SessionResult represents result sent by session worker to service
SessionResult ResultType = "SessionResult"
)
// StatusComm is a struct that holds channels to pass status
// between ssmAgentCore go routine and agent's main go routine
type StatusComm struct {
TerminationChan chan struct{}
DoneChan chan struct{}
}