// handleSingleMessage processes a single refresh credentials message. func (refreshHandler *refreshCredentialsHandler) handleSingleMessage(message *ecsacs.IAMRoleCredentialsMessage) error { // Validate fields in the message err := validateIAMRoleCredentialsMessage(message) if err != nil { seelog.Errorf("Error validating credentials message: %v", err) return err } taskArn := aws.StringValue(message.TaskArn) messageId := aws.StringValue(message.MessageId) task, ok := refreshHandler.taskEngine.GetTaskByArn(taskArn) if !ok { seelog.Errorf("Task not found in the engine for the arn in credentials message, arn: %s, messageId: %s", taskArn, messageId) return fmt.Errorf("Task not found in the engine for the arn in credentials message, arn: %s", taskArn) } taskCredentials := credentials.TaskIAMRoleCredentials{ ARN: taskArn, IAMRoleCredentials: credentials.IAMRoleCredentialsFromACS(message.RoleCredentials), } err = refreshHandler.credentialsManager.SetTaskCredentials(taskCredentials) if err != nil { seelog.Errorf("Error updating credentials, err: %v messageId: %s", err, messageId) return fmt.Errorf("Error updating credentials %v", err) } task.SetCredentialsId(aws.StringValue(message.RoleCredentials.CredentialsId)) go func() { response := &ecsacs.IAMRoleCredentialsAckRequest{ Expiration: message.RoleCredentials.Expiration, MessageId: message.MessageId, CredentialsId: message.RoleCredentials.CredentialsId, } refreshHandler.ackRequest <- response }() return nil }
// addPayloadTasks does validation on each task and, for all valid ones, adds // it to the task engine. It returns a bool indicating if it could add every // task to the taskEngine and a slice of credential ack requests func (payloadHandler *payloadRequestHandler) addPayloadTasks(payload *ecsacs.PayloadMessage) ([]*ecsacs.IAMRoleCredentialsAckRequest, bool) { // verify thatwe were able to work with all tasks in this payload so we know whether to ack the whole thing or not allTasksOK := true validTasks := make([]*api.Task, 0, len(payload.Tasks)) for _, task := range payload.Tasks { if task == nil { seelog.Criticalf("Recieved nil task for messageId: %s", *payload.MessageId) allTasksOK = false continue } apiTask, err := api.TaskFromACS(task, payload) if err != nil { payloadHandler.handleUnrecognizedTask(task, err, payload) allTasksOK = false continue } if task.RoleCredentials != nil { // The payload from ACS for the task has credentials for the // task. Add those to the credentials manager and set the // credentials id for the task as well taskCredentials := credentials.TaskIAMRoleCredentials{ ARN: aws.StringValue(task.Arn), IAMRoleCredentials: credentials.IAMRoleCredentialsFromACS(task.RoleCredentials), } err = payloadHandler.credentialsManager.SetTaskCredentials(taskCredentials) if err != nil { payloadHandler.handleUnrecognizedTask(task, err, payload) allTasksOK = false continue } apiTask.SetCredentialsId(taskCredentials.IAMRoleCredentials.CredentialsId) } validTasks = append(validTasks, apiTask) } // Add 'stop' transitions first to allow seqnum ordering to work out // Because a 'start' sequence number should only be proceeded if all 'stop's // of the same sequence number have completed, the 'start' events need to be // added after the 'stop' events are there to block them. stoppedTasksCredentialsAcks, stoppedTasksAddedOK := payloadHandler.addTasks(payload, validTasks, isTaskStatusNotStopped) newTasksCredentialsAcks, newTasksAddedOK := payloadHandler.addTasks(payload, validTasks, isTaskStatusStopped) if !stoppedTasksAddedOK || !newTasksAddedOK { allTasksOK = false } // Construct a slice with credentials acks from all tasks var credentialsAcks []*ecsacs.IAMRoleCredentialsAckRequest credentialsAcks = append(stoppedTasksCredentialsAcks, newTasksCredentialsAcks...) return credentialsAcks, allTasksOK }