func v1HandlersSetup(serverMux *http.ServeMux,
	containerInstanceArn *string,
	taskEngine handlersutils.DockerStateResolver,
	cfg *config.Config) {
	serverMux.HandleFunc(v1.AgentMetadataPath, v1.AgentMetadataHandler(containerInstanceArn, cfg))
	serverMux.HandleFunc(v1.TaskContainerMetadataPath, v1.TaskContainerMetadataHandler(taskEngine))
	serverMux.HandleFunc(v1.LicensePath, v1.LicenseHandler)
}

func v1HandlersSetup ( serverMux * http . ServeMux , containerInstanceArn * string , taskEngine handlersutils . DockerStateResolver , cfg * config . Config ) { serverMux . HandleFunc ( v1 . AgentMetadataPath , v1 . AgentMetadataHandler ( containerInstanceArn , cfg ) ) serverMux . HandleFunc ( v1 . TaskContainerMetadataPath , v1 . TaskContainerMetadataHandler ( taskEngine ) ) serverMux . HandleFunc ( v1 . LicensePath , v1 . LicenseHandler ) }

// v1HandlersSetup adds all handlers except CredentialsHandler in v1 package to the server mux.

v1HandlersSetup adds all handlers except CredentialsHandler in v1 package to the server mux .


func (dc *DockerContainer) String() string {
	if dc == nil {
		return "nil"
	}
	return fmt.Sprintf("Id: %s, Name: %s, Container: %s", dc.DockerID, dc.DockerName, dc.Container.String())
}

func ( dc * DockerContainer ) String ( ) string { if dc == nil { return " " } return fmt . Sprintf ( " " , dc . DockerID , dc . DockerName , dc . Container . String ( ) ) }

// String returns a human readable string representation of DockerContainer


func NewContainerWithSteadyState(steadyState apicontainerstatus.ContainerStatus) *Container {
	steadyStateStatus := steadyState
	return &Container{
		SteadyStateStatusUnsafe: &steadyStateStatus,
	}
}

func NewContainerWithSteadyState ( steadyState apicontainerstatus . ContainerStatus ) * Container { steadyStateStatus := steadyState return & Container { SteadyStateStatusUnsafe : & steadyStateStatus , } }

// NewContainerWithSteadyState creates a new Container object with the specified
// steady state. Containers that need the non default steady state set will
// use this method instead of setting it directly

NewContainerWithSteadyState creates a new Container object with the specified steady state . Containers that need the non default steady state set will use this method instead of setting it directly


func (c *Container) GetKnownStatus() apicontainerstatus.ContainerStatus {
	c.lock.RLock()
	defer c.lock.RUnlock()

	return c.KnownStatusUnsafe
}

func ( c * Container ) GetKnownStatus ( ) apicontainerstatus . ContainerStatus { c . lock . RLock ( ) defer c . lock . RUnlock ( ) return c . KnownStatusUnsafe }

// GetKnownStatus returns the known status of the container


func (c *Container) SetKnownStatus(status apicontainerstatus.ContainerStatus) {
	c.lock.Lock()
	defer c.lock.Unlock()

	c.KnownStatusUnsafe = status
	c.updateAppliedStatusUnsafe(status)
}

func ( c * Container ) SetKnownStatus ( status apicontainerstatus . ContainerStatus ) { c . lock . Lock ( ) defer c . lock . Unlock ( ) c . KnownStatusUnsafe = status c . updateAppliedStatusUnsafe ( status ) }

// SetKnownStatus sets the known status of the container and update the container
// applied status

SetKnownStatus sets the known status of the container and update the container applied status


func (c *Container) GetDesiredStatus() apicontainerstatus.ContainerStatus {
	c.lock.RLock()
	defer c.lock.RUnlock()

	return c.DesiredStatusUnsafe
}

func ( c * Container ) GetDesiredStatus ( ) apicontainerstatus . ContainerStatus { c . lock . RLock ( ) defer c . lock . RUnlock ( ) return c . DesiredStatusUnsafe }

// GetDesiredStatus gets the desired status of the container


func (c *Container) SetDesiredStatus(status apicontainerstatus.ContainerStatus) {
	c.lock.Lock()
	defer c.lock.Unlock()

	c.DesiredStatusUnsafe = status
}

func ( c * Container ) SetDesiredStatus ( status apicontainerstatus . ContainerStatus ) { c . lock . Lock ( ) defer c . lock . Unlock ( ) c . DesiredStatusUnsafe = status }

// SetDesiredStatus sets the desired status of the container


func (c *Container) GetSentStatus() apicontainerstatus.ContainerStatus {
	c.lock.RLock()
	defer c.lock.RUnlock()

	return c.SentStatusUnsafe
}

func ( c * Container ) GetSentStatus ( ) apicontainerstatus . ContainerStatus { c . lock . RLock ( ) defer c . lock . RUnlock ( ) return c . SentStatusUnsafe }

// GetSentStatus safely returns the SentStatusUnsafe of the container


func (c *Container) SetSentStatus(status apicontainerstatus.ContainerStatus) {
	c.lock.Lock()
	defer c.lock.Unlock()

	c.SentStatusUnsafe = status
}

func ( c * Container ) SetSentStatus ( status apicontainerstatus . ContainerStatus ) { c . lock . Lock ( ) defer c . lock . Unlock ( ) c . SentStatusUnsafe = status }

// SetSentStatus safely sets the SentStatusUnsafe of the container


func (c *Container) SetKnownExitCode(i *int) {
	c.lock.Lock()
	defer c.lock.Unlock()

	c.KnownExitCodeUnsafe = i
}

func ( c * Container ) SetKnownExitCode ( i * int ) { c . lock . Lock ( ) defer c . lock . Unlock ( ) c . KnownExitCodeUnsafe = i }

// SetKnownExitCode sets exit code field in container struct


func (c *Container) GetKnownExitCode() *int {
	c.lock.RLock()
	defer c.lock.RUnlock()

	return c.KnownExitCodeUnsafe
}

func ( c * Container ) GetKnownExitCode ( ) * int { c . lock . RLock ( ) defer c . lock . RUnlock ( ) return c . KnownExitCodeUnsafe }

// GetKnownExitCode returns the container exit code


func (c *Container) SetRegistryAuthCredentials(credential credentials.IAMRoleCredentials) {
	c.lock.Lock()
	defer c.lock.Unlock()

	c.RegistryAuthentication.ECRAuthData.SetPullCredentials(credential)
}

func ( c * Container ) SetRegistryAuthCredentials ( credential credentials . IAMRoleCredentials ) { c . lock . Lock ( ) defer c . lock . Unlock ( ) c . RegistryAuthentication . ECRAuthData . SetPullCredentials ( credential ) }

// SetRegistryAuthCredentials sets the credentials for pulling image from ECR


func (c *Container) ShouldPullWithExecutionRole() bool {
	c.lock.RLock()
	defer c.lock.RUnlock()

	return c.RegistryAuthentication != nil &&
		c.RegistryAuthentication.Type == AuthTypeECR &&
		c.RegistryAuthentication.ECRAuthData != nil &&
		c.RegistryAuthentication.ECRAuthData.UseExecutionRole
}

func ( c * Container ) ShouldPullWithExecutionRole ( ) bool { c . lock . RLock ( ) defer c . lock . RUnlock ( ) return c . RegistryAuthentication != nil && c . RegistryAuthentication . Type == AuthTypeECR && c . RegistryAuthentication . ECRAuthData != nil && c . RegistryAuthentication . ECRAuthData . UseExecutionRole }

// ShouldPullWithExecutionRole returns whether this container has its own ECR credentials


func (c *Container) GetSteadyStateStatus() apicontainerstatus.ContainerStatus {
	if c.SteadyStateStatusUnsafe == nil {
		return defaultContainerSteadyStateStatus
	}
	return *c.SteadyStateStatusUnsafe
}

func ( c * Container ) GetSteadyStateStatus ( ) apicontainerstatus . ContainerStatus { if c . SteadyStateStatusUnsafe == nil { return defaultContainerSteadyStateStatus } return * c . SteadyStateStatusUnsafe }

// GetSteadyStateStatus returns the steady state status for the container. If
// Container.steadyState is not initialized, the default steady state status
// defined by `defaultContainerSteadyStateStatus` is returned. The 'pause'
// container's steady state differs from that of other containers, as the
// 'pause' container can reach its teady state once networking resources
// have been provisioned for it, which is done in the `ContainerResourcesProvisioned`
// state

GetSteadyStateStatus returns the steady state status for the container . If Container . steadyState is not initialized the default steady state status defined by defaultContainerSteadyStateStatus is returned . The pause container s steady state differs from that of other containers as the pause container can reach its teady state once networking resources have been provisioned for it which is done in the ContainerResourcesProvisioned state


func (c *Container) IsKnownSteadyState() bool {
	knownStatus := c.GetKnownStatus()
	return knownStatus == c.GetSteadyStateStatus()
}

func ( c * Container ) IsKnownSteadyState ( ) bool { knownStatus := c . GetKnownStatus ( ) return knownStatus == c . GetSteadyStateStatus ( ) }

// IsKnownSteadyState returns true if the `KnownState` of the container equals
// the `steadyState` defined for the container

IsKnownSteadyState returns true if the KnownState of the container equals the steadyState defined for the container


func (c *Container) IsMetadataFileUpdated() bool {
	c.lock.RLock()
	defer c.lock.RUnlock()

	return c.MetadataFileUpdated
}

func ( c * Container ) IsMetadataFileUpdated ( ) bool { c . lock . RLock ( ) defer c . lock . RUnlock ( ) return c . MetadataFileUpdated }

// IsMetadataFileUpdated returns true if the metadata file has been once the
// metadata file is ready and will no longer change

IsMetadataFileUpdated returns true if the metadata file has been once the metadata file is ready and will no longer change


func (c *Container) SetMetadataFileUpdated() {
	c.lock.Lock()
	defer c.lock.Unlock()

	c.MetadataFileUpdated = true
}

func ( c * Container ) SetMetadataFileUpdated ( ) { c . lock . Lock ( ) defer c . lock . Unlock ( ) c . MetadataFileUpdated = true }

// SetMetadataFileUpdated sets the container's MetadataFileUpdated status to true

SetMetadataFileUpdated sets the container s MetadataFileUpdated status to true


func (c *Container) IsEssential() bool {
	c.lock.RLock()
	defer c.lock.RUnlock()

	return c.Essential
}

func ( c * Container ) IsEssential ( ) bool { c . lock . RLock ( ) defer c . lock . RUnlock ( ) return c . Essential }

// IsEssential returns whether the container is an essential container or not


func (c *Container) SetCreatedAt(createdAt time.Time) {
	if createdAt.IsZero() {
		return
	}
	c.lock.Lock()
	defer c.lock.Unlock()

	c.createdAt = createdAt
}

func ( c * Container ) SetCreatedAt ( createdAt time . Time ) { if createdAt . IsZero ( ) { return } c . lock . Lock ( ) defer c . lock . Unlock ( ) c . createdAt = createdAt }

// SetCreatedAt sets the timestamp for container's creation time

SetCreatedAt sets the timestamp for container s creation time


func (c *Container) SetStartedAt(startedAt time.Time) {
	if startedAt.IsZero() {
		return
	}

	c.lock.Lock()
	defer c.lock.Unlock()

	c.startedAt = startedAt
}

func ( c * Container ) SetStartedAt ( startedAt time . Time ) { if startedAt . IsZero ( ) { return } c . lock . Lock ( ) defer c . lock . Unlock ( ) c . startedAt = startedAt }

// SetStartedAt sets the timestamp for container's start time

SetStartedAt sets the timestamp for container s start time


func (c *Container) SetFinishedAt(finishedAt time.Time) {
	if finishedAt.IsZero() {
		return
	}

	c.lock.Lock()
	defer c.lock.Unlock()

	c.finishedAt = finishedAt
}

func ( c * Container ) SetFinishedAt ( finishedAt time . Time ) { if finishedAt . IsZero ( ) { return } c . lock . Lock ( ) defer c . lock . Unlock ( ) c . finishedAt = finishedAt }

// SetFinishedAt sets the timestamp for container's stopped time

SetFinishedAt sets the timestamp for container s stopped time


func (c *Container) GetCreatedAt() time.Time {
	c.lock.RLock()
	defer c.lock.RUnlock()

	return c.createdAt
}

func ( c * Container ) GetCreatedAt ( ) time . Time { c . lock . RLock ( ) defer c . lock . RUnlock ( ) return c . createdAt }

// GetCreatedAt sets the timestamp for container's creation time

GetCreatedAt sets the timestamp for container s creation time


func (c *Container) GetStartedAt() time.Time {
	c.lock.RLock()
	defer c.lock.RUnlock()

	return c.startedAt
}

func ( c * Container ) GetStartedAt ( ) time . Time { c . lock . RLock ( ) defer c . lock . RUnlock ( ) return c . startedAt }

// GetStartedAt sets the timestamp for container's start time

GetStartedAt sets the timestamp for container s start time


func (c *Container) GetFinishedAt() time.Time {
	c.lock.RLock()
	defer c.lock.RUnlock()

	return c.finishedAt
}

func ( c * Container ) GetFinishedAt ( ) time . Time { c . lock . RLock ( ) defer c . lock . RUnlock ( ) return c . finishedAt }

// GetFinishedAt sets the timestamp for container's stopped time

GetFinishedAt sets the timestamp for container s stopped time


func (c *Container) SetLabels(labels map[string]string) {
	c.lock.Lock()
	defer c.lock.Unlock()

	c.labels = labels
}

func ( c * Container ) SetLabels ( labels map [ string ] string ) { c . lock . Lock ( ) defer c . lock . Unlock ( ) c . labels = labels }

// SetLabels sets the labels for a container


func (c *Container) GetLabels() map[string]string {
	c.lock.RLock()
	defer c.lock.RUnlock()

	return c.labels
}

func ( c * Container ) GetLabels ( ) map [ string ] string { c . lock . RLock ( ) defer c . lock . RUnlock ( ) return c . labels }

// GetLabels gets the labels for a container


func (c *Container) SetKnownPortBindings(ports []PortBinding) {
	c.lock.Lock()
	defer c.lock.Unlock()

	c.KnownPortBindingsUnsafe = ports
}

func ( c * Container ) SetKnownPortBindings ( ports [ ] PortBinding ) { c . lock . Lock ( ) defer c . lock . Unlock ( ) c . KnownPortBindingsUnsafe = ports }

// SetKnownPortBindings sets the ports for a container


func (c *Container) GetKnownPortBindings() []PortBinding {
	c.lock.RLock()
	defer c.lock.RUnlock()

	return c.KnownPortBindingsUnsafe
}

func ( c * Container ) GetKnownPortBindings ( ) [ ] PortBinding { c . lock . RLock ( ) defer c . lock . RUnlock ( ) return c . KnownPortBindingsUnsafe }

// GetKnownPortBindings gets the ports for a container


func (c *Container) SetVolumes(volumes []types.MountPoint) {
	c.lock.Lock()
	defer c.lock.Unlock()

	c.VolumesUnsafe = volumes
}

func ( c * Container ) SetVolumes ( volumes [ ] types . MountPoint ) { c . lock . Lock ( ) defer c . lock . Unlock ( ) c . VolumesUnsafe = volumes }

// SetVolumes sets the volumes mounted in a container


func (c *Container) GetVolumes() []types.MountPoint {
	c.lock.RLock()
	defer c.lock.RUnlock()

	return c.VolumesUnsafe
}

func ( c * Container ) GetVolumes ( ) [ ] types . MountPoint { c . lock . RLock ( ) defer c . lock . RUnlock ( ) return c . VolumesUnsafe }

// GetVolumes returns the volumes mounted in a container


func (c *Container) SetNetworkSettings(networks *types.NetworkSettings) {
	c.lock.Lock()
	defer c.lock.Unlock()

	c.NetworkSettingsUnsafe = networks
}

func ( c * Container ) SetNetworkSettings ( networks * types . NetworkSettings ) { c . lock . Lock ( ) defer c . lock . Unlock ( ) c . NetworkSettingsUnsafe = networks }

// SetNetworkSettings sets the networks field in a container


func (c *Container) GetNetworkSettings() *types.NetworkSettings {
	c.lock.RLock()
	defer c.lock.RUnlock()

	return c.NetworkSettingsUnsafe
}

func ( c * Container ) GetNetworkSettings ( ) * types . NetworkSettings { c . lock . RLock ( ) defer c . lock . RUnlock ( ) return c . NetworkSettingsUnsafe }

// GetNetworkSettings returns the networks field in a container


func (c *Container) SetNetworkMode(networkMode string) {
	c.lock.Lock()
	defer c.lock.Unlock()

	c.NetworkModeUnsafe = networkMode
}

func ( c * Container ) SetNetworkMode ( networkMode string ) { c . lock . Lock ( ) defer c . lock . Unlock ( ) c . NetworkModeUnsafe = networkMode }

// SetNetworkMode sets the network mode of the container


func (c *Container) GetNetworkMode() string {
	c.lock.RLock()
	defer c.lock.RUnlock()

	return c.NetworkModeUnsafe
}

func ( c * Container ) GetNetworkMode ( ) string { c . lock . RLock ( ) defer c . lock . RUnlock ( ) return c . NetworkModeUnsafe }

// GetNetworkMode returns the network mode of the container


func (c *Container) SetHealthStatus(health HealthStatus) {
	c.lock.Lock()
	defer c.lock.Unlock()

	if c.Health.Status == health.Status {
		return
	}

	c.Health.Status = health.Status
	c.Health.Since = aws.Time(time.Now())
	c.Health.Output = health.Output

	// Set the health exit code if the health check failed
	if c.Health.Status == apicontainerstatus.ContainerUnhealthy {
		c.Health.ExitCode = health.ExitCode
	}
}

// SetHealthStatus sets the container health status


func (c *Container) GetHealthStatus() HealthStatus {
	c.lock.RLock()
	defer c.lock.RUnlock()

	// Copy the pointer to avoid race condition
	copyHealth := c.Health

	if c.Health.Since != nil {
		copyHealth.Since = aws.Time(aws.TimeValue(c.Health.Since))
	}

	return copyHealth
}

// GetHealthStatus returns the container health information


func (c *Container) BuildContainerDependency(contName string,
	satisfiedStatus apicontainerstatus.ContainerStatus,
	dependentStatus apicontainerstatus.ContainerStatus) {
	contDep := ContainerDependency{
		ContainerName:   contName,
		SatisfiedStatus: satisfiedStatus,
	}
	if _, ok := c.TransitionDependenciesMap[dependentStatus]; !ok {
		c.TransitionDependenciesMap[dependentStatus] = TransitionDependencySet{}
	}
	deps := c.TransitionDependenciesMap[dependentStatus]
	deps.ContainerDependencies = append(deps.ContainerDependencies, contDep)
	c.TransitionDependenciesMap[dependentStatus] = deps
}

func ( c * Container ) BuildContainerDependency ( contName string , satisfiedStatus apicontainerstatus . ContainerStatus , dependentStatus apicontainerstatus . ContainerStatus ) { contDep := ContainerDependency { ContainerName : contName , SatisfiedStatus : satisfiedStatus , } if _ , ok := c . TransitionDependenciesMap [ dependentStatus ] ; ! ok { c . TransitionDependenciesMap [ dependentStatus ] = TransitionDependencySet { } } deps := c . TransitionDependenciesMap [ dependentStatus ] deps . ContainerDependencies = append ( deps . ContainerDependencies , contDep ) c . TransitionDependenciesMap [ dependentStatus ] = deps }

// BuildContainerDependency adds a new dependency container and satisfied status
// to the dependent container

BuildContainerDependency adds a new dependency container and satisfied status to the dependent container


func (c *Container) updateAppliedStatusUnsafe(knownStatus apicontainerstatus.ContainerStatus) {
	if c.AppliedStatus == apicontainerstatus.ContainerStatusNone {
		return
	}

	// Check if the container transition has already finished
	if c.AppliedStatus <= knownStatus {
		c.AppliedStatus = apicontainerstatus.ContainerStatusNone
	}
}

// updateAppliedStatusUnsafe updates the container transitioning status


func (c *Container) SetAppliedStatus(status apicontainerstatus.ContainerStatus) bool {
	c.lock.Lock()
	defer c.lock.Unlock()

	if c.AppliedStatus != apicontainerstatus.ContainerStatusNone {
		// return false to indicate the set operation failed
		return false
	}

	c.AppliedStatus = status
	return true
}

// SetAppliedStatus sets the applied status of container and returns whether
// the container is already in a transition

SetAppliedStatus sets the applied status of container and returns whether the container is already in a transition


func (c *Container) GetAppliedStatus() apicontainerstatus.ContainerStatus {
	c.lock.RLock()
	defer c.lock.RUnlock()

	return c.AppliedStatus
}

func ( c * Container ) GetAppliedStatus ( ) apicontainerstatus . ContainerStatus { c . lock . RLock ( ) defer c . lock . RUnlock ( ) return c . AppliedStatus }

// GetAppliedStatus returns the transitioning status of container


func (c *Container) ShouldPullWithASMAuth() bool {
	c.lock.RLock()
	defer c.lock.RUnlock()

	return c.RegistryAuthentication != nil &&
		c.RegistryAuthentication.Type == AuthTypeASM &&
		c.RegistryAuthentication.ASMAuthData != nil
}

func ( c * Container ) ShouldPullWithASMAuth ( ) bool { c . lock . RLock ( ) defer c . lock . RUnlock ( ) return c . RegistryAuthentication != nil && c . RegistryAuthentication . Type == AuthTypeASM && c . RegistryAuthentication . ASMAuthData != nil }

// ShouldPullWithASMAuth returns true if this container needs to retrieve
// private registry authentication data from ASM

ShouldPullWithASMAuth returns true if this container needs to retrieve private registry authentication data from ASM


func (c *Container) SetASMDockerAuthConfig(dac types.AuthConfig) {
	c.RegistryAuthentication.ASMAuthData.SetDockerAuthConfig(dac)
}

func ( c * Container ) SetASMDockerAuthConfig ( dac types . AuthConfig ) { c . RegistryAuthentication . ASMAuthData . SetDockerAuthConfig ( dac ) }

// SetASMDockerAuthConfig add the docker auth config data to the
// RegistryAuthentication struct held by the container, this is then passed down
// to the docker client to pull the image

SetASMDockerAuthConfig add the docker auth config data to the RegistryAuthentication struct held by the container this is then passed down to the docker client to pull the image


func (c *Container) SetV3EndpointID(v3EndpointID string) {
	c.lock.Lock()
	defer c.lock.Unlock()

	c.V3EndpointID = v3EndpointID
}

func ( c * Container ) SetV3EndpointID ( v3EndpointID string ) { c . lock . Lock ( ) defer c . lock . Unlock ( ) c . V3EndpointID = v3EndpointID }

// SetV3EndpointID sets the v3 endpoint id of container


func (c *Container) GetV3EndpointID() string {
	c.lock.RLock()
	defer c.lock.RUnlock()

	return c.V3EndpointID
}

func ( c * Container ) GetV3EndpointID ( ) string { c . lock . RLock ( ) defer c . lock . RUnlock ( ) return c . V3EndpointID }

// GetV3EndpointID returns the v3 endpoint id of container


func (c *Container) InjectV3MetadataEndpoint() {
	c.lock.Lock()
	defer c.lock.Unlock()

	// don't assume that the environment variable map has been initialized by others
	if c.Environment == nil {
		c.Environment = make(map[string]string)
	}

	c.Environment[MetadataURIEnvironmentVariableName] =
		fmt.Sprintf(MetadataURIFormat, c.V3EndpointID)
}

// InjectV3MetadataEndpoint injects the v3 metadata endpoint as an environment variable for a container


func (c *Container) ShouldCreateWithSSMSecret() bool {
	c.lock.RLock()
	defer c.lock.RUnlock()

	// Secrets field will be nil if there is no secrets for container
	if c.Secrets == nil {
		return false
	}

	for _, secret := range c.Secrets {
		if secret.Provider == SecretProviderSSM {
			return true
		}
	}
	return false
}

// ShouldCreateWithSSMSecret returns true if this container needs to get secret
// value from SSM Parameter Store

ShouldCreateWithSSMSecret returns true if this container needs to get secret value from SSM Parameter Store


func (c *Container) ShouldCreateWithASMSecret() bool {
	c.lock.RLock()
	defer c.lock.RUnlock()

	// Secrets field will be nil if there is no secrets for container
	if c.Secrets == nil {
		return false
	}

	for _, secret := range c.Secrets {
		if secret.Provider == SecretProviderASM {
			return true
		}
	}
	return false
}

// ShouldCreateWithASMSecret returns true if this container needs to get secret
// value from AWS Secrets Manager

ShouldCreateWithASMSecret returns true if this container needs to get secret value from AWS Secrets Manager


func getMetadataFilePath(taskARN string, containerName string, dataDir string) (string, error) {
	taskID, err := getTaskIDfromARN(taskARN)
	// Empty task ID indicates malformed ARN (Should not happen)
	if err != nil {
		return "", fmt.Errorf("get metdata file path of task %s container %s: %v", taskARN, containerName, err)
	}
	return filepath.Join(dataDir, metadataJoinSuffix, taskID, containerName), nil
}

// getMetadataFilePath gives the metadata file path for any agent-managed container

getMetadataFilePath gives the metadata file path for any agent - managed container


func getTaskMetadataDir(taskARN string, dataDir string) (string, error) {
	taskID, err := getTaskIDfromARN(taskARN)
	if err != nil {
		return "", fmt.Errorf("get task metadata directory: %v", err)
	}
	return filepath.Join(dataDir, metadataJoinSuffix, taskID), err
}

func getTaskMetadataDir ( taskARN string , dataDir string ) ( string , error ) { taskID , err := getTaskIDfromARN ( taskARN ) if err != nil { return " " , fmt . Errorf ( " " , err ) } return filepath . Join ( dataDir , metadataJoinSuffix , taskID ) , err }

// getTaskMetadataDir acquires the directory with all of the metadata
// files of a given task

getTaskMetadataDir acquires the directory with all of the metadata files of a given task


func (b Conditional) MarshalJSON() ([]byte, error) {
	switch b {
	case ExplicitlyEnabled:
		return json.Marshal(true)
	case ExplicitlyDisabled:
		return json.Marshal(false)
	default:
		return json.Marshal(nil)
	}
}

func ( b Conditional ) MarshalJSON ( ) ( [ ] byte , error ) { switch b { case ExplicitlyEnabled : return json . Marshal ( true ) case ExplicitlyDisabled : return json . Marshal ( false ) default : return json . Marshal ( nil ) } }

// MarshalJSON is used to serialize the type to json, per the Marshaller interface

MarshalJSON is used to serialize the type to json per the Marshaller interface


func (b *Conditional) UnmarshalJSON(jsonData []byte) error {
	jsonString := string(jsonData)
	jsonBool, err := strconv.ParseBool(jsonString)
	if err != nil && jsonString != "null" {
		return err
	}

	if jsonString == "" || jsonString == "null" {
		*b = DefaultEnabled
	} else if jsonBool {
		*b = ExplicitlyEnabled
	} else {
		*b = ExplicitlyDisabled
	}

	return nil
}

func ( b * Conditional ) UnmarshalJSON ( jsonData [ ] byte ) error { jsonString := string ( jsonData ) jsonBool , err := strconv . ParseBool ( jsonString ) if err != nil && jsonString != " " { return err } if jsonString == " " || jsonString == " " { * b = DefaultEnabled } else if jsonBool { * b = ExplicitlyEnabled } else { * b = ExplicitlyDisabled } return nil }

// UnmarshalJSON is used to deserialize json types into Conditional, per the Unmarshaller interface

UnmarshalJSON is used to deserialize json types into Conditional per the Unmarshaller interface


func NewASMSecretResource(taskARN string,
	asmSecrets map[string]apicontainer.Secret,
	executionCredentialsID string,
	credentialsManager credentials.Manager,
	asmClientCreator factory.ClientCreator) *ASMSecretResource {

	s := &ASMSecretResource{
		taskARN:                taskARN,
		requiredSecrets:        asmSecrets,
		credentialsManager:     credentialsManager,
		executionCredentialsID: executionCredentialsID,
		asmClientCreator:       asmClientCreator,
	}

	s.initStatusToTransition()
	return s
}

func NewASMSecretResource ( taskARN string , asmSecrets map [ string ] apicontainer . Secret , executionCredentialsID string , credentialsManager credentials . Manager , asmClientCreator factory . ClientCreator ) * ASMSecretResource { s := & ASMSecretResource { taskARN : taskARN , requiredSecrets : asmSecrets , credentialsManager : credentialsManager , executionCredentialsID : executionCredentialsID , asmClientCreator : asmClientCreator , } s . initStatusToTransition ( ) return s }

// NewASMSecretResource creates a new ASMSecretResource object


func (secret *ASMSecretResource) Create() error {

	// To fail fast, check execution role first
	executionCredentials, ok := secret.credentialsManager.GetTaskCredentials(secret.getExecutionCredentialsID())
	if !ok {
		// No need to log here. managedTask.applyResourceState already does that
		err := errors.New("ASM secret resource: unable to find execution role credentials")
		secret.setTerminalReason(err.Error())
		return err
	}
	iamCredentials := executionCredentials.GetIAMRoleCredentials()

	var wg sync.WaitGroup

	// Get the maximum number of errors to be returned, which will be one error per goroutine
	errorEvents := make(chan error, len(secret.requiredSecrets))

	seelog.Infof("ASM secret resource: retrieving secrets for containers in task: [%s]", secret.taskARN)
	secret.secretData = make(map[string]string)

	for _, asmsecret := range secret.getRequiredSecrets() {
		wg.Add(1)
		// Spin up goroutine per secret to speed up processing time
		go secret.retrieveASMSecretValue(asmsecret, iamCredentials, &wg, errorEvents)
	}

	wg.Wait()
	close(errorEvents)

	if len(errorEvents) > 0 {
		var terminalReasons []string
		for err := range errorEvents {
			terminalReasons = append(terminalReasons, err.Error())
		}

		errorString := strings.Join(terminalReasons, ";")
		secret.setTerminalReason(errorString)
		return errors.New(errorString)
	}
	return nil
}

// It spins up multiple goroutines in order to retrieve values in parallel.

It spins up multiple goroutines in order to retrieve values in parallel .


func (secret *ASMSecretResource) retrieveASMSecretValue(apiSecret apicontainer.Secret, iamCredentials credentials.IAMRoleCredentials, wg *sync.WaitGroup, errorEvents chan error) {
	defer wg.Done()

	asmClient := secret.asmClientCreator.NewASMClient(apiSecret.Region, iamCredentials)
	seelog.Infof("ASM secret resource: retrieving resource for secret %v in region %s for task: [%s]", apiSecret.ValueFrom, apiSecret.Region, secret.taskARN)
	//for asm secret, ValueFrom can be arn or name
	secretValue, err := asm.GetSecretFromASM(apiSecret.ValueFrom, asmClient)
	if err != nil {
		errorEvents <- fmt.Errorf("fetching secret data from AWS Secrets Manager in region %s: %v", apiSecret.Region, err)
		return
	}

	secret.lock.Lock()
	defer secret.lock.Unlock()

	// put secret value in secretData
	secretKey := apiSecret.GetSecretResourceCacheKey()
	secret.secretData[secretKey] = secretValue
}

// retrieveASMSecretValue reads secret value from cache first, if not exists, call GetSecretFromASM to retrieve value
// AWS secrets Manager

retrieveASMSecretValue reads secret value from cache first if not exists call GetSecretFromASM to retrieve value AWS secrets Manager


func (secret *ASMSecretResource) getRequiredSecrets() map[string]apicontainer.Secret {
	secret.lock.RLock()
	defer secret.lock.RUnlock()

	return secret.requiredSecrets
}

func ( secret * ASMSecretResource ) getRequiredSecrets ( ) map [ string ] apicontainer . Secret { secret . lock . RLock ( ) defer secret . lock . RUnlock ( ) return secret . requiredSecrets }

// getRequiredSecrets returns the requiredSecrets field of asmsecret task resource


func (secret *ASMSecretResource) clearASMSecretValue() {
	secret.lock.Lock()
	defer secret.lock.Unlock()

	for key := range secret.secretData {
		delete(secret.secretData, key)
	}
}

func ( secret * ASMSecretResource ) clearASMSecretValue ( ) { secret . lock . Lock ( ) defer secret . lock . Unlock ( ) for key := range secret . secretData { delete ( secret . secretData , key ) } }

// clearASMSecretValue cycles through the collection of secret value data and
// removes them from the task

clearASMSecretValue cycles through the collection of secret value data and removes them from the task


func (secret *ASMSecretResource) MarshalJSON() ([]byte, error) {
	if secret == nil {
		return nil, errors.New("asmsecret resource is nil")
	}
	createdAt := secret.GetCreatedAt()
	return json.Marshal(ASMSecretResourceJSON{
		TaskARN:   secret.taskARN,
		CreatedAt: &createdAt,
		DesiredStatus: func() *ASMSecretStatus {
			desiredState := secret.GetDesiredStatus()
			s := ASMSecretStatus(desiredState)
			return &s
		}(),
		KnownStatus: func() *ASMSecretStatus {
			knownState := secret.GetKnownStatus()
			s := ASMSecretStatus(knownState)
			return &s
		}(),
		RequiredSecrets:        secret.getRequiredSecrets(),
		ExecutionCredentialsID: secret.getExecutionCredentialsID(),
	})
}

func ( secret * ASMSecretResource ) MarshalJSON ( ) ( [ ] byte , error ) { if secret == nil { return nil , errors . New ( " " ) } createdAt := secret . GetCreatedAt ( ) return json . Marshal ( ASMSecretResourceJSON { TaskARN : secret . taskARN , CreatedAt : & createdAt , DesiredStatus : func ( ) * ASMSecretStatus { desiredState := secret . GetDesiredStatus ( ) s := ASMSecretStatus ( desiredState ) return & s } ( ) , KnownStatus : func ( ) * ASMSecretStatus { knownState := secret . GetKnownStatus ( ) s := ASMSecretStatus ( knownState ) return & s } ( ) , RequiredSecrets : secret . getRequiredSecrets ( ) , ExecutionCredentialsID : secret . getExecutionCredentialsID ( ) , } ) }

// MarshalJSON serialises the ASMSecretResource struct to JSON


func (secret *ASMSecretResource) UnmarshalJSON(b []byte) error {
	temp := ASMSecretResourceJSON{}

	if err := json.Unmarshal(b, &temp); err != nil {
		return err
	}

	if temp.DesiredStatus != nil {
		secret.SetDesiredStatus(resourcestatus.ResourceStatus(*temp.DesiredStatus))
	}
	if temp.KnownStatus != nil {
		secret.SetKnownStatus(resourcestatus.ResourceStatus(*temp.KnownStatus))
	}
	if temp.CreatedAt != nil && !temp.CreatedAt.IsZero() {
		secret.SetCreatedAt(*temp.CreatedAt)
	}
	if temp.RequiredSecrets != nil {
		secret.requiredSecrets = temp.RequiredSecrets
	}
	secret.taskARN = temp.TaskARN
	secret.executionCredentialsID = temp.ExecutionCredentialsID

	return nil
}

func ( secret * ASMSecretResource ) UnmarshalJSON ( b [ ] byte ) error { temp := ASMSecretResourceJSON { } if err := json . Unmarshal ( b , & temp ) ; err != nil { return err } if temp . DesiredStatus != nil { secret . SetDesiredStatus ( resourcestatus . ResourceStatus ( * temp . DesiredStatus ) ) } if temp . KnownStatus != nil { secret . SetKnownStatus ( resourcestatus . ResourceStatus ( * temp . KnownStatus ) ) } if temp . CreatedAt != nil && ! temp . CreatedAt . IsZero ( ) { secret . SetCreatedAt ( * temp . CreatedAt ) } if temp . RequiredSecrets != nil { secret . requiredSecrets = temp . RequiredSecrets } secret . taskARN = temp . TaskARN secret . executionCredentialsID = temp . ExecutionCredentialsID return nil }

// UnmarshalJSON deserialises the raw JSON to a ASMSecretResource struct


func (c *control) Create(cgroupSpec *Spec) (cgroups.Cgroup, error) {
	// Validate incoming spec
	err := validateCgroupSpec(cgroupSpec)
	if err != nil {
		return nil, errors.Wrapf(err, "cgroup create: failed to validate spec")
	}

	// Create cgroup
	seelog.Infof("Creating cgroup %s", cgroupSpec.Root)
	controller, err := c.New(cgroups.V1, cgroups.StaticPath(cgroupSpec.Root), cgroupSpec.Specs)

	if err != nil {
		return nil, errors.Wrapf(err, "cgroup create: unable to create controller")
	}

	return controller, nil
}

func
(
c
*
control
)
Create
(
cgroupSpec
*
Spec
)
(
cgroups
.
Cgroup
,
error
)
{
// Validate incoming spec
err
:=
validateCgroupSpec
(
cgroupSpec
)
if
err
!=
{
return
,
errors
.
Wrapf
(
err
,
"
"
)
}
// Create cgroup
seelog
.
Infof
(
"
"
,
cgroupSpec
.
Root
)
controller
,
err
:=
c
.
New
(
cgroups
.
V1
,
cgroups
.
StaticPath
(
cgroupSpec
.
Root
)
,
cgroupSpec
.
Specs
)
if
err
!=
{
return
,
errors
.
Wrapf
(
err
,
"
"
)
}
return
controller
,
}

// Create creates a new cgroup based off the spec post validation


func (c *control) Remove(cgroupPath string) error {
	seelog.Debugf("Removing cgroup %s", cgroupPath)

	controller, err := c.Load(cgroups.V1, cgroups.StaticPath(cgroupPath))
	if err != nil {
		return errors.Wrapf(err, "cgroup remove: unable to obtain controller")
	}

	// Delete cgroup
	err = controller.Delete()
	if err != nil {
		return errors.Wrapf(err, "cgroup remove: unable to delete cgroup")
	}
	return nil
}

func
(
c
*
control
)
Remove
(
cgroupPath
string
)
error
{
seelog
.
Debugf
(
"
"
,
cgroupPath
)
controller
,
err
:=
c
.
Load
(
cgroups
.
V1
,
cgroups
.
StaticPath
(
cgroupPath
)
)
if
err
!=
{
return
errors
.
Wrapf
(
err
,
"
"
)
}
// Delete cgroup
err
=
controller
.
Delete
(
)
if
err
!=
{
return
errors
.
Wrapf
(
err
,
"
"
)
}
return
}


func (c *control) Exists(cgroupPath string) bool {
	seelog.Debugf("Checking existence of cgroup: %s", cgroupPath)

	controller, err := c.Load(cgroups.V1, cgroups.StaticPath(cgroupPath))
	if err != nil || controller == nil {
		return false
	}

	return true
}

func ( c * control ) Exists ( cgroupPath string ) bool { seelog . Debugf ( " " , cgroupPath ) controller , err := c . Load ( cgroups . V1 , cgroups . StaticPath ( cgroupPath ) ) if err != nil || controller == nil { return false } return true }

// Exists is used to verify the existence of a cgroup


func validateCgroupSpec(cgroupSpec *Spec) error {
	if cgroupSpec == nil {
		return errors.New("cgroup spec validator: empty cgroup spec")
	}

	if cgroupSpec.Root == "" {
		return errors.New("cgroup spec validator: invalid cgroup root")
	}

	// Validate the linux resource specs
	if cgroupSpec.Specs == nil {
		return errors.New("cgroup spec validator: empty linux resource spec")
	}
	return nil
}

func
validateCgroupSpec
(
cgroupSpec
*
Spec
)
error
{
if
cgroupSpec
==
{
return
errors
.
New
(
"
"
)
}
if
cgroupSpec
.
Root
==
"
"
{
return
errors
.
New
(
"
"
)
}
// Validate the linux resource specs
if
cgroupSpec
.
Specs
==
{
return
errors
.
New
(
"
"
)
}
return
}

// validateCgroupSpec checks the cgroup spec for valid path and specifications


func handleInactivityTimeout(reader io.ReadCloser, timeout time.Duration, cancelRequest func(), canceled *uint32) (io.ReadCloser, chan<- struct{}) {
	done := make(chan struct{})
	proxyReader := &proxyReader{ReadCloser: reader}
	go func() {
		var lastCallCount uint64
		for {
			select {
			case <-time.After(timeout):
			case <-done:
				return
			}
			curCallCount := proxyReader.callCount()
			if curCallCount == lastCallCount {
				atomic.AddUint32(canceled, 1)
				cancelRequest()
				return
			}
			lastCallCount = curCallCount
		}
	}()
	return proxyReader, done
}

func handleInactivityTimeout ( reader io . ReadCloser , timeout time . Duration , cancelRequest func ( ) , canceled * uint32 ) ( io . ReadCloser , chan <- struct { } ) { done := make ( chan struct { } ) proxyReader := & proxyReader { ReadCloser : reader } go func ( ) { var lastCallCount uint64 for { select { case <- time . After ( timeout ) : case <- done : return } curCallCount := proxyReader . callCount ( ) if curCallCount == lastCallCount { atomic . AddUint32 ( canceled , 1 ) cancelRequest ( ) return } lastCallCount = curCallCount } } ( ) return proxyReader , done }

// When pulling an image, the docker api will pull and then subsequently unzip the downloaded artifacts. Docker does
// not separate the "pull" from the "unpack" step. What this means is that this timeout doesn't 'tick' while unpacking
// the downloaded files. This only causes noticeable impact with large files, but we should investigate improving this.

When pulling an image the docker api will pull and then subsequently unzip the downloaded artifacts . Docker does not separate the pull from the unpack step . What this means is that this timeout doesn t tick while unpacking the downloaded files . This only causes noticeable impact with large files but we should investigate improving this .


func NewImageManager(cfg *config.Config, client dockerapi.DockerClient, state dockerstate.TaskEngineState) ImageManager {
	return &dockerImageManager{
		client:                             client,
		state:                              state,
		minimumAgeBeforeDeletion:           cfg.MinimumImageDeletionAge,
		numImagesToDelete:                  cfg.NumImagesToDeletePerCycle,
		imageCleanupTimeInterval:           cfg.ImageCleanupInterval,
		imagePullBehavior:                  cfg.ImagePullBehavior,
		imageCleanupExclusionList:          cfg.ImageCleanupExclusionList,
		deleteNonECSImagesEnabled:          cfg.DeleteNonECSImagesEnabled,
		nonECSContainerCleanupWaitDuration: cfg.TaskCleanupWaitDuration,
		numNonECSContainersToDelete:        cfg.NumNonECSContainersToDeletePerCycle,
	}
}

func NewImageManager ( cfg * config . Config , client dockerapi . DockerClient , state dockerstate . TaskEngineState ) ImageManager { return & dockerImageManager { client : client , state : state , minimumAgeBeforeDeletion : cfg . MinimumImageDeletionAge , numImagesToDelete : cfg . NumImagesToDeletePerCycle , imageCleanupTimeInterval : cfg . ImageCleanupInterval , imagePullBehavior : cfg . ImagePullBehavior , imageCleanupExclusionList : cfg . ImageCleanupExclusionList , deleteNonECSImagesEnabled : cfg . DeleteNonECSImagesEnabled , nonECSContainerCleanupWaitDuration : cfg . TaskCleanupWaitDuration , numNonECSContainersToDelete : cfg . NumNonECSContainersToDeletePerCycle , } }

// NewImageManager returns a new ImageManager


func (imageManager *dockerImageManager) RecordContainerReference(container *apicontainer.Container) error {
	// the image state has been updated, save the new state
	defer imageManager.saver.ForceSave()
	// On agent restart, container ID was retrieved from agent state file
	// TODO add setter and getter for modifying this
	if container.ImageID != "" {
		if !imageManager.addContainerReferenceToExistingImageState(container) {
			return fmt.Errorf("Failed to add container to existing image state")
		}
		return nil
	}

	if container.Image == "" {
		return fmt.Errorf("Invalid container reference: Empty image name")
	}

	// Inspect image for obtaining Container's Image ID
	imageInspected, err := imageManager.client.InspectImage(container.Image)
	if err != nil {
		seelog.Errorf("Error inspecting image %v: %v", container.Image, err)
		return err
	}

	container.ImageID = imageInspected.ID
	added := imageManager.addContainerReferenceToExistingImageState(container)
	if !added {
		imageManager.addContainerReferenceToNewImageState(container, imageInspected.Size)
	}
	return nil
}

// RecordContainerReference adds container reference to the corresponding imageState object


func (imageManager *dockerImageManager) RemoveContainerReferenceFromImageState(container *apicontainer.Container) error {
	// the image state has been updated, save the new state
	defer imageManager.saver.ForceSave()
	// this lock is for reading image states and finding the one that the container belongs to
	imageManager.updateLock.RLock()
	defer imageManager.updateLock.RUnlock()
	if container.ImageID == "" {
		return fmt.Errorf("Invalid container reference: Empty image id")
	}

	// Find image state that this container is part of, and remove the reference
	imageState, ok := imageManager.getImageState(container.ImageID)
	if !ok {
		return fmt.Errorf("Cannot find image state for the container to be removed")
	}
	// Found matching ImageState
	return imageState.RemoveContainerReference(container)
}

// RemoveContainerReferenceFromImageState removes container reference from the corresponding imageState object


func (imageManager *dockerImageManager) getImageState(containerImageID string) (*image.ImageState, bool) {
	for _, imageState := range imageManager.getAllImageStates() {
		if imageState.Image.ImageID == containerImageID {
			return imageState, true
		}
	}
	return nil, false
}

func ( imageManager * dockerImageManager ) getImageState ( containerImageID string ) ( * image . ImageState , bool ) { for _ , imageState := range imageManager . getAllImageStates ( ) { if imageState . Image . ImageID == containerImageID { return imageState , true } } return nil , false }

// getImageState returns the ImageState object that the container is referenced at


func (imageManager *dockerImageManager) removeImageState(imageStateToBeRemoved *image.ImageState) {
	for i, imageState := range imageManager.imageStates {
		if imageState.Image.ImageID == imageStateToBeRemoved.Image.ImageID {
			// Image State found; hence remove it
			seelog.Infof("Removing Image State: [%s] from Image Manager", imageState.String())
			imageManager.imageStates = append(imageManager.imageStates[:i], imageManager.imageStates[i+1:]...)
			return
		}
	}
}

func
(
imageManager
*
dockerImageManager
)
removeImageState
(
imageStateToBeRemoved
*
image
.
ImageState
)
{
for
i
,
imageState
:=
range
imageManager
.
imageStates
{
if
imageState
.
Image
.
ImageID
==
imageStateToBeRemoved
.
Image
.
ImageID
{
// Image State found; hence remove it
seelog
.
Infof
(
"
"
,
imageState
.
String
(
)
)
imageManager
.
imageStates
=
append
(
imageManager
.
imageStates
[
:
i
]
,
imageManager
.
imageStates
[
i
+
1
:
]
...
)
return
}
}
}

// removeImageState removes the imageState from the list of imageState objects in ImageManager


func (cfg *Config) Merge(rhs Config) *Config {
	left := reflect.ValueOf(cfg).Elem()
	right := reflect.ValueOf(&rhs).Elem()

	for i := 0; i < left.NumField(); i++ {
		leftField := left.Field(i)
		if utils.ZeroOrNil(leftField.Interface()) {
			leftField.Set(reflect.ValueOf(right.Field(i).Interface()))
		}
	}

	return cfg //make it chainable
}

func
(
cfg
*
Config
)
Merge
(
rhs
Config
)
*
Config
{
left
:=
reflect
.
ValueOf
(
cfg
)
.
Elem
(
)
right
:=
reflect
.
ValueOf
(
&
rhs
)
.
Elem
(
)
for
i
:=
0
;
i
<
left
.
NumField
(
)
;
i
++
{
leftField
:=
left
.
Field
(
i
)
if
utils
.
ZeroOrNil
(
leftField
.
Interface
(
)
)
{
leftField
.
Set
(
reflect
.
ValueOf
(
right
.
Field
(
i
)
.
Interface
(
)
)
)
}
}
return
cfg
//make it chainable
}

// Merge merges two config files, preferring the ones on the left. Any nil or
// zero values present in the left that are not present in the right will be
// overridden

Merge merges two config files preferring the ones on the left . Any nil or zero values present in the left that are not present in the right will be overridden


func NewConfig(ec2client ec2.EC2MetadataClient) (*Config, error) {
	var errs []error
	envConfig, err := environmentConfig() //Environment overrides all else
	if err != nil {
		errs = append(errs, err)
	}
	config := &envConfig

	if config.complete() {
		// No need to do file / network IO
		return config, nil
	}

	fcfg, err := fileConfig()
	if err != nil {
		errs = append(errs, err)
	}
	config.Merge(fcfg)

	config.Merge(userDataConfig(ec2client))

	if config.AWSRegion == "" {
		if config.NoIID {
			// get it from AWS SDK if we don't have instance identity document
			awsRegion, err := ec2client.Region()
			if err != nil {
				errs = append(errs, err)
			}
			config.AWSRegion = awsRegion
		} else {
			// Get it from metadata only if we need to (network io)
			config.Merge(ec2MetadataConfig(ec2client))
		}
	}

	return config, config.mergeDefaultConfig(errs)
}

// NewConfig returns a config struct created by merging environment variables,
// a config file, and EC2 Metadata info.
// The 'config' struct it returns can be used, even if an error is returned. An
// error is returned, however, if the config is incomplete in some way that is
// considered fatal.

NewConfig returns a config struct created by merging environment variables a config file and EC2 Metadata info . The config struct it returns can be used even if an error is returned . An error is returned however if the config is incomplete in some way that is considered fatal .


func (cfg *Config) trimWhitespace() {
	cfgElem := reflect.ValueOf(cfg).Elem()
	cfgStructField := reflect.Indirect(reflect.ValueOf(cfg)).Type()

	for i := 0; i < cfgElem.NumField(); i++ {
		cfgField := cfgElem.Field(i)
		if !cfgField.CanInterface() {
			continue
		}
		trimTag := cfgStructField.Field(i).Tag.Get("trim")
		if len(trimTag) == 0 {
			continue
		}

		if cfgField.Kind() != reflect.String {
			seelog.Warnf("Cannot trim non-string field type %v index %v", cfgField.Kind().String(), i)
			continue
		}
		str := cfgField.Interface().(string)
		cfgField.SetString(strings.TrimSpace(str))
	}
}

func ( cfg * Config ) trimWhitespace ( ) { cfgElem := reflect . ValueOf ( cfg ) . Elem ( ) cfgStructField := reflect . Indirect ( reflect . ValueOf ( cfg ) ) . Type ( ) for i := 0 ; i < cfgElem . NumField ( ) ; i ++ { cfgField := cfgElem . Field ( i ) if ! cfgField . CanInterface ( ) { continue } trimTag := cfgStructField . Field ( i ) . Tag . Get ( " " ) if len ( trimTag ) == 0 { continue } if cfgField . Kind ( ) != reflect . String { seelog . Warnf ( " " , cfgField . Kind ( ) . String ( ) , i ) continue } str := cfgField . Interface ( ) . ( string ) cfgField . SetString ( strings . TrimSpace ( str ) ) } }

// trimWhitespace trims whitespace from all string cfg values with the
// `trim` tag

trimWhitespace trims whitespace from all string cfg values with the trim tag


func (cfg *Config) validateAndOverrideBounds() error {
	err := cfg.checkMissingAndDepreciated()
	if err != nil {
		return err
	}

	if cfg.DockerStopTimeout < minimumDockerStopTimeout {
		return fmt.Errorf("config: invalid value for docker container stop timeout: %v", cfg.DockerStopTimeout.String())
	}

	if cfg.ContainerStartTimeout < minimumContainerStartTimeout {
		return fmt.Errorf("config: invalid value for docker container start timeout: %v", cfg.ContainerStartTimeout.String())
	}
	var badDrivers []string
	for _, driver := range cfg.AvailableLoggingDrivers {
		_, ok := dockerclient.LoggingDriverMinimumVersion[driver]
		if !ok {
			badDrivers = append(badDrivers, string(driver))
		}
	}
	if len(badDrivers) > 0 {
		return errors.New("Invalid logging drivers: " + strings.Join(badDrivers, ", "))
	}

	// If a value has been set for taskCleanupWaitDuration and the value is less than the minimum allowed cleanup duration,
	// print a warning and override it
	if cfg.TaskCleanupWaitDuration < minimumTaskCleanupWaitDuration {
		seelog.Warnf("Invalid value for image cleanup duration, will be overridden with the default value: %s. Parsed value: %v, minimum value: %v.", DefaultTaskCleanupWaitDuration.String(), cfg.TaskCleanupWaitDuration, minimumTaskCleanupWaitDuration)
		cfg.TaskCleanupWaitDuration = DefaultTaskCleanupWaitDuration
	}

	if cfg.ImagePullInactivityTimeout < minimumImagePullInactivityTimeout {
		seelog.Warnf("Invalid value for image pull inactivity timeout duration, will be overridden with the default value: %s. Parsed value: %v, minimum value: %v.", defaultImagePullInactivityTimeout.String(), cfg.ImagePullInactivityTimeout, minimumImagePullInactivityTimeout)
		cfg.ImagePullInactivityTimeout = defaultImagePullInactivityTimeout
	}

	if cfg.ImageCleanupInterval < minimumImageCleanupInterval {
		seelog.Warnf("Invalid value for image cleanup duration, will be overridden with the default value: %s. Parsed value: %v, minimum value: %v.", DefaultImageCleanupTimeInterval.String(), cfg.ImageCleanupInterval, minimumImageCleanupInterval)
		cfg.ImageCleanupInterval = DefaultImageCleanupTimeInterval
	}

	if cfg.NumImagesToDeletePerCycle < minimumNumImagesToDeletePerCycle {
		seelog.Warnf("Invalid value for number of images to delete for image cleanup, will be overridden with the default value: %d. Parsed value: %d, minimum value: %d.", DefaultImageDeletionAge, cfg.NumImagesToDeletePerCycle, minimumNumImagesToDeletePerCycle)
		cfg.NumImagesToDeletePerCycle = DefaultNumImagesToDeletePerCycle
	}

	if cfg.TaskMetadataSteadyStateRate <= 0 || cfg.TaskMetadataBurstRate <= 0 {
		seelog.Warnf("Invalid values for rate limits, will be overridden with default values: %d,%d.", DefaultTaskMetadataSteadyStateRate, DefaultTaskMetadataBurstRate)
		cfg.TaskMetadataSteadyStateRate = DefaultTaskMetadataSteadyStateRate
		cfg.TaskMetadataBurstRate = DefaultTaskMetadataBurstRate
	}

	// check the PollMetrics specific configurations
	cfg.pollMetricsOverrides()

	cfg.platformOverrides()

	return nil
}

// validateAndOverrideBounds performs validation over members of the Config struct
// and check the value against the minimum required value.

validateAndOverrideBounds performs validation over members of the Config struct and check the value against the minimum required value .


func NewTaskStatsResponse(taskARN string,
	state dockerstate.TaskEngineState,
	statsEngine stats.Engine) (map[string]*types.StatsJSON, error) {

	containerMap, ok := state.ContainerMapByArn(taskARN)
	if !ok {
		return nil, errors.Errorf(
			"v2 task stats response: unable to lookup containers for task %s",
			taskARN)
	}

	resp := make(map[string]*types.StatsJSON)
	for _, dockerContainer := range containerMap {
		containerID := dockerContainer.DockerID
		dockerStats, err := statsEngine.ContainerDockerStats(taskARN, containerID)
		if err != nil {
			seelog.Warnf("V2 task stats response: Unable to get stats for container '%s' for task '%s': %v",
				containerID, taskARN, err)
			resp[containerID] = nil
			continue
		}

		resp[containerID] = dockerStats
	}

	return resp, nil
}

func NewTaskStatsResponse ( taskARN string , state dockerstate . TaskEngineState , statsEngine stats . Engine ) ( map [ string ] * types . StatsJSON , error ) { containerMap , ok := state . ContainerMapByArn ( taskARN ) if ! ok { return nil , errors . Errorf ( " " , taskARN ) } resp := make ( map [ string ] * types . StatsJSON ) for _ , dockerContainer := range containerMap { containerID := dockerContainer . DockerID dockerStats , err := statsEngine . ContainerDockerStats ( taskARN , containerID ) if err != nil { seelog . Warnf ( " " , containerID , taskARN , err ) resp [ containerID ] = nil continue } resp [ containerID ] = dockerStats } return resp , nil }

// NewTaskStatsResponse returns a new task stats response object


func NewSession(ctx context.Context,
	config *config.Config,
	deregisterInstanceEventStream *eventstream.EventStream,
	containerInstanceArn string,
	credentialsProvider *credentials.Credentials,
	ecsClient api.ECSClient,
	taskEngineState dockerstate.TaskEngineState,
	stateManager statemanager.StateManager,
	taskEngine engine.TaskEngine,
	credentialsManager rolecredentials.Manager,
	taskHandler *eventhandler.TaskHandler) Session {
	resources := newSessionResources(credentialsProvider)
	backoff := retry.NewExponentialBackoff(connectionBackoffMin, connectionBackoffMax,
		connectionBackoffJitter, connectionBackoffMultiplier)
	derivedContext, cancel := context.WithCancel(ctx)

	return &session{
		agentConfig:                     config,
		deregisterInstanceEventStream:   deregisterInstanceEventStream,
		containerInstanceARN:            containerInstanceArn,
		credentialsProvider:             credentialsProvider,
		ecsClient:                       ecsClient,
		state:                           taskEngineState,
		stateManager:                    stateManager,
		taskEngine:                      taskEngine,
		credentialsManager:              credentialsManager,
		taskHandler:                     taskHandler,
		ctx:                             derivedContext,
		cancel:                          cancel,
		backoff:                         backoff,
		resources:                       resources,
		_heartbeatTimeout:               heartbeatTimeout,
		_heartbeatJitter:                heartbeatJitter,
		_inactiveInstanceReconnectDelay: inactiveInstanceReconnectDelay,
	}
}

func NewSession ( ctx context . Context , config * config . Config , deregisterInstanceEventStream * eventstream . EventStream , containerInstanceArn string , credentialsProvider * credentials . Credentials , ecsClient api . ECSClient , taskEngineState dockerstate . TaskEngineState , stateManager statemanager . StateManager , taskEngine engine . TaskEngine , credentialsManager rolecredentials . Manager , taskHandler * eventhandler . TaskHandler ) Session { resources := newSessionResources ( credentialsProvider ) backoff := retry . NewExponentialBackoff ( connectionBackoffMin , connectionBackoffMax , connectionBackoffJitter , connectionBackoffMultiplier ) derivedContext , cancel := context . WithCancel ( ctx ) return & session { agentConfig : config , deregisterInstanceEventStream : deregisterInstanceEventStream , containerInstanceARN : containerInstanceArn , credentialsProvider : credentialsProvider , ecsClient : ecsClient , state : taskEngineState , stateManager : stateManager , taskEngine : taskEngine , credentialsManager : credentialsManager , taskHandler : taskHandler , ctx : derivedContext , cancel : cancel , backoff : backoff , resources : resources , _heartbeatTimeout : heartbeatTimeout , _heartbeatJitter : heartbeatJitter , _inactiveInstanceReconnectDelay : inactiveInstanceReconnectDelay , } }

// NewSession creates a new Session object


func (acsSession *session) startSessionOnce() error {
	acsEndpoint, err := acsSession.ecsClient.DiscoverPollEndpoint(acsSession.containerInstanceARN)
	if err != nil {
		seelog.Errorf("acs: unable to discover poll endpoint, err: %v", err)
		return err
	}

	url := acsWsURL(acsEndpoint, acsSession.agentConfig.Cluster, acsSession.containerInstanceARN, acsSession.taskEngine, acsSession.resources)
	client := acsSession.resources.createACSClient(url, acsSession.agentConfig)
	defer client.Close()

	return acsSession.startACSSession(client)
}

func ( acsSession * session ) startSessionOnce ( ) error { acsEndpoint , err := acsSession . ecsClient . DiscoverPollEndpoint ( acsSession . containerInstanceARN ) if err != nil { seelog . Errorf ( " " , err ) return err } url := acsWsURL ( acsEndpoint , acsSession . agentConfig . Cluster , acsSession . containerInstanceARN , acsSession . taskEngine , acsSession . resources ) client := acsSession . resources . createACSClient ( url , acsSession . agentConfig ) defer client . Close ( ) return acsSession . startACSSession ( client ) }

// startSessionOnce creates a session with ACS and handles requests using the passed
// in arguments

startSessionOnce creates a session with ACS and handles requests using the passed in arguments


func (acsSession *session) startACSSession(client wsclient.ClientServer) error {
	cfg := acsSession.agentConfig

	refreshCredsHandler := newRefreshCredentialsHandler(acsSession.ctx, cfg.Cluster, acsSession.containerInstanceARN,
		client, acsSession.credentialsManager, acsSession.taskEngine)
	defer refreshCredsHandler.clearAcks()
	refreshCredsHandler.start()
	defer refreshCredsHandler.stop()

	client.AddRequestHandler(refreshCredsHandler.handlerFunc())

	// Add handler to ack ENI attach message
	eniAttachHandler := newAttachENIHandler(
		acsSession.ctx,
		cfg.Cluster,
		acsSession.containerInstanceARN,
		client,
		acsSession.state,
		acsSession.stateManager,
	)
	eniAttachHandler.start()
	defer eniAttachHandler.stop()

	client.AddRequestHandler(eniAttachHandler.handlerFunc())

	// Add request handler for handling payload messages from ACS
	payloadHandler := newPayloadRequestHandler(
		acsSession.ctx,
		acsSession.taskEngine,
		acsSession.ecsClient,
		cfg.Cluster,
		acsSession.containerInstanceARN,
		client,
		acsSession.stateManager,
		refreshCredsHandler,
		acsSession.credentialsManager,
		acsSession.taskHandler)
	// Clear the acks channel on return because acks of messageids don't have any value across sessions
	defer payloadHandler.clearAcks()
	payloadHandler.start()
	defer payloadHandler.stop()

	client.AddRequestHandler(payloadHandler.handlerFunc())

	// Ignore heartbeat messages; anyMessageHandler gets 'em
	client.AddRequestHandler(func(*ecsacs.HeartbeatMessage) {})

	updater.AddAgentUpdateHandlers(client, cfg, acsSession.stateManager, acsSession.taskEngine)

	err := client.Connect()
	if err != nil {
		seelog.Errorf("Error connecting to ACS: %v", err)
		return err
	}
	seelog.Info("Connected to ACS endpoint")
	// Start inactivity timer for closing the connection
	timer := newDisconnectionTimer(client, acsSession.heartbeatTimeout(), acsSession.heartbeatJitter())
	// Any message from the server resets the disconnect timeout
	client.SetAnyRequestHandler(anyMessageHandler(timer, client))
	defer timer.Stop()

	acsSession.resources.connectedToACS()

	backoffResetTimer := time.AfterFunc(
		retry.AddJitter(acsSession.heartbeatTimeout(), acsSession.heartbeatJitter()), func() {
			// If we do not have an error connecting and remain connected for at
			// least 1 or so minutes, reset the backoff. This prevents disconnect
			// errors that only happen infrequently from damaging the reconnect
			// delay as significantly.
			acsSession.backoff.Reset()
		})
	defer backoffResetTimer.Stop()

	serveErr := make(chan error, 1)
	go func() {
		serveErr <- client.Serve()
	}()

	for {
		select {
		case <-acsSession.ctx.Done():
			// Stop receiving and sending messages from and to ACS when
			// the context received from the main function is canceled
			return acsSession.ctx.Err()
		case err := <-serveErr:
			// Stop receiving and sending messages from and to ACS when
			// client.Serve returns an error. This can happen when the
			// the connection is closed by ACS or the agent
			return err
		}
	}
}

// startACSSession starts a session with ACS. It adds request handlers for various
// kinds of messages expected from ACS. It returns on server disconnection or when
// the context is cancelled

startACSSession starts a session with ACS . It adds request handlers for various kinds of messages expected from ACS . It returns on server disconnection or when the context is cancelled


func (acsSession *session) waitForDuration(delay time.Duration) bool {
	reconnectTimer := time.NewTimer(delay)
	select {
	case <-reconnectTimer.C:
		return true
	case <-acsSession.ctx.Done():
		reconnectTimer.Stop()
		return false
	}
}

func ( acsSession * session ) waitForDuration ( delay time . Duration ) bool { reconnectTimer := time . NewTimer ( delay ) select { case <- reconnectTimer . C : return true case <- acsSession . ctx . Done ( ) : reconnectTimer . Stop ( ) return false } }

// waitForDuration waits for the specified duration of time. If the wait is interrupted,
// it returns a false value. Else, it returns true, indicating completion of wait time.

waitForDuration waits for the specified duration of time . If the wait is interrupted it returns a false value . Else it returns true indicating completion of wait time .


func (acsResources *acsSessionResources) createACSClient(url string, cfg *config.Config) wsclient.ClientServer {
	return acsclient.New(url, cfg, acsResources.credentialsProvider, wsRWTimeout)
}

func ( acsResources * acsSessionResources ) createACSClient ( url string , cfg * config . Config ) wsclient . ClientServer { return acsclient . New ( url , cfg , acsResources . credentialsProvider , wsRWTimeout ) }

// createACSClient creates the ACS Client using the specified URL


func acsWsURL(endpoint, cluster, containerInstanceArn string, taskEngine engine.TaskEngine, acsSessionState sessionState) string {
	acsURL := endpoint
	if endpoint[len(endpoint)-1] != '/' {
		acsURL += "/"
	}
	acsURL += "ws"
	query := url.Values{}
	query.Set("clusterArn", cluster)
	query.Set("containerInstanceArn", containerInstanceArn)
	query.Set("agentHash", version.GitHashString())
	query.Set("agentVersion", version.Version)
	query.Set("seqNum", "1")
	if dockerVersion, err := taskEngine.Version(); err == nil {
		query.Set("dockerVersion", "DockerVersion: "+dockerVersion)
	}
	query.Set(sendCredentialsURLParameterName, acsSessionState.getSendCredentialsURLParameter())
	return acsURL + "?" + query.Encode()
}

func acsWsURL ( endpoint , cluster , containerInstanceArn string , taskEngine engine . TaskEngine , acsSessionState sessionState ) string { acsURL := endpoint if endpoint [ len ( endpoint ) - 1 ] != '/' { acsURL += " " } acsURL += " " query := url . Values { } query . Set ( " " , cluster ) query . Set ( " " , containerInstanceArn ) query . Set ( " " , version . GitHashString ( ) ) query . Set ( " " , version . Version ) query . Set ( " " , " " ) if dockerVersion , err := taskEngine . Version ( ) ; err == nil { query . Set ( " " , " " + dockerVersion ) } query . Set ( sendCredentialsURLParameterName , acsSessionState . getSendCredentialsURLParameter ( ) ) return acsURL + " " + query . Encode ( ) }

// acsWsURL returns the websocket url for ACS given the endpoint


func newDisconnectionTimer(client wsclient.ClientServer, timeout time.Duration, jitter time.Duration) ttime.Timer {
	timer := time.AfterFunc(retry.AddJitter(timeout, jitter), func() {
		seelog.Warn("ACS Connection hasn't had any activity for too long; closing connection")
		if err := client.Close(); err != nil {
			seelog.Warnf("Error disconnecting: %v", err)
		}
		seelog.Info("Disconnected from ACS")
	})

	return timer
}

func newDisconnectionTimer ( client wsclient . ClientServer , timeout time . Duration , jitter time . Duration ) ttime . Timer { timer := time . AfterFunc ( retry . AddJitter ( timeout , jitter ) , func ( ) { seelog . Warn ( " " ) if err := client . Close ( ) ; err != nil { seelog . Warnf ( " " , err ) } seelog . Info ( " " ) } ) return timer }

// newDisconnectionTimer creates a new time object, with a callback to
// disconnect from ACS on inactivity

newDisconnectionTimer creates a new time object with a callback to disconnect from ACS on inactivity


func anyMessageHandler(timer ttime.Timer, client wsclient.ClientServer) func(interface{}) {
	return func(interface{}) {
		seelog.Debug("ACS activity occurred")
		// Reset read deadline as there's activity on the channel
		if err := client.SetReadDeadline(time.Now().Add(wsRWTimeout)); err != nil {
			seelog.Warnf("Unable to extend read deadline for ACS connection: %v", err)
		}

		// Reset heartbeat timer
		timer.Reset(retry.AddJitter(heartbeatTimeout, heartbeatJitter))
	}
}

// anyMessageHandler handles any server message. Any server message means the
// connection is active and thus the heartbeat disconnect should not occur

anyMessageHandler handles any server message . Any server message means the connection is active and thus the heartbeat disconnect should not occur


func validateIPRules() error {
	var iptable *iptables.IPTables
	var err error

	if iptable, err = iptables.NewWithProtocol(iptables.ProtocolIPv4); err != nil {
		return err
	}

	// Print detailed info for debugging.
	str, _ := iptable.ListChains("nat")
	fmt.Printf("List Chains:%v", str)

	strs, _ := iptable.Stats("nat", ingressChain)
	for _, str = range strs {
		fmt.Printf("Ingress chain stats:%v", str)
	}
	strs, _ = iptable.Stats("nat", egressChain)
	for _, str = range strs {
		fmt.Printf("Egress chain stats:%v", str)
	}

	if exist, err := iptable.Exists("nat", ingressChain, "-p", "tcp", "-m", "multiport", "--dports",
		appPorts, "-j", "REDIRECT", "--to-port", proxyIngressPort); !exist {
		return fmt.Errorf("failed to set rules to redirect app ports to proxy: %v\n", err)
	}

	if exist, err := iptable.Exists("nat", "PREROUTING", "-p", "tcp", "-m", "addrtype", "!",
		"--src-type", "LOCAL", "-j", ingressChain); !exist {
		return fmt.Errorf("failed to set rule to jump from PREROUTING to ingress chain: %v\n", err)
	}

	if exist, err := iptable.Exists("nat", egressChain, "-m", "owner", "--gid-owner", gid, "-j", "RETURN"); !exist {
		return fmt.Errorf("failed to set ignoredGID: %v\n", err)
	}

	if exist, err := iptable.Exists("nat", egressChain, "-p", "tcp", "-m", "multiport", "--dports",
		egressIgnoredPorts, "-j", "RETURN"); !exist {
		return fmt.Errorf("failed to set egressIgnoredPorts: %v\n", err)
	}

	if exist, err := iptable.Exists("nat", egressChain, "-p", "tcp", "-d", egressIgnoredIPv4Addresses,
		"-j", "RETURN"); !exist {
		return fmt.Errorf("failed to set egressIgnoredIPv4IPs: %v\n", err)
	}

	if exist, err := iptable.Exists("nat", egressChain, "-p", "tcp", "-j", "REDIRECT", "--to",
		proxyEgressPort); !exist {
		return fmt.Errorf("failed to set rule to redirect traffic to proxyEgressPort: %v\n", err)
	}

	if exist, err := iptable.Exists("nat", "OUTPUT", "-p", "tcp", "-m", "addrtype", "!",
		"--dst-type", "LOCAL", "-j", egressChain); !exist {
		return fmt.Errorf("failed to set rule to jump from OUTPUT to egress chain: %v\n", err)
	}

	return nil
}

func
validateIPRules
(
)
error
{
var
iptable
*
iptables
.
IPTables
var
err
error
if
iptable
,
err
=
iptables
.
NewWithProtocol
(
iptables
.
ProtocolIPv4
)
;
err
!=
{
return
err
}
// Print detailed info for debugging.
str
,
_
:=
iptable
.
ListChains
(
"
"
)
fmt
.
Printf
(
"
"
,
str
)
strs
,
_
:=
iptable
.
Stats
(
"
"
,
ingressChain
)
for
_
,
str
=
range
strs
{
fmt
.
Printf
(
"
"
,
str
)
}
strs
,
_
=
iptable
.
Stats
(
"
"
,
egressChain
)
for
_
,
str
=
range
strs
{
fmt
.
Printf
(
"
"
,
str
)
}
if
exist
,
err
:=
iptable
.
Exists
(
"
"
,
ingressChain
,
"
"
,
"
"
,
"
"
,
"
"
,
"
"
,
appPorts
,
"
"
,
"
"
,
"
"
,
proxyIngressPort
)
;
!
exist
{
return
fmt
.
Errorf
(
"
\n
"
,
err
)
}
if
exist
,
err
:=
iptable
.
Exists
(
"
"
,
"
"
,
"
"
,
"
"
,
"
"
,
"
"
,
"
"
,
"
"
,
"
"
,
"
"
,
ingressChain
)
;
!
exist
{
return
fmt
.
Errorf
(
"
\n
"
,
err
)
}
if
exist
,
err
:=
iptable
.
Exists
(
"
"
,
egressChain
,
"
"
,
"
"
,
"
"
,
gid
,
"
"
,
"
"
)
;
!
exist
{
return
fmt
.
Errorf
(
"
\n
"
,
err
)
}
if
exist
,
err
:=
iptable
.
Exists
(
"
"
,
egressChain
,
"
"
,
"
"
,
"
"
,
"
"
,
"
"
,
egressIgnoredPorts
,
"
"
,
"
"
)
;
!
exist
{
return
fmt
.
Errorf
(
"
\n
"
,
err
)
}
if
exist
,
err
:=
iptable
.
Exists
(
"
"
,
egressChain
,
"
"
,
"
"
,
"
"
,
egressIgnoredIPv4Addresses
,
"
"
,
"
"
)
;
!
exist
{
return
fmt
.
Errorf
(
"
\n
"
,
err
)
}
if
exist
,
err
:=
iptable
.
Exists
(
"
"
,
egressChain
,
"
"
,
"
"
,
"
"
,
"
"
,
"
"
,
proxyEgressPort
)
;
!
exist
{
return
fmt
.
Errorf
(
"
\n
"
,
err
)
}
if
exist
,
err
:=
iptable
.
Exists
(
"
"
,
"
"
,
"
"
,
"
"
,
"
"
,
"
"
,
"
"
,
"
"
,
"
"
,
"
"
,
egressChain
)
;
!
exist
{
return
fmt
.
Errorf
(
"
\n
"
,
err
)
}
return
}

// validateIPRules validates IP rules created in the container network namespace.

validateIPRules validates IP rules created in the container network namespace .


func WriteJSONToResponse(w http.ResponseWriter, httpStatusCode int, responseJSON []byte, requestType string) {
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(httpStatusCode)
	_, err := w.Write(responseJSON)
	if err != nil {
		seelog.Errorf(
			"Unable to write %s json response message to ResponseWriter",
			requestType)
	}
}

func WriteJSONToResponse ( w http . ResponseWriter , httpStatusCode int , responseJSON [ ] byte , requestType string ) { w . Header ( ) . Set ( " " , " " ) w . WriteHeader ( httpStatusCode ) _ , err := w . Write ( responseJSON ) if err != nil { seelog . Errorf ( " " , requestType ) } }

// WriteJSONToResponse writes the header, JSON response to a ResponseWriter, and
// log the error if necessary.

WriteJSONToResponse writes the header JSON response to a ResponseWriter and log the error if necessary .


func ValueFromRequest(r *http.Request, field string) (string, bool) {
	values := r.URL.Query()
	_, exists := values[field]
	return values.Get(field), exists
}

func ValueFromRequest ( r * http . Request , field string ) ( string , bool ) { values := r . URL . Query ( ) _ , exists := values [ field ] return values . Get ( field ) , exists }

// ValueFromRequest returns the value of a field in the http request. The boolean value is
// set to true if the field exists in the query.

ValueFromRequest returns the value of a field in the http request . The boolean value is set to true if the field exists in the query .


func GetMuxValueFromRequest(r *http.Request, gorillaMuxName string) (string, bool) {
	vars := mux.Vars(r)
	val, ok := vars[gorillaMuxName]
	return val, ok
}

func GetMuxValueFromRequest ( r * http . Request , gorillaMuxName string ) ( string , bool ) { vars := mux . Vars ( r ) val , ok := vars [ gorillaMuxName ] return val , ok }

// GetMuxValueFromRequest extracts the mux value from the request using a gorilla
// mux name

GetMuxValueFromRequest extracts the mux value from the request using a gorilla mux name


func LimitReachedHandler(auditLogger audit.AuditLogger) func(http.ResponseWriter, *http.Request) {
	return func(w http.ResponseWriter, r *http.Request) {
		logRequest := request.LogRequest{
			Request: r,
		}
		auditLogger.Log(logRequest, http.StatusTooManyRequests, "")
	}
}

func LimitReachedHandler ( auditLogger audit . AuditLogger ) func ( http . ResponseWriter , * http . Request ) { return func ( w http . ResponseWriter , r * http . Request ) { logRequest := request . LogRequest { Request : r , } auditLogger . Log ( logRequest , http . StatusTooManyRequests , " " ) } }

// LimitReachedHandler logs the throttled request in the credentials audit log


func (td *TransitionDependenciesMap) UnmarshalJSON(b []byte) error {
	depMap := make(map[apicontainerstatus.ContainerStatus]TransitionDependencySet)
	err := json.Unmarshal(b, &depMap)
	if err == nil {
		*td = depMap
		return nil
	}
	seelog.Debugf("Unmarshal 'TransitionDependencySet': %s, not a map: %v", string(b), err)
	// Unmarshal to deprecated 'TransitionDependencySet' and then convert to a map
	tdSet := TransitionDependencySet{}
	if err := json.Unmarshal(b, &tdSet); err != nil {
		return errors.Wrapf(err,
			"Unmarshal 'TransitionDependencySet': does not comply with any of the dependency types")
	}
	for _, dep := range tdSet.ContainerDependencies {
		dependentStatus := dep.DependentStatus
		// no need for DependentStatus field anymore, since it becomes the map's key
		dep.DependentStatus = 0
		if _, ok := depMap[dependentStatus]; !ok {
			depMap[dependentStatus] = TransitionDependencySet{}
		}
		deps := depMap[dependentStatus]
		deps.ContainerDependencies = append(deps.ContainerDependencies, dep)
		depMap[dependentStatus] = deps
	}
	*td = depMap
	return nil
}

// UnmarshalJSON decodes the TransitionDependencySet tag in the JSON encoded string
// into the TransitionDependenciesMap object

UnmarshalJSON decodes the TransitionDependencySet tag in the JSON encoded string into the TransitionDependenciesMap object


func (s *SequentialWaitGroup) Add(sequence int64, delta int) {
	s.mutex.Lock()
	defer s.mutex.Unlock()

	_, ok := s.semaphores[sequence]
	if ok {
		s.semaphores[sequence] += delta
	} else {
		s.semaphores[sequence] = delta
	}
	if s.semaphores[sequence] <= 0 {
		delete(s.semaphores, sequence)
		s.change.Broadcast()
	}
}

func ( s * SequentialWaitGroup ) Add ( sequence int64 , delta int ) { s . mutex . Lock ( ) defer s . mutex . Unlock ( ) _ , ok := s . semaphores [ sequence ] if ok { s . semaphores [ sequence ] += delta } else { s . semaphores [ sequence ] = delta } if s . semaphores [ sequence ] <= 0 { delete ( s . semaphores , sequence ) s . change . Broadcast ( ) } }

// Add adds the given delta to the waitgroup at the given sequence


func (s *SequentialWaitGroup) Done(sequence int64) {
	s.mutex.Lock()
	defer s.mutex.Unlock()
	_, ok := s.semaphores[sequence]
	if ok {
		s.semaphores[sequence]--
		if s.semaphores[sequence] == 0 {
			delete(s.semaphores, sequence)
			s.change.Broadcast()
		}
	}
}

func ( s * SequentialWaitGroup ) Done ( sequence int64 ) { s . mutex . Lock ( ) defer s . mutex . Unlock ( ) _ , ok := s . semaphores [ sequence ] if ok { s . semaphores [ sequence ] -- if s . semaphores [ sequence ] == 0 { delete ( s . semaphores , sequence ) s . change . Broadcast ( ) } } }

// Done decrements the waitgroup at the given sequence by one


func NewMockCgroup(ctrl *gomock.Controller) *MockCgroup {
	mock := &MockCgroup{ctrl: ctrl}
	mock.recorder = &MockCgroupMockRecorder{mock}
	return mock
}

func NewMockCgroup ( ctrl * gomock . Controller ) * MockCgroup { mock := & MockCgroup { ctrl : ctrl } mock . recorder = & MockCgroupMockRecorder { mock } return mock }

// NewMockCgroup creates a new mock instance


func (m *MockCgroup) Add(arg0 cgroups.Process) error {
	ret := m.ctrl.Call(m, "Add", arg0)
	ret0, _ := ret[0].(error)
	return ret0
}

func ( m * MockCgroup ) Add ( arg0 cgroups . Process ) error { ret := m . ctrl . Call ( m , " " , arg0 ) ret0 , _ := ret [ 0 ] . ( error ) return ret0 }


func (mr *MockCgroupMockRecorder) Add(arg0 interface{}) *gomock.Call {
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Add", reflect.TypeOf((*MockCgroup)(nil).Add), arg0)
}

func ( mr * MockCgroupMockRecorder ) Add ( arg0 interface { } ) * gomock . Call { return mr . mock . ctrl . RecordCallWithMethodType ( mr . mock , " " , reflect . TypeOf ( ( * MockCgroup ) ( nil ) . Add ) , arg0 ) }

// Add indicates an expected call of Add


func (mr *MockCgroupMockRecorder) Delete() *gomock.Call {
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockCgroup)(nil).Delete))
}

func ( mr * MockCgroupMockRecorder ) Delete ( ) * gomock . Call { return mr . mock . ctrl . RecordCallWithMethodType ( mr . mock , " " , reflect . TypeOf ( ( * MockCgroup ) ( nil ) . Delete ) ) }

// Delete indicates an expected call of Delete


func (m *MockCgroup) MoveTo(arg0 cgroups.Cgroup) error {
	ret := m.ctrl.Call(m, "MoveTo", arg0)
	ret0, _ := ret[0].(error)
	return ret0
}

func ( m * MockCgroup ) MoveTo ( arg0 cgroups . Cgroup ) error { ret := m . ctrl . Call ( m , " " , arg0 ) ret0 , _ := ret [ 0 ] . ( error ) return ret0 }


func (m *MockCgroup) OOMEventFD() (uintptr, error) {
	ret := m.ctrl.Call(m, "OOMEventFD")
	ret0, _ := ret[0].(uintptr)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

func ( m * MockCgroup ) OOMEventFD ( ) ( uintptr , error ) { ret := m . ctrl . Call ( m , " " ) ret0 , _ := ret [ 0 ] . ( uintptr ) ret1 , _ := ret [ 1 ] . ( error ) return ret0 , ret1 }


func (m *MockCgroup) Processes(arg0 cgroups.Name, arg1 bool) ([]cgroups.Process, error) {
	ret := m.ctrl.Call(m, "Processes", arg0, arg1)
	ret0, _ := ret[0].([]cgroups.Process)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

func ( m * MockCgroup ) Processes ( arg0 cgroups . Name , arg1 bool ) ( [ ] cgroups . Process , error ) { ret := m . ctrl . Call ( m , " " , arg0 , arg1 ) ret0 , _ := ret [ 0 ] . ( [ ] cgroups . Process ) ret1 , _ := ret [ 1 ] . ( error ) return ret0 , ret1 }


func (m *MockCgroup) Stat(arg0 ...cgroups.ErrorHandler) (*cgroups.Stats, error) {
	varargs := []interface{}{}
	for _, a := range arg0 {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "Stat", varargs...)
	ret0, _ := ret[0].(*cgroups.Stats)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

func ( m * MockCgroup ) Stat ( arg0 ... cgroups . ErrorHandler ) ( * cgroups . Stats , error ) { varargs := [ ] interface { } { } for _ , a := range arg0 { varargs = append ( varargs , a ) } ret := m . ctrl . Call ( m , " " , varargs ... ) ret0 , _ := ret [ 0 ] . ( * cgroups . Stats ) ret1 , _ := ret [ 1 ] . ( error ) return ret0 , ret1 }


func (m *MockCgroup) Subsystems() []cgroups.Subsystem {
	ret := m.ctrl.Call(m, "Subsystems")
	ret0, _ := ret[0].([]cgroups.Subsystem)
	return ret0
}

func ( m * MockCgroup ) Subsystems ( ) [ ] cgroups . Subsystem { ret := m . ctrl . Call ( m , " " ) ret0 , _ := ret [ 0 ] . ( [ ] cgroups . Subsystem ) return ret0 }


func TaskStatsHandler(state dockerstate.TaskEngineState, statsEngine stats.Engine) func(http.ResponseWriter, *http.Request) {
	return func(w http.ResponseWriter, r *http.Request) {
		taskARN, err := getTaskARNByRequest(r, state)
		if err != nil {
			errResponseJSON, _ := json.Marshal(
				fmt.Sprintf("V3 task stats handler: unable to get task arn from request: %s", err.Error()))
			utils.WriteJSONToResponse(w, http.StatusBadRequest, errResponseJSON, utils.RequestTypeTaskStats)
			return
		}

		seelog.Infof("V3 task stats handler: writing response for task '%s'", taskARN)

		// v3 handler shares the same task stats response format with v2 handler.
		v2.WriteTaskStatsResponse(w, taskARN, state, statsEngine)
	}
}

// TaskStatsHandler returns the handler method for handling task stats requests.

TaskStatsHandler returns the handler method for handling task stats requests .


func GetKnownAPIVersions() []DockerVersion {
	return []DockerVersion{
		Version_1_17,
		Version_1_18,
		Version_1_19,
		Version_1_20,
		Version_1_21,
		Version_1_22,
		Version_1_23,
		Version_1_24,
		Version_1_25,
		Version_1_26,
		Version_1_27,
		Version_1_28,
		Version_1_29,
		Version_1_30,
		Version_1_31,
		Version_1_32,
	}
}

// GetKnownAPIVersions returns all of the API versions that we know about.
// It doesn't care if the version is supported by Docker or ECS agent

GetKnownAPIVersions returns all of the API versions that we know about . It doesn t care if the version is supported by Docker or ECS agent


func NewMockUdev(ctrl *gomock.Controller) *MockUdev {
	mock := &MockUdev{ctrl: ctrl}
	mock.recorder = &MockUdevMockRecorder{mock}
	return mock
}

func NewMockUdev ( ctrl * gomock . Controller ) * MockUdev { mock := & MockUdev { ctrl : ctrl } mock . recorder = & MockUdevMockRecorder { mock } return mock }

// NewMockUdev creates a new mock instance


func (m *MockUdev) Monitor(arg0 chan *udev.UEvent) chan bool {
	ret := m.ctrl.Call(m, "Monitor", arg0)
	ret0, _ := ret[0].(chan bool)
	return ret0
}

func ( m * MockUdev ) Monitor ( arg0 chan * udev . UEvent ) chan bool { ret := m . ctrl . Call ( m , " " , arg0 ) ret0 , _ := ret [ 0 ] . ( chan bool ) return ret0 }


func (mr *MockUdevMockRecorder) Monitor(arg0 interface{}) *gomock.Call {
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Monitor", reflect.TypeOf((*MockUdev)(nil).Monitor), arg0)
}

func ( mr * MockUdevMockRecorder ) Monitor ( arg0 interface { } ) * gomock . Call { return mr . mock . ctrl . RecordCallWithMethodType ( mr . mock , " " , reflect . TypeOf ( ( * MockUdev ) ( nil ) . Monitor ) , arg0 ) }

// Monitor indicates an expected call of Monitor


func (s *ContainerDefinition) SetInferenceDevices(v []*string) *ContainerDefinition {
	s.InferenceDevices = v
	return s
}

func ( s * ContainerDefinition ) SetInferenceDevices ( v [ ] * string ) * ContainerDefinition { s . InferenceDevices = v return s }

// SetInferenceDevices sets the InferenceDevices field's value.

SetInferenceDevices sets the InferenceDevices field s value .


func (s *InferenceAccelerator) SetDeviceName(v string) *InferenceAccelerator {
	s.DeviceName = &v
	return s
}

func ( s * InferenceAccelerator ) SetDeviceName ( v string ) * InferenceAccelerator { s . DeviceName = & v return s }

// SetDeviceName sets the DeviceName field's value.

SetDeviceName sets the DeviceName field s value .


func (s *InferenceAccelerator) SetDeviceType(v string) *InferenceAccelerator {
	s.DeviceType = &v
	return s
}

func ( s * InferenceAccelerator ) SetDeviceType ( v string ) * InferenceAccelerator { s . DeviceType = & v return s }

// SetDeviceType sets the DeviceType field's value.

SetDeviceType sets the DeviceType field s value .


func DefaultConfig() Config {
	return Config{
		DockerEndpoint:                      "unix:///var/run/docker.sock",
		ReservedPorts:                       []uint16{SSHPort, DockerReservedPort, DockerReservedSSLPort, AgentIntrospectionPort, AgentCredentialsPort},
		ReservedPortsUDP:                    []uint16{},
		DataDir:                             "/data/",
		DataDirOnHost:                       "/var/lib/ecs",
		DisableMetrics:                      false,
		ReservedMemory:                      0,
		AvailableLoggingDrivers:             []dockerclient.LoggingDriver{dockerclient.JSONFileDriver, dockerclient.NoneDriver},
		TaskCleanupWaitDuration:             DefaultTaskCleanupWaitDuration,
		DockerStopTimeout:                   defaultDockerStopTimeout,
		ContainerStartTimeout:               defaultContainerStartTimeout,
		CredentialsAuditLogFile:             defaultCredentialsAuditLogFile,
		CredentialsAuditLogDisabled:         false,
		ImageCleanupDisabled:                false,
		MinimumImageDeletionAge:             DefaultImageDeletionAge,
		ImageCleanupInterval:                DefaultImageCleanupTimeInterval,
		ImagePullInactivityTimeout:          defaultImagePullInactivityTimeout,
		NumImagesToDeletePerCycle:           DefaultNumImagesToDeletePerCycle,
		NumNonECSContainersToDeletePerCycle: DefaultNumNonECSContainersToDeletePerCycle,
		CNIPluginsPath:                      defaultCNIPluginsPath,
		PauseContainerTarballPath:           pauseContainerTarballPath,
		PauseContainerImageName:             DefaultPauseContainerImageName,
		PauseContainerTag:                   DefaultPauseContainerTag,
		AWSVPCBlockInstanceMetdata:          false,
		ContainerMetadataEnabled:            false,
		TaskCPUMemLimit:                     DefaultEnabled,
		CgroupPath:                          defaultCgroupPath,
		TaskMetadataSteadyStateRate:         DefaultTaskMetadataSteadyStateRate,
		TaskMetadataBurstRate:               DefaultTaskMetadataBurstRate,
		SharedVolumeMatchFullConfig:         false, // only requiring shared volumes to match on name, which is default docker behavior
		ContainerInstancePropagateTagsFrom:  ContainerInstancePropagateTagsFromNoneType,
		PrometheusMetricsEnabled:            false,
		PollMetrics:                         false,
		PollingMetricsWaitDuration:          DefaultPollingMetricsWaitDuration,
		NvidiaRuntime:                       DefaultNvidiaRuntime,
	}
}

// DefaultConfig returns the default configuration for Linux


func (cfg *Config) platformString() string {
	// Returns a string if the default image name/tag of the Pause container has
	// been overridden
	if cfg.PauseContainerImageName == DefaultPauseContainerImageName &&
		cfg.PauseContainerTag == DefaultPauseContainerTag {
		return fmt.Sprintf(", PauseContainerImageName: %s, PauseContainerTag: %s",
			cfg.PauseContainerImageName, cfg.PauseContainerTag)
	}
	return ""
}

// platformString returns platform-specific config data that can be serialized
// to string for debugging

platformString returns platform - specific config data that can be serialized to string for debugging


func MapTaskToContainerStatus(desiredState TaskStatus, steadyState apicontainerstatus.ContainerStatus) apicontainerstatus.ContainerStatus {
	switch desiredState {
	case TaskStatusNone:
		return apicontainerstatus.ContainerStatusNone
	case TaskCreated:
		return apicontainerstatus.ContainerCreated
	case TaskRunning:
		return steadyState
	case TaskStopped:
		return apicontainerstatus.ContainerStopped
	}
	return apicontainerstatus.ContainerStatusNone
}

func MapTaskToContainerStatus ( desiredState TaskStatus , steadyState apicontainerstatus . ContainerStatus ) apicontainerstatus . ContainerStatus { switch desiredState { case TaskStatusNone : return apicontainerstatus . ContainerStatusNone case TaskCreated : return apicontainerstatus . ContainerCreated case TaskRunning : return steadyState case TaskStopped : return apicontainerstatus . ContainerStopped } return apicontainerstatus . ContainerStatusNone }

// MapTaskToContainerStatus maps the task status to the corresponding container status


func (me MultiErr) Error() string {
	ret := make([]string, len(me.errors)+1)
	ret[0] = "Multiple error:"
	for ndx, err := range me.errors {
		ret[ndx+1] = fmt.Sprintf("\t%d: %s", ndx, err.Error())
	}
	return strings.Join(ret, "\n")
}

func ( me MultiErr ) Error ( ) string { ret := make ( [ ] string , len ( me . errors ) + 1 ) ret [ 0 ] = " " for ndx , err := range me . errors { ret [ ndx + 1 ] = fmt . Sprintf ( " \t " , ndx , err . Error ( ) ) } return strings . Join ( ret , " \n " ) }

// Error returns the error string for MultiErr


func NewMultiError(errs ...error) error {
	errors := make([]error, 0, len(errs))
	for _, err := range errs {
		if err != nil {
			errors = append(errors, err)
		}
	}
	return MultiErr{errors}
}

func NewMultiError ( errs ... error ) error { errors := make ( [ ] error , 0 , len ( errs ) ) for _ , err := range errs { if err != nil { errors = append ( errors , err ) } } return MultiErr { errors } }

// NewMultiError creates a new MultErr object


func (auth *ECRAuthData) GetPullCredentials() credentials.IAMRoleCredentials {
	auth.lock.RLock()
	defer auth.lock.RUnlock()

	return auth.pullCredentials
}

func ( auth * ECRAuthData ) GetPullCredentials ( ) credentials . IAMRoleCredentials { auth . lock . RLock ( ) defer auth . lock . RUnlock ( ) return auth . pullCredentials }

// GetPullCredentials returns the pull credentials in the auth


func (auth *ECRAuthData) SetPullCredentials(creds credentials.IAMRoleCredentials) {
	auth.lock.Lock()
	defer auth.lock.Unlock()

	auth.pullCredentials = creds
}

func ( auth * ECRAuthData ) SetPullCredentials ( creds credentials . IAMRoleCredentials ) { auth . lock . Lock ( ) defer auth . lock . Unlock ( ) auth . pullCredentials = creds }

// SetPullCredentials sets the credentials to pull from ECR in the auth


func (auth *ASMAuthData) GetDockerAuthConfig() types.AuthConfig {
	auth.lock.RLock()
	defer auth.lock.RUnlock()

	return auth.dockerAuthConfig
}

func ( auth * ASMAuthData ) GetDockerAuthConfig ( ) types . AuthConfig { auth . lock . RLock ( ) defer auth . lock . RUnlock ( ) return auth . dockerAuthConfig }

// GetDockerAuthConfig returns the pull credentials in the auth


func (auth *ASMAuthData) SetDockerAuthConfig(dac types.AuthConfig) {
	auth.lock.Lock()
	defer auth.lock.Unlock()

	auth.dockerAuthConfig = dac
}

func ( auth * ASMAuthData ) SetDockerAuthConfig ( dac types . AuthConfig ) { auth . lock . Lock ( ) defer auth . lock . Unlock ( ) auth . dockerAuthConfig = dac }

// SetDockerAuthConfig sets the credentials to pull from ECR in the
// auth

SetDockerAuthConfig sets the credentials to pull from ECR in the auth


func NewMockSecretsManagerAPI(ctrl *gomock.Controller) *MockSecretsManagerAPI {
	mock := &MockSecretsManagerAPI{ctrl: ctrl}
	mock.recorder = &MockSecretsManagerAPIMockRecorder{mock}
	return mock
}

func NewMockSecretsManagerAPI ( ctrl * gomock . Controller ) * MockSecretsManagerAPI { mock := & MockSecretsManagerAPI { ctrl : ctrl } mock . recorder = & MockSecretsManagerAPIMockRecorder { mock } return mock }

// NewMockSecretsManagerAPI creates a new mock instance


func (m *MockSecretsManagerAPI) CancelRotateSecret(arg0 *secretsmanager.CancelRotateSecretInput) (*secretsmanager.CancelRotateSecretOutput, error) {
	ret := m.ctrl.Call(m, "CancelRotateSecret", arg0)
	ret0, _ := ret[0].(*secretsmanager.CancelRotateSecretOutput)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

func ( m * MockSecretsManagerAPI ) CancelRotateSecret ( arg0 * secretsmanager . CancelRotateSecretInput ) ( * secretsmanager . CancelRotateSecretOutput , error ) { ret := m . ctrl . Call ( m , " " , arg0 ) ret0 , _ := ret [ 0 ] . ( * secretsmanager . CancelRotateSecretOutput ) ret1 , _ := ret [ 1 ] . ( error ) return ret0 , ret1 }


func (mr *MockSecretsManagerAPIMockRecorder) CancelRotateSecret(arg0 interface{}) *gomock.Call {
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CancelRotateSecret", reflect.TypeOf((*MockSecretsManagerAPI)(nil).CancelRotateSecret), arg0)
}

func ( mr * MockSecretsManagerAPIMockRecorder ) CancelRotateSecret ( arg0 interface { } ) * gomock . Call { return mr . mock . ctrl . RecordCallWithMethodType ( mr . mock , " " , reflect . TypeOf ( ( * MockSecretsManagerAPI ) ( nil ) . CancelRotateSecret ) , arg0 ) }

// CancelRotateSecret indicates an expected call of CancelRotateSecret


func (m *MockSecretsManagerAPI) CancelRotateSecretRequest(arg0 *secretsmanager.CancelRotateSecretInput) (*request.Request, *secretsmanager.CancelRotateSecretOutput) {
	ret := m.ctrl.Call(m, "CancelRotateSecretRequest", arg0)
	ret0, _ := ret[0].(*request.Request)
	ret1, _ := ret[1].(*secretsmanager.CancelRotateSecretOutput)
	return ret0, ret1
}

func ( m * MockSecretsManagerAPI ) CancelRotateSecretRequest ( arg0 * secretsmanager . CancelRotateSecretInput ) ( * request . Request , * secretsmanager . CancelRotateSecretOutput ) { ret := m . ctrl . Call ( m , " " , arg0 ) ret0 , _ := ret [ 0 ] . ( * request . Request ) ret1 , _ := ret [ 1 ] . ( * secretsmanager . CancelRotateSecretOutput ) return ret0 , ret1 }

// CancelRotateSecretRequest mocks base method


func (m *MockSecretsManagerAPI) CancelRotateSecretWithContext(arg0 aws.Context, arg1 *secretsmanager.CancelRotateSecretInput, arg2 ...request.Option) (*secretsmanager.CancelRotateSecretOutput, error) {
	varargs := []interface{}{arg0, arg1}
	for _, a := range arg2 {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "CancelRotateSecretWithContext", varargs...)
	ret0, _ := ret[0].(*secretsmanager.CancelRotateSecretOutput)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

func ( m * MockSecretsManagerAPI ) CancelRotateSecretWithContext ( arg0 aws . Context , arg1 * secretsmanager . CancelRotateSecretInput , arg2 ... request . Option ) ( * secretsmanager . CancelRotateSecretOutput , error ) { varargs := [ ] interface { } { arg0 , arg1 } for _ , a := range arg2 { varargs = append ( varargs , a ) } ret := m . ctrl . Call ( m , " " , varargs ... ) ret0 , _ := ret [ 0 ] . ( * secretsmanager . CancelRotateSecretOutput ) ret1 , _ := ret [ 1 ] . ( error ) return ret0 , ret1 }

// CancelRotateSecretWithContext mocks base method


func (m *MockSecretsManagerAPI) CreateSecret(arg0 *secretsmanager.CreateSecretInput) (*secretsmanager.CreateSecretOutput, error) {
	ret := m.ctrl.Call(m, "CreateSecret", arg0)
	ret0, _ := ret[0].(*secretsmanager.CreateSecretOutput)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

func ( m * MockSecretsManagerAPI ) CreateSecret ( arg0 * secretsmanager . CreateSecretInput ) ( * secretsmanager . CreateSecretOutput , error ) { ret := m . ctrl . Call ( m , " " , arg0 ) ret0 , _ := ret [ 0 ] . ( * secretsmanager . CreateSecretOutput ) ret1 , _ := ret [ 1 ] . ( error ) return ret0 , ret1 }


func (m *MockSecretsManagerAPI) CreateSecretRequest(arg0 *secretsmanager.CreateSecretInput) (*request.Request, *secretsmanager.CreateSecretOutput) {
	ret := m.ctrl.Call(m, "CreateSecretRequest", arg0)
	ret0, _ := ret[0].(*request.Request)
	ret1, _ := ret[1].(*secretsmanager.CreateSecretOutput)
	return ret0, ret1
}

func ( m * MockSecretsManagerAPI ) CreateSecretRequest ( arg0 * secretsmanager . CreateSecretInput ) ( * request . Request , * secretsmanager . CreateSecretOutput ) { ret := m . ctrl . Call ( m , " " , arg0 ) ret0 , _ := ret [ 0 ] . ( * request . Request ) ret1 , _ := ret [ 1 ] . ( * secretsmanager . CreateSecretOutput ) return ret0 , ret1 }

// CreateSecretRequest mocks base method


func (m *MockSecretsManagerAPI) CreateSecretWithContext(arg0 aws.Context, arg1 *secretsmanager.CreateSecretInput, arg2 ...request.Option) (*secretsmanager.CreateSecretOutput, error) {
	varargs := []interface{}{arg0, arg1}
	for _, a := range arg2 {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "CreateSecretWithContext", varargs...)
	ret0, _ := ret[0].(*secretsmanager.CreateSecretOutput)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

func ( m * MockSecretsManagerAPI ) CreateSecretWithContext ( arg0 aws . Context , arg1 * secretsmanager . CreateSecretInput , arg2 ... request . Option ) ( * secretsmanager . CreateSecretOutput , error ) { varargs := [ ] interface { } { arg0 , arg1 } for _ , a := range arg2 { varargs = append ( varargs , a ) } ret := m . ctrl . Call ( m , " " , varargs ... ) ret0 , _ := ret [ 0 ] . ( * secretsmanager . CreateSecretOutput ) ret1 , _ := ret [ 1 ] . ( error ) return ret0 , ret1 }

// CreateSecretWithContext mocks base method


func (m *MockSecretsManagerAPI) DeleteResourcePolicy(arg0 *secretsmanager.DeleteResourcePolicyInput) (*secretsmanager.DeleteResourcePolicyOutput, error) {
	ret := m.ctrl.Call(m, "DeleteResourcePolicy", arg0)
	ret0, _ := ret[0].(*secretsmanager.DeleteResourcePolicyOutput)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

func ( m * MockSecretsManagerAPI ) DeleteResourcePolicy ( arg0 * secretsmanager . DeleteResourcePolicyInput ) ( * secretsmanager . DeleteResourcePolicyOutput , error ) { ret := m . ctrl . Call ( m , " " , arg0 ) ret0 , _ := ret [ 0 ] . ( * secretsmanager . DeleteResourcePolicyOutput ) ret1 , _ := ret [ 1 ] . ( error ) return ret0 , ret1 }

// DeleteResourcePolicy mocks base method


func (m *MockSecretsManagerAPI) DeleteResourcePolicyRequest(arg0 *secretsmanager.DeleteResourcePolicyInput) (*request.Request, *secretsmanager.DeleteResourcePolicyOutput) {
	ret := m.ctrl.Call(m, "DeleteResourcePolicyRequest", arg0)
	ret0, _ := ret[0].(*request.Request)
	ret1, _ := ret[1].(*secretsmanager.DeleteResourcePolicyOutput)
	return ret0, ret1
}

func ( m * MockSecretsManagerAPI ) DeleteResourcePolicyRequest ( arg0 * secretsmanager . DeleteResourcePolicyInput ) ( * request . Request , * secretsmanager . DeleteResourcePolicyOutput ) { ret := m . ctrl . Call ( m , " " , arg0 ) ret0 , _ := ret [ 0 ] . ( * request . Request ) ret1 , _ := ret [ 1 ] . ( * secretsmanager . DeleteResourcePolicyOutput ) return ret0 , ret1 }

// DeleteResourcePolicyRequest mocks base method


func (m *MockSecretsManagerAPI) DeleteResourcePolicyWithContext(arg0 aws.Context, arg1 *secretsmanager.DeleteResourcePolicyInput, arg2 ...request.Option) (*secretsmanager.DeleteResourcePolicyOutput, error) {
	varargs := []interface{}{arg0, arg1}
	for _, a := range arg2 {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "DeleteResourcePolicyWithContext", varargs...)
	ret0, _ := ret[0].(*secretsmanager.DeleteResourcePolicyOutput)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

func ( m * MockSecretsManagerAPI ) DeleteResourcePolicyWithContext ( arg0 aws . Context , arg1 * secretsmanager . DeleteResourcePolicyInput , arg2 ... request . Option ) ( * secretsmanager . DeleteResourcePolicyOutput , error ) { varargs := [ ] interface { } { arg0 , arg1 } for _ , a := range arg2 { varargs = append ( varargs , a ) } ret := m . ctrl . Call ( m , " " , varargs ... ) ret0 , _ := ret [ 0 ] . ( * secretsmanager . DeleteResourcePolicyOutput ) ret1 , _ := ret [ 1 ] . ( error ) return ret0 , ret1 }

// DeleteResourcePolicyWithContext mocks base method


func (m *MockSecretsManagerAPI) DeleteSecret(arg0 *secretsmanager.DeleteSecretInput) (*secretsmanager.DeleteSecretOutput, error) {
	ret := m.ctrl.Call(m, "DeleteSecret", arg0)
	ret0, _ := ret[0].(*secretsmanager.DeleteSecretOutput)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

func ( m * MockSecretsManagerAPI ) DeleteSecret ( arg0 * secretsmanager . DeleteSecretInput ) ( * secretsmanager . DeleteSecretOutput , error ) { ret := m . ctrl . Call ( m , " " , arg0 ) ret0 , _ := ret [ 0 ] . ( * secretsmanager . DeleteSecretOutput ) ret1 , _ := ret [ 1 ] . ( error ) return ret0 , ret1 }


func (m *MockSecretsManagerAPI) DeleteSecretRequest(arg0 *secretsmanager.DeleteSecretInput) (*request.Request, *secretsmanager.DeleteSecretOutput) {
	ret := m.ctrl.Call(m, "DeleteSecretRequest", arg0)
	ret0, _ := ret[0].(*request.Request)
	ret1, _ := ret[1].(*secretsmanager.DeleteSecretOutput)
	return ret0, ret1
}

func ( m * MockSecretsManagerAPI ) DeleteSecretRequest ( arg0 * secretsmanager . DeleteSecretInput ) ( * request . Request , * secretsmanager . DeleteSecretOutput ) { ret := m . ctrl . Call ( m , " " , arg0 ) ret0 , _ := ret [ 0 ] . ( * request . Request ) ret1 , _ := ret [ 1 ] . ( * secretsmanager . DeleteSecretOutput ) return ret0 , ret1 }

// DeleteSecretRequest mocks base method


func (m *MockSecretsManagerAPI) DeleteSecretWithContext(arg0 aws.Context, arg1 *secretsmanager.DeleteSecretInput, arg2 ...request.Option) (*secretsmanager.DeleteSecretOutput, error) {
	varargs := []interface{}{arg0, arg1}
	for _, a := range arg2 {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "DeleteSecretWithContext", varargs...)
	ret0, _ := ret[0].(*secretsmanager.DeleteSecretOutput)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

func ( m * MockSecretsManagerAPI ) DeleteSecretWithContext ( arg0 aws . Context , arg1 * secretsmanager . DeleteSecretInput , arg2 ... request . Option ) ( * secretsmanager . DeleteSecretOutput , error ) { varargs := [ ] interface { } { arg0 , arg1 } for _ , a := range arg2 { varargs = append ( varargs , a ) } ret := m . ctrl . Call ( m , " " , varargs ... ) ret0 , _ := ret [ 0 ] . ( * secretsmanager . DeleteSecretOutput ) ret1 , _ := ret [ 1 ] . ( error ) return ret0 , ret1 }

// DeleteSecretWithContext mocks base method


func (m *MockSecretsManagerAPI) DescribeSecret(arg0 *secretsmanager.DescribeSecretInput) (*secretsmanager.DescribeSecretOutput, error) {
	ret := m.ctrl.Call(m, "DescribeSecret", arg0)
	ret0, _ := ret[0].(*secretsmanager.DescribeSecretOutput)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

func ( m * MockSecretsManagerAPI ) DescribeSecret ( arg0 * secretsmanager . DescribeSecretInput ) ( * secretsmanager . DescribeSecretOutput , error ) { ret := m . ctrl . Call ( m , " " , arg0 ) ret0 , _ := ret [ 0 ] . ( * secretsmanager . DescribeSecretOutput ) ret1 , _ := ret [ 1 ] . ( error ) return ret0 , ret1 }


func (m *MockSecretsManagerAPI) DescribeSecretRequest(arg0 *secretsmanager.DescribeSecretInput) (*request.Request, *secretsmanager.DescribeSecretOutput) {
	ret := m.ctrl.Call(m, "DescribeSecretRequest", arg0)
	ret0, _ := ret[0].(*request.Request)
	ret1, _ := ret[1].(*secretsmanager.DescribeSecretOutput)
	return ret0, ret1
}

func ( m * MockSecretsManagerAPI ) DescribeSecretRequest ( arg0 * secretsmanager . DescribeSecretInput ) ( * request . Request , * secretsmanager . DescribeSecretOutput ) { ret := m . ctrl . Call ( m , " " , arg0 ) ret0 , _ := ret [ 0 ] . ( * request . Request ) ret1 , _ := ret [ 1 ] . ( * secretsmanager . DescribeSecretOutput ) return ret0 , ret1 }

// DescribeSecretRequest mocks base method