Example #1
0
// prepareRuntimeStatus creates the structure for the runtimeStatus section of the payload of SendReply
// for a particular plugin.
func prepareRuntimeStatus(log log.T, pluginResult contracts.PluginResult) contracts.PluginRuntimeStatus {
	var resultAsString string

	if err := pluginResult.Error; err == nil {
		resultAsString = fmt.Sprintf("%v", pluginResult.Output)
	} else {
		resultAsString = err.Error()
	}

	runtimeStatus := contracts.PluginRuntimeStatus{
		Code:          pluginResult.Code,
		Status:        pluginResult.Status,
		Output:        resultAsString,
		StartDateTime: times.ToIso8601UTC(pluginResult.StartDateTime),
		EndDateTime:   times.ToIso8601UTC(pluginResult.EndDateTime),
	}

	if pluginResult.OutputS3BucketName != "" {
		runtimeStatus.OutputS3BucketName = pluginResult.OutputS3BucketName
		if pluginResult.OutputS3KeyPrefix != "" {
			runtimeStatus.OutputS3KeyPrefix = pluginResult.OutputS3KeyPrefix
		}
	}

	if runtimeStatus.Status == contracts.ResultStatusFailed && runtimeStatus.Code == 0 {
		runtimeStatus.Code = 1
	}

	return runtimeStatus
}
Example #2
0
// PrepareReplyPayload creates the payload object for SendReply based on plugin outputs.
func PrepareReplyPayload(pluginID string, runtimeStatuses map[string]*contracts.PluginRuntimeStatus, dateTime time.Time, agentInfo contracts.AgentInfo) (payload messageContracts.SendReplyPayload) {

	// TODO instance this needs to be revised to be in parity with ec2config
	documentStatus := contracts.ResultStatusSuccess
	var runtimeStatusCounts = map[string]int{}
	pluginCounts := len(runtimeStatuses)

	for _, pluginResult := range runtimeStatuses {
		if pluginResult.Status == contracts.ResultStatusFailed {
			documentStatus = contracts.ResultStatusFailed
		}
		runtimeStatusCounts[string(pluginResult.Status)]++
	}

	//	  New precedence order of plugin states
	//	  Failed > TimedOut > Cancelled > Success > Cancelling > InProgress > Pending
	//	  The above order is a contract between SSM service and agent and hence for the calculation of aggregate
	//	  status of a (command) document, we follow the above precedence order.
	//
	//	  Note:
	//	  A command could have been failed/cancelled even before a plugin started executing, during which pendingItems > 0
	//	  but overallResult.Status would be Failed/Cancelled. That's the reason we check for OverallResult status along
	//	  with number of failed/cancelled items.
	//    TODO : We need to handle above to be able to send document traceoutput in case of document level errors.

	if runtimeStatusCounts[string(contracts.ResultStatusFailed)] > 0 {
		documentStatus = contracts.ResultStatusFailed
	} else if runtimeStatusCounts[string(contracts.ResultStatusTimedOut)] > 0 {
		documentStatus = contracts.ResultStatusTimedOut
	} else if runtimeStatusCounts[string(contracts.ResultStatusCancelled)] > 0 {
		documentStatus = contracts.ResultStatusCancelled
	} else if runtimeStatusCounts[string(contracts.ResultStatusSuccessAndReboot)] > 0 {
		documentStatus = contracts.ResultStatusSuccessAndReboot
	} else if runtimeStatusCounts[string(contracts.ResultStatusSuccess)] == pluginCounts {
		documentStatus = contracts.ResultStatusSuccess
	} else {
		documentStatus = contracts.ResultStatusInProgress
	}

	runtimeStatusesFiltered := make(map[string]*contracts.PluginRuntimeStatus)

	if pluginID != "" {
		runtimeStatusesFiltered[pluginID] = runtimeStatuses[pluginID]
	} else {
		runtimeStatusesFiltered = runtimeStatuses
	}

	payload = messageContracts.SendReplyPayload{
		AdditionalInfo: contracts.AdditionalInfo{
			Agent:               agentInfo,
			DateTime:            times.ToIso8601UTC(dateTime),
			RuntimeStatusCounts: runtimeStatusCounts,
		},
		DocumentStatus:      documentStatus,
		DocumentTraceOutput: "", // TODO: Fill me appropriately
		RuntimeStatus:       runtimeStatusesFiltered,
	}
	return
}
Example #3
0
// prepareRuntimeStatus creates the structure for the runtimeStatus section of the payload of SendReply
// for a particular plugin.
func prepareRuntimeStatus(update *UpdateDetail) contracts.PluginRuntimeStatus {
	// Set default as failed, this will help us catch issues more proactively
	pluginStatus := update.Result
	code := 0
	if pluginStatus == contracts.ResultStatusFailed {
		code = 1
	}

	output := contracts.TruncateOutput(update.StandardOut,
		update.StandardError,
		contracts.MaximumPluginOutputSize)

	return contracts.PluginRuntimeStatus{
		Code:               code,
		Status:             pluginStatus,
		Output:             output,
		OutputS3BucketName: update.OutputS3BucketName,
		OutputS3KeyPrefix:  update.OutputS3KeyPrefix,
		StartDateTime:      times.ToIso8601UTC(update.StartDateTime),
		EndDateTime:        times.ToIso8601UTC(time.Now()),
	}
}
Example #4
0
func createMDSMessage(commandID string, payload string, topic string, instanceID string) ssmmds.Message {
	messageCreatedDate := time.Date(2015, 7, 9, 23, 22, 39, 19000000, time.UTC)

	c := sha256.New()
	c.Write([]byte(payload))
	payloadDigest := string(c.Sum(nil))

	return ssmmds.Message{
		CreatedDate:   aws.String(times.ToIso8601UTC(messageCreatedDate)),
		Destination:   aws.String(instanceID),
		MessageId:     aws.String("aws.ssm." + commandID + "." + instanceID),
		Payload:       aws.String(payload),
		PayloadDigest: aws.String(payloadDigest),
		Topic:         aws.String(topic),
	}
}
Example #5
0
// prepareReplyPayload setups the reply payload
func prepareReplyPayload(config appconfig.SsmagentConfig, update *UpdateDetail) (payload *messageContracts.SendReplyPayload) {
	runtimeStatuses := make(map[string]*contracts.PluginRuntimeStatus)
	rs := prepareRuntimeStatus(update)
	runtimeStatuses[appconfig.PluginNameAwsAgentUpdate] = &rs
	agentInfo := contracts.AgentInfo{
		Lang:      config.Os.Lang,
		Name:      config.Agent.Name,
		Version:   config.Agent.Version,
		Os:        config.Os.Name,
		OsVersion: config.Os.Version,
	}

	payload = &messageContracts.SendReplyPayload{
		AdditionalInfo: contracts.AdditionalInfo{
			Agent:    agentInfo,
			DateTime: times.ToIso8601UTC(time.Now()),
		},
		DocumentStatus:      rs.Status,
		DocumentTraceOutput: "",
		RuntimeStatus:       runtimeStatuses,
	}

	return payload
}