Skip to content

Commit

Permalink
Adding enableFaultInjection to task payload
Browse files Browse the repository at this point in the history
  • Loading branch information
Harish Senthilkumar committed Sep 25, 2024
1 parent 08341f7 commit 74c3067
Show file tree
Hide file tree
Showing 10 changed files with 64 additions and 54 deletions.
6 changes: 6 additions & 0 deletions agent/acs/session/payload_responder.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,12 @@ func (pmHandler *payloadMessageHandler) addPayloadTasks(payload *ecsacs.PayloadM
loggerfield.DesiredStatus: apiTask.GetDesiredStatus(),
})

if apiTask.IsFaultInjectionEnabled() {
logger.Info("Fault Injection Enabled for task", logger.Fields{
loggerfield.TaskARN: apiTask.Arn,
})
}

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
Expand Down
10 changes: 7 additions & 3 deletions agent/api/task/task.go
Original file line number Diff line number Diff line change
Expand Up @@ -299,8 +299,7 @@ type Task struct {

NetworkNamespace string `json:"NetworkNamespace,omitempty"`

// TODO: Will need to initialize/set the value in a follow PR
FaultInjectionEnabled bool `json:"FaultInjectionEnabled,omitempty"`
EnableFaultInjection bool `json:"enableFaultInjection,omitempty"`

// DefaultIfname is used to reference the default network interface name on the task network namespace
// For AWSVPC mode, it can be eth0 which corresponds to the interface name on the task ENI
Expand All @@ -322,6 +321,11 @@ func TaskFromACS(acsTask *ecsacs.Task, envelope *ecsacs.PayloadMessage) (*Task,
return nil, err
}

// Set the EnableFaultInjection field if present
if acsTask.EnableFaultInjection != nil {
task.EnableFaultInjection = aws.BoolValue(acsTask.EnableFaultInjection)
}

// Overrides the container command if it's set
for _, container := range task.Containers {
if (container.Overrides != apicontainer.ContainerOverrides{}) && container.Overrides.Command != nil {
Expand Down Expand Up @@ -3771,7 +3775,7 @@ func (task *Task) IsFaultInjectionEnabled() bool {
task.lock.RLock()
defer task.lock.RUnlock()

return task.FaultInjectionEnabled
return task.EnableFaultInjection
}

func (task *Task) GetNetworkMode() string {
Expand Down
24 changes: 12 additions & 12 deletions agent/handlers/task_server_setup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -456,9 +456,9 @@ var (
}},
})

agentStateExpectations = func(state *mock_dockerstate.MockTaskEngineState, faultInjectionEnabled bool, networkMode string) {
agentStateExpectations = func(state *mock_dockerstate.MockTaskEngineState, enableFaultInjection bool, networkMode string) {
task := standardTask()
task.FaultInjectionEnabled = faultInjectionEnabled
task.EnableFaultInjection = enableFaultInjection
task.NetworkMode = networkMode
task.NetworkNamespace = networkNamespace
task.DefaultIfname = defaultIfname
Expand Down Expand Up @@ -589,7 +589,7 @@ func expectedV4TaskResponse() v4.TaskResponse {
)
}

func expectedV4TaskNetworkConfig(faultInjectionEnabled bool, networkMode, path, deviceName string) *v4.TaskNetworkConfig {
func expectedV4TaskNetworkConfig(enableFaultInjection bool, networkMode, path, deviceName string) *v4.TaskNetworkConfig {
return v4.NewTaskNetworkConfig(networkMode, path, deviceName)
}

Expand Down Expand Up @@ -2092,7 +2092,7 @@ func TestV4TaskMetadata(t *testing.T) {
testTMDSRequest(t, TMDSTestCase[v4.TaskResponse]{
path: v4BasePath + v3EndpointID + "/task",
setStateExpectations: func(state *mock_dockerstate.MockTaskEngineState) {
task.FaultInjectionEnabled = true
task.EnableFaultInjection = true
task.NetworkNamespace = networkNamespace
task.DefaultIfname = defaultIfname
gomock.InOrder(
Expand All @@ -2115,7 +2115,7 @@ func TestV4TaskMetadata(t *testing.T) {
path: v4BasePath + v3EndpointID + "/task",
setStateExpectations: func(state *mock_dockerstate.MockTaskEngineState) {
hostTask := standardHostTask()
hostTask.FaultInjectionEnabled = true
hostTask.EnableFaultInjection = true
hostTask.NetworkNamespace = networkNamespace
hostTask.DefaultIfname = defaultIfname
gomock.InOrder(
Expand Down Expand Up @@ -3732,9 +3732,9 @@ type networkFaultTestCase struct {
expectedStatusCode int
requestBody interface{}
expectedFaultResponse faulttype.NetworkFaultInjectionResponse
setStateExpectations func(state *mock_dockerstate.MockTaskEngineState, faultInjectionEnabled bool, networkMode string)
setStateExpectations func(state *mock_dockerstate.MockTaskEngineState, enableFaultInjection bool, networkMode string)
setExecExpectations execExpectations
faultInjectionEnabled bool
enableFaultInjection bool
networkMode string
}

Expand All @@ -3749,7 +3749,7 @@ func generateCommonNetworkFaultInjectionTestCases(requestType, successResponse s
expectedFaultResponse: faulttype.NewNetworkFaultInjectionSuccessResponse(successResponse),
setStateExpectations: agentStateExpectations,
setExecExpectations: exec,
faultInjectionEnabled: true,
enableFaultInjection: true,
networkMode: apitask.HostNetworkMode,
},
{
Expand All @@ -3759,7 +3759,7 @@ func generateCommonNetworkFaultInjectionTestCases(requestType, successResponse s
expectedFaultResponse: faulttype.NewNetworkFaultInjectionSuccessResponse(successResponse),
setStateExpectations: agentStateExpectations,
setExecExpectations: exec,
faultInjectionEnabled: true,
enableFaultInjection: true,
networkMode: apitask.AWSVPCNetworkMode,
},
}
Expand Down Expand Up @@ -3909,7 +3909,7 @@ func testRegisterFaultHandler(t *testing.T, tcs []networkFaultTestCase, method,
execWrapper := mock_execwrapper.NewMockExec(ctrl)

if tc.setStateExpectations != nil {
tc.setStateExpectations(state, tc.faultInjectionEnabled, tc.networkMode)
tc.setStateExpectations(state, tc.enableFaultInjection, tc.networkMode)
}

if tc.setExecExpectations != nil {
Expand Down Expand Up @@ -3954,7 +3954,7 @@ func TestV4GetTaskMetadataWithTaskNetworkConfig(t *testing.T) {
name: "happy case with awsvpc mode",
setStateExpectations: func(state *mock_dockerstate.MockTaskEngineState) {
task := standardTask()
task.FaultInjectionEnabled = true
task.EnableFaultInjection = true
task.NetworkNamespace = networkNamespace
task.DefaultIfname = defaultIfname
gomock.InOrder(
Expand All @@ -3973,7 +3973,7 @@ func TestV4GetTaskMetadataWithTaskNetworkConfig(t *testing.T) {
name: "happy case with host mode",
setStateExpectations: func(state *mock_dockerstate.MockTaskEngineState) {
hostTask := standardHostTask()
hostTask.FaultInjectionEnabled = true
hostTask.EnableFaultInjection = true
hostTask.NetworkNamespace = networkNamespace
hostTask.DefaultIfname = defaultIfname
gomock.InOrder(
Expand Down
2 changes: 1 addition & 1 deletion agent/handlers/v4/tmdsstate.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ func (s *TMDSAgentState) getTaskMetadata(v3EndpointID string, includeTags bool)
NewPulledContainerResponse(dockerContainer, task.GetPrimaryENI()))
}

taskResponse.FaultInjectionEnabled = task.IsFaultInjectionEnabled()
taskResponse.EnableFaultInjection = task.IsFaultInjectionEnabled()
var taskNetworkConfig *tmdsv4.TaskNetworkConfig
if task.IsNetworkModeHost() {
// For host most, we don't really need the network namespace in order to do anything within the host instance network namespace
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion ecs-agent/tmds/handlers/fault/v1/handlers/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -952,7 +952,7 @@ func validateTaskMetadata(w http.ResponseWriter, agentState state.AgentState, re
}

// Check if task is FIS-enabled
if !taskMetadata.FaultInjectionEnabled {
if !taskMetadata.EnableFaultInjection {
errResponse := fmt.Sprintf(faultInjectionEnabledError, taskMetadata.TaskARN)
responseBody := types.NewNetworkFaultInjectionErrorResponse(errResponse)
logger.Error("Error: Task is not fault injection enabled.", logger.Fields{
Expand Down
60 changes: 30 additions & 30 deletions ecs-agent/tmds/handlers/fault/v1/handlers/handlers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,9 @@ var (
}

happyTaskResponse = state.TaskResponse{
TaskResponse: &v2.TaskResponse{TaskARN: taskARN},
TaskNetworkConfig: &happyTaskNetworkConfig,
FaultInjectionEnabled: true,
TaskResponse: &v2.TaskResponse{TaskARN: taskARN},
TaskNetworkConfig: &happyTaskNetworkConfig,
EnableFaultInjection: true,
}

happyBlackHolePortReqBody = map[string]interface{}{
Expand Down Expand Up @@ -353,8 +353,8 @@ func generateCommonNetworkBlackHolePortTestCases(name string) []networkFaultInje
expectedResponseBody: types.NewNetworkFaultInjectionErrorResponse(fmt.Sprintf(faultInjectionEnabledError, taskARN)),
setAgentStateExpectations: func(agentState *mock_state.MockAgentState) {
agentState.EXPECT().GetTaskMetadata(endpointId).Return(state.TaskResponse{
TaskResponse: &v2.TaskResponse{TaskARN: taskARN},
FaultInjectionEnabled: false,
TaskResponse: &v2.TaskResponse{TaskARN: taskARN},
EnableFaultInjection: false,
}, nil).Times(1)
},
},
Expand All @@ -365,8 +365,8 @@ func generateCommonNetworkBlackHolePortTestCases(name string) []networkFaultInje
expectedResponseBody: types.NewNetworkFaultInjectionErrorResponse(fmt.Sprintf(invalidNetworkModeError, invalidNetworkMode)),
setAgentStateExpectations: func(agentState *mock_state.MockAgentState) {
agentState.EXPECT().GetTaskMetadata(endpointId).Return(state.TaskResponse{
TaskResponse: &v2.TaskResponse{TaskARN: taskARN},
FaultInjectionEnabled: true,
TaskResponse: &v2.TaskResponse{TaskARN: taskARN},
EnableFaultInjection: true,
TaskNetworkConfig: &state.TaskNetworkConfig{
NetworkMode: invalidNetworkMode,
NetworkNamespaces: happyNetworkNamespaces,
Expand All @@ -382,9 +382,9 @@ func generateCommonNetworkBlackHolePortTestCases(name string) []networkFaultInje
fmt.Sprintf("failed to get task metadata due to internal server error for container: %s", endpointId)),
setAgentStateExpectations: func(agentState *mock_state.MockAgentState) {
agentState.EXPECT().GetTaskMetadata(endpointId).Return(state.TaskResponse{
TaskResponse: &v2.TaskResponse{TaskARN: taskARN},
FaultInjectionEnabled: true,
TaskNetworkConfig: nil,
TaskResponse: &v2.TaskResponse{TaskARN: taskARN},
EnableFaultInjection: true,
TaskNetworkConfig: nil,
}, nil).Times(1)
},
},
Expand All @@ -396,8 +396,8 @@ func generateCommonNetworkBlackHolePortTestCases(name string) []networkFaultInje
fmt.Sprintf("failed to get task metadata due to internal server error for container: %s", endpointId)),
setAgentStateExpectations: func(agentState *mock_state.MockAgentState) {
agentState.EXPECT().GetTaskMetadata(endpointId).Return(state.TaskResponse{
TaskResponse: &v2.TaskResponse{TaskARN: taskARN},
FaultInjectionEnabled: true,
TaskResponse: &v2.TaskResponse{TaskARN: taskARN},
EnableFaultInjection: true,
TaskNetworkConfig: &state.TaskNetworkConfig{
NetworkMode: awsvpcNetworkMode,
NetworkNamespaces: nil,
Expand All @@ -413,8 +413,8 @@ func generateCommonNetworkBlackHolePortTestCases(name string) []networkFaultInje
fmt.Sprintf("failed to get task metadata due to internal server error for container: %s", endpointId)),
setAgentStateExpectations: func(agentState *mock_state.MockAgentState) {
agentState.EXPECT().GetTaskMetadata(endpointId).Return(state.TaskResponse{
TaskResponse: &v2.TaskResponse{TaskARN: taskARN},
FaultInjectionEnabled: true,
TaskResponse: &v2.TaskResponse{TaskARN: taskARN},
EnableFaultInjection: true,
TaskNetworkConfig: &state.TaskNetworkConfig{
NetworkMode: awsvpcNetworkMode,
NetworkNamespaces: noPathInNetworkNamespaces,
Expand All @@ -430,8 +430,8 @@ func generateCommonNetworkBlackHolePortTestCases(name string) []networkFaultInje
fmt.Sprintf("failed to get task metadata due to internal server error for container: %s", endpointId)),
setAgentStateExpectations: func(agentState *mock_state.MockAgentState) {
agentState.EXPECT().GetTaskMetadata(endpointId).Return(state.TaskResponse{
TaskResponse: &v2.TaskResponse{TaskARN: taskARN},
FaultInjectionEnabled: true,
TaskResponse: &v2.TaskResponse{TaskARN: taskARN},
EnableFaultInjection: true,
TaskNetworkConfig: &state.TaskNetworkConfig{
NetworkMode: awsvpcNetworkMode,
NetworkNamespaces: []*state.NetworkNamespace{
Expand Down Expand Up @@ -1121,8 +1121,8 @@ func generateNetworkLatencyTestCases(name, expectedHappyResponseBody string) []n
expectedResponseBody: types.NewNetworkFaultInjectionErrorResponse(fmt.Sprintf(faultInjectionEnabledError, taskARN)),
setAgentStateExpectations: func(agentState *mock_state.MockAgentState) {
agentState.EXPECT().GetTaskMetadata(endpointId).Return(state.TaskResponse{
TaskResponse: &v2.TaskResponse{TaskARN: taskARN},
FaultInjectionEnabled: false,
TaskResponse: &v2.TaskResponse{TaskARN: taskARN},
EnableFaultInjection: false,
}, nil)
},
},
Expand All @@ -1133,8 +1133,8 @@ func generateNetworkLatencyTestCases(name, expectedHappyResponseBody string) []n
expectedResponseBody: types.NewNetworkFaultInjectionErrorResponse(fmt.Sprintf(invalidNetworkModeError, invalidNetworkMode)),
setAgentStateExpectations: func(agentState *mock_state.MockAgentState) {
agentState.EXPECT().GetTaskMetadata(endpointId).Return(state.TaskResponse{
TaskResponse: &v2.TaskResponse{TaskARN: taskARN},
FaultInjectionEnabled: true,
TaskResponse: &v2.TaskResponse{TaskARN: taskARN},
EnableFaultInjection: true,
TaskNetworkConfig: &state.TaskNetworkConfig{
NetworkMode: invalidNetworkMode,
NetworkNamespaces: happyNetworkNamespaces,
Expand All @@ -1149,9 +1149,9 @@ func generateNetworkLatencyTestCases(name, expectedHappyResponseBody string) []n
expectedResponseBody: types.NewNetworkFaultInjectionErrorResponse(fmt.Sprintf("failed to get task metadata due to internal server error for container: %s", endpointId)),
setAgentStateExpectations: func(agentState *mock_state.MockAgentState) {
agentState.EXPECT().GetTaskMetadata(endpointId).Return(state.TaskResponse{
TaskResponse: &v2.TaskResponse{TaskARN: taskARN},
FaultInjectionEnabled: true,
TaskNetworkConfig: nil,
TaskResponse: &v2.TaskResponse{TaskARN: taskARN},
EnableFaultInjection: true,
TaskNetworkConfig: nil,
}, nil)
},
},
Expand Down Expand Up @@ -1329,8 +1329,8 @@ func generateCommonNetworkPacketLossTestCases(name string) []networkFaultInjecti
expectedResponseBody: types.NewNetworkFaultInjectionErrorResponse(fmt.Sprintf(faultInjectionEnabledError, taskARN)),
setAgentStateExpectations: func(agentState *mock_state.MockAgentState) {
agentState.EXPECT().GetTaskMetadata(endpointId).Return(state.TaskResponse{
TaskResponse: &v2.TaskResponse{TaskARN: taskARN},
FaultInjectionEnabled: false,
TaskResponse: &v2.TaskResponse{TaskARN: taskARN},
EnableFaultInjection: false,
}, nil)
},
},
Expand All @@ -1341,8 +1341,8 @@ func generateCommonNetworkPacketLossTestCases(name string) []networkFaultInjecti
expectedResponseBody: types.NewNetworkFaultInjectionErrorResponse(fmt.Sprintf(invalidNetworkModeError, invalidNetworkMode)),
setAgentStateExpectations: func(agentState *mock_state.MockAgentState) {
agentState.EXPECT().GetTaskMetadata(endpointId).Return(state.TaskResponse{
TaskResponse: &v2.TaskResponse{TaskARN: taskARN},
FaultInjectionEnabled: true,
TaskResponse: &v2.TaskResponse{TaskARN: taskARN},
EnableFaultInjection: true,
TaskNetworkConfig: &state.TaskNetworkConfig{
NetworkMode: invalidNetworkMode,
NetworkNamespaces: happyNetworkNamespaces,
Expand All @@ -1357,9 +1357,9 @@ func generateCommonNetworkPacketLossTestCases(name string) []networkFaultInjecti
expectedResponseBody: types.NewNetworkFaultInjectionErrorResponse(fmt.Sprintf("failed to get task metadata due to internal server error for container: %s", endpointId)),
setAgentStateExpectations: func(agentState *mock_state.MockAgentState) {
agentState.EXPECT().GetTaskMetadata(endpointId).Return(state.TaskResponse{
TaskResponse: &v2.TaskResponse{TaskARN: taskARN},
FaultInjectionEnabled: true,
TaskNetworkConfig: nil,
TaskResponse: &v2.TaskResponse{TaskARN: taskARN},
EnableFaultInjection: true,
TaskNetworkConfig: nil,
}, nil)
},
},
Expand Down
8 changes: 4 additions & 4 deletions ecs-agent/tmds/handlers/v4/handlers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ func taskResponse() *state.TaskResponse {
// taskResponseWithFaultInjectionEnabled returns a standard agent task response with FaultInjection enabled
func taskResponseWithFaultInjectionEnabled() *state.TaskResponse {
taskResponse := taskResponse()
taskResponse.FaultInjectionEnabled = true
taskResponse.EnableFaultInjection = true
return taskResponse
}

Expand Down Expand Up @@ -299,9 +299,9 @@ func TestTaskMetadata(t *testing.T) {
t.Run("happy case with FaultInjection enabled", func(t *testing.T) {
metadata := taskResponseWithFaultInjectionEnabled()
expectedTaskResponse := taskResponseWithFaultInjectionEnabled()
expectedTaskResponse.CredentialsID = "" // credentials ID not expected
expectedTaskResponse.TaskNetworkConfig = nil // TaskNetworkConfig is not expected and would be used internally
expectedTaskResponse.FaultInjectionEnabled = false // FaultInjectionEnabled is not expected and would be used internally
expectedTaskResponse.CredentialsID = "" // credentials ID not expected
expectedTaskResponse.TaskNetworkConfig = nil // TaskNetworkConfig is not expected and would be used internally
expectedTaskResponse.EnableFaultInjection = false // EnableFaultInjection is not expected and would be used internally

handler, _, agentState, _ := setup(t)
agentState.EXPECT().
Expand Down
2 changes: 1 addition & 1 deletion ecs-agent/tmds/handlers/v4/state/response.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ type TaskResponse struct {
EphemeralStorageMetrics *EphemeralStorageMetrics `json:"EphemeralStorageMetrics,omitempty"`
CredentialsID string `json:"-"`
TaskNetworkConfig *TaskNetworkConfig `json:"-"`
FaultInjectionEnabled bool `json:"-"`
EnableFaultInjection bool `json:"-"`
}

// TaskNetworkConfig contains required network configurations for network faults injection.
Expand Down

0 comments on commit 74c3067

Please sign in to comment.