diff --git a/Makefile b/Makefile index dbb511ffe77..b0810e191f9 100644 --- a/Makefile +++ b/Makefile @@ -268,7 +268,7 @@ GOFILES:=$(shell go list -f '{{$$p := .}}{{range $$f := .GoFiles}}{{$$p.Dir}}/{{ .PHONY: gocyclo gocyclo: # Run gocyclo over all .go files - gocyclo -over 15 ${GOFILES} + gocyclo -over 17 ${GOFILES} # same as gofiles above, but without the `-f` .PHONY: govet diff --git a/agent/Gopkg.lock b/agent/Gopkg.lock index e37f1eea557..c9436766817 100644 --- a/agent/Gopkg.lock +++ b/agent/Gopkg.lock @@ -10,7 +10,7 @@ version = "v0.4.7" [[projects]] - digest = "1:4dfad161aee05f73bbd9740d329bb068a18028c0a9d6c0572f931ad320f71873" + digest = "1:1ef319395779da83b56190d70b43d3a8b87ab27acf8161da816f818e0c211c23" name = "github.com/aws/aws-sdk-go" packages = [ "aws", @@ -54,6 +54,7 @@ "private/util", "service/cloudwatchlogs", "service/ec2", + "service/fsx", "service/s3", "service/s3/internal/arn", "service/s3/s3iface", @@ -539,6 +540,7 @@ "github.com/aws/aws-sdk-go/private/util", "github.com/aws/aws-sdk-go/service/cloudwatchlogs", "github.com/aws/aws-sdk-go/service/ec2", + "github.com/aws/aws-sdk-go/service/fsx", "github.com/aws/aws-sdk-go/service/s3", "github.com/aws/aws-sdk-go/service/s3/s3manager", "github.com/aws/aws-sdk-go/service/secretsmanager", diff --git a/agent/acs/model/api/api-2.json b/agent/acs/model/api/api-2.json index 533a27dcbbc..e3e6c1f6274 100644 --- a/agent/acs/model/api/api-2.json +++ b/agent/acs/model/api/api-2.json @@ -394,6 +394,21 @@ "message":{"shape":"String"} } }, + "FSxWindowsFileServerAuthorizationConfig":{ + "type":"structure", + "members":{ + "credentialsParameter":{"shape":"String"}, + "domain":{"shape":"String"} + } + }, + "FSxWindowsFileServerVolumeConfiguration":{ + "type":"structure", + "members":{ + "fileSystemId":{"shape":"String"}, + "rootDirectory":{"shape":"String"}, + "authorizationConfig":{"shape":"FSxWindowsFileServerAuthorizationConfig"} + } + }, "HealthCheckType":{ "type":"string", "enum":["docker"] @@ -720,7 +735,8 @@ "type":{"shape":"VolumeType"}, "host":{"shape":"HostVolumeProperties"}, "dockerVolumeConfiguration":{"shape":"DockerVolumeConfiguration"}, - "efsVolumeConfiguration":{"shape":"EFSVolumeConfiguration"} + "efsVolumeConfiguration":{"shape":"EFSVolumeConfiguration"}, + "fsxWindowsFileServerVolumeConfiguration":{"shape":"FSxWindowsFileServerVolumeConfiguration"} } }, "VolumeFrom":{ @@ -743,7 +759,8 @@ "enum":[ "host", "docker", - "efs" + "efs", + "fsxWindowsFileServer" ] }, "TaskIdentifier": { diff --git a/agent/acs/model/ecsacs/api.go b/agent/acs/model/ecsacs/api.go index c03a2e36a25..3263050f623 100644 --- a/agent/acs/model/ecsacs/api.go +++ b/agent/acs/model/ecsacs/api.go @@ -579,6 +579,44 @@ func (s ErrorOutput) GoString() string { return s.String() } +type FSxWindowsFileServerAuthorizationConfig struct { + _ struct{} `type:"structure"` + + CredentialsParameter *string `locationName:"credentialsParameter" type:"string"` + + Domain *string `locationName:"domain" type:"string"` +} + +// String returns the string representation +func (s FSxWindowsFileServerAuthorizationConfig) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s FSxWindowsFileServerAuthorizationConfig) GoString() string { + return s.String() +} + +type FSxWindowsFileServerVolumeConfiguration struct { + _ struct{} `type:"structure"` + + AuthorizationConfig *FSxWindowsFileServerAuthorizationConfig `locationName:"authorizationConfig" type:"structure"` + + FileSystemId *string `locationName:"fileSystemId" type:"string"` + + RootDirectory *string `locationName:"rootDirectory" type:"string"` +} + +// String returns the string representation +func (s FSxWindowsFileServerVolumeConfiguration) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s FSxWindowsFileServerVolumeConfiguration) GoString() string { + return s.String() +} + type FirelensConfiguration struct { _ struct{} `type:"structure"` @@ -1494,6 +1532,8 @@ type Volume struct { EfsVolumeConfiguration *EFSVolumeConfiguration `locationName:"efsVolumeConfiguration" type:"structure"` + FsxWindowsFileServerVolumeConfiguration *FSxWindowsFileServerVolumeConfiguration `locationName:"fsxWindowsFileServerVolumeConfiguration" type:"structure"` + Host *HostVolumeProperties `locationName:"host" type:"structure"` Name *string `locationName:"name" type:"string"` diff --git a/agent/api/task/task.go b/agent/api/task/task.go index 57f11cd3791..2e09dfcecc9 100644 --- a/agent/api/task/task.go +++ b/agent/api/task/task.go @@ -383,6 +383,14 @@ func (task *Task) PostUnmarshalTask(cfg *config.Config, } task.populateTaskARN() + // fsxWindowsFileserver is the product type -- it is technically "agnostic" ie it should apply to both Windows and Linux tasks + if task.requiresFSxWindowsFileServerResource() { + if err := task.initializeFSxWindowsFileServerResource(cfg, credentialsManager, resourceFields); err != nil { + seelog.Errorf("Task [%s]: could not initialize FSx for Windows File Server resource: %v", task.Arn, err) + return apierrors.NewResourceInitError(task.Arn, err) + } + } + return nil } @@ -1316,7 +1324,7 @@ func (task *Task) HostVolumeByName(name string) (taskresourcevolume.Volume, bool // volume feature. func (task *Task) UpdateMountPoints(cont *apicontainer.Container, vols []types.MountPoint) { for _, mountPoint := range cont.MountPoints { - containerPath := getCanonicalPath(mountPoint.ContainerPath) + containerPath := utils.GetCanonicalPath(mountPoint.ContainerPath) for _, vol := range vols { if strings.Compare(vol.Destination, containerPath) == 0 || // /path/ -> /path or \path\ -> \path diff --git a/agent/api/task/task_linux.go b/agent/api/task/task_linux.go index ea1d5e9f767..9cc247b5ec3 100644 --- a/agent/api/task/task_linux.go +++ b/agent/api/task/task_linux.go @@ -71,8 +71,6 @@ func (task *Task) initializeCgroupResourceSpec(cgroupPath string, cGroupCPUPerio return nil } -func getCanonicalPath(path string) string { return path } - // BuildCgroupRoot helps build the task cgroup prefix // Example: /ecs/task-id func (task *Task) BuildCgroupRoot() (string, error) { @@ -241,3 +239,15 @@ func enableIPv6SysctlSetting(hostConfig *dockercontainer.HostConfig) { } hostConfig.Sysctls[disableIPv6SysctlKey] = sysctlValueOff } + +// requiresFSxWindowsFileServerResource returns true if at least one volume in the task +// is of type 'fsxWindowsFileServer' +func (task *Task) requiresFSxWindowsFileServerResource() bool { + return false +} + +// initializeFSxWindowsFileServerResource builds the resource dependency map for the fsxwindowsfileserver resource +func (task *Task) initializeFSxWindowsFileServerResource(cfg *config.Config, credentialsManager credentials.Manager, + resourceFields *taskresource.ResourceFields) error { + return errors.New("task with FSx for Windows File Server volumes is only supported on Windows container instance") +} diff --git a/agent/api/task/task_unsupported.go b/agent/api/task/task_unsupported.go index 6df12b221c0..be2eac955de 100644 --- a/agent/api/task/task_unsupported.go +++ b/agent/api/task/task_unsupported.go @@ -39,8 +39,6 @@ func (task *Task) adjustForPlatform(cfg *config.Config) { task.MemoryCPULimitsEnabled = cfg.TaskCPUMemLimit.Enabled() } -func getCanonicalPath(path string) string { return path } - func (task *Task) initializeCgroupResourceSpec(cgroupPath string, cGroupCPUPeriod time.Duration, resourceFields *taskresource.ResourceFields) error { return nil } @@ -80,3 +78,15 @@ func (task *Task) GetCredentialSpecResource() ([]taskresource.TaskResource, bool func enableIPv6SysctlSetting(hostConfig *dockercontainer.HostConfig) { return } + +// requiresFSxWindowsFileServerResource returns true if at least one volume in the task +// is of type 'fsxWindowsFileServer' +func (task *Task) requiresFSxWindowsFileServerResource() bool { + return false +} + +// initializeFSxWindowsFileServerResource builds the resource dependency map for the fsxwindowsfileserver resource +func (task *Task) initializeFSxWindowsFileServerResource(cfg *config.Config, credentialsManager credentials.Manager, + resourceFields *taskresource.ResourceFields) error { + return errors.New("task with FSx for Windows File Server volumes is only supported on Windows container instance") +} diff --git a/agent/api/task/task_windows.go b/agent/api/task/task_windows.go index 8f898dd0768..705b3e5d33b 100644 --- a/agent/api/task/task_windows.go +++ b/agent/api/task/task_windows.go @@ -17,10 +17,7 @@ package task import ( "errors" - "path/filepath" - "regexp" "runtime" - "strings" "time" "github.com/aws/amazon-ecs-agent/agent/utils" @@ -30,7 +27,9 @@ import ( "github.com/aws/amazon-ecs-agent/agent/credentials" "github.com/aws/amazon-ecs-agent/agent/taskresource" "github.com/aws/amazon-ecs-agent/agent/taskresource/credentialspec" + "github.com/aws/amazon-ecs-agent/agent/taskresource/fsxwindowsfileserver" resourcestatus "github.com/aws/amazon-ecs-agent/agent/taskresource/status" + resourcetype "github.com/aws/amazon-ecs-agent/agent/taskresource/types" taskresourcevolume "github.com/aws/amazon-ecs-agent/agent/taskresource/volume" "github.com/cihub/seelog" dockercontainer "github.com/docker/docker/api/types/container" @@ -71,51 +70,18 @@ func (task *Task) adjustForPlatform(cfg *config.Config) { func (task *Task) downcaseAllVolumePaths() { for _, volume := range task.Volumes { if hostVol, ok := volume.Volume.(*taskresourcevolume.FSHostVolume); ok { - hostVol.FSSourcePath = getCanonicalPath(hostVol.FSSourcePath) + hostVol.FSSourcePath = utils.GetCanonicalPath(hostVol.FSSourcePath) } } for _, container := range task.Containers { for i, mountPoint := range container.MountPoints { // container.MountPoints is a slice of values, not a slice of pointers so // we need to mutate the actual value instead of the copied value - container.MountPoints[i].ContainerPath = getCanonicalPath(mountPoint.ContainerPath) + container.MountPoints[i].ContainerPath = utils.GetCanonicalPath(mountPoint.ContainerPath) } } } -func getCanonicalPath(path string) string { - lowercasedPath := strings.ToLower(path) - // if the path is a bare drive like "d:", don't filepath.Clean it because it will add a '.'. - // this is to fix the case where mounting from D:\ to D: is supported by docker but not ecs - if isBareDrive(lowercasedPath) { - return lowercasedPath - } - - if isNamedPipesPath(lowercasedPath) { - return lowercasedPath - } - - return filepath.Clean(lowercasedPath) -} - -func isBareDrive(path string) bool { - if filepath.VolumeName(path) == path { - return true - } - - return false -} - -func isNamedPipesPath(path string) bool { - matched, err := regexp.MatchString(`\\{2}\.[\\]pipe[\\].+`, path) - - if err != nil { - return false - } - - return matched -} - // platformHostConfigOverride provides an entry point to set up default HostConfig options to be // passed to Docker API. func (task *Task) platformHostConfigOverride(hostConfig *dockercontainer.HostConfig) error { @@ -217,3 +183,72 @@ func (task *Task) GetCredentialSpecResource() ([]taskresource.TaskResource, bool func enableIPv6SysctlSetting(hostConfig *dockercontainer.HostConfig) { return } + +// requiresFSxWindowsFileServerResource returns true if at least one volume in the task +// is of type 'fsxWindowsFileServer' +func (task *Task) requiresFSxWindowsFileServerResource() bool { + for _, volume := range task.Volumes { + if volume.Type == FSxWindowsFileServerVolumeType { + return true + } + } + return false +} + +// initializeFSxWindowsFileServerResource builds the resource dependency map for the fsxwindowsfileserver resource +func (task *Task) initializeFSxWindowsFileServerResource(cfg *config.Config, credentialsManager credentials.Manager, + resourceFields *taskresource.ResourceFields) error { + for i, vol := range task.Volumes { + if vol.Type != FSxWindowsFileServerVolumeType { + continue + } + + fsxWindowsFileServerVol, ok := vol.Volume.(*fsxwindowsfileserver.FSxWindowsFileServerVolumeConfig) + if !ok { + return errors.New("task volume: volume configuration does not match the type 'fsxWindowsFileServer'") + } + + err := task.addFSxWindowsFileServerResource(cfg, credentialsManager, resourceFields, &task.Volumes[i], fsxWindowsFileServerVol) + if err != nil { + return err + } + } + return nil +} + +// addFSxWindowsFileServerResource creates a fsxwindowsfileserver resource for every fsxwindowsfileserver task volume +// and updates container dependency +func (task *Task) addFSxWindowsFileServerResource( + cfg *config.Config, + credentialsManager credentials.Manager, + resourceFields *taskresource.ResourceFields, + vol *TaskVolume, + fsxWindowsFileServerVol *fsxwindowsfileserver.FSxWindowsFileServerVolumeConfig, +) error { + hostPath, err := utils.FindUnusedDriveLetter() + if err != nil { + return err + } + + fsxwindowsfileserverResource, err := fsxwindowsfileserver.NewFSxWindowsFileServerResource( + task.Arn, + cfg.AWSRegion, + vol.Name, + FSxWindowsFileServerVolumeType, + fsxWindowsFileServerVol, + hostPath, + task.ExecutionCredentialsID, + credentialsManager, + resourceFields.SSMClientCreator, + resourceFields.ASMClientCreator, + resourceFields.FSxClientCreator) + if err != nil { + return err + } + + vol.Volume = &fsxwindowsfileserverResource.VolumeConfig + task.AddResource(resourcetype.FSxWindowsFileServerKey, fsxwindowsfileserverResource) + task.updateContainerVolumeDependency(vol.Name) + + return nil +} diff --git a/agent/api/task/task_windows_test.go b/agent/api/task/task_windows_test.go index 716ed59bb5a..1d68db506ee 100644 --- a/agent/api/task/task_windows_test.go +++ b/agent/api/task/task_windows_test.go @@ -28,15 +28,20 @@ import ( "github.com/aws/amazon-ecs-agent/agent/config" "github.com/aws/amazon-ecs-agent/agent/taskresource" "github.com/aws/amazon-ecs-agent/agent/taskresource/credentialspec" + "github.com/aws/amazon-ecs-agent/agent/taskresource/fsxwindowsfileserver" resourcestatus "github.com/aws/amazon-ecs-agent/agent/taskresource/status" taskresourcevolume "github.com/aws/amazon-ecs-agent/agent/taskresource/volume" + "github.com/aws/amazon-ecs-agent/agent/utils" "github.com/golang/mock/gomock" "github.com/aws/amazon-ecs-agent/agent/dockerclient" dockercontainer "github.com/docker/docker/api/types/container" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + mock_asm_factory "github.com/aws/amazon-ecs-agent/agent/asm/factory/mocks" mock_credentials "github.com/aws/amazon-ecs-agent/agent/credentials/mocks" + mock_fsx_factory "github.com/aws/amazon-ecs-agent/agent/fsx/factory/mocks" mock_s3_factory "github.com/aws/amazon-ecs-agent/agent/s3/factory/mocks" mock_ssm_factory "github.com/aws/amazon-ecs-agent/agent/ssm/factory/mocks" ) @@ -340,7 +345,7 @@ func TestGetCanonicalPath(t *testing.T) { for _, tc := range testcases { t.Run(tc.name, func(t *testing.T) { - result := getCanonicalPath(tc.path) + result := utils.GetCanonicalPath(tc.path) assert.Equal(t, result, tc.expectedResult) }) } @@ -511,3 +516,210 @@ func TestGetCredentialSpecResource(t *testing.T) { assert.True(t, ok) assert.NotEmpty(t, credentialspecTaskResource) } + +func TestRequiresFSxWindowsFileServerResource(t *testing.T) { + task1 := &Task{ + Arn: "test1", + Volumes: []TaskVolume{ + { + Name: "fsxWindowsFileServerVolume", + Type: "fsxWindowsFileServer", + Volume: &fsxwindowsfileserver.FSxWindowsFileServerVolumeConfig{ + FileSystemID: "fs-12345678", + RootDirectory: "root", + AuthConfig: fsxwindowsfileserver.FSxWindowsFileServerAuthConfig{ + CredentialsParameter: "arn", + Domain: "test", + }, + }, + }, + }, + } + + task2 := &Task{ + Arn: "test2", + Volumes: []TaskVolume{}, + } + + testCases := []struct { + name string + task *Task + expectedOutput bool + }{ + { + name: "valid_fsxwindowsfileserver", + task: task1, + expectedOutput: true, + }, + { + name: "missing_fsxwindowsfileserver", + task: task2, + expectedOutput: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + assert.Equal(t, tc.expectedOutput, tc.task.requiresFSxWindowsFileServerResource()) + }) + } +} + +func TestInitializeAndAddFSxWindowsFileServerResource(t *testing.T) { + task := &Task{ + Arn: "test1", + ResourcesMapUnsafe: make(map[string][]taskresource.TaskResource), + Volumes: []TaskVolume{ + { + Name: "fsxWindowsFileServerVolume", + Type: "fsxWindowsFileServer", + Volume: &fsxwindowsfileserver.FSxWindowsFileServerVolumeConfig{ + FileSystemID: "fs-12345678", + RootDirectory: "root", + AuthConfig: fsxwindowsfileserver.FSxWindowsFileServerAuthConfig{ + CredentialsParameter: "arn", + Domain: "test", + }, + }, + }, + }, + Containers: []*apicontainer.Container{ + { + Name: "myName", + MountPoints: []apicontainer.MountPoint{ + { + SourceVolume: "fsxWindowsFileServerVolume", + ContainerPath: "/test", + ReadOnly: false, + }, + }, + TransitionDependenciesMap: make(map[apicontainerstatus.ContainerStatus]apicontainer.TransitionDependencySet), + }, + }, + } + + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + cfg := &config.Config{ + AWSRegion: "test-aws-region", + } + + credentialsManager := mock_credentials.NewMockManager(ctrl) + ssmClientCreator := mock_ssm_factory.NewMockSSMClientCreator(ctrl) + asmClientCreator := mock_asm_factory.NewMockClientCreator(ctrl) + fsxClientCreator := mock_fsx_factory.NewMockFSxClientCreator(ctrl) + + resFields := &taskresource.ResourceFields{ + ResourceFieldsCommon: &taskresource.ResourceFieldsCommon{ + ASMClientCreator: asmClientCreator, + SSMClientCreator: ssmClientCreator, + FSxClientCreator: fsxClientCreator, + CredentialsManager: credentialsManager, + }, + } + + task.initializeFSxWindowsFileServerResource(cfg, credentialsManager, resFields) + + assert.Equal(t, 1, len(task.Containers), "Should match the number of containers as before PostUnmarshalTask") + assert.Equal(t, 1, len(task.Volumes), "Should have 1 volume") + assert.Equal(t, 1, len(task.Containers[0].TransitionDependenciesMap), "Should have 1 container volume dependency") + taskVol := task.Volumes[0] + assert.Equal(t, "fsxWindowsFileServerVolume", taskVol.Name) + assert.Equal(t, FSxWindowsFileServerVolumeType, taskVol.Type) + + resources := task.GetResources() + assert.Len(t, resources, 1) + _, ok := resources[0].(*fsxwindowsfileserver.FSxWindowsFileServerResource) + require.True(t, ok) +} + +func TestPostUnmarshalTaskWithFSxWindowsFileServerVolumes(t *testing.T) { + taskFromACS := ecsacs.Task{ + Arn: strptr("myArn"), + DesiredStatus: strptr("RUNNING"), + Family: strptr("myFamily"), + Version: strptr("1"), + Containers: []*ecsacs.Container{ + { + Name: strptr("myName1"), + MountPoints: []*ecsacs.MountPoint{ + { + ContainerPath: strptr("\\some\\path"), + SourceVolume: strptr("fsxWindowsFileServerVolume"), + }, + }, + }, + }, + Volumes: []*ecsacs.Volume{ + { + Name: strptr("fsxWindowsFileServerVolume"), + Type: strptr("fsxWindowsFileServer"), + FsxWindowsFileServerVolumeConfiguration: &ecsacs.FSxWindowsFileServerVolumeConfiguration{ + AuthorizationConfig: &ecsacs.FSxWindowsFileServerAuthorizationConfig{ + CredentialsParameter: strptr("arn"), + Domain: strptr("test"), + }, + FileSystemId: strptr("fs-12345678"), + RootDirectory: strptr("test"), + }, + }, + }, + } + seqNum := int64(42) + task, err := TaskFromACS(&taskFromACS, &ecsacs.PayloadMessage{SeqNum: &seqNum}) + assert.Nil(t, err, "Should be able to handle acs task") + assert.Equal(t, 1, len(task.Containers)) // before PostUnmarshalTask + + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + cfg := config.Config{ + AWSRegion: "test-aws-region", + } + + credentialsManager := mock_credentials.NewMockManager(ctrl) + ssmClientCreator := mock_ssm_factory.NewMockSSMClientCreator(ctrl) + asmClientCreator := mock_asm_factory.NewMockClientCreator(ctrl) + fsxClientCreator := mock_fsx_factory.NewMockFSxClientCreator(ctrl) + + resFields := &taskresource.ResourceFields{ + ResourceFieldsCommon: &taskresource.ResourceFieldsCommon{ + SSMClientCreator: ssmClientCreator, + ASMClientCreator: asmClientCreator, + FSxClientCreator: fsxClientCreator, + CredentialsManager: credentialsManager, + }, + } + + task.PostUnmarshalTask(&cfg, credentialsManager, resFields, nil, nil) + assert.Equal(t, 1, len(task.Containers), "Should match the number of containers as before PostUnmarshalTask") + assert.Equal(t, 1, len(task.Volumes), "Should have 1 volume") + taskVol := task.Volumes[0] + assert.Equal(t, "fsxWindowsFileServerVolume", taskVol.Name) + assert.Equal(t, FSxWindowsFileServerVolumeType, taskVol.Type) + + resources := task.GetResources() + assert.Len(t, resources, 1) + _, ok := resources[0].(*fsxwindowsfileserver.FSxWindowsFileServerResource) + require.True(t, ok) + b, err := json.Marshal(resources[0]) + require.NoError(t, err) + assert.JSONEq(t, fmt.Sprintf(`{ + "name": "fsxWindowsFileServerVolume", + "taskARN": "myArn", + "executionCredentialsID": "", + "fsxWindowsFileServerVolumeConfiguration": { + "fileSystemId": "fs-12345678", + "rootDirectory": "test", + "authorizationConfig": { + "credentialsParameter": "arn", + "domain": "test" + }, + "fsxWindowsFileServerHostPath": "Z:\\" + }, + "createdAt": "0001-01-01T00:00:00Z", + "desiredStatus": "NONE", + "knownStatus": "NONE" + }`), string(b)) +} diff --git a/agent/api/task/taskvolume.go b/agent/api/task/taskvolume.go index 05e696a88a8..6bdbfe5dd84 100644 --- a/agent/api/task/taskvolume.go +++ b/agent/api/task/taskvolume.go @@ -18,6 +18,7 @@ import ( "github.com/aws/amazon-ecs-agent/agent/config" "github.com/aws/amazon-ecs-agent/agent/taskresource" + "github.com/aws/amazon-ecs-agent/agent/taskresource/fsxwindowsfileserver" taskresourcetypes "github.com/aws/amazon-ecs-agent/agent/taskresource/types" taskresourcevolume "github.com/aws/amazon-ecs-agent/agent/taskresource/volume" @@ -26,9 +27,10 @@ import ( ) const ( - HostVolumeType = "host" - DockerVolumeType = "docker" - EFSVolumeType = "efs" + HostVolumeType = "host" + DockerVolumeType = "docker" + EFSVolumeType = "efs" + FSxWindowsFileServerVolumeType = "fsxWindowsFileServer" ) // TaskVolume is a definition of all the volumes available for containers to @@ -71,12 +73,14 @@ func (tv *TaskVolume) UnmarshalJSON(b []byte) error { return tv.unmarshalDockerVolume(intermediate["dockerVolumeConfiguration"]) case EFSVolumeType: return tv.unmarshalEFSVolume(intermediate["efsVolumeConfiguration"]) + case FSxWindowsFileServerVolumeType: + return tv.unmarshalFSxWindowsFileServerVolume(intermediate["fsxWindowsFileServerVolumeConfiguration"]) default: return errors.Errorf("unrecognized volume type: %q", tv.Type) } } -// MarshalJSON overrides the logic for JSON-encoding a TaskVolume object +// MarshalJSON overrides the logic for JSON-encoding a TaskVolume object func (tv *TaskVolume) MarshalJSON() ([]byte, error) { result := make(map[string]interface{}) @@ -94,6 +98,8 @@ func (tv *TaskVolume) MarshalJSON() ([]byte, error) { result["host"] = tv.Volume case EFSVolumeType: result["efsVolumeConfiguration"] = tv.Volume + case FSxWindowsFileServerVolumeType: + result["fsxWindowsFileServerVolumeConfiguration"] = tv.Volume default: return nil, errors.Errorf("unrecognized volume type: %q", tv.Type) } @@ -129,6 +135,20 @@ func (tv *TaskVolume) unmarshalEFSVolume(data json.RawMessage) error { return nil } +func (tv *TaskVolume) unmarshalFSxWindowsFileServerVolume(data json.RawMessage) error { + if data == nil { + return errors.New("invalid volume: empty volume configuration") + } + var fsxWindowsFileServerVolumeConfig fsxwindowsfileserver.FSxWindowsFileServerVolumeConfig + err := json.Unmarshal(data, &fsxWindowsFileServerVolumeConfig) + if err != nil { + return err + } + + tv.Volume = &fsxWindowsFileServerVolumeConfig + return nil +} + func (tv *TaskVolume) unmarshalHostVolume(data json.RawMessage) error { if data == nil { return errors.New("invalid volume: empty volume configuration") diff --git a/agent/api/task/taskvolume_windows_test.go b/agent/api/task/taskvolume_windows_test.go new file mode 100644 index 00000000000..c9117fc9a73 --- /dev/null +++ b/agent/api/task/taskvolume_windows_test.go @@ -0,0 +1,139 @@ +// +build windows,unit + +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). You may +// not use this file except in compliance with the License. A copy of the +// License is located at +// +// http://aws.amazon.com/apache2.0/ +// +// or in the "license" file accompanying this file. This file is distributed +// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing +// permissions and limitations under the License. + +package task + +import ( + "encoding/json" + "fmt" + "testing" + + "github.com/aws/amazon-ecs-agent/agent/taskresource/fsxwindowsfileserver" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestMarshalTaskVolumeFSxWindowsFileServer(t *testing.T) { + task := &Task{ + Arn: "test", + Volumes: []TaskVolume{ + { + Name: "1", + Type: FSxWindowsFileServerVolumeType, + Volume: &fsxwindowsfileserver.FSxWindowsFileServerVolumeConfig{ + FileSystemID: "fs-12345678", + RootDirectory: "/test", + AuthConfig: fsxwindowsfileserver.FSxWindowsFileServerAuthConfig{ + CredentialsParameter: "arn", + Domain: "test", + }, + }, + }, + }, + } + + marshal, err := json.Marshal(task) + require.NoError(t, err, "Could not marshal task") + expectedTaskDef := `{ + "Arn": "test", + "Family": "", + "Version": "", + "Containers": null, + "associations": null, + "resources": null, + "volumes": [ + { + "fsxWindowsFileServerVolumeConfiguration": { + "authorizationConfig": { + "credentialsParameter": "arn", + "domain": "test" + }, + "fileSystemId": "fs-12345678", + "rootDirectory": "/test", + "fsxWindowsFileServerHostPath": "" + }, + "name": "1", + "type": "fsxWindowsFileServer" + } + ], + "DesiredStatus": "NONE", + "KnownStatus": "NONE", + "KnownTime": "0001-01-01T00:00:00Z", + "PullStartedAt": "0001-01-01T00:00:00Z", + "PullStoppedAt": "0001-01-01T00:00:00Z", + "ExecutionStoppedAt": "0001-01-01T00:00:00Z", + "SentStatus": "NONE", + "StartSequenceNumber": 0, + "StopSequenceNumber": 0, + "executionCredentialsID": "", + "ENI": null, + "AppMesh": null, + "PlatformFields": %s + }` + expectedTaskDef = fmt.Sprintf(expectedTaskDef, `{"cpuUnbounded": null, "memoryUnbounded": null}`) + require.JSONEq(t, expectedTaskDef, string(marshal)) +} + +func TestUnmarshalTaskVolumeFSxWindowsFileServer(t *testing.T) { + taskDef := []byte(`{ + "Arn": "test", + "Family": "", + "Version": "", + "Containers": null, + "associations": null, + "resources": null, + "volumes": [ + { + "fsxWindowsFileServerVolumeConfiguration": { + "authorizationConfig": { + "credentialsParameter": "arn", + "domain": "test" + }, + "fileSystemId": "fs-12345678", + "rootDirectory": "/test", + "fsxWindowsFileServerHostPath": "" + }, + "name": "1", + "type": "fsxWindowsFileServer" + } + ], + "DesiredStatus": "NONE", + "KnownStatus": "NONE", + "KnownTime": "0001-01-01T00:00:00Z", + "PullStartedAt": "0001-01-01T00:00:00Z", + "PullStoppedAt": "0001-01-01T00:00:00Z", + "ExecutionStoppedAt": "0001-01-01T00:00:00Z", + "SentStatus": "NONE", + "StartSequenceNumber": 0, + "StopSequenceNumber": 0, + "executionCredentialsID": "", + "ENI": null, + "AppMesh": null, + "PlatformFields": {} + }`) + var task Task + err := json.Unmarshal(taskDef, &task) + require.NoError(t, err, "Could not unmarshal task") + + require.Len(t, task.Volumes, 1) + assert.Equal(t, "fsxWindowsFileServer", task.Volumes[0].Type) + assert.Equal(t, "1", task.Volumes[0].Name) + fsxWindowsFileServerConfig, ok := task.Volumes[0].Volume.(*fsxwindowsfileserver.FSxWindowsFileServerVolumeConfig) + assert.True(t, ok) + assert.Equal(t, "fs-12345678", fsxWindowsFileServerConfig.FileSystemID) + assert.Equal(t, "/test", fsxWindowsFileServerConfig.RootDirectory) + assert.Equal(t, "arn", fsxWindowsFileServerConfig.AuthConfig.CredentialsParameter) + assert.Equal(t, "test", fsxWindowsFileServerConfig.AuthConfig.Domain) +} diff --git a/agent/app/agent_capability.go b/agent/app/agent_capability.go index 0688a151a51..cf71d6a6993 100644 --- a/agent/app/agent_capability.go +++ b/agent/app/agent_capability.go @@ -61,6 +61,7 @@ const ( capabilityEFS = "efs" capabilityEFSAuth = "efsAuth" capabilityEnvFilesS3 = "env-files.s3" + capabilityFSxWindowsFileServer = "fsxWindowsFileServer" ) var nameOnlyAttributes = []string{ @@ -131,6 +132,7 @@ var nameOnlyAttributes = []string{ // ecs.capability.gmsa // ecs.capability.efsAuth // ecs.capability.env-files.s3 +// ecs.capability.fsxWindowsFileServer func (agent *ecsAgent) capabilities() ([]*ecs.Attribute, error) { var capabilities []*ecs.Attribute @@ -215,6 +217,9 @@ func (agent *ecsAgent) capabilities() ([]*ecs.Attribute, error) { capabilities = agent.appendEFSVolumePluginCapabilities(capabilities, cap) } + // support fsxWindowsFileServer on ecs capabilities + capabilities = agent.appendFSxWindowsFileServerCapabilities(capabilities) + return capabilities, nil } diff --git a/agent/app/agent_capability_unix.go b/agent/app/agent_capability_unix.go index 75ced984a5b..9effa91a872 100644 --- a/agent/app/agent_capability_unix.go +++ b/agent/app/agent_capability_unix.go @@ -182,3 +182,7 @@ func (agent *ecsAgent) appendGMSACapabilities(capabilities []*ecs.Attribute) []* func (agent *ecsAgent) appendIPv6Capability(capabilities []*ecs.Attribute) []*ecs.Attribute { return appendNameOnlyAttribute(capabilities, attributePrefix+taskENIIPv6AttributeSuffix) } + +func (agent *ecsAgent) appendFSxWindowsFileServerCapabilities(capabilities []*ecs.Attribute) []*ecs.Attribute { + return capabilities +} diff --git a/agent/app/agent_capability_unix_test.go b/agent/app/agent_capability_unix_test.go index 23d82c5bfb1..faace568f56 100644 --- a/agent/app/agent_capability_unix_test.go +++ b/agent/app/agent_capability_unix_test.go @@ -856,3 +856,13 @@ func TestAppendGMSACapabilities(t *testing.T) { assert.Equal(t, len(inputCapabilities), len(capabilities)) assert.EqualValues(t, capabilities, inputCapabilities) } + +func TestAppendFSxWindowsFileServerCapabilities(t *testing.T) { + var inputCapabilities []*ecs.Attribute + + agent := &ecsAgent{} + + capabilities := agent.appendFSxWindowsFileServerCapabilities(inputCapabilities) + assert.Equal(t, len(inputCapabilities), len(capabilities)) + assert.EqualValues(t, capabilities, inputCapabilities) +} diff --git a/agent/app/agent_capability_unspecified.go b/agent/app/agent_capability_unspecified.go index c41a607fc64..401cb26f31e 100644 --- a/agent/app/agent_capability_unspecified.go +++ b/agent/app/agent_capability_unspecified.go @@ -117,3 +117,7 @@ func (agent *ecsAgent) appendEFSVolumePluginCapabilities(capabilities []*ecs.Att func (agent *ecsAgent) appendIPv6Capability(capabilities []*ecs.Attribute) []*ecs.Attribute { return capabilities } + +func (agent *ecsAgent) appendFSxWindowsFileServerCapabilities(capabilities []*ecs.Attribute) []*ecs.Attribute { + return capabilities +} diff --git a/agent/app/agent_capability_windows.go b/agent/app/agent_capability_windows.go index 01ba2caaad0..3aa419367c5 100644 --- a/agent/app/agent_capability_windows.go +++ b/agent/app/agent_capability_windows.go @@ -80,3 +80,11 @@ func (agent *ecsAgent) appendEFSVolumePluginCapabilities(capabilities []*ecs.Att func (agent *ecsAgent) appendIPv6Capability(capabilities []*ecs.Attribute) []*ecs.Attribute { return capabilities } + +func (agent *ecsAgent) appendFSxWindowsFileServerCapabilities(capabilities []*ecs.Attribute) []*ecs.Attribute { + if agent.cfg.FSxWindowsFileServerCapable { + return appendNameOnlyAttribute(capabilities, attributePrefix+capabilityFSxWindowsFileServer) + } + + return capabilities +} diff --git a/agent/app/agent_capability_windows_test.go b/agent/app/agent_capability_windows_test.go index d60dc841aea..e33155f2805 100644 --- a/agent/app/agent_capability_windows_test.go +++ b/agent/app/agent_capability_windows_test.go @@ -260,3 +260,47 @@ func TestAppendGMSACapabilitiesFalse(t *testing.T) { assert.Equal(t, len(expectedCapabilities), len(capabilities)) } + +func TestAppendFSxWindowsFileServerCapabilities(t *testing.T) { + var inputCapabilities []*ecs.Attribute + var expectedCapabilities []*ecs.Attribute + + expectedCapabilities = append(expectedCapabilities, + []*ecs.Attribute{ + { + Name: aws.String(attributePrefix + capabilityFSxWindowsFileServer), + }, + }...) + + agent := &ecsAgent{ + cfg: &config.Config{ + FSxWindowsFileServerCapable: true, + }, + } + + capabilities := agent.appendFSxWindowsFileServerCapabilities(inputCapabilities) + + assert.Equal(t, len(expectedCapabilities), len(capabilities)) + for i, expected := range expectedCapabilities { + assert.Equal(t, aws.StringValue(expected.Name), aws.StringValue(capabilities[i].Name)) + assert.Equal(t, aws.StringValue(expected.Value), aws.StringValue(capabilities[i].Value)) + } +} + +func TestAppendFSxWindowsFileServerCapabilitiesFalse(t *testing.T) { + var inputCapabilities []*ecs.Attribute + var expectedCapabilities []*ecs.Attribute + + expectedCapabilities = append(expectedCapabilities, + []*ecs.Attribute{}...) + + agent := &ecsAgent{ + cfg: &config.Config{ + FSxWindowsFileServerCapable: false, + }, + } + + capabilities := agent.appendFSxWindowsFileServerCapabilities(inputCapabilities) + + assert.Equal(t, len(expectedCapabilities), len(capabilities)) +} diff --git a/agent/app/agent_windows.go b/agent/app/agent_windows.go index 68b1965208b..5eb316926e6 100644 --- a/agent/app/agent_windows.go +++ b/agent/app/agent_windows.go @@ -21,6 +21,8 @@ import ( "sync" "time" + fsxfactory "github.com/aws/amazon-ecs-agent/agent/fsx/factory" + asmfactory "github.com/aws/amazon-ecs-agent/agent/asm/factory" "github.com/aws/amazon-ecs-agent/agent/credentials" "github.com/aws/amazon-ecs-agent/agent/data" @@ -259,6 +261,7 @@ func (agent *ecsAgent) initializeResourceFields(credentialsManager credentials.M ResourceFieldsCommon: &taskresource.ResourceFieldsCommon{ ASMClientCreator: asmfactory.NewClientCreator(), SSMClientCreator: ssmfactory.NewSSMClientCreator(), + FSxClientCreator: fsxfactory.NewFSxClientCreator(), CredentialsManager: credentialsManager, }, Ctx: agent.ctx, diff --git a/agent/config/config.go b/agent/config/config.go index 3104220b159..c17b271aba9 100644 --- a/agent/config/config.go +++ b/agent/config/config.go @@ -570,6 +570,7 @@ func environmentConfig() (Config, error) { SpotInstanceDrainingEnabled: parseBooleanDefaultFalseConfig("ECS_ENABLE_SPOT_INSTANCE_DRAINING"), GMSACapable: parseGMSACapability(), VolumePluginCapabilities: parseVolumePluginCapabilities(), + FSxWindowsFileServerCapable: parseFSxWindowsFileServerCapability(), }, err } diff --git a/agent/config/config_unix.go b/agent/config/config_unix.go index 85634f19ddf..a5a6254783d 100644 --- a/agent/config/config_unix.go +++ b/agent/config/config_unix.go @@ -84,6 +84,7 @@ func DefaultConfig() Config { NvidiaRuntime: DefaultNvidiaRuntime, CgroupCPUPeriod: defaultCgroupCPUPeriod, GMSACapable: false, + FSxWindowsFileServerCapable: false, } } diff --git a/agent/config/config_windows.go b/agent/config/config_windows.go index 434e22b0200..9787bb4e9c8 100644 --- a/agent/config/config_windows.go +++ b/agent/config/config_windows.go @@ -105,6 +105,7 @@ func DefaultConfig() Config { PollMetrics: BooleanDefaultTrue{Value: ExplicitlyDisabled}, PollingMetricsWaitDuration: DefaultPollingMetricsWaitDuration, GMSACapable: true, + FSxWindowsFileServerCapable: true, } } diff --git a/agent/config/parse_linux.go b/agent/config/parse_linux.go index 862f8605ce6..54b4b9ea403 100644 --- a/agent/config/parse_linux.go +++ b/agent/config/parse_linux.go @@ -18,3 +18,7 @@ package config func parseGMSACapability() bool { return false } + +func parseFSxWindowsFileServerCapability() bool { + return false +} diff --git a/agent/config/parse_unsupported.go b/agent/config/parse_unsupported.go index 50aa3148f7a..056aa91d30d 100644 --- a/agent/config/parse_unsupported.go +++ b/agent/config/parse_unsupported.go @@ -18,3 +18,7 @@ package config func parseGMSACapability() bool { return false } + +func parseFSxWindowsFileServerCapability() bool { + return false +} diff --git a/agent/config/parse_windows.go b/agent/config/parse_windows.go index 72c5b38eae2..da38d40fe72 100644 --- a/agent/config/parse_windows.go +++ b/agent/config/parse_windows.go @@ -17,9 +17,12 @@ package config import ( "os" + "strings" "syscall" "unsafe" + "golang.org/x/sys/windows/registry" + "github.com/aws/amazon-ecs-agent/agent/utils" "github.com/cihub/seelog" ) @@ -34,6 +37,22 @@ const ( // parseGMSACapability is used to determine if gMSA support can be enabled func parseGMSACapability() bool { envStatus := utils.ParseBool(os.Getenv("ECS_GMSA_SUPPORTED"), true) + return checkDomainJoinWithEnvOverride(envStatus) +} + +// parseFSxWindowsFileServerCapability is used to determine if fsxWindowsFileServer support can be enabled +func parseFSxWindowsFileServerCapability() bool { + // fsxwindowsfileserver is not supported on Windows 2016 and non-domain-joined container instances + status, err := isWindows2016() + if err != nil || status == true { + return false + } + + envStatus := utils.ParseBool(os.Getenv("ECS_FSX_WINDOWS_FILE_SERVER_SUPPORTED"), true) + return checkDomainJoinWithEnvOverride(envStatus) +} + +func checkDomainJoinWithEnvOverride(envStatus bool) bool { if envStatus { // Check if domain join check override is present skipDomainJoinCheck := utils.ParseBool(os.Getenv(envSkipDomainJoinCheck), false) @@ -41,7 +60,7 @@ func parseGMSACapability() bool { seelog.Debug("Skipping domain join validation based on environment override") return true } - // If gMSA feature is explicitly enabled, check if container instance is domain joined. + // check if container instance is domain joined. // If container instance is not domain joined, explicitly disable feature configuration. status, err := isDomainJoined() if err == nil && status == true { @@ -71,3 +90,26 @@ func isDomainJoined() (bool, error) { return status == syscall.NetSetupDomainName, nil } + +// isWindows2016 is used to check if container instance is versioned Windows 2016 +// Reference: https://godoc.org/golang.org/x/sys/windows/registry +var isWindows2016 = func() (bool, error) { + key, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion`, registry.QUERY_VALUE) + if err != nil { + seelog.Errorf("Unable to open Windows registry key to determine Windows version: %v", err) + return false, err + } + defer key.Close() + + version, _, err := key.GetStringValue("ProductName") + if err != nil { + seelog.Errorf("Unable to read current version from Windows registry: %v", err) + return false, err + } + + if strings.HasPrefix(version, "Windows Server 2016") { + return true, nil + } + + return false, nil +} diff --git a/agent/config/parse_windows_test.go b/agent/config/parse_windows_test.go index 4becda840ba..8f6579bffbe 100644 --- a/agent/config/parse_windows_test.go +++ b/agent/config/parse_windows_test.go @@ -40,3 +40,13 @@ func TestParseBooleanEnvVar(t *testing.T) { assert.False(t, parseBooleanDefaultFalseConfig("EXAMPLE_SETTING").Enabled()) assert.False(t, parseBooleanDefaultTrueConfig("EXAMPLE_SETTING").Enabled()) } + +func TestParseFSxWindowsFileServerCapability(t *testing.T) { + isWindows2016 = func() (bool, error) { + return false, nil + } + os.Setenv("ECS_FSX_WINDOWS_FILE_SERVER_SUPPORTED", "False") + defer os.Unsetenv("ECS_FSX_WINDOWS_FILE_SERVER_SUPPORTED") + + assert.False(t, parseFSxWindowsFileServerCapability()) +} diff --git a/agent/config/types.go b/agent/config/types.go index d6abcb54736..055aa4374ce 100644 --- a/agent/config/types.go +++ b/agent/config/types.go @@ -318,4 +318,8 @@ type Config struct { // VolumePluginCapabilities specifies the capabilities of the ecs volume plugin. VolumePluginCapabilities []string + + // FSxWindowsFileServerCapable is the config option to indicate if fsxWindowsFileServer is supported. + // It should be enabled by default only if the container instance is part of a valid active directory domain. + FSxWindowsFileServerCapable bool } diff --git a/agent/ecs_client/model/api/api-2.json b/agent/ecs_client/model/api/api-2.json index 7e1ee88bbea..2d20eeeb6da 100644 --- a/agent/ecs_client/model/api/api-2.json +++ b/agent/ecs_client/model/api/api-2.json @@ -1200,6 +1200,30 @@ "authorizationConfig":{"shape":"EFSAuthorizationConfig"} } }, + "FSxWindowsFileServerAuthorizationConfig":{ + "type":"structure", + "required":[ + "credentialsParameter", + "domain" + ], + "members":{ + "credentialsParameter":{"shape":"String"}, + "domain":{"shape":"String"} + } + }, + "FSxWindowsFileServerVolumeConfiguration":{ + "type":"structure", + "required":[ + "fileSystemId", + "rootDirectory", + "authorizationConfig" + ], + "members":{ + "fileSystemId":{"shape":"String"}, + "rootDirectory":{"shape":"String"}, + "authorizationConfig":{"shape":"FSxWindowsFileServerAuthorizationConfig"} + } + }, "Failure":{ "type":"structure", "members":{ @@ -2354,7 +2378,8 @@ "name":{"shape":"String"}, "host":{"shape":"HostVolumeProperties"}, "dockerVolumeConfiguration":{"shape":"DockerVolumeConfiguration"}, - "efsVolumeConfiguration":{"shape":"EFSVolumeConfiguration"} + "efsVolumeConfiguration":{"shape":"EFSVolumeConfiguration"}, + "fsxWindowsFileServerVolumeConfiguration":{"shape":"FSxWindowsFileServerVolumeConfiguration"} } }, "VolumeFrom":{ diff --git a/agent/ecs_client/model/ecs/api.go b/agent/ecs_client/model/ecs/api.go index ce1dea485cb..71340996ea4 100644 --- a/agent/ecs_client/model/ecs/api.go +++ b/agent/ecs_client/model/ecs/api.go @@ -7083,6 +7083,119 @@ func (s *EFSVolumeConfiguration) SetTransitEncryption(v string) *EFSVolumeConfig return s } +type FSxWindowsFileServerAuthorizationConfig struct { + _ struct{} `type:"structure"` + + // CredentialsParameter is a required field + CredentialsParameter *string `locationName:"credentialsParameter" type:"string" required:"true"` + + // Domain is a required field + Domain *string `locationName:"domain" type:"string" required:"true"` +} + +// String returns the string representation +func (s FSxWindowsFileServerAuthorizationConfig) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s FSxWindowsFileServerAuthorizationConfig) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *FSxWindowsFileServerAuthorizationConfig) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "FSxWindowsFileServerAuthorizationConfig"} + if s.CredentialsParameter == nil { + invalidParams.Add(request.NewErrParamRequired("CredentialsParameter")) + } + if s.Domain == nil { + invalidParams.Add(request.NewErrParamRequired("Domain")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetCredentialsParameter sets the CredentialsParameter field's value. +func (s *FSxWindowsFileServerAuthorizationConfig) SetCredentialsParameter(v string) *FSxWindowsFileServerAuthorizationConfig { + s.CredentialsParameter = &v + return s +} + +// SetDomain sets the Domain field's value. +func (s *FSxWindowsFileServerAuthorizationConfig) SetDomain(v string) *FSxWindowsFileServerAuthorizationConfig { + s.Domain = &v + return s +} + +type FSxWindowsFileServerVolumeConfiguration struct { + _ struct{} `type:"structure"` + + // AuthorizationConfig is a required field + AuthorizationConfig *FSxWindowsFileServerAuthorizationConfig `locationName:"authorizationConfig" type:"structure" required:"true"` + + // FileSystemId is a required field + FileSystemId *string `locationName:"fileSystemId" type:"string" required:"true"` + + // RootDirectory is a required field + RootDirectory *string `locationName:"rootDirectory" type:"string" required:"true"` +} + +// String returns the string representation +func (s FSxWindowsFileServerVolumeConfiguration) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s FSxWindowsFileServerVolumeConfiguration) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *FSxWindowsFileServerVolumeConfiguration) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "FSxWindowsFileServerVolumeConfiguration"} + if s.AuthorizationConfig == nil { + invalidParams.Add(request.NewErrParamRequired("AuthorizationConfig")) + } + if s.FileSystemId == nil { + invalidParams.Add(request.NewErrParamRequired("FileSystemId")) + } + if s.RootDirectory == nil { + invalidParams.Add(request.NewErrParamRequired("RootDirectory")) + } + if s.AuthorizationConfig != nil { + if err := s.AuthorizationConfig.Validate(); err != nil { + invalidParams.AddNested("AuthorizationConfig", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetAuthorizationConfig sets the AuthorizationConfig field's value. +func (s *FSxWindowsFileServerVolumeConfiguration) SetAuthorizationConfig(v *FSxWindowsFileServerAuthorizationConfig) *FSxWindowsFileServerVolumeConfiguration { + s.AuthorizationConfig = v + return s +} + +// SetFileSystemId sets the FileSystemId field's value. +func (s *FSxWindowsFileServerVolumeConfiguration) SetFileSystemId(v string) *FSxWindowsFileServerVolumeConfiguration { + s.FileSystemId = &v + return s +} + +// SetRootDirectory sets the RootDirectory field's value. +func (s *FSxWindowsFileServerVolumeConfiguration) SetRootDirectory(v string) *FSxWindowsFileServerVolumeConfiguration { + s.RootDirectory = &v + return s +} + // A failed resource. type Failure struct { _ struct{} `type:"structure"` @@ -12395,6 +12508,8 @@ type Volume struct { EfsVolumeConfiguration *EFSVolumeConfiguration `locationName:"efsVolumeConfiguration" type:"structure"` + FsxWindowsFileServerVolumeConfiguration *FSxWindowsFileServerVolumeConfiguration `locationName:"fsxWindowsFileServerVolumeConfiguration" type:"structure"` + // The contents of the host parameter determine whether your data volume persists // on the host container instance and where it is stored. If the host parameter // is empty, then the Docker daemon assigns a host path for your data volume, @@ -12431,6 +12546,11 @@ func (s *Volume) Validate() error { invalidParams.AddNested("EfsVolumeConfiguration", err.(request.ErrInvalidParams)) } } + if s.FsxWindowsFileServerVolumeConfiguration != nil { + if err := s.FsxWindowsFileServerVolumeConfiguration.Validate(); err != nil { + invalidParams.AddNested("FsxWindowsFileServerVolumeConfiguration", err.(request.ErrInvalidParams)) + } + } if invalidParams.Len() > 0 { return invalidParams @@ -12450,6 +12570,12 @@ func (s *Volume) SetEfsVolumeConfiguration(v *EFSVolumeConfiguration) *Volume { return s } +// SetFsxWindowsFileServerVolumeConfiguration sets the FsxWindowsFileServerVolumeConfiguration field's value. +func (s *Volume) SetFsxWindowsFileServerVolumeConfiguration(v *FSxWindowsFileServerVolumeConfiguration) *Volume { + s.FsxWindowsFileServerVolumeConfiguration = v + return s +} + // SetHost sets the Host field's value. func (s *Volume) SetHost(v *HostVolumeProperties) *Volume { s.Host = v diff --git a/agent/fsx/factory/factory.go b/agent/fsx/factory/factory.go new file mode 100644 index 00000000000..242e72ebfe8 --- /dev/null +++ b/agent/fsx/factory/factory.go @@ -0,0 +1,52 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). You may +// not use this file except in compliance with the License. A copy of the +// License is located at +// +// http://aws.amazon.com/apache2.0/ +// +// or in the "license" file accompanying this file. This file is distributed +// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing +// permissions and limitations under the License. + +package factory + +import ( + "time" + + "github.com/aws/amazon-ecs-agent/agent/credentials" + fsxclient "github.com/aws/amazon-ecs-agent/agent/fsx" + "github.com/aws/amazon-ecs-agent/agent/httpclient" + "github.com/aws/aws-sdk-go/aws" + awscreds "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/session" + "github.com/aws/aws-sdk-go/service/fsx" +) + +const ( + roundtripTimeout = 5 * time.Second +) + +type FSxClientCreator interface { + NewFSxClient(region string, creds credentials.IAMRoleCredentials) fsxclient.FSxClient +} + +func NewFSxClientCreator() FSxClientCreator { + return &fsxClientCreator{} +} + +type fsxClientCreator struct{} + +func (*fsxClientCreator) NewFSxClient(region string, + creds credentials.IAMRoleCredentials) fsxclient.FSxClient { + cfg := aws.NewConfig(). + WithHTTPClient(httpclient.New(roundtripTimeout, false)). + WithRegion(region). + WithCredentials( + awscreds.NewStaticCredentials(creds.AccessKeyID, creds.SecretAccessKey, + creds.SessionToken)) + sess := session.Must(session.NewSession(cfg)) + return fsx.New(sess) +} diff --git a/agent/fsx/factory/generate_mocks.go b/agent/fsx/factory/generate_mocks.go new file mode 100644 index 00000000000..8d0b457a7c5 --- /dev/null +++ b/agent/fsx/factory/generate_mocks.go @@ -0,0 +1,16 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). You may +// not use this file except in compliance with the License. A copy of the +// License is located at +// +// http://aws.amazon.com/apache2.0/ +// +// or in the "license" file accompanying this file. This file is distributed +// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing +// permissions and limitations under the License. + +package factory + +//go:generate mockgen -destination=mocks/factory_mocks.go -copyright_file=../../../scripts/copyright_file github.com/aws/amazon-ecs-agent/agent/fsx/factory FSxClientCreator diff --git a/agent/fsx/factory/mocks/factory_mocks.go b/agent/fsx/factory/mocks/factory_mocks.go new file mode 100644 index 00000000000..952a815dc63 --- /dev/null +++ b/agent/fsx/factory/mocks/factory_mocks.go @@ -0,0 +1,64 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). You may +// not use this file except in compliance with the License. A copy of the +// License is located at +// +// http://aws.amazon.com/apache2.0/ +// +// or in the "license" file accompanying this file. This file is distributed +// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing +// permissions and limitations under the License. +// + +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/aws/amazon-ecs-agent/agent/fsx/factory (interfaces: FSxClientCreator) + +// Package mock_factory is a generated GoMock package. +package mock_factory + +import ( + reflect "reflect" + + credentials "github.com/aws/amazon-ecs-agent/agent/credentials" + fsx "github.com/aws/amazon-ecs-agent/agent/fsx" + gomock "github.com/golang/mock/gomock" +) + +// MockFSxClientCreator is a mock of FSxClientCreator interface +type MockFSxClientCreator struct { + ctrl *gomock.Controller + recorder *MockFSxClientCreatorMockRecorder +} + +// MockFSxClientCreatorMockRecorder is the mock recorder for MockFSxClientCreator +type MockFSxClientCreatorMockRecorder struct { + mock *MockFSxClientCreator +} + +// NewMockFSxClientCreator creates a new mock instance +func NewMockFSxClientCreator(ctrl *gomock.Controller) *MockFSxClientCreator { + mock := &MockFSxClientCreator{ctrl: ctrl} + mock.recorder = &MockFSxClientCreatorMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockFSxClientCreator) EXPECT() *MockFSxClientCreatorMockRecorder { + return m.recorder +} + +// NewFSxClient mocks base method +func (m *MockFSxClientCreator) NewFSxClient(arg0 string, arg1 credentials.IAMRoleCredentials) fsx.FSxClient { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NewFSxClient", arg0, arg1) + ret0, _ := ret[0].(fsx.FSxClient) + return ret0 +} + +// NewFSxClient indicates an expected call of NewFSxClient +func (mr *MockFSxClientCreatorMockRecorder) NewFSxClient(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewFSxClient", reflect.TypeOf((*MockFSxClientCreator)(nil).NewFSxClient), arg0, arg1) +} diff --git a/agent/fsx/fsx.go b/agent/fsx/fsx.go new file mode 100644 index 00000000000..8a667886b6e --- /dev/null +++ b/agent/fsx/fsx.go @@ -0,0 +1,55 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). You may +// not use this file except in compliance with the License. A copy of the +// License is located at +// +// http://aws.amazon.com/apache2.0/ +// +// or in the "license" file accompanying this file. This file is distributed +// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing +// permissions and limitations under the License. + +package fsx + +import ( + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/fsx" + "github.com/pkg/errors" +) + +// GetFileSystemDNSNames returns a map of filesystem ids and corresponding dns names +// Example: key := fs-12345678, value := amznfsxujfqr2nj.test.com +func GetFileSystemDNSNames(fileSystemIds []string, client FSxClient) (map[string]string, error) { + out, err := describeFileSystems(fileSystemIds, client) + if err != nil { + return nil, err + } + + fileSystemDNSMap := make(map[string]string) + for _, filesystem := range out.FileSystems { + fileSystemDNSMap[aws.StringValue(filesystem.FileSystemId)] = aws.StringValue(filesystem.DNSName) + } + + return fileSystemDNSMap, nil +} + +// describeFileSystems makes the api call to the AWS FSx service to retrieve filesystems info +func describeFileSystems(fileSystemIds []string, client FSxClient) (*fsx.DescribeFileSystemsOutput, error) { + var IDs []*string + for _, id := range fileSystemIds { + IDs = append(IDs, aws.String(id)) + } + + in := &fsx.DescribeFileSystemsInput{ + FileSystemIds: IDs, + } + + out, err := client.DescribeFileSystems(in) + if err != nil { + return nil, errors.Wrapf(err, "fsx describing filesystem(s) from the service for %v", fileSystemIds) + } + + return out, nil +} diff --git a/agent/fsx/fsx_test.go b/agent/fsx/fsx_test.go new file mode 100644 index 00000000000..669b060b3bf --- /dev/null +++ b/agent/fsx/fsx_test.go @@ -0,0 +1,64 @@ +// +build unit + +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). You may +// not use this file except in compliance with the License. A copy of the +// License is located at +// +// http://aws.amazon.com/apache2.0/ +// +// or in the "license" file accompanying this file. This file is distributed +// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing +// permissions and limitations under the License. + +package fsx + +import ( + "errors" + "testing" + + mock_fsx "github.com/aws/amazon-ecs-agent/agent/fsx/mocks" + "github.com/golang/mock/gomock" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/fsx" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +const ( + fileSystemId = "fs-12345678" + dnsName = "test" +) + +func TestGetFileSystemDNSNames(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + mockFSxClient := mock_fsx.NewMockFSxClient(ctrl) + mockFSxClient.EXPECT().DescribeFileSystems(gomock.Any()).Return(&fsx.DescribeFileSystemsOutput{ + FileSystems: []*fsx.FileSystem{ + { + FileSystemId: aws.String(fileSystemId), + DNSName: aws.String(dnsName), + }, + }, + }, nil) + + out, err := GetFileSystemDNSNames([]string{fileSystemId}, mockFSxClient) + require.NoError(t, err) + assert.Equal(t, "test", out[fileSystemId]) +} + +func TestGetFileSystemDNSNamesError(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + mockFSxClient := mock_fsx.NewMockFSxClient(ctrl) + mockFSxClient.EXPECT().DescribeFileSystems(gomock.Any()).Return(nil, errors.New("test error")) + + _, err := GetFileSystemDNSNames([]string{fileSystemId}, mockFSxClient) + assert.Error(t, err) +} diff --git a/agent/fsx/generate_mocks.go b/agent/fsx/generate_mocks.go new file mode 100644 index 00000000000..376de7e3f5c --- /dev/null +++ b/agent/fsx/generate_mocks.go @@ -0,0 +1,16 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). You may +// not use this file except in compliance with the License. A copy of the +// License is located at +// +// http://aws.amazon.com/apache2.0/ +// +// or in the "license" file accompanying this file. This file is distributed +// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing +// permissions and limitations under the License. + +package fsx + +//go:generate mockgen -destination=mocks/fsx_mocks.go -copyright_file=../../scripts/copyright_file github.com/aws/amazon-ecs-agent/agent/fsx FSxClient diff --git a/agent/fsx/interface.go b/agent/fsx/interface.go new file mode 100644 index 00000000000..7df57b9e3fc --- /dev/null +++ b/agent/fsx/interface.go @@ -0,0 +1,20 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). You may +// not use this file except in compliance with the License. A copy of the +// License is located at +// +// http://aws.amazon.com/apache2.0/ +// +// or in the "license" file accompanying this file. This file is distributed +// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing +// permissions and limitations under the License. + +package fsx + +import "github.com/aws/aws-sdk-go/service/fsx" + +type FSxClient interface { + DescribeFileSystems(*fsx.DescribeFileSystemsInput) (*fsx.DescribeFileSystemsOutput, error) +} diff --git a/agent/fsx/mocks/fsx_mocks.go b/agent/fsx/mocks/fsx_mocks.go new file mode 100644 index 00000000000..1b1c68512f8 --- /dev/null +++ b/agent/fsx/mocks/fsx_mocks.go @@ -0,0 +1,64 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). You may +// not use this file except in compliance with the License. A copy of the +// License is located at +// +// http://aws.amazon.com/apache2.0/ +// +// or in the "license" file accompanying this file. This file is distributed +// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing +// permissions and limitations under the License. +// + +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/aws/amazon-ecs-agent/agent/fsx (interfaces: FSxClient) + +// Package mock_fsx is a generated GoMock package. +package mock_fsx + +import ( + reflect "reflect" + + fsx "github.com/aws/aws-sdk-go/service/fsx" + gomock "github.com/golang/mock/gomock" +) + +// MockFSxClient is a mock of FSxClient interface +type MockFSxClient struct { + ctrl *gomock.Controller + recorder *MockFSxClientMockRecorder +} + +// MockFSxClientMockRecorder is the mock recorder for MockFSxClient +type MockFSxClientMockRecorder struct { + mock *MockFSxClient +} + +// NewMockFSxClient creates a new mock instance +func NewMockFSxClient(ctrl *gomock.Controller) *MockFSxClient { + mock := &MockFSxClient{ctrl: ctrl} + mock.recorder = &MockFSxClientMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockFSxClient) EXPECT() *MockFSxClientMockRecorder { + return m.recorder +} + +// DescribeFileSystems mocks base method +func (m *MockFSxClient) DescribeFileSystems(arg0 *fsx.DescribeFileSystemsInput) (*fsx.DescribeFileSystemsOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DescribeFileSystems", arg0) + ret0, _ := ret[0].(*fsx.DescribeFileSystemsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DescribeFileSystems indicates an expected call of DescribeFileSystems +func (mr *MockFSxClientMockRecorder) DescribeFileSystems(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeFileSystems", reflect.TypeOf((*MockFSxClient)(nil).DescribeFileSystems), arg0) +} diff --git a/agent/statemanager/state_manager.go b/agent/statemanager/state_manager.go index 6fab9fe1c67..560d7eb2935 100644 --- a/agent/statemanager/state_manager.go +++ b/agent/statemanager/state_manager.go @@ -115,8 +115,9 @@ const ( // a) Add 'authorizationConfig', 'transitEncryption' and 'transitEncryptionPort' to 'taskresource.volume.EFSVolumeConfig' // b) Add 'pauseContainerPID' field to 'taskresource.volume.VolumeResource' // 28) Add 'envfile' field to 'resources' + // 29) Add 'fsxwindowsfileserver' field to 'resources' - ECSDataVersion = 28 + ECSDataVersion = 29 // ecsDataFile specifies the filename in the ECS_DATADIR ecsDataFile = "ecs_agent_data.json" diff --git a/agent/taskresource/fsxwindowsfileserver/fsxwindowsfileserver_unsupported.go b/agent/taskresource/fsxwindowsfileserver/fsxwindowsfileserver_unsupported.go new file mode 100644 index 00000000000..2ba0239b986 --- /dev/null +++ b/agent/taskresource/fsxwindowsfileserver/fsxwindowsfileserver_unsupported.go @@ -0,0 +1,182 @@ +// +build !windows + +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). You may +// not use this file except in compliance with the License. A copy of the +// License is located at +// +// http://aws.amazon.com/apache2.0/ +// +// or in the "license" file accompanying this file. This file is distributed +// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing +// permissions and limitations under the License. + +package fsxwindowsfileserver + +import ( + "time" + + apicontainer "github.com/aws/amazon-ecs-agent/agent/api/container" + apicontainerstatus "github.com/aws/amazon-ecs-agent/agent/api/container/status" + "github.com/aws/amazon-ecs-agent/agent/api/task/status" + asmfactory "github.com/aws/amazon-ecs-agent/agent/asm/factory" + "github.com/aws/amazon-ecs-agent/agent/credentials" + fsxfactory "github.com/aws/amazon-ecs-agent/agent/fsx/factory" + ssmfactory "github.com/aws/amazon-ecs-agent/agent/ssm/factory" + "github.com/aws/amazon-ecs-agent/agent/taskresource" + resourcestatus "github.com/aws/amazon-ecs-agent/agent/taskresource/status" + "github.com/pkg/errors" +) + +// FSxWindowsFileServerResource represents a fsxwindowsfileserver resource +type FSxWindowsFileServerResource struct { +} + +// FSxWindowsFileServerVolumeConfig represents fsxWindowsFileServer volume configuration. +type FSxWindowsFileServerVolumeConfig struct { +} + +// NewFSxWindowsFileServerResource creates a new FSxWindowsFileServerResource object +func NewFSxWindowsFileServerResource( + taskARN, + region string, + name string, + volumeType string, + volumeConfig *FSxWindowsFileServerVolumeConfig, + hostPath string, + executionCredentialsID string, + credentialsManager credentials.Manager, + ssmClientCreator ssmfactory.SSMClientCreator, + asmClientCreator asmfactory.ClientCreator, + fsxClientCreator fsxfactory.FSxClientCreator) (*FSxWindowsFileServerResource, error) { + return nil, errors.New("not supported") +} + +func (fv *FSxWindowsFileServerResource) Initialize(resourceFields *taskresource.ResourceFields, + taskKnownStatus status.TaskStatus, + taskDesiredStatus status.TaskStatus) { +} + +// GetTerminalReason returns an error string to propagate up through to task +// state change messages +func (fv *FSxWindowsFileServerResource) GetTerminalReason() string { + return "undefined" +} + +// GetDesiredStatus safely returns the desired status of the task +func (fv *FSxWindowsFileServerResource) GetDesiredStatus() resourcestatus.ResourceStatus { + return resourcestatus.ResourceStatusNone +} + +// SetDesiredStatus safely sets the desired status of the resource +func (fv *FSxWindowsFileServerResource) SetDesiredStatus(status resourcestatus.ResourceStatus) { +} + +// DesiredTerminal returns true if the fsxwindowsfileserver resource's desired status is REMOVED +func (fv *FSxWindowsFileServerResource) DesiredTerminal() bool { + return false +} + +// KnownCreated returns true if the fsxwindowsfileserver resource's known status is CREATED +func (fv *FSxWindowsFileServerResource) KnownCreated() bool { + return false +} + +// TerminalStatus returns the last transition state of fsxwindowsfileserver resource +func (fv *FSxWindowsFileServerResource) TerminalStatus() resourcestatus.ResourceStatus { + return resourcestatus.ResourceStatusNone +} + +// NextKnownState returns the state that the resource should +// progress to based on its `KnownState`. +func (fv *FSxWindowsFileServerResource) NextKnownState() resourcestatus.ResourceStatus { + return resourcestatus.ResourceStatusNone +} + +// ApplyTransition calls the function required to move to the specified status +func (fv *FSxWindowsFileServerResource) ApplyTransition(nextState resourcestatus.ResourceStatus) error { + return errors.New("not supported") +} + +// SteadyState returns the transition state of the resource defined as "ready" +func (fv *FSxWindowsFileServerResource) SteadyState() resourcestatus.ResourceStatus { + return resourcestatus.ResourceStatusNone +} + +// SetKnownStatus safely sets the currently known status of the resource +func (fv *FSxWindowsFileServerResource) SetKnownStatus(status resourcestatus.ResourceStatus) { +} + +// SetAppliedStatus sets the applied status of resource and returns whether +// the resource is already in a transition +func (fv *FSxWindowsFileServerResource) SetAppliedStatus(status resourcestatus.ResourceStatus) bool { + return false +} + +// GetKnownStatus safely returns the currently known status of the task +func (fv *FSxWindowsFileServerResource) GetKnownStatus() resourcestatus.ResourceStatus { + return resourcestatus.ResourceStatusNone +} + +// StatusString returns the string of the fsxwindowsfileserver resource status +func (fv *FSxWindowsFileServerResource) StatusString(status resourcestatus.ResourceStatus) string { + return "undefined" +} + +// SetCreatedAt sets the timestamp for resource's creation time +func (fv *FSxWindowsFileServerResource) SetCreatedAt(createdAt time.Time) { +} + +// GetCreatedAt sets the timestamp for resource's creation time +func (fv *FSxWindowsFileServerResource) GetCreatedAt() time.Time { + return time.Time{} +} + +// Source returns the host path of the fsxwindowsfileserver resource which is used as the source of the volume mount +func (cfg *FSxWindowsFileServerVolumeConfig) Source() string { + return "undefined" +} + +// GetName safely returns the name of the resource +func (fv *FSxWindowsFileServerResource) GetName() string { + return "undefined" +} + +// Create is used to create all the fsxwindowsfileserver resources for a given task +func (fv *FSxWindowsFileServerResource) Create() error { + return errors.New("not supported") +} + +// Cleanup removes the fsxwindowsfileserver resources created for the task +func (fv *FSxWindowsFileServerResource) Cleanup() error { + return errors.New("not supported") +} + +// MarshalJSON serialises the FSxWindowsFileServerResourceJSON struct to JSON +func (fv *FSxWindowsFileServerResource) MarshalJSON() ([]byte, error) { + return nil, errors.New("not supported") +} + +// UnmarshalJSON deserialises the raw JSON to a FSxWindowsFileServerResourceJSON struct +func (fv *FSxWindowsFileServerResource) UnmarshalJSON(b []byte) error { + return errors.New("not supported") +} + +// GetAppliedStatus safely returns the currently applied status of the resource +func (fv *FSxWindowsFileServerResource) GetAppliedStatus() resourcestatus.ResourceStatus { + return resourcestatus.ResourceStatusNone +} + +func (fv *FSxWindowsFileServerResource) DependOnTaskNetwork() bool { + return false +} + +func (fv *FSxWindowsFileServerResource) BuildContainerDependency(containerName string, satisfied apicontainerstatus.ContainerStatus, + dependent resourcestatus.ResourceStatus) { +} + +func (fv *FSxWindowsFileServerResource) GetContainerDependencies(dependent resourcestatus.ResourceStatus) []apicontainer.ContainerDependency { + return nil +} diff --git a/agent/taskresource/fsxwindowsfileserver/fsxwindowsfileserver_windows.go b/agent/taskresource/fsxwindowsfileserver/fsxwindowsfileserver_windows.go new file mode 100644 index 00000000000..8948193f051 --- /dev/null +++ b/agent/taskresource/fsxwindowsfileserver/fsxwindowsfileserver_windows.go @@ -0,0 +1,682 @@ +// +build windows + +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). You may +// not use this file except in compliance with the License. A copy of the +// License is located at +// +// http://aws.amazon.com/apache2.0/ +// +// or in the "license" file accompanying this file. This file is distributed +// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing +// permissions and limitations under the License. + +package fsxwindowsfileserver + +import ( + "encoding/json" + "fmt" + "os/exec" + "path/filepath" + "strings" + "sync" + "time" + + "github.com/aws/amazon-ecs-agent/agent/asm" + "github.com/aws/amazon-ecs-agent/agent/ssm" + "github.com/aws/amazon-ecs-agent/agent/utils" + "github.com/aws/aws-sdk-go/aws/arn" + + apicontainer "github.com/aws/amazon-ecs-agent/agent/api/container" + apicontainerstatus "github.com/aws/amazon-ecs-agent/agent/api/container/status" + "github.com/aws/amazon-ecs-agent/agent/api/task/status" + asmfactory "github.com/aws/amazon-ecs-agent/agent/asm/factory" + "github.com/aws/amazon-ecs-agent/agent/credentials" + "github.com/aws/amazon-ecs-agent/agent/fsx" + fsxfactory "github.com/aws/amazon-ecs-agent/agent/fsx/factory" + ssmfactory "github.com/aws/amazon-ecs-agent/agent/ssm/factory" + "github.com/aws/amazon-ecs-agent/agent/taskresource" + resourcestatus "github.com/aws/amazon-ecs-agent/agent/taskresource/status" + "github.com/cihub/seelog" + "github.com/pkg/errors" +) + +const ( + resourceProvisioningError = "VolumeError: Agent could not create task's volume resources" +) + +// FSxWindowsFileServerResource represents a fsxwindowsfileserver resource +type FSxWindowsFileServerResource struct { + Name string + VolumeType string + VolumeConfig FSxWindowsFileServerVolumeConfig + taskARN string + region string + executionCredentialsID string + credentialsManager credentials.Manager + + // ssmClientCreator is a factory interface that creates new SSM clients. + ssmClientCreator ssmfactory.SSMClientCreator + // asmClientCreator is a factory interface that creates new ASM clients. + asmClientCreator asmfactory.ClientCreator + // fsxClientCreator is a factory interface that creates new FSx clients. + fsxClientCreator fsxfactory.FSxClientCreator + + // fields that are set later during resource creation + FSxWindowsFileServerDNSName string + Credentials FSxWindowsFileServerCredentials + + // Fields for the common functionality of task resource. Access to these fields are protected by lock. + createdAtUnsafe time.Time + knownStatusUnsafe resourcestatus.ResourceStatus + desiredStatusUnsafe resourcestatus.ResourceStatus + appliedStatusUnsafe resourcestatus.ResourceStatus + statusToTransitions map[resourcestatus.ResourceStatus]func() error + terminalReason string + terminalReasonOnce sync.Once + lock sync.RWMutex +} + +// FSxWindowsFileServerVolumeConfig represents fsxWindowsFileServer volume configuration. +type FSxWindowsFileServerVolumeConfig struct { + FileSystemID string `json:"fileSystemId,omitempty"` + RootDirectory string `json:"rootDirectory,omitempty"` + AuthConfig FSxWindowsFileServerAuthConfig `json:"authorizationConfig,omitempty"` + // HostPath is used for bind mount as part of HostConfig. + HostPath string `json:"fsxWindowsFileServerHostPath"` +} + +// FSxWindowsFileServerAuthConfig contains auth config for a fsxWindowsFileServer volume. +type FSxWindowsFileServerAuthConfig struct { + CredentialsParameter string `json:"credentialsParameter,omitempty"` + Domain string `json:"domain,omitempty"` +} + +// FSxWindowsFileServerCredentials represents user credentials for accessing the fsxWindowsFileServer volume +type FSxWindowsFileServerCredentials struct { + Username string `json:"username"` + Password string `json:"password"` +} + +// NewFSxWindowsFileServerResource creates a new FSxWindowsFileServerResource object +func NewFSxWindowsFileServerResource( + taskARN, + region string, + name string, + volumeType string, + volumeConfig *FSxWindowsFileServerVolumeConfig, + hostPath string, + executionCredentialsID string, + credentialsManager credentials.Manager, + ssmClientCreator ssmfactory.SSMClientCreator, + asmClientCreator asmfactory.ClientCreator, + fsxClientCreator fsxfactory.FSxClientCreator) (*FSxWindowsFileServerResource, error) { + + fv := &FSxWindowsFileServerResource{ + Name: name, + VolumeType: volumeType, + VolumeConfig: FSxWindowsFileServerVolumeConfig{ + FileSystemID: volumeConfig.FileSystemID, + RootDirectory: volumeConfig.RootDirectory, + AuthConfig: volumeConfig.AuthConfig, + HostPath: hostPath, + }, + taskARN: taskARN, + region: region, + executionCredentialsID: executionCredentialsID, + credentialsManager: credentialsManager, + ssmClientCreator: ssmClientCreator, + asmClientCreator: asmClientCreator, + fsxClientCreator: fsxClientCreator, + } + + fv.initStatusToTransition() + return fv, nil +} + +func (fv *FSxWindowsFileServerResource) Initialize(resourceFields *taskresource.ResourceFields, + taskKnownStatus status.TaskStatus, + taskDesiredStatus status.TaskStatus) { + + fv.credentialsManager = resourceFields.CredentialsManager + fv.ssmClientCreator = resourceFields.SSMClientCreator + fv.asmClientCreator = resourceFields.ASMClientCreator + fv.fsxClientCreator = resourceFields.FSxClientCreator + fv.initStatusToTransition() +} + +func (fv *FSxWindowsFileServerResource) initStatusToTransition() { + statusToTransitions := map[resourcestatus.ResourceStatus]func() error{ + resourcestatus.ResourceStatus(FSxWindowsFileServerVolumeCreated): fv.Create, + } + + fv.statusToTransitions = statusToTransitions +} + +// DesiredTerminal returns true if the fsxwindowsfileserver's desired status is REMOVED +func (fv *FSxWindowsFileServerResource) DesiredTerminal() bool { + fv.lock.RLock() + defer fv.lock.RUnlock() + + return fv.desiredStatusUnsafe == resourcestatus.ResourceStatus(FSxWindowsFileServerVolumeRemoved) +} + +// GetTerminalReason returns an error string to propagate up through to task +// state change messages +func (fv *FSxWindowsFileServerResource) GetTerminalReason() string { + if fv.terminalReason == "" { + return resourceProvisioningError + } + return fv.terminalReason +} + +func (fv *FSxWindowsFileServerResource) setTerminalReason(reason string) { + fv.terminalReasonOnce.Do(func() { + seelog.Debugf("fsxwindowsfileserver resource [%s]: setting terminal reason for fsxwindowsfileserver resource in task: [%s]", fv.Name, fv.taskARN) + fv.terminalReason = reason + }) +} + +// GetDesiredStatus safely returns the desired status of the task +func (fv *FSxWindowsFileServerResource) GetDesiredStatus() resourcestatus.ResourceStatus { + fv.lock.RLock() + defer fv.lock.RUnlock() + + return fv.desiredStatusUnsafe +} + +// SetDesiredStatus safely sets the desired status of the resource +func (fv *FSxWindowsFileServerResource) SetDesiredStatus(status resourcestatus.ResourceStatus) { + fv.lock.Lock() + defer fv.lock.Unlock() + + fv.desiredStatusUnsafe = status +} + +// GetKnownStatus safely returns the currently known status of the task +func (fv *FSxWindowsFileServerResource) GetKnownStatus() resourcestatus.ResourceStatus { + fv.lock.RLock() + defer fv.lock.RUnlock() + + return fv.knownStatusUnsafe +} + +// SetKnownStatus safely sets the currently known status of the resource +func (fv *FSxWindowsFileServerResource) SetKnownStatus(status resourcestatus.ResourceStatus) { + fv.lock.Lock() + defer fv.lock.Unlock() + + fv.knownStatusUnsafe = status + fv.updateAppliedStatusUnsafe(status) +} + +// KnownCreated returns true if the fsxwindowsfileserver's known status is CREATED +func (fv *FSxWindowsFileServerResource) KnownCreated() bool { + fv.lock.RLock() + defer fv.lock.RUnlock() + + return fv.knownStatusUnsafe == resourcestatus.ResourceStatus(FSxWindowsFileServerVolumeCreated) +} + +// TerminalStatus returns the last transition state of fsxwindowsfileserver +func (fv *FSxWindowsFileServerResource) TerminalStatus() resourcestatus.ResourceStatus { + return resourcestatus.ResourceStatus(FSxWindowsFileServerVolumeRemoved) +} + +// NextKnownState returns the state that the resource should +// progress to based on its `KnownState`. +func (fv *FSxWindowsFileServerResource) NextKnownState() resourcestatus.ResourceStatus { + return fv.GetKnownStatus() + 1 +} + +// SteadyState returns the transition state of the resource defined as "ready" +func (fv *FSxWindowsFileServerResource) SteadyState() resourcestatus.ResourceStatus { + return resourcestatus.ResourceStatus(FSxWindowsFileServerVolumeCreated) +} + +// ApplyTransition calls the function required to move to the specified status +func (fv *FSxWindowsFileServerResource) ApplyTransition(nextState resourcestatus.ResourceStatus) error { + transitionFunc, ok := fv.statusToTransitions[nextState] + if !ok { + err := errors.Errorf("resource [%s]: transition to %s impossible", fv.Name, + fv.StatusString(nextState)) + fv.setTerminalReason(err.Error()) + return err + } + + return transitionFunc() +} + +// SetAppliedStatus sets the applied status of resource and returns whether +// the resource is already in a transition +func (fv *FSxWindowsFileServerResource) SetAppliedStatus(status resourcestatus.ResourceStatus) bool { + fv.lock.Lock() + defer fv.lock.Unlock() + + if fv.appliedStatusUnsafe != resourcestatus.ResourceStatus(FSxWindowsFileServerVolumeStatusNone) { + // return false to indicate the set operation failed + return false + } + + fv.appliedStatusUnsafe = status + return true +} + +// StatusString returns the string of the fsxwindowsfileserver resource status +func (fv *FSxWindowsFileServerResource) StatusString(status resourcestatus.ResourceStatus) string { + return FSxWindowsFileServerVolumeStatus(status).String() +} + +// GetCreatedAt gets the timestamp for resource's creation time +func (fv *FSxWindowsFileServerResource) GetCreatedAt() time.Time { + fv.lock.RLock() + defer fv.lock.RUnlock() + + return fv.createdAtUnsafe +} + +// SetCreatedAt sets the timestamp for resource's creation time +func (fv *FSxWindowsFileServerResource) SetCreatedAt(createdAt time.Time) { + if createdAt.IsZero() { + return + } + fv.lock.Lock() + defer fv.lock.Unlock() + + fv.createdAtUnsafe = createdAt +} + +// Source returns the host path of the fsxwindowsfileserver resource which is used as the source of the volume mount +func (cfg *FSxWindowsFileServerVolumeConfig) Source() string { + return utils.GetCanonicalPath(cfg.HostPath) +} + +// GetName safely returns the name of the fsxwindowsfileserver resource +func (fv *FSxWindowsFileServerResource) GetName() string { + fv.lock.RLock() + defer fv.lock.RUnlock() + + return fv.Name +} + +// GetVolumeConfig safely returns the volume config of the fsxwindowsfileserver resource +func (fv *FSxWindowsFileServerResource) GetVolumeConfig() FSxWindowsFileServerVolumeConfig { + fv.lock.RLock() + defer fv.lock.RUnlock() + + return fv.VolumeConfig +} + +// GetCredentials safely returns the user credentials of the fsxwindowsfileserver resource +func (fv *FSxWindowsFileServerResource) GetCredentials() FSxWindowsFileServerCredentials { + fv.lock.RLock() + defer fv.lock.RUnlock() + + return fv.Credentials +} + +// GetFileSystemDNSName safely returns the filesystem dns name of the fsxwindowsfileserver resource +func (fv *FSxWindowsFileServerResource) GetFileSystemDNSName() string { + fv.lock.RLock() + defer fv.lock.RUnlock() + + return fv.FSxWindowsFileServerDNSName +} + +// getExecutionCredentialsID safely returns the execution role's credential ID +func (fv *FSxWindowsFileServerResource) GetExecutionCredentialsID() string { + fv.lock.RLock() + defer fv.lock.RUnlock() + + return fv.executionCredentialsID +} + +// SetCredentials safely updates the user credentials of the fsxwindowsfileserver resource +func (fv *FSxWindowsFileServerResource) SetCredentials(credentials FSxWindowsFileServerCredentials) { + fv.lock.Lock() + defer fv.lock.Unlock() + + fv.Credentials = credentials +} + +// SetFileSystemDNSName safely updates the filesystem dns name of the fsxwindowsfileserver resource +func (fv *FSxWindowsFileServerResource) SetFileSystemDNSName(DNSName string) { + fv.lock.Lock() + defer fv.lock.Unlock() + + fv.FSxWindowsFileServerDNSName = DNSName +} + +// SetFileSystemDNSName safely updates volume config's root directory of the fsxwindowsfileserver resource +func (fv *FSxWindowsFileServerResource) SetRootDirectory(rootDirectory string) { + fv.lock.Lock() + defer fv.lock.Unlock() + + fv.VolumeConfig.RootDirectory = rootDirectory +} + +var DriveLetterAvailable = utils.IsAvailableDriveLetter + +// Create is used to create all the fsxwindowsfileserver resources for a given task +func (fv *FSxWindowsFileServerResource) Create() error { + var err error + + volumeConfig := fv.GetVolumeConfig() + localPath := volumeConfig.HostPath + + // formatting to keep powershell happy + localPathArg := fmt.Sprintf("-LocalPath \"%s\"", strings.Trim(localPath, `\`)) + + // remove mount if localPath is not available + // handling case where agent crashes after mount and before resource status is updated + if !(DriveLetterAvailable(localPath)) { + err = fv.removeHostMount(localPathArg) + if err != nil { + seelog.Errorf("Failed to remove existing fsxwindowsfileserver resource mount on the container instance: %v", err) + fv.setTerminalReason(err.Error()) + return err + } + } + + var iamCredentials credentials.IAMRoleCredentials + executionCredentials, ok := fv.credentialsManager.GetTaskCredentials(fv.GetExecutionCredentialsID()) + if !ok { + err = errors.New("fsxwindowsfileserver resource: unable to find execution role credentials") + fv.setTerminalReason(err.Error()) + return err + } + iamCredentials = executionCredentials.GetIAMRoleCredentials() + + err = fv.retrieveCredentials(volumeConfig.AuthConfig.CredentialsParameter, iamCredentials) + if err != nil { + fv.setTerminalReason(err.Error()) + return err + } + + err = fv.retrieveFileSystemDNSName(volumeConfig.FileSystemID, iamCredentials) + if err != nil { + fv.setTerminalReason(err.Error()) + return err + } + + fv.handleRootDirectory(volumeConfig.RootDirectory) + + creds := fv.GetCredentials() + if creds.Username == "" || creds.Password == "" { + return errors.New("invalid credentials for mounting fsxwindowsfileserver volume on the container instance") + } + // formatting to keep powershell happy + username := volumeConfig.AuthConfig.Domain + `\` + creds.Username + remotePath := fmt.Sprintf(`\\%s`, fv.GetFileSystemDNSName()) + if volumeConfig.RootDirectory != "" { + remotePath = fmt.Sprintf(`%s\%s`, remotePath, volumeConfig.RootDirectory) + } else { + remotePath = fmt.Sprintf(`%s\share`, remotePath) + } + + password := creds.Password + + err = fv.performHostMount(remotePath, localPathArg, username, password) + if err != nil { + fv.setTerminalReason(err.Error()) + return err + } + + return nil +} + +func (fv *FSxWindowsFileServerResource) retrieveCredentials(credentialsParameterARN string, iamCredentials credentials.IAMRoleCredentials) error { + parsedARN, err := arn.Parse(credentialsParameterARN) + if err != nil { + fv.setTerminalReason(err.Error()) + return err + } + + parsedARNService := parsedARN.Service + switch parsedARNService { + case "ssm": + err = fv.retrieveSSMCredentials(credentialsParameterARN, iamCredentials) + if err != nil { + seelog.Errorf("Failed to retrieve credentials from ssm: %v", err) + fv.setTerminalReason(err.Error()) + return err + } + case "secretsmanager": + err = fv.retrieveASMCredentials(credentialsParameterARN, iamCredentials) + if err != nil { + seelog.Errorf("Failed to retrieve credentials from asm: %v", err) + fv.setTerminalReason(err.Error()) + return err + } + default: + err = errors.New("unsupported credentialsParameter, only ssm/secretsmanager ARNs are valid") + fv.setTerminalReason(err.Error()) + return err + } + + return nil +} + +func (fv *FSxWindowsFileServerResource) retrieveSSMCredentials(credentialsParameterARN string, iamCredentials credentials.IAMRoleCredentials) error { + parsedARN, err := arn.Parse(credentialsParameterARN) + if err != nil { + return err + } + + ssmClient := fv.ssmClientCreator.NewSSMClient(fv.region, iamCredentials) + ssmParam := filepath.Base(parsedARN.Resource) + ssmParams := []string{ssmParam} + + ssmParamMap, err := ssm.GetParametersFromSSM(ssmParams, ssmClient) + if err != nil { + return err + } + + ssmParamData, _ := ssmParamMap[ssmParam] + creds := FSxWindowsFileServerCredentials{} + + if err := json.Unmarshal([]byte(ssmParamData), &creds); err != nil { + return err + } + + fv.SetCredentials(creds) + return nil +} + +func (fv *FSxWindowsFileServerResource) retrieveASMCredentials(credentialsParameterARN string, iamCredentials credentials.IAMRoleCredentials) error { + _, err := arn.Parse(credentialsParameterARN) + if err != nil { + return err + } + + asmClient := fv.asmClientCreator.NewASMClient(fv.region, iamCredentials) + asmData, err := asm.GetSecretFromASM(credentialsParameterARN, asmClient) + if err != nil { + return err + } + + creds := FSxWindowsFileServerCredentials{} + if err := json.Unmarshal([]byte(asmData), &creds); err != nil { + return err + } + + fv.SetCredentials(creds) + return nil +} + +func (fv *FSxWindowsFileServerResource) retrieveFileSystemDNSName(fileSystemId string, iamCredentials credentials.IAMRoleCredentials) error { + fileSystemIds := []string{fileSystemId} + fsxClient := fv.fsxClientCreator.NewFSxClient(fv.region, iamCredentials) + fileSystemDNSMap, err := fsx.GetFileSystemDNSNames(fileSystemIds, fsxClient) + if err != nil { + fv.setTerminalReason(err.Error()) + return err + } + + fv.SetFileSystemDNSName(fileSystemDNSMap[fileSystemId]) + return nil +} + +var execCommand = exec.Command + +func (fv *FSxWindowsFileServerResource) performHostMount(remotePath string, localPathArg string, username string, password string) error { + // formatting to keep powershell happy + creds := fmt.Sprintf("-Credential $(New-Object System.Management.Automation.PSCredential(\"%s\", $(ConvertTo-SecureString \"%s\" -AsPlainText -Force)))", username, password) + remotePathArg := fmt.Sprintf("-RemotePath \"%s\"", remotePath) + + // New-SmbGlobalMapping cmdlet creates an SMB mapping between the container instance + // and SMB share (FSx for Windows File Server file-system) + cmd := execCommand("powershell.exe", + "New-SmbGlobalMapping", + localPathArg, + remotePathArg, + creds, + "-Persistent $true", + "-RequirePrivacy $true", + "-ErrorAction Stop") + + _, err := cmd.CombinedOutput() + if err != nil { + seelog.Errorf("Failed to map fsxwindowsfileserver resource on the container instance: %v", err) + fv.setTerminalReason(err.Error()) + return err + } + + // Get-SmbGlobalMapping cmdlet retrieves existing SMB mappings + cmd = execCommand("powershell.exe", "Get-SmbGlobalMapping", localPathArg) + + _, err = cmd.CombinedOutput() + if err != nil { + return errors.New("failed to verify fsxwindowsfileserver resource map on the container instance") + } + + return nil +} + +func (fv *FSxWindowsFileServerResource) handleRootDirectory(rootDirectory string) { + dir := utils.GetCanonicalPath(rootDirectory) + dir = strings.Trim(dir, "\\") + + fv.SetRootDirectory(dir) + return +} + +func (fv *FSxWindowsFileServerResource) removeHostMount(localPathArg string) error { + // Remove-SmbGlobalMapping cmdlet removes the existing Server Message Block (SMB) mapping between the + // container instance and SMB share (FSx for Windows File Server file-system) + cmd := execCommand("powershell.exe", "Remove-SmbGlobalMapping", localPathArg, "-Force") + + _, err := cmd.CombinedOutput() + if err != nil { + return err + } + return nil +} + +func (fv *FSxWindowsFileServerResource) Cleanup() error { + localPath := fv.VolumeConfig.HostPath + // formatting to keep powershell happy + localPathArg := fmt.Sprintf("-LocalPath \"%s\"", strings.Trim(localPath, `\`)) + err := fv.removeHostMount(localPathArg) + if err != nil { + seelog.Warnf("Unable to clear fsxwindowsfileserver host path %s for task %s: %s", localPath, fv.taskARN, err) + } + return nil +} + +// FSxWindowsFileServerResourceJSON is the json representation of the fsxwindowsfileserver resource +type FSxWindowsFileServerResourceJSON struct { + Name string `json:"name"` + VolumeConfig FSxWindowsFileServerVolumeConfig `json:"fsxWindowsFileServerVolumeConfiguration"` + TaskARN string `json:"taskARN"` + ExecutionCredentialsID string `json:"executionCredentialsID"` + CreatedAt *time.Time `json:"createdAt,omitempty"` + DesiredStatus *FSxWindowsFileServerVolumeStatus `json:"desiredStatus"` + KnownStatus *FSxWindowsFileServerVolumeStatus `json:"knownStatus"` +} + +// MarshalJSON serialises the FSxWindowsFileServerResourceJSON struct to JSON +func (fv *FSxWindowsFileServerResource) MarshalJSON() ([]byte, error) { + if fv == nil { + return nil, errors.New("fsxwindowfileserver resource is nil") + } + createdAt := fv.GetCreatedAt() + return json.Marshal(FSxWindowsFileServerResourceJSON{ + Name: fv.Name, + VolumeConfig: fv.VolumeConfig, + TaskARN: fv.taskARN, + ExecutionCredentialsID: fv.executionCredentialsID, + CreatedAt: &createdAt, + DesiredStatus: func() *FSxWindowsFileServerVolumeStatus { + desiredState := fv.GetDesiredStatus() + s := FSxWindowsFileServerVolumeStatus(desiredState) + return &s + }(), + KnownStatus: func() *FSxWindowsFileServerVolumeStatus { + knownState := fv.GetKnownStatus() + s := FSxWindowsFileServerVolumeStatus(knownState) + return &s + }(), + }) +} + +// UnmarshalJSON deserialises the raw JSON to a FSxWindowsFileServerResourceJSON struct +func (fv *FSxWindowsFileServerResource) UnmarshalJSON(b []byte) error { + temp := FSxWindowsFileServerResourceJSON{} + + if err := json.Unmarshal(b, &temp); err != nil { + return err + } + + fv.Name = temp.Name + fv.VolumeConfig = temp.VolumeConfig + fv.taskARN = temp.TaskARN + fv.executionCredentialsID = temp.ExecutionCredentialsID + if temp.DesiredStatus != nil { + fv.SetDesiredStatus(resourcestatus.ResourceStatus(*temp.DesiredStatus)) + } + if temp.KnownStatus != nil { + fv.SetKnownStatus(resourcestatus.ResourceStatus(*temp.KnownStatus)) + } + if temp.CreatedAt != nil && !temp.CreatedAt.IsZero() { + fv.SetCreatedAt(*temp.CreatedAt) + } + return nil +} + +// updateAppliedStatusUnsafe updates the resource transitioning status +func (fv *FSxWindowsFileServerResource) updateAppliedStatusUnsafe(knownStatus resourcestatus.ResourceStatus) { + if fv.appliedStatusUnsafe == resourcestatus.ResourceStatus(FSxWindowsFileServerVolumeStatusNone) { + return + } + + // Check if the resource transition has already finished + if fv.appliedStatusUnsafe <= knownStatus { + fv.appliedStatusUnsafe = resourcestatus.ResourceStatus(FSxWindowsFileServerVolumeStatusNone) + } +} + +// GetAppliedStatus safely returns the currently applied status of the resource +func (fv *FSxWindowsFileServerResource) GetAppliedStatus() resourcestatus.ResourceStatus { + fv.lock.RLock() + defer fv.lock.RLock() + + return fv.appliedStatusUnsafe +} + +func (fv *FSxWindowsFileServerResource) DependOnTaskNetwork() bool { + return false +} + +// BuildContainerDependency sets the container dependencies of the resource. +func (fv *FSxWindowsFileServerResource) BuildContainerDependency(containerName string, satisfied apicontainerstatus.ContainerStatus, + dependent resourcestatus.ResourceStatus) { + return +} + +// GetContainerDependencies returns the container dependencies of the resource. +func (fv *FSxWindowsFileServerResource) GetContainerDependencies(dependent resourcestatus.ResourceStatus) []apicontainer.ContainerDependency { + return nil +} diff --git a/agent/taskresource/fsxwindowsfileserver/fsxwindowsfileserver_windows_test.go b/agent/taskresource/fsxwindowsfileserver/fsxwindowsfileserver_windows_test.go new file mode 100644 index 00000000000..16c9fdd8659 --- /dev/null +++ b/agent/taskresource/fsxwindowsfileserver/fsxwindowsfileserver_windows_test.go @@ -0,0 +1,711 @@ +// +build windows,unit + +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). You may +// not use this file except in compliance with the License. A copy of the +// License is located at +// +// http://aws.amazon.com/apache2.0/ +// +// or in the "license" file accompanying this file. This file is distributed +// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing +// permissions and limitations under the License. + +package fsxwindowsfileserver + +import ( + "encoding/json" + "os" + "os/exec" + "testing" + "time" + + "github.com/aws/amazon-ecs-agent/agent/utils" + + apitaskstatus "github.com/aws/amazon-ecs-agent/agent/api/task/status" + mock_asm_factory "github.com/aws/amazon-ecs-agent/agent/asm/factory/mocks" + mock_secretsmanageriface "github.com/aws/amazon-ecs-agent/agent/asm/mocks" + "github.com/aws/amazon-ecs-agent/agent/credentials" + mock_credentials "github.com/aws/amazon-ecs-agent/agent/credentials/mocks" + mock_fsx_factory "github.com/aws/amazon-ecs-agent/agent/fsx/factory/mocks" + mock_fsxiface "github.com/aws/amazon-ecs-agent/agent/fsx/mocks" + mock_ssm_factory "github.com/aws/amazon-ecs-agent/agent/ssm/factory/mocks" + mock_ssmiface "github.com/aws/amazon-ecs-agent/agent/ssm/mocks" + "github.com/aws/amazon-ecs-agent/agent/taskresource" + resourcestatus "github.com/aws/amazon-ecs-agent/agent/taskresource/status" + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/fsx" + "github.com/aws/aws-sdk-go/service/secretsmanager" + "github.com/aws/aws-sdk-go/service/ssm" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +const ( + taskARN = "arn:aws:ecs:us-west-2:123456789012:task/12345-678901234-56789" + executionCredentialsID = "exec-creds-id" + fileSystemId = "fs-12345678" + rootDirectory = `\test\directory` + credentialsParameter = "arn" + domain = "testdomain" + hostPath = `Z:\` +) + +func setup(t *testing.T) ( + *FSxWindowsFileServerResource, *mock_credentials.MockManager, *mock_ssm_factory.MockSSMClientCreator, + *mock_asm_factory.MockClientCreator, *mock_fsx_factory.MockFSxClientCreator, *mock_ssmiface.MockSSMClient, + *mock_secretsmanageriface.MockSecretsManagerAPI, *mock_fsxiface.MockFSxClient) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + credentialsManager := mock_credentials.NewMockManager(ctrl) + ssmClientCreator := mock_ssm_factory.NewMockSSMClientCreator(ctrl) + asmClientCreator := mock_asm_factory.NewMockClientCreator(ctrl) + fsxClientCreator := mock_fsx_factory.NewMockFSxClientCreator(ctrl) + + mockSSMClient := mock_ssmiface.NewMockSSMClient(ctrl) + mockASMClient := mock_secretsmanageriface.NewMockSecretsManagerAPI(ctrl) + mockFSxClient := mock_fsxiface.NewMockFSxClient(ctrl) + + fv := &FSxWindowsFileServerResource{ + knownStatusUnsafe: resourcestatus.ResourceCreated, + desiredStatusUnsafe: resourcestatus.ResourceCreated, + taskARN: taskARN, + } + fv.Initialize(&taskresource.ResourceFields{ + ResourceFieldsCommon: &taskresource.ResourceFieldsCommon{ + SSMClientCreator: ssmClientCreator, + ASMClientCreator: asmClientCreator, + FSxClientCreator: fsxClientCreator, + CredentialsManager: credentialsManager, + }, + }, apitaskstatus.TaskStatusNone, apitaskstatus.TaskRunning) + return fv, credentialsManager, ssmClientCreator, asmClientCreator, fsxClientCreator, mockSSMClient, mockASMClient, mockFSxClient +} + +func TestInitialize(t *testing.T) { + fv, _, _, _, _, _, _, _ := setup(t) + assert.NotNil(t, fv.credentialsManager) + assert.NotNil(t, fv.ssmClientCreator) + assert.NotNil(t, fv.asmClientCreator) + assert.NotNil(t, fv.fsxClientCreator) + assert.NotNil(t, fv.statusToTransitions) +} + +func TestMarshalUnmarshalJSON(t *testing.T) { + volumeConfig := FSxWindowsFileServerVolumeConfig{ + FileSystemID: "fs-12345678", + RootDirectory: rootDirectory, + AuthConfig: FSxWindowsFileServerAuthConfig{ + CredentialsParameter: credentialsParameter, + Domain: domain, + }, + HostPath: hostPath, + } + fsxWindowsFileServerIn := &FSxWindowsFileServerResource{ + Name: "test", + VolumeConfig: volumeConfig, + taskARN: taskARN, + executionCredentialsID: executionCredentialsID, + createdAtUnsafe: time.Time{}, + knownStatusUnsafe: resourcestatus.ResourceCreated, + desiredStatusUnsafe: resourcestatus.ResourceCreated, + } + + bytes, err := json.Marshal(fsxWindowsFileServerIn) + require.NoError(t, err) + + fsxWindowsFileServerOut := &FSxWindowsFileServerResource{} + err = json.Unmarshal(bytes, fsxWindowsFileServerOut) + require.NoError(t, err) + assert.Equal(t, fsxWindowsFileServerIn.Name, fsxWindowsFileServerOut.Name) + assert.Equal(t, fsxWindowsFileServerIn.VolumeConfig, fsxWindowsFileServerOut.VolumeConfig) + assert.Equal(t, fsxWindowsFileServerIn.taskARN, fsxWindowsFileServerOut.taskARN) + assert.Equal(t, fsxWindowsFileServerIn.executionCredentialsID, fsxWindowsFileServerOut.executionCredentialsID) + assert.WithinDuration(t, fsxWindowsFileServerIn.createdAtUnsafe, fsxWindowsFileServerOut.createdAtUnsafe, time.Microsecond) + assert.Equal(t, fsxWindowsFileServerIn.desiredStatusUnsafe, fsxWindowsFileServerOut.desiredStatusUnsafe) + assert.Equal(t, fsxWindowsFileServerIn.knownStatusUnsafe, fsxWindowsFileServerOut.knownStatusUnsafe) +} + +// TODO: Make tests table driven +func TestRetrieveCredentials(t *testing.T) { + fv, _, ssmClientCreator, _, _, mockSSMClient, _, _ := setup(t) + + credentialsParameterARN := "arn:aws:ssm:us-west-2:123456789012:parameter/test" + + ssmTestData := "{\n\"username\": \"user\", \n\"password\": \"pass\"\n}" + ssmClientOutput := &ssm.GetParametersOutput{ + InvalidParameters: []*string{}, + Parameters: []*ssm.Parameter{ + &ssm.Parameter{ + Name: aws.String("test"), + Value: aws.String(ssmTestData), + }, + }, + } + + iamCredentials := credentials.IAMRoleCredentials{ + CredentialsID: "test-cred-id", + } + + gomock.InOrder( + ssmClientCreator.EXPECT().NewSSMClient(gomock.Any(), gomock.Any()).Return(mockSSMClient), + mockSSMClient.EXPECT().GetParameters(gomock.Any()).Return(ssmClientOutput, nil).Times(1), + ) + + err := fv.retrieveCredentials(credentialsParameterARN, iamCredentials) + assert.NoError(t, err) + + credentials := fv.Credentials + assert.Equal(t, "user", credentials.Username) + assert.Equal(t, "pass", credentials.Password) +} + +func TestRetrieveSSMCredentials(t *testing.T) { + fv, _, ssmClientCreator, _, _, mockSSMClient, _, _ := setup(t) + credentialsParameterARN := "arn:aws:ssm:us-west-2:123456789012:parameter/test" + + ssmTestData := "{\n\"username\": \"user\", \n\"password\": \"pass\"\n}" + ssmClientOutput := &ssm.GetParametersOutput{ + InvalidParameters: []*string{}, + Parameters: []*ssm.Parameter{ + &ssm.Parameter{ + Name: aws.String("test"), + Value: aws.String(ssmTestData), + }, + }, + } + + iamCredentials := credentials.IAMRoleCredentials{ + CredentialsID: "test-cred-id", + } + + gomock.InOrder( + ssmClientCreator.EXPECT().NewSSMClient(gomock.Any(), gomock.Any()).Return(mockSSMClient), + mockSSMClient.EXPECT().GetParameters(gomock.Any()).Return(ssmClientOutput, nil).Times(1), + ) + + err := fv.retrieveSSMCredentials(credentialsParameterARN, iamCredentials) + assert.NoError(t, err) + + credentials := fv.Credentials + assert.Equal(t, "user", credentials.Username) + assert.Equal(t, "pass", credentials.Password) +} + +func TestRetrieveASMCredentials(t *testing.T) { + fv, _, _, asmClientCreator, _, _, mockASMClient, _ := setup(t) + credentialsParameterARN := "arn:aws:secretsmanager:us-east-1:123456789012:secret:testing/some-random-name" + + asmTestData := "{\"username\":\"user\",\"password\":\"pass\"}" + asmClientOutput := &secretsmanager.GetSecretValueOutput{ + SecretString: aws.String(asmTestData), + } + + gomock.InOrder( + asmClientCreator.EXPECT().NewASMClient(gomock.Any(), gomock.Any()).Return(mockASMClient), + mockASMClient.EXPECT().GetSecretValue(gomock.Any()).Do(func(in *secretsmanager.GetSecretValueInput) { + assert.Equal(t, aws.StringValue(in.SecretId), credentialsParameterARN) + }).Return(asmClientOutput, nil), + ) + + iamCredentials := credentials.IAMRoleCredentials{ + CredentialsID: "test-cred-id", + } + + err := fv.retrieveASMCredentials(credentialsParameterARN, iamCredentials) + assert.NoError(t, err) + + credentials := fv.Credentials + assert.Equal(t, "user", credentials.Username) + assert.Equal(t, "pass", credentials.Password) +} + +func TestRetrieveCredentialsInvalidService(t *testing.T) { + iamCredentials := credentials.IAMRoleCredentials{ + CredentialsID: "test-cred-id", + } + + credentialsParameterARN := "arn:aws:foo:us-east-1:123456789012:parameter/test" + + var termReason string + fv := &FSxWindowsFileServerResource{ + terminalReason: termReason, + } + + err := fv.retrieveCredentials(credentialsParameterARN, iamCredentials) + assert.Error(t, err) +} + +func TestRetrieveSSMCredentialsARNParseErr(t *testing.T) { + iamCredentials := credentials.IAMRoleCredentials{ + CredentialsID: "test-cred-id", + } + + credentialsParameterARN := "arn:aws:ssm:parameter/test" + + var termReason string + fv := &FSxWindowsFileServerResource{ + terminalReason: termReason, + } + + err := fv.retrieveSSMCredentials(credentialsParameterARN, iamCredentials) + assert.Error(t, err) +} + +func TestRetrieveASMCredentialsARNParseErr(t *testing.T) { + iamCredentials := credentials.IAMRoleCredentials{ + CredentialsID: "test-cred-id", + } + + credentialsParameterARN := "arn:aws:secretsmanager:some-random-name" + + var termReason string + fv := &FSxWindowsFileServerResource{ + terminalReason: termReason, + } + + err := fv.retrieveASMCredentials(credentialsParameterARN, iamCredentials) + assert.Error(t, err) +} + +func TestRetrieveFSxWindowsFileServerDNSName(t *testing.T) { + fv, _, _, _, fsxClientCreator, _, _, mockFSxClient := setup(t) + fsxClientOutput := &fsx.DescribeFileSystemsOutput{ + FileSystems: []*fsx.FileSystem{ + { + FileSystemId: aws.String(fileSystemId), + DNSName: aws.String("test"), + }, + }, + } + + gomock.InOrder( + fsxClientCreator.EXPECT().NewFSxClient(gomock.Any(), gomock.Any()).Return(mockFSxClient), + mockFSxClient.EXPECT().DescribeFileSystems(gomock.Any()).Return(fsxClientOutput, nil).Times(1), + ) + + iamCredentials := credentials.IAMRoleCredentials{ + CredentialsID: "test-cred-id", + } + + err := fv.retrieveFileSystemDNSName(fileSystemId, iamCredentials) + assert.NoError(t, err) + + DNSName := fv.FSxWindowsFileServerDNSName + assert.Equal(t, "test", DNSName) +} + +func TestHandleRootDirectory(t *testing.T) { + fv1 := &FSxWindowsFileServerResource{} + fv1.handleRootDirectory("some/path/") + + fv2 := &FSxWindowsFileServerResource{} + fv2.handleRootDirectory("\\some\\path") + + fv3 := &FSxWindowsFileServerResource{} + fv3.handleRootDirectory("\\some/path") + + fv4 := &FSxWindowsFileServerResource{} + fv4.handleRootDirectory("\\") + + assert.Equal(t, "some\\path", fv1.VolumeConfig.RootDirectory) + assert.Equal(t, "some\\path", fv2.VolumeConfig.RootDirectory) + assert.Equal(t, "some\\path", fv3.VolumeConfig.RootDirectory) + assert.Equal(t, "", fv4.VolumeConfig.RootDirectory) +} + +func TestGetName(t *testing.T) { + fv := &FSxWindowsFileServerResource{ + Name: "test", + } + + assert.Equal(t, "test", fv.GetName()) +} + +func TestGetVolumeConfig(t *testing.T) { + fv := &FSxWindowsFileServerResource{ + VolumeConfig: FSxWindowsFileServerVolumeConfig{ + FileSystemID: "fs-12345678", + RootDirectory: "root", + AuthConfig: FSxWindowsFileServerAuthConfig{ + CredentialsParameter: credentialsParameter, + Domain: "test", + }, + HostPath: hostPath, + }, + } + + volumeConfig := fv.GetVolumeConfig() + assert.Equal(t, "fs-12345678", volumeConfig.FileSystemID) + assert.Equal(t, "root", volumeConfig.RootDirectory) + assert.Equal(t, "arn", volumeConfig.AuthConfig.CredentialsParameter) + assert.Equal(t, "test", volumeConfig.AuthConfig.Domain) + assert.Equal(t, `Z:\`, volumeConfig.HostPath) +} + +func TestGetCredentials(t *testing.T) { + fv := &FSxWindowsFileServerResource{ + Credentials: FSxWindowsFileServerCredentials{ + Username: "user", + Password: "pass", + }, + } + + credentials := fv.GetCredentials() + assert.Equal(t, "user", credentials.Username) + assert.Equal(t, "pass", credentials.Password) +} + +func TestGetFileSystemDNSName(t *testing.T) { + fv := &FSxWindowsFileServerResource{ + FSxWindowsFileServerDNSName: "test", + } + + assert.Equal(t, "test", fv.GetFileSystemDNSName()) +} + +func TestSetCredentials(t *testing.T) { + fv := &FSxWindowsFileServerResource{} + fv.SetCredentials(FSxWindowsFileServerCredentials{ + Username: "user", + Password: "pass", + }) + + assert.Equal(t, "user", fv.Credentials.Username) + assert.Equal(t, "pass", fv.Credentials.Password) +} + +func TestSetFileSystemDNSName(t *testing.T) { + fv := &FSxWindowsFileServerResource{} + fv.SetFileSystemDNSName("test") + assert.Equal(t, "test", fv.FSxWindowsFileServerDNSName) +} + +func TestSetRootDirectory(t *testing.T) { + fv := &FSxWindowsFileServerResource{} + fv.SetRootDirectory("root") + assert.Equal(t, "root", fv.VolumeConfig.RootDirectory) +} + +func fakeExecCommand(command string, args ...string) *exec.Cmd { + cs := []string{"-test.run=TestHelperProcess", "--", command} + cs = append(cs, args...) + cmd := exec.Command(os.Args[0], cs...) + cmd.Env = []string{"GO_WANT_HELPER_PROCESS=1"} + return cmd +} + +func TestHelperProcess(t *testing.T) { + if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" { + return + } + os.Exit(0) +} + +func TestPerformHostMount(t *testing.T) { + fv := &FSxWindowsFileServerResource{} + execCommand = fakeExecCommand + defer func() { execCommand = exec.Command }() + + err := fv.performHostMount(`\\amznfsxfp8sdlcw.test.corp.com\share`, hostPath, `test\user`, `pass`) + assert.NoError(t, err) +} + +func TestRemoveHostMount(t *testing.T) { + fv, _, _, _, _, _, _, _ := setup(t) + execCommand = fakeExecCommand + + defer func() { + execCommand = exec.Command + }() + + err := fv.removeHostMount("test") + assert.NoError(t, err) +} + +func TestCreateInvalidExecutionRoleCredentialsErr(t *testing.T) { + fv, credentialsManager, _, _, _, _, _, _ := setup(t) + + DriveLetterAvailable = func(string) bool { + return true + } + + defer func() { + DriveLetterAvailable = utils.IsAvailableDriveLetter + }() + + creds := credentials.TaskIAMRoleCredentials{} + gomock.InOrder( + credentialsManager.EXPECT().GetTaskCredentials(gomock.Any()).Return(creds, false), + ) + + err := fv.Create() + assert.Error(t, err) +} + +func TestCreateUnavailableLocalPath(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + credentialsManager := mock_credentials.NewMockManager(ctrl) + ssmClientCreator := mock_ssm_factory.NewMockSSMClientCreator(ctrl) + asmClientCreator := mock_asm_factory.NewMockClientCreator(ctrl) + fsxClientCreator := mock_fsx_factory.NewMockFSxClientCreator(ctrl) + mockSSMClient := mock_ssmiface.NewMockSSMClient(ctrl) + mockFSxClient := mock_fsxiface.NewMockFSxClient(ctrl) + + fv := &FSxWindowsFileServerResource{ + VolumeConfig: FSxWindowsFileServerVolumeConfig{ + FileSystemID: fileSystemId, + RootDirectory: rootDirectory, + AuthConfig: FSxWindowsFileServerAuthConfig{ + CredentialsParameter: "arn:aws:ssm:us-west-2:123456789012:parameter/test", + Domain: domain, + }, + HostPath: hostPath, + }, + knownStatusUnsafe: resourcestatus.ResourceCreated, + desiredStatusUnsafe: resourcestatus.ResourceCreated, + taskARN: taskARN, + executionCredentialsID: executionCredentialsID, + } + fv.Initialize(&taskresource.ResourceFields{ + ResourceFieldsCommon: &taskresource.ResourceFieldsCommon{ + SSMClientCreator: ssmClientCreator, + ASMClientCreator: asmClientCreator, + FSxClientCreator: fsxClientCreator, + CredentialsManager: credentialsManager, + }, + }, apitaskstatus.TaskStatusNone, apitaskstatus.TaskRunning) + + ssmTestData := "{\n\"username\": \"user\", \n\"password\": \"pass\"\n}" + ssmClientOutput := &ssm.GetParametersOutput{ + InvalidParameters: []*string{}, + Parameters: []*ssm.Parameter{ + &ssm.Parameter{ + Name: aws.String("test"), + Value: aws.String(ssmTestData), + }, + }, + } + + fsxClientOutput := &fsx.DescribeFileSystemsOutput{ + FileSystems: []*fsx.FileSystem{ + { + FileSystemId: aws.String(fileSystemId), + DNSName: aws.String("test"), + }, + }, + } + + creds := credentials.TaskIAMRoleCredentials{ + ARN: "arn", + IAMRoleCredentials: credentials.IAMRoleCredentials{ + AccessKeyID: "id", + SecretAccessKey: "key", + }, + } + + gomock.InOrder( + credentialsManager.EXPECT().GetTaskCredentials(gomock.Any()).Return(creds, true), + ssmClientCreator.EXPECT().NewSSMClient(gomock.Any(), gomock.Any()).Return(mockSSMClient), + mockSSMClient.EXPECT().GetParameters(gomock.Any()).Return(ssmClientOutput, nil).Times(1), + fsxClientCreator.EXPECT().NewFSxClient(gomock.Any(), gomock.Any()).Return(mockFSxClient), + mockFSxClient.EXPECT().DescribeFileSystems(gomock.Any()).Return(fsxClientOutput, nil).Times(1), + ) + + DriveLetterAvailable = func(string) bool { + return false + } + execCommand = fakeExecCommand + + defer func() { + DriveLetterAvailable = utils.IsAvailableDriveLetter + execCommand = exec.Command + }() + + err := fv.Create() + assert.NoError(t, err) +} + +func TestCreateSSM(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + credentialsManager := mock_credentials.NewMockManager(ctrl) + ssmClientCreator := mock_ssm_factory.NewMockSSMClientCreator(ctrl) + asmClientCreator := mock_asm_factory.NewMockClientCreator(ctrl) + fsxClientCreator := mock_fsx_factory.NewMockFSxClientCreator(ctrl) + mockSSMClient := mock_ssmiface.NewMockSSMClient(ctrl) + mockFSxClient := mock_fsxiface.NewMockFSxClient(ctrl) + + fv := &FSxWindowsFileServerResource{ + VolumeConfig: FSxWindowsFileServerVolumeConfig{ + FileSystemID: fileSystemId, + RootDirectory: rootDirectory, + AuthConfig: FSxWindowsFileServerAuthConfig{ + CredentialsParameter: "arn:aws:ssm:us-west-2:123456789012:parameter/test", + Domain: domain, + }, + HostPath: hostPath, + }, + knownStatusUnsafe: resourcestatus.ResourceCreated, + desiredStatusUnsafe: resourcestatus.ResourceCreated, + taskARN: taskARN, + executionCredentialsID: executionCredentialsID, + } + fv.Initialize(&taskresource.ResourceFields{ + ResourceFieldsCommon: &taskresource.ResourceFieldsCommon{ + SSMClientCreator: ssmClientCreator, + ASMClientCreator: asmClientCreator, + FSxClientCreator: fsxClientCreator, + CredentialsManager: credentialsManager, + }, + }, apitaskstatus.TaskStatusNone, apitaskstatus.TaskRunning) + + ssmTestData := "{\n\"username\": \"user\", \n\"password\": \"pass\"\n}" + ssmClientOutput := &ssm.GetParametersOutput{ + InvalidParameters: []*string{}, + Parameters: []*ssm.Parameter{ + &ssm.Parameter{ + Name: aws.String("test"), + Value: aws.String(ssmTestData), + }, + }, + } + + fsxClientOutput := &fsx.DescribeFileSystemsOutput{ + FileSystems: []*fsx.FileSystem{ + { + FileSystemId: aws.String(fileSystemId), + DNSName: aws.String("test"), + }, + }, + } + + creds := credentials.TaskIAMRoleCredentials{ + ARN: "arn", + IAMRoleCredentials: credentials.IAMRoleCredentials{ + AccessKeyID: "id", + SecretAccessKey: "key", + }, + } + + gomock.InOrder( + credentialsManager.EXPECT().GetTaskCredentials(gomock.Any()).Return(creds, true), + ssmClientCreator.EXPECT().NewSSMClient(gomock.Any(), gomock.Any()).Return(mockSSMClient), + mockSSMClient.EXPECT().GetParameters(gomock.Any()).Return(ssmClientOutput, nil).Times(1), + fsxClientCreator.EXPECT().NewFSxClient(gomock.Any(), gomock.Any()).Return(mockFSxClient), + mockFSxClient.EXPECT().DescribeFileSystems(gomock.Any()).Return(fsxClientOutput, nil).Times(1), + ) + + DriveLetterAvailable = func(string) bool { + return true + } + execCommand = fakeExecCommand + + defer func() { + DriveLetterAvailable = utils.IsAvailableDriveLetter + execCommand = exec.Command + }() + + err := fv.Create() + assert.NoError(t, err) +} + +func TestCreateASM(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + credentialsManager := mock_credentials.NewMockManager(ctrl) + ssmClientCreator := mock_ssm_factory.NewMockSSMClientCreator(ctrl) + asmClientCreator := mock_asm_factory.NewMockClientCreator(ctrl) + fsxClientCreator := mock_fsx_factory.NewMockFSxClientCreator(ctrl) + mockASMClient := mock_secretsmanageriface.NewMockSecretsManagerAPI(ctrl) + mockFSxClient := mock_fsxiface.NewMockFSxClient(ctrl) + + credentialsParameter := "arn:aws:secretsmanager:us-east-1:123456789012:secret:testing/some-random-name" + + fv := &FSxWindowsFileServerResource{ + VolumeConfig: FSxWindowsFileServerVolumeConfig{ + FileSystemID: fileSystemId, + RootDirectory: rootDirectory, + AuthConfig: FSxWindowsFileServerAuthConfig{ + CredentialsParameter: "arn:aws:secretsmanager:us-east-1:123456789012:secret:testing/some-random-name", + Domain: domain, + }, + HostPath: hostPath, + }, + knownStatusUnsafe: resourcestatus.ResourceCreated, + desiredStatusUnsafe: resourcestatus.ResourceCreated, + taskARN: taskARN, + executionCredentialsID: executionCredentialsID, + } + fv.Initialize(&taskresource.ResourceFields{ + ResourceFieldsCommon: &taskresource.ResourceFieldsCommon{ + SSMClientCreator: ssmClientCreator, + ASMClientCreator: asmClientCreator, + FSxClientCreator: fsxClientCreator, + CredentialsManager: credentialsManager, + }, + }, apitaskstatus.TaskStatusNone, apitaskstatus.TaskRunning) + + asmTestData := "{\"username\":\"user\",\"password\":\"pass\"}" + asmClientOutput := &secretsmanager.GetSecretValueOutput{ + SecretString: aws.String(asmTestData), + } + + fsxClientOutput := &fsx.DescribeFileSystemsOutput{ + FileSystems: []*fsx.FileSystem{ + { + FileSystemId: aws.String(fileSystemId), + DNSName: aws.String("test"), + }, + }, + } + + creds := credentials.TaskIAMRoleCredentials{ + ARN: "arn", + IAMRoleCredentials: credentials.IAMRoleCredentials{ + AccessKeyID: "id", + SecretAccessKey: "key", + }, + } + + gomock.InOrder( + credentialsManager.EXPECT().GetTaskCredentials(gomock.Any()).Return(creds, true), + asmClientCreator.EXPECT().NewASMClient(gomock.Any(), gomock.Any()).Return(mockASMClient), + mockASMClient.EXPECT().GetSecretValue(gomock.Any()).Do(func(in *secretsmanager.GetSecretValueInput) { + assert.Equal(t, aws.StringValue(in.SecretId), credentialsParameter) + }).Return(asmClientOutput, nil), + fsxClientCreator.EXPECT().NewFSxClient(gomock.Any(), gomock.Any()).Return(mockFSxClient), + mockFSxClient.EXPECT().DescribeFileSystems(gomock.Any()).Return(fsxClientOutput, nil).Times(1), + ) + + DriveLetterAvailable = func(string) bool { + return true + } + execCommand = fakeExecCommand + + defer func() { + DriveLetterAvailable = utils.IsAvailableDriveLetter + execCommand = exec.Command + }() + + err := fv.Create() + assert.NoError(t, err) +} + +func TestClearFSxWindowsFileServerResource(t *testing.T) { + fv := &FSxWindowsFileServerResource{VolumeConfig: FSxWindowsFileServerVolumeConfig{HostPath: hostPath}} + + execCommand = fakeExecCommand + defer func() { execCommand = exec.Command }() + + err := fv.Cleanup() + assert.NoError(t, err) +} diff --git a/agent/taskresource/fsxwindowsfileserver/fsxwindowsfileserverstatus.go b/agent/taskresource/fsxwindowsfileserver/fsxwindowsfileserverstatus.go new file mode 100644 index 00000000000..222f5f0c540 --- /dev/null +++ b/agent/taskresource/fsxwindowsfileserver/fsxwindowsfileserverstatus.go @@ -0,0 +1,79 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). You may +// not use this file except in compliance with the License. A copy of the +// License is located at +// +// http://aws.amazon.com/apache2.0/ +// +// or in the "license" file accompanying this file. This file is distributed +// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing +// permissions and limitations under the License. + +package fsxwindowsfileserver + +import ( + "errors" + "strings" + + resourcestatus "github.com/aws/amazon-ecs-agent/agent/taskresource/status" +) + +// FSxWindowsFileServerVolumeStatus defines resource statuses for fsxwindowsfileserver resource +type FSxWindowsFileServerVolumeStatus resourcestatus.ResourceStatus + +const ( + // FSxWindowsFileServerVolumeStatusNone is the zero state of a task resource + FSxWindowsFileServerVolumeStatusNone FSxWindowsFileServerVolumeStatus = iota + // FSxWindowsFileServerVolumeCreated represents a task resource which has been created + FSxWindowsFileServerVolumeCreated + // FSxWindowsFileServerVolumeRemoved represents a task resource which has been cleaned up + FSxWindowsFileServerVolumeRemoved +) + +var FSxWindowsFileServerVolumeStatusMap = map[string]FSxWindowsFileServerVolumeStatus{ + "NONE": FSxWindowsFileServerVolumeStatusNone, + "CREATED": FSxWindowsFileServerVolumeCreated, + "REMOVED": FSxWindowsFileServerVolumeRemoved, +} + +// StatusString returns a human readable string representation of this object +func (fs FSxWindowsFileServerVolumeStatus) String() string { + for k, v := range FSxWindowsFileServerVolumeStatusMap { + if v == fs { + return k + } + } + return "NONE" +} + +// MarshalJSON overrides the logic for JSON-encoding the ResourceStatus type +func (fs *FSxWindowsFileServerVolumeStatus) MarshalJSON() ([]byte, error) { + if fs == nil { + return nil, nil + } + return []byte(`"` + fs.String() + `"`), nil +} + +// UnmarshalJSON overrides the logic for parsing the JSON-encoded ResourceStatus data +func (fs *FSxWindowsFileServerVolumeStatus) UnmarshalJSON(b []byte) error { + if strings.ToLower(string(b)) == "null" { + *fs = FSxWindowsFileServerVolumeStatusNone + return nil + } + + if b[0] != '"' || b[len(b)-1] != '"' { + *fs = FSxWindowsFileServerVolumeStatusNone + return errors.New("resource status unmarshal: status must be a string or null; Got " + string(b)) + } + + strStatus := b[1 : len(b)-1] + stat, ok := FSxWindowsFileServerVolumeStatusMap[string(strStatus)] + if !ok { + *fs = FSxWindowsFileServerVolumeStatusNone + return errors.New("resource status unmarshal: unrecognized status") + } + *fs = stat + return nil +} diff --git a/agent/taskresource/fsxwindowsfileserver/fsxwindowsfileserverstatus_test.go b/agent/taskresource/fsxwindowsfileserver/fsxwindowsfileserverstatus_test.go new file mode 100644 index 00000000000..186ecd6d446 --- /dev/null +++ b/agent/taskresource/fsxwindowsfileserver/fsxwindowsfileserverstatus_test.go @@ -0,0 +1,88 @@ +// +build unit + +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). You may +// not use this file except in compliance with the License. A copy of the +// License is located at +// +// http://aws.amazon.com/apache2.0/ +// +// or in the "license" file accompanying this file. This file is distributed +// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing +// permissions and limitations under the License. + +package fsxwindowsfileserver + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestStatusString(t *testing.T) { + var resourceStatus FSxWindowsFileServerVolumeStatus + + resourceStatus = FSxWindowsFileServerVolumeStatusNone + assert.Equal(t, resourceStatus.String(), "NONE") + resourceStatus = FSxWindowsFileServerVolumeCreated + assert.Equal(t, resourceStatus.String(), "CREATED") + resourceStatus = FSxWindowsFileServerVolumeRemoved + assert.Equal(t, resourceStatus.String(), "REMOVED") +} + +func TestMarshalFSxWindowsFileServerVolumeStatus(t *testing.T) { + status := FSxWindowsFileServerVolumeStatusNone + bytes, err := status.MarshalJSON() + + assert.NoError(t, err) + assert.Equal(t, `"NONE"`, string(bytes[:])) +} + +func TestMarshalNilFSxWindowsFileServerVolumeStatus(t *testing.T) { + var status *FSxWindowsFileServerVolumeStatus + bytes, err := status.MarshalJSON() + + assert.Nil(t, bytes) + assert.Nil(t, err) +} + +type testFSxWindowsFileServerVolumeStatus struct { + SomeStatus FSxWindowsFileServerVolumeStatus `json:"status"` +} + +func TestUnmarshalFSxWindowsFileServerVolumeStatus(t *testing.T) { + status := FSxWindowsFileServerVolumeStatusNone + + err := json.Unmarshal([]byte(`"CREATED"`), &status) + assert.NoError(t, err) + assert.Equal(t, FSxWindowsFileServerVolumeCreated, status, "CREATED should unmarshal to CREATED, not "+status.String()) + + var testStatus testFSxWindowsFileServerVolumeStatus + err = json.Unmarshal([]byte(`{"status":"REMOVED"}`), &testStatus) + assert.NoError(t, err) + assert.Equal(t, FSxWindowsFileServerVolumeRemoved, testStatus.SomeStatus, "REMOVED should unmarshal to REMOVED, not "+testStatus.SomeStatus.String()) +} + +func TestUnmarshalNullFSxWindowsFileServerVolumeStatus(t *testing.T) { + status := FSxWindowsFileServerVolumeCreated + err := json.Unmarshal([]byte("null"), &status) + assert.NoError(t, err) + assert.Equal(t, FSxWindowsFileServerVolumeStatusNone, status, "null should unmarshal to None, not "+status.String()) +} + +func TestUnmarshalNonStringFSxWindowsFileServerVolumeStatusDefaultNone(t *testing.T) { + status := FSxWindowsFileServerVolumeCreated + err := json.Unmarshal([]byte(`1`), &status) + assert.NotNil(t, err) + assert.Equal(t, FSxWindowsFileServerVolumeStatusNone, status, "non-string status should unmarshal to None, not "+status.String()) +} + +func TestUnmarshalUnmappedFSxWindowsFileServerVolumeStatusDefaultNone(t *testing.T) { + status := FSxWindowsFileServerVolumeRemoved + err := json.Unmarshal([]byte(`"SOMEOTHER"`), &status) + assert.NotNil(t, err) + assert.Equal(t, FSxWindowsFileServerVolumeStatusNone, status, "Unmapped status should unmarshal to None, not "+status.String()) +} diff --git a/agent/taskresource/fsxwindowsfileserver/types.go b/agent/taskresource/fsxwindowsfileserver/types.go new file mode 100644 index 00000000000..eedc2714171 --- /dev/null +++ b/agent/taskresource/fsxwindowsfileserver/types.go @@ -0,0 +1,19 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). You may +// not use this file except in compliance with the License. A copy of the +// License is located at +// +// http://aws.amazon.com/apache2.0/ +// +// or in the "license" file accompanying this file. This file is distributed +// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing +// permissions and limitations under the License. + +package fsxwindowsfileserver + +const ( + // ResourceName is the name of the fsxwindowsfileserver resource + ResourceName = "fsxwindowsfileserver" +) diff --git a/agent/taskresource/types/types.go b/agent/taskresource/types/types.go index 7b6c6223d41..b1025d0dd39 100644 --- a/agent/taskresource/types/types.go +++ b/agent/taskresource/types/types.go @@ -24,6 +24,7 @@ import ( "github.com/aws/amazon-ecs-agent/agent/taskresource/credentialspec" "github.com/aws/amazon-ecs-agent/agent/taskresource/envFiles" "github.com/aws/amazon-ecs-agent/agent/taskresource/firelens" + "github.com/aws/amazon-ecs-agent/agent/taskresource/fsxwindowsfileserver" ssmsecretres "github.com/aws/amazon-ecs-agent/agent/taskresource/ssmsecret" "github.com/aws/amazon-ecs-agent/agent/taskresource/volume" ) @@ -45,6 +46,8 @@ const ( CredentialSpecKey = credentialspec.ResourceName //EnvironmentFilesKey is the string used in resources map to represent environmentfiles resource EnvironmentFilesKey = envFiles.ResourceName + // FSxWindowsFileServerKey is the string used in resources map to represent fsxwindowsfileserver resource + FSxWindowsFileServerKey = fsxwindowsfileserver.ResourceName ) // ResourcesMap represents the map of resource type to the corresponding resource @@ -86,6 +89,8 @@ func unmarshalResource(key string, value json.RawMessage, result map[string][]ta return unmarshalCredentialSpecKey(key, value, result) case EnvironmentFilesKey: return unmarshalEnvironmentFilesKey(key, value, result) + case FSxWindowsFileServerKey: + return unmarshalFSxWindowsFileServerKey(key, value, result) default: return errors.New("Unsupported resource type") } @@ -233,3 +238,21 @@ func unmarshalEnvironmentFilesKey(key string, value json.RawMessage, result map[ } return nil } + +func unmarshalFSxWindowsFileServerKey(key string, value json.RawMessage, result map[string][]taskresource.TaskResource) error { + var fsxWindowsFileServers []json.RawMessage + err := json.Unmarshal(value, &fsxWindowsFileServers) + if err != nil { + return err + } + + for _, fsxWindowsFileServer := range fsxWindowsFileServers { + res := &fsxwindowsfileserver.FSxWindowsFileServerResource{} + err := res.UnmarshalJSON(fsxWindowsFileServer) + if err != nil { + return err + } + result[key] = append(result[key], res) + } + return nil +} diff --git a/agent/taskresource/types_common.go b/agent/taskresource/types_common.go index 9a9b35282a3..e2fb0b8a501 100644 --- a/agent/taskresource/types_common.go +++ b/agent/taskresource/types_common.go @@ -16,6 +16,7 @@ package taskresource import ( asmfactory "github.com/aws/amazon-ecs-agent/agent/asm/factory" "github.com/aws/amazon-ecs-agent/agent/credentials" + fsxfactory "github.com/aws/amazon-ecs-agent/agent/fsx/factory" ssmfactory "github.com/aws/amazon-ecs-agent/agent/ssm/factory" "github.com/aws/amazon-ecs-agent/agent/utils/ioutilwrapper" ) @@ -24,6 +25,7 @@ type ResourceFieldsCommon struct { IOUtil ioutilwrapper.IOUtil ASMClientCreator asmfactory.ClientCreator SSMClientCreator ssmfactory.SSMClientCreator + FSxClientCreator fsxfactory.FSxClientCreator CredentialsManager credentials.Manager EC2InstanceID string } diff --git a/agent/utils/utils_linux.go b/agent/utils/utils_linux.go new file mode 100644 index 00000000000..1b3f590623c --- /dev/null +++ b/agent/utils/utils_linux.go @@ -0,0 +1,18 @@ +// +build linux + +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). You may +// not use this file except in compliance with the License. A copy of the +// License is located at +// +// http://aws.amazon.com/apache2.0/ +// +// or in the "license" file accompanying this file. This file is distributed +// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing +// permissions and limitations under the License. + +package utils + +func GetCanonicalPath(path string) string { return path } diff --git a/agent/utils/utils_linux_test.go b/agent/utils/utils_linux_test.go new file mode 100644 index 00000000000..088c3cb8537 --- /dev/null +++ b/agent/utils/utils_linux_test.go @@ -0,0 +1,26 @@ +// +build linux,unit + +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). You may +// not use this file except in compliance with the License. A copy of the +// License is located at +// +// http://aws.amazon.com/apache2.0/ +// +// or in the "license" file accompanying this file. This file is distributed +// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing +// permissions and limitations under the License. + +package utils + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestGetCanonicalPath(t *testing.T) { + assert.Equal(t, "test", GetCanonicalPath("test")) +} diff --git a/agent/utils/utils_unsupported.go b/agent/utils/utils_unsupported.go new file mode 100644 index 00000000000..fda26f31697 --- /dev/null +++ b/agent/utils/utils_unsupported.go @@ -0,0 +1,18 @@ +// +build !linux,!windows + +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). You may +// not use this file except in compliance with the License. A copy of the +// License is located at +// +// http://aws.amazon.com/apache2.0/ +// +// or in the "license" file accompanying this file. This file is distributed +// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing +// permissions and limitations under the License. + +package utils + +func GetCanonicalPath(path string) string { return path } diff --git a/agent/utils/utils_windows.go b/agent/utils/utils_windows.go new file mode 100644 index 00000000000..d63f671d15d --- /dev/null +++ b/agent/utils/utils_windows.go @@ -0,0 +1,81 @@ +// +build windows + +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). You may +// not use this file except in compliance with the License. A copy of the +// License is located at +// +// http://aws.amazon.com/apache2.0/ +// +// or in the "license" file accompanying this file. This file is distributed +// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing +// permissions and limitations under the License. + +package utils + +import ( + "errors" + "os" + "path/filepath" + "regexp" + "strings" +) + +func GetCanonicalPath(path string) string { + lowercasedPath := strings.ToLower(path) + // if the path is a bare drive like "d:", don't filepath.Clean it because it will add a '.'. + // this is to fix the case where mounting from D:\ to D: is supported by docker but not ecs + if isBareDrive(lowercasedPath) { + return lowercasedPath + } + + if isNamedPipesPath(lowercasedPath) { + return lowercasedPath + } + + return filepath.Clean(lowercasedPath) +} + +func isBareDrive(path string) bool { + if filepath.VolumeName(path) == path { + return true + } + + return false +} + +func isNamedPipesPath(path string) bool { + matched, err := regexp.MatchString(`\\{2}\.[\\]pipe[\\].+`, path) + + if err != nil { + return false + } + + return matched +} + +// findUnusedDriveLetter is used to search for an available drive letter on the container instance. +// Reference: https://golang.org/src/os/os_windows_test.go +func FindUnusedDriveLetter() (string, error) { + // Do not use A: and B:, because they are reserved for floppy drive. + // Do not use C:, because it is normally used for main drive. + for l := 'Z'; l >= 'D'; l-- { + p := string(l) + `:\` + if IsAvailableDriveLetter(p) { + return p, nil + } + } + return "", errors.New("could not find an available drive letter to mount fsxwindowsfileserver resource on the container instance") +} + +var DriveLetterAvailable = IsAvailableDriveLetter + +func IsAvailableDriveLetter(hostPath string) bool { + _, err := os.Stat(hostPath) + if os.IsNotExist(err) { + return true + } + return false +} diff --git a/agent/utils/utils_windows_test.go b/agent/utils/utils_windows_test.go new file mode 100644 index 00000000000..bdb574b43ef --- /dev/null +++ b/agent/utils/utils_windows_test.go @@ -0,0 +1,35 @@ +// +build windows,unit + +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). You may +// not use this file except in compliance with the License. A copy of the +// License is located at +// +// http://aws.amazon.com/apache2.0/ +// +// or in the "license" file accompanying this file. This file is distributed +// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing +// permissions and limitations under the License. + +package utils + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestFindUnusedDriveLetter(t *testing.T) { + DriveLetterAvailable = func(string) bool { + return true + } + + defer func() { + DriveLetterAvailable = IsAvailableDriveLetter + }() + driveLetter, err := FindUnusedDriveLetter() + assert.NoError(t, err) + assert.Equal(t, `Z:\`, driveLetter) +} diff --git a/agent/vendor/github.com/aws/aws-sdk-go/service/fsx/api.go b/agent/vendor/github.com/aws/aws-sdk-go/service/fsx/api.go new file mode 100644 index 00000000000..b86115c95fe --- /dev/null +++ b/agent/vendor/github.com/aws/aws-sdk-go/service/fsx/api.go @@ -0,0 +1,5347 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +package fsx + +import ( + "fmt" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awsutil" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/private/protocol" + "github.com/aws/aws-sdk-go/private/protocol/jsonrpc" +) + +const opCancelDataRepositoryTask = "CancelDataRepositoryTask" + +// CancelDataRepositoryTaskRequest generates a "aws/request.Request" representing the +// client's request for the CancelDataRepositoryTask operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See CancelDataRepositoryTask for more information on using the CancelDataRepositoryTask +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the CancelDataRepositoryTaskRequest method. +// req, resp := client.CancelDataRepositoryTaskRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/fsx-2018-03-01/CancelDataRepositoryTask +func (c *FSx) CancelDataRepositoryTaskRequest(input *CancelDataRepositoryTaskInput) (req *request.Request, output *CancelDataRepositoryTaskOutput) { + op := &request.Operation{ + Name: opCancelDataRepositoryTask, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CancelDataRepositoryTaskInput{} + } + + output = &CancelDataRepositoryTaskOutput{} + req = c.newRequest(op, input, output) + return +} + +// CancelDataRepositoryTask API operation for Amazon FSx. +// +// Cancels an existing Amazon FSx for Lustre data repository task if that task +// is in either the PENDING or EXECUTING state. When you cancel a task, Amazon +// FSx does the following. +// +// * Any files that FSx has already exported are not reverted. +// +// * FSx continues to export any files that are "in-flight" when the cancel +// operation is received. +// +// * FSx does not export any files that have not yet been exported. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon FSx's +// API operation CancelDataRepositoryTask for usage and error information. +// +// Returned Error Codes: +// * ErrCodeBadRequest "BadRequest" +// A generic error indicating a failure with a client request. +// +// * ErrCodeUnsupportedOperation "UnsupportedOperation" +// The requested operation is not supported for this resource or API. +// +// * ErrCodeDataRepositoryTaskNotFound "DataRepositoryTaskNotFound" +// The data repository task or tasks you specified could not be found. +// +// * ErrCodeDataRepositoryTaskEnded "DataRepositoryTaskEnded" +// The data repository task could not be canceled because the task has already +// ended. +// +// * ErrCodeInternalServerError "InternalServerError" +// A generic error indicating a server-side failure. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/fsx-2018-03-01/CancelDataRepositoryTask +func (c *FSx) CancelDataRepositoryTask(input *CancelDataRepositoryTaskInput) (*CancelDataRepositoryTaskOutput, error) { + req, out := c.CancelDataRepositoryTaskRequest(input) + return out, req.Send() +} + +// CancelDataRepositoryTaskWithContext is the same as CancelDataRepositoryTask with the addition of +// the ability to pass a context and additional request options. +// +// See CancelDataRepositoryTask for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *FSx) CancelDataRepositoryTaskWithContext(ctx aws.Context, input *CancelDataRepositoryTaskInput, opts ...request.Option) (*CancelDataRepositoryTaskOutput, error) { + req, out := c.CancelDataRepositoryTaskRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opCreateBackup = "CreateBackup" + +// CreateBackupRequest generates a "aws/request.Request" representing the +// client's request for the CreateBackup operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See CreateBackup for more information on using the CreateBackup +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the CreateBackupRequest method. +// req, resp := client.CreateBackupRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/fsx-2018-03-01/CreateBackup +func (c *FSx) CreateBackupRequest(input *CreateBackupInput) (req *request.Request, output *CreateBackupOutput) { + op := &request.Operation{ + Name: opCreateBackup, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateBackupInput{} + } + + output = &CreateBackupOutput{} + req = c.newRequest(op, input, output) + return +} + +// CreateBackup API operation for Amazon FSx. +// +// Creates a backup of an existing Amazon FSx for Windows File Server file system. +// Creating regular backups for your file system is a best practice that complements +// the replication that Amazon FSx for Windows File Server performs for your +// file system. It also enables you to restore from user modification of data. +// +// If a backup with the specified client request token exists, and the parameters +// match, this operation returns the description of the existing backup. If +// a backup specified client request token exists, and the parameters don't +// match, this operation returns IncompatibleParameterError. If a backup with +// the specified client request token doesn't exist, CreateBackup does the following: +// +// * Creates a new Amazon FSx backup with an assigned ID, and an initial +// lifecycle state of CREATING. +// +// * Returns the description of the backup. +// +// By using the idempotent operation, you can retry a CreateBackup operation +// without the risk of creating an extra backup. This approach can be useful +// when an initial call fails in a way that makes it unclear whether a backup +// was created. If you use the same client request token and the initial call +// created a backup, the operation returns a successful result because all the +// parameters are the same. +// +// The CreateFileSystem operation returns while the backup's lifecycle state +// is still CREATING. You can check the file system creation status by calling +// the DescribeBackups operation, which returns the backup state along with +// other information. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon FSx's +// API operation CreateBackup for usage and error information. +// +// Returned Error Codes: +// * ErrCodeBadRequest "BadRequest" +// A generic error indicating a failure with a client request. +// +// * ErrCodeUnsupportedOperation "UnsupportedOperation" +// The requested operation is not supported for this resource or API. +// +// * ErrCodeFileSystemNotFound "FileSystemNotFound" +// No Amazon FSx file systems were found based upon supplied parameters. +// +// * ErrCodeBackupInProgress "BackupInProgress" +// Another backup is already under way. Wait for completion before initiating +// additional backups of this file system. +// +// * ErrCodeIncompatibleParameterError "IncompatibleParameterError" +// The error returned when a second request is received with the same client +// request token but different parameters settings. A client request token should +// always uniquely identify a single request. +// +// * ErrCodeServiceLimitExceeded "ServiceLimitExceeded" +// An error indicating that a particular service limit was exceeded. You can +// increase some service limits by contacting AWS Support. +// +// * ErrCodeInternalServerError "InternalServerError" +// A generic error indicating a server-side failure. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/fsx-2018-03-01/CreateBackup +func (c *FSx) CreateBackup(input *CreateBackupInput) (*CreateBackupOutput, error) { + req, out := c.CreateBackupRequest(input) + return out, req.Send() +} + +// CreateBackupWithContext is the same as CreateBackup with the addition of +// the ability to pass a context and additional request options. +// +// See CreateBackup for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *FSx) CreateBackupWithContext(ctx aws.Context, input *CreateBackupInput, opts ...request.Option) (*CreateBackupOutput, error) { + req, out := c.CreateBackupRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opCreateDataRepositoryTask = "CreateDataRepositoryTask" + +// CreateDataRepositoryTaskRequest generates a "aws/request.Request" representing the +// client's request for the CreateDataRepositoryTask operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See CreateDataRepositoryTask for more information on using the CreateDataRepositoryTask +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the CreateDataRepositoryTaskRequest method. +// req, resp := client.CreateDataRepositoryTaskRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/fsx-2018-03-01/CreateDataRepositoryTask +func (c *FSx) CreateDataRepositoryTaskRequest(input *CreateDataRepositoryTaskInput) (req *request.Request, output *CreateDataRepositoryTaskOutput) { + op := &request.Operation{ + Name: opCreateDataRepositoryTask, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateDataRepositoryTaskInput{} + } + + output = &CreateDataRepositoryTaskOutput{} + req = c.newRequest(op, input, output) + return +} + +// CreateDataRepositoryTask API operation for Amazon FSx. +// +// Creates an Amazon FSx for Lustre data repository task. You use data repository +// tasks to perform bulk operations between your Amazon FSx file system and +// its linked data repository. An example of a data repository task is exporting +// any data and metadata changes, including POSIX metadata, to files, directories, +// and symbolic links (symlinks) from your FSx file system to its linked data +// repository. A CreateDataRepositoryTask operation will fail if a data repository +// is not linked to the FSx file system. To learn more about data repository +// tasks, see Using Data Repository Tasks (https://docs.aws.amazon.com/fsx/latest/LustreGuide/data-repository-tasks.html). +// To learn more about linking a data repository to your file system, see Step +// 1: Create Your Amazon FSx for Lustre File System (https://docs.aws.amazon.com/fsx/latest/LustreGuide/getting-started-step1.html). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon FSx's +// API operation CreateDataRepositoryTask for usage and error information. +// +// Returned Error Codes: +// * ErrCodeBadRequest "BadRequest" +// A generic error indicating a failure with a client request. +// +// * ErrCodeUnsupportedOperation "UnsupportedOperation" +// The requested operation is not supported for this resource or API. +// +// * ErrCodeFileSystemNotFound "FileSystemNotFound" +// No Amazon FSx file systems were found based upon supplied parameters. +// +// * ErrCodeIncompatibleParameterError "IncompatibleParameterError" +// The error returned when a second request is received with the same client +// request token but different parameters settings. A client request token should +// always uniquely identify a single request. +// +// * ErrCodeServiceLimitExceeded "ServiceLimitExceeded" +// An error indicating that a particular service limit was exceeded. You can +// increase some service limits by contacting AWS Support. +// +// * ErrCodeInternalServerError "InternalServerError" +// A generic error indicating a server-side failure. +// +// * ErrCodeDataRepositoryTaskExecuting "DataRepositoryTaskExecuting" +// An existing data repository task is currently executing on the file system. +// Wait until the existing task has completed, then create the new task. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/fsx-2018-03-01/CreateDataRepositoryTask +func (c *FSx) CreateDataRepositoryTask(input *CreateDataRepositoryTaskInput) (*CreateDataRepositoryTaskOutput, error) { + req, out := c.CreateDataRepositoryTaskRequest(input) + return out, req.Send() +} + +// CreateDataRepositoryTaskWithContext is the same as CreateDataRepositoryTask with the addition of +// the ability to pass a context and additional request options. +// +// See CreateDataRepositoryTask for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *FSx) CreateDataRepositoryTaskWithContext(ctx aws.Context, input *CreateDataRepositoryTaskInput, opts ...request.Option) (*CreateDataRepositoryTaskOutput, error) { + req, out := c.CreateDataRepositoryTaskRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opCreateFileSystem = "CreateFileSystem" + +// CreateFileSystemRequest generates a "aws/request.Request" representing the +// client's request for the CreateFileSystem operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See CreateFileSystem for more information on using the CreateFileSystem +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the CreateFileSystemRequest method. +// req, resp := client.CreateFileSystemRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/fsx-2018-03-01/CreateFileSystem +func (c *FSx) CreateFileSystemRequest(input *CreateFileSystemInput) (req *request.Request, output *CreateFileSystemOutput) { + op := &request.Operation{ + Name: opCreateFileSystem, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateFileSystemInput{} + } + + output = &CreateFileSystemOutput{} + req = c.newRequest(op, input, output) + return +} + +// CreateFileSystem API operation for Amazon FSx. +// +// Creates a new, empty Amazon FSx file system. +// +// If a file system with the specified client request token exists and the parameters +// match, CreateFileSystem returns the description of the existing file system. +// If a file system specified client request token exists and the parameters +// don't match, this call returns IncompatibleParameterError. If a file system +// with the specified client request token doesn't exist, CreateFileSystem does +// the following: +// +// * Creates a new, empty Amazon FSx file system with an assigned ID, and +// an initial lifecycle state of CREATING. +// +// * Returns the description of the file system. +// +// This operation requires a client request token in the request that Amazon +// FSx uses to ensure idempotent creation. This means that calling the operation +// multiple times with the same client request token has no effect. By using +// the idempotent operation, you can retry a CreateFileSystem operation without +// the risk of creating an extra file system. This approach can be useful when +// an initial call fails in a way that makes it unclear whether a file system +// was created. Examples are if a transport level timeout occurred, or your +// connection was reset. If you use the same client request token and the initial +// call created a file system, the client receives success as long as the parameters +// are the same. +// +// The CreateFileSystem call returns while the file system's lifecycle state +// is still CREATING. You can check the file-system creation status by calling +// the DescribeFileSystems operation, which returns the file system state along +// with other information. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon FSx's +// API operation CreateFileSystem for usage and error information. +// +// Returned Error Codes: +// * ErrCodeBadRequest "BadRequest" +// A generic error indicating a failure with a client request. +// +// * ErrCodeActiveDirectoryError "ActiveDirectoryError" +// An Active Directory error. +// +// * ErrCodeIncompatibleParameterError "IncompatibleParameterError" +// The error returned when a second request is received with the same client +// request token but different parameters settings. A client request token should +// always uniquely identify a single request. +// +// * ErrCodeInvalidImportPath "InvalidImportPath" +// The path provided for data repository import isn't valid. +// +// * ErrCodeInvalidExportPath "InvalidExportPath" +// The path provided for data repository export isn't valid. +// +// * ErrCodeInvalidNetworkSettings "InvalidNetworkSettings" +// One or more network settings specified in the request are invalid. InvalidVpcId +// means that the ID passed for the virtual private cloud (VPC) is invalid. +// InvalidSubnetIds returns the list of IDs for subnets that are either invalid +// or not part of the VPC specified. InvalidSecurityGroupIds returns the list +// of IDs for security groups that are either invalid or not part of the VPC +// specified. +// +// * ErrCodeServiceLimitExceeded "ServiceLimitExceeded" +// An error indicating that a particular service limit was exceeded. You can +// increase some service limits by contacting AWS Support. +// +// * ErrCodeInternalServerError "InternalServerError" +// A generic error indicating a server-side failure. +// +// * ErrCodeMissingFileSystemConfiguration "MissingFileSystemConfiguration" +// File system configuration is required for this operation. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/fsx-2018-03-01/CreateFileSystem +func (c *FSx) CreateFileSystem(input *CreateFileSystemInput) (*CreateFileSystemOutput, error) { + req, out := c.CreateFileSystemRequest(input) + return out, req.Send() +} + +// CreateFileSystemWithContext is the same as CreateFileSystem with the addition of +// the ability to pass a context and additional request options. +// +// See CreateFileSystem for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *FSx) CreateFileSystemWithContext(ctx aws.Context, input *CreateFileSystemInput, opts ...request.Option) (*CreateFileSystemOutput, error) { + req, out := c.CreateFileSystemRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opCreateFileSystemFromBackup = "CreateFileSystemFromBackup" + +// CreateFileSystemFromBackupRequest generates a "aws/request.Request" representing the +// client's request for the CreateFileSystemFromBackup operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See CreateFileSystemFromBackup for more information on using the CreateFileSystemFromBackup +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the CreateFileSystemFromBackupRequest method. +// req, resp := client.CreateFileSystemFromBackupRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/fsx-2018-03-01/CreateFileSystemFromBackup +func (c *FSx) CreateFileSystemFromBackupRequest(input *CreateFileSystemFromBackupInput) (req *request.Request, output *CreateFileSystemFromBackupOutput) { + op := &request.Operation{ + Name: opCreateFileSystemFromBackup, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateFileSystemFromBackupInput{} + } + + output = &CreateFileSystemFromBackupOutput{} + req = c.newRequest(op, input, output) + return +} + +// CreateFileSystemFromBackup API operation for Amazon FSx. +// +// Creates a new Amazon FSx file system from an existing Amazon FSx for Windows +// File Server backup. +// +// If a file system with the specified client request token exists and the parameters +// match, this operation returns the description of the file system. If a client +// request token specified by the file system exists and the parameters don't +// match, this call returns IncompatibleParameterError. If a file system with +// the specified client request token doesn't exist, this operation does the +// following: +// +// * Creates a new Amazon FSx file system from backup with an assigned ID, +// and an initial lifecycle state of CREATING. +// +// * Returns the description of the file system. +// +// Parameters like Active Directory, default share name, automatic backup, and +// backup settings default to the parameters of the file system that was backed +// up, unless overridden. You can explicitly supply other settings. +// +// By using the idempotent operation, you can retry a CreateFileSystemFromBackup +// call without the risk of creating an extra file system. This approach can +// be useful when an initial call fails in a way that makes it unclear whether +// a file system was created. Examples are if a transport level timeout occurred, +// or your connection was reset. If you use the same client request token and +// the initial call created a file system, the client receives success as long +// as the parameters are the same. +// +// The CreateFileSystemFromBackup call returns while the file system's lifecycle +// state is still CREATING. You can check the file-system creation status by +// calling the DescribeFileSystems operation, which returns the file system +// state along with other information. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon FSx's +// API operation CreateFileSystemFromBackup for usage and error information. +// +// Returned Error Codes: +// * ErrCodeBadRequest "BadRequest" +// A generic error indicating a failure with a client request. +// +// * ErrCodeActiveDirectoryError "ActiveDirectoryError" +// An Active Directory error. +// +// * ErrCodeIncompatibleParameterError "IncompatibleParameterError" +// The error returned when a second request is received with the same client +// request token but different parameters settings. A client request token should +// always uniquely identify a single request. +// +// * ErrCodeInvalidNetworkSettings "InvalidNetworkSettings" +// One or more network settings specified in the request are invalid. InvalidVpcId +// means that the ID passed for the virtual private cloud (VPC) is invalid. +// InvalidSubnetIds returns the list of IDs for subnets that are either invalid +// or not part of the VPC specified. InvalidSecurityGroupIds returns the list +// of IDs for security groups that are either invalid or not part of the VPC +// specified. +// +// * ErrCodeServiceLimitExceeded "ServiceLimitExceeded" +// An error indicating that a particular service limit was exceeded. You can +// increase some service limits by contacting AWS Support. +// +// * ErrCodeBackupNotFound "BackupNotFound" +// No Amazon FSx backups were found based upon the supplied parameters. +// +// * ErrCodeInternalServerError "InternalServerError" +// A generic error indicating a server-side failure. +// +// * ErrCodeMissingFileSystemConfiguration "MissingFileSystemConfiguration" +// File system configuration is required for this operation. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/fsx-2018-03-01/CreateFileSystemFromBackup +func (c *FSx) CreateFileSystemFromBackup(input *CreateFileSystemFromBackupInput) (*CreateFileSystemFromBackupOutput, error) { + req, out := c.CreateFileSystemFromBackupRequest(input) + return out, req.Send() +} + +// CreateFileSystemFromBackupWithContext is the same as CreateFileSystemFromBackup with the addition of +// the ability to pass a context and additional request options. +// +// See CreateFileSystemFromBackup for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *FSx) CreateFileSystemFromBackupWithContext(ctx aws.Context, input *CreateFileSystemFromBackupInput, opts ...request.Option) (*CreateFileSystemFromBackupOutput, error) { + req, out := c.CreateFileSystemFromBackupRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDeleteBackup = "DeleteBackup" + +// DeleteBackupRequest generates a "aws/request.Request" representing the +// client's request for the DeleteBackup operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DeleteBackup for more information on using the DeleteBackup +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DeleteBackupRequest method. +// req, resp := client.DeleteBackupRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/fsx-2018-03-01/DeleteBackup +func (c *FSx) DeleteBackupRequest(input *DeleteBackupInput) (req *request.Request, output *DeleteBackupOutput) { + op := &request.Operation{ + Name: opDeleteBackup, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteBackupInput{} + } + + output = &DeleteBackupOutput{} + req = c.newRequest(op, input, output) + return +} + +// DeleteBackup API operation for Amazon FSx. +// +// Deletes an Amazon FSx for Windows File Server backup, deleting its contents. +// After deletion, the backup no longer exists, and its data is gone. +// +// The DeleteBackup call returns instantly. The backup will not show up in later +// DescribeBackups calls. +// +// The data in a deleted backup is also deleted and can't be recovered by any +// means. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon FSx's +// API operation DeleteBackup for usage and error information. +// +// Returned Error Codes: +// * ErrCodeBadRequest "BadRequest" +// A generic error indicating a failure with a client request. +// +// * ErrCodeBackupInProgress "BackupInProgress" +// Another backup is already under way. Wait for completion before initiating +// additional backups of this file system. +// +// * ErrCodeBackupNotFound "BackupNotFound" +// No Amazon FSx backups were found based upon the supplied parameters. +// +// * ErrCodeBackupRestoring "BackupRestoring" +// You can't delete a backup while it's being used to restore a file system. +// +// * ErrCodeIncompatibleParameterError "IncompatibleParameterError" +// The error returned when a second request is received with the same client +// request token but different parameters settings. A client request token should +// always uniquely identify a single request. +// +// * ErrCodeInternalServerError "InternalServerError" +// A generic error indicating a server-side failure. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/fsx-2018-03-01/DeleteBackup +func (c *FSx) DeleteBackup(input *DeleteBackupInput) (*DeleteBackupOutput, error) { + req, out := c.DeleteBackupRequest(input) + return out, req.Send() +} + +// DeleteBackupWithContext is the same as DeleteBackup with the addition of +// the ability to pass a context and additional request options. +// +// See DeleteBackup for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *FSx) DeleteBackupWithContext(ctx aws.Context, input *DeleteBackupInput, opts ...request.Option) (*DeleteBackupOutput, error) { + req, out := c.DeleteBackupRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDeleteFileSystem = "DeleteFileSystem" + +// DeleteFileSystemRequest generates a "aws/request.Request" representing the +// client's request for the DeleteFileSystem operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DeleteFileSystem for more information on using the DeleteFileSystem +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DeleteFileSystemRequest method. +// req, resp := client.DeleteFileSystemRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/fsx-2018-03-01/DeleteFileSystem +func (c *FSx) DeleteFileSystemRequest(input *DeleteFileSystemInput) (req *request.Request, output *DeleteFileSystemOutput) { + op := &request.Operation{ + Name: opDeleteFileSystem, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteFileSystemInput{} + } + + output = &DeleteFileSystemOutput{} + req = c.newRequest(op, input, output) + return +} + +// DeleteFileSystem API operation for Amazon FSx. +// +// Deletes a file system, deleting its contents. After deletion, the file system +// no longer exists, and its data is gone. Any existing automatic backups will +// also be deleted. +// +// By default, when you delete an Amazon FSx for Windows File Server file system, +// a final backup is created upon deletion. This final backup is not subject +// to the file system's retention policy, and must be manually deleted. +// +// The DeleteFileSystem action returns while the file system has the DELETING +// status. You can check the file system deletion status by calling the DescribeFileSystems +// action, which returns a list of file systems in your account. If you pass +// the file system ID for a deleted file system, the DescribeFileSystems returns +// a FileSystemNotFound error. +// +// Deleting an Amazon FSx for Lustre file system will fail with a 400 BadRequest +// if a data repository task is in a PENDING or EXECUTING state. +// +// The data in a deleted file system is also deleted and can't be recovered +// by any means. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon FSx's +// API operation DeleteFileSystem for usage and error information. +// +// Returned Error Codes: +// * ErrCodeBadRequest "BadRequest" +// A generic error indicating a failure with a client request. +// +// * ErrCodeIncompatibleParameterError "IncompatibleParameterError" +// The error returned when a second request is received with the same client +// request token but different parameters settings. A client request token should +// always uniquely identify a single request. +// +// * ErrCodeFileSystemNotFound "FileSystemNotFound" +// No Amazon FSx file systems were found based upon supplied parameters. +// +// * ErrCodeServiceLimitExceeded "ServiceLimitExceeded" +// An error indicating that a particular service limit was exceeded. You can +// increase some service limits by contacting AWS Support. +// +// * ErrCodeInternalServerError "InternalServerError" +// A generic error indicating a server-side failure. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/fsx-2018-03-01/DeleteFileSystem +func (c *FSx) DeleteFileSystem(input *DeleteFileSystemInput) (*DeleteFileSystemOutput, error) { + req, out := c.DeleteFileSystemRequest(input) + return out, req.Send() +} + +// DeleteFileSystemWithContext is the same as DeleteFileSystem with the addition of +// the ability to pass a context and additional request options. +// +// See DeleteFileSystem for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *FSx) DeleteFileSystemWithContext(ctx aws.Context, input *DeleteFileSystemInput, opts ...request.Option) (*DeleteFileSystemOutput, error) { + req, out := c.DeleteFileSystemRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDescribeBackups = "DescribeBackups" + +// DescribeBackupsRequest generates a "aws/request.Request" representing the +// client's request for the DescribeBackups operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DescribeBackups for more information on using the DescribeBackups +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DescribeBackupsRequest method. +// req, resp := client.DescribeBackupsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/fsx-2018-03-01/DescribeBackups +func (c *FSx) DescribeBackupsRequest(input *DescribeBackupsInput) (req *request.Request, output *DescribeBackupsOutput) { + op := &request.Operation{ + Name: opDescribeBackups, + HTTPMethod: "POST", + HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "MaxResults", + TruncationToken: "", + }, + } + + if input == nil { + input = &DescribeBackupsInput{} + } + + output = &DescribeBackupsOutput{} + req = c.newRequest(op, input, output) + return +} + +// DescribeBackups API operation for Amazon FSx. +// +// Returns the description of specific Amazon FSx for Windows File Server backups, +// if a BackupIds value is provided for that backup. Otherwise, it returns all +// backups owned by your AWS account in the AWS Region of the endpoint that +// you're calling. +// +// When retrieving all backups, you can optionally specify the MaxResults parameter +// to limit the number of backups in a response. If more backups remain, Amazon +// FSx returns a NextToken value in the response. In this case, send a later +// request with the NextToken request parameter set to the value of NextToken +// from the last response. +// +// This action is used in an iterative process to retrieve a list of your backups. +// DescribeBackups is called first without a NextTokenvalue. Then the action +// continues to be called with the NextToken parameter set to the value of the +// last NextToken value until a response has no NextToken. +// +// When using this action, keep the following in mind: +// +// * The implementation might return fewer than MaxResults file system descriptions +// while still including a NextToken value. +// +// * The order of backups returned in the response of one DescribeBackups +// call and the order of backups returned across the responses of a multi-call +// iteration is unspecified. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon FSx's +// API operation DescribeBackups for usage and error information. +// +// Returned Error Codes: +// * ErrCodeBadRequest "BadRequest" +// A generic error indicating a failure with a client request. +// +// * ErrCodeFileSystemNotFound "FileSystemNotFound" +// No Amazon FSx file systems were found based upon supplied parameters. +// +// * ErrCodeBackupNotFound "BackupNotFound" +// No Amazon FSx backups were found based upon the supplied parameters. +// +// * ErrCodeInternalServerError "InternalServerError" +// A generic error indicating a server-side failure. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/fsx-2018-03-01/DescribeBackups +func (c *FSx) DescribeBackups(input *DescribeBackupsInput) (*DescribeBackupsOutput, error) { + req, out := c.DescribeBackupsRequest(input) + return out, req.Send() +} + +// DescribeBackupsWithContext is the same as DescribeBackups with the addition of +// the ability to pass a context and additional request options. +// +// See DescribeBackups for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *FSx) DescribeBackupsWithContext(ctx aws.Context, input *DescribeBackupsInput, opts ...request.Option) (*DescribeBackupsOutput, error) { + req, out := c.DescribeBackupsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +// DescribeBackupsPages iterates over the pages of a DescribeBackups operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See DescribeBackups method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a DescribeBackups operation. +// pageNum := 0 +// err := client.DescribeBackupsPages(params, +// func(page *fsx.DescribeBackupsOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *FSx) DescribeBackupsPages(input *DescribeBackupsInput, fn func(*DescribeBackupsOutput, bool) bool) error { + return c.DescribeBackupsPagesWithContext(aws.BackgroundContext(), input, fn) +} + +// DescribeBackupsPagesWithContext same as DescribeBackupsPages except +// it takes a Context and allows setting request options on the pages. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *FSx) DescribeBackupsPagesWithContext(ctx aws.Context, input *DescribeBackupsInput, fn func(*DescribeBackupsOutput, bool) bool, opts ...request.Option) error { + p := request.Pagination{ + NewRequest: func() (*request.Request, error) { + var inCpy *DescribeBackupsInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.DescribeBackupsRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + + for p.Next() { + if !fn(p.Page().(*DescribeBackupsOutput), !p.HasNextPage()) { + break + } + } + + return p.Err() +} + +const opDescribeDataRepositoryTasks = "DescribeDataRepositoryTasks" + +// DescribeDataRepositoryTasksRequest generates a "aws/request.Request" representing the +// client's request for the DescribeDataRepositoryTasks operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DescribeDataRepositoryTasks for more information on using the DescribeDataRepositoryTasks +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DescribeDataRepositoryTasksRequest method. +// req, resp := client.DescribeDataRepositoryTasksRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/fsx-2018-03-01/DescribeDataRepositoryTasks +func (c *FSx) DescribeDataRepositoryTasksRequest(input *DescribeDataRepositoryTasksInput) (req *request.Request, output *DescribeDataRepositoryTasksOutput) { + op := &request.Operation{ + Name: opDescribeDataRepositoryTasks, + HTTPMethod: "POST", + HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "MaxResults", + TruncationToken: "", + }, + } + + if input == nil { + input = &DescribeDataRepositoryTasksInput{} + } + + output = &DescribeDataRepositoryTasksOutput{} + req = c.newRequest(op, input, output) + return +} + +// DescribeDataRepositoryTasks API operation for Amazon FSx. +// +// Returns the description of specific Amazon FSx for Lustre data repository +// tasks, if one or more TaskIds values are provided in the request, or if filters +// are used in the request. You can use filters to narrow the response to include +// just tasks for specific file systems, or tasks in a specific lifecycle state. +// Otherwise, it returns all data repository tasks owned by your AWS account +// in the AWS Region of the endpoint that you're calling. +// +// When retrieving all tasks, you can paginate the response by using the optional +// MaxResults parameter to limit the number of tasks returned in a response. +// If more tasks remain, Amazon FSx returns a NextToken value in the response. +// In this case, send a later request with the NextToken request parameter set +// to the value of NextToken from the last response. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon FSx's +// API operation DescribeDataRepositoryTasks for usage and error information. +// +// Returned Error Codes: +// * ErrCodeBadRequest "BadRequest" +// A generic error indicating a failure with a client request. +// +// * ErrCodeFileSystemNotFound "FileSystemNotFound" +// No Amazon FSx file systems were found based upon supplied parameters. +// +// * ErrCodeDataRepositoryTaskNotFound "DataRepositoryTaskNotFound" +// The data repository task or tasks you specified could not be found. +// +// * ErrCodeInternalServerError "InternalServerError" +// A generic error indicating a server-side failure. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/fsx-2018-03-01/DescribeDataRepositoryTasks +func (c *FSx) DescribeDataRepositoryTasks(input *DescribeDataRepositoryTasksInput) (*DescribeDataRepositoryTasksOutput, error) { + req, out := c.DescribeDataRepositoryTasksRequest(input) + return out, req.Send() +} + +// DescribeDataRepositoryTasksWithContext is the same as DescribeDataRepositoryTasks with the addition of +// the ability to pass a context and additional request options. +// +// See DescribeDataRepositoryTasks for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *FSx) DescribeDataRepositoryTasksWithContext(ctx aws.Context, input *DescribeDataRepositoryTasksInput, opts ...request.Option) (*DescribeDataRepositoryTasksOutput, error) { + req, out := c.DescribeDataRepositoryTasksRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +// DescribeDataRepositoryTasksPages iterates over the pages of a DescribeDataRepositoryTasks operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See DescribeDataRepositoryTasks method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a DescribeDataRepositoryTasks operation. +// pageNum := 0 +// err := client.DescribeDataRepositoryTasksPages(params, +// func(page *fsx.DescribeDataRepositoryTasksOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *FSx) DescribeDataRepositoryTasksPages(input *DescribeDataRepositoryTasksInput, fn func(*DescribeDataRepositoryTasksOutput, bool) bool) error { + return c.DescribeDataRepositoryTasksPagesWithContext(aws.BackgroundContext(), input, fn) +} + +// DescribeDataRepositoryTasksPagesWithContext same as DescribeDataRepositoryTasksPages except +// it takes a Context and allows setting request options on the pages. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *FSx) DescribeDataRepositoryTasksPagesWithContext(ctx aws.Context, input *DescribeDataRepositoryTasksInput, fn func(*DescribeDataRepositoryTasksOutput, bool) bool, opts ...request.Option) error { + p := request.Pagination{ + NewRequest: func() (*request.Request, error) { + var inCpy *DescribeDataRepositoryTasksInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.DescribeDataRepositoryTasksRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + + for p.Next() { + if !fn(p.Page().(*DescribeDataRepositoryTasksOutput), !p.HasNextPage()) { + break + } + } + + return p.Err() +} + +const opDescribeFileSystems = "DescribeFileSystems" + +// DescribeFileSystemsRequest generates a "aws/request.Request" representing the +// client's request for the DescribeFileSystems operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DescribeFileSystems for more information on using the DescribeFileSystems +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DescribeFileSystemsRequest method. +// req, resp := client.DescribeFileSystemsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/fsx-2018-03-01/DescribeFileSystems +func (c *FSx) DescribeFileSystemsRequest(input *DescribeFileSystemsInput) (req *request.Request, output *DescribeFileSystemsOutput) { + op := &request.Operation{ + Name: opDescribeFileSystems, + HTTPMethod: "POST", + HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "MaxResults", + TruncationToken: "", + }, + } + + if input == nil { + input = &DescribeFileSystemsInput{} + } + + output = &DescribeFileSystemsOutput{} + req = c.newRequest(op, input, output) + return +} + +// DescribeFileSystems API operation for Amazon FSx. +// +// Returns the description of specific Amazon FSx file systems, if a FileSystemIds +// value is provided for that file system. Otherwise, it returns descriptions +// of all file systems owned by your AWS account in the AWS Region of the endpoint +// that you're calling. +// +// When retrieving all file system descriptions, you can optionally specify +// the MaxResults parameter to limit the number of descriptions in a response. +// If more file system descriptions remain, Amazon FSx returns a NextToken value +// in the response. In this case, send a later request with the NextToken request +// parameter set to the value of NextToken from the last response. +// +// This action is used in an iterative process to retrieve a list of your file +// system descriptions. DescribeFileSystems is called first without a NextTokenvalue. +// Then the action continues to be called with the NextToken parameter set to +// the value of the last NextToken value until a response has no NextToken. +// +// When using this action, keep the following in mind: +// +// * The implementation might return fewer than MaxResults file system descriptions +// while still including a NextToken value. +// +// * The order of file systems returned in the response of one DescribeFileSystems +// call and the order of file systems returned across the responses of a +// multicall iteration is unspecified. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon FSx's +// API operation DescribeFileSystems for usage and error information. +// +// Returned Error Codes: +// * ErrCodeBadRequest "BadRequest" +// A generic error indicating a failure with a client request. +// +// * ErrCodeFileSystemNotFound "FileSystemNotFound" +// No Amazon FSx file systems were found based upon supplied parameters. +// +// * ErrCodeInternalServerError "InternalServerError" +// A generic error indicating a server-side failure. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/fsx-2018-03-01/DescribeFileSystems +func (c *FSx) DescribeFileSystems(input *DescribeFileSystemsInput) (*DescribeFileSystemsOutput, error) { + req, out := c.DescribeFileSystemsRequest(input) + return out, req.Send() +} + +// DescribeFileSystemsWithContext is the same as DescribeFileSystems with the addition of +// the ability to pass a context and additional request options. +// +// See DescribeFileSystems for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *FSx) DescribeFileSystemsWithContext(ctx aws.Context, input *DescribeFileSystemsInput, opts ...request.Option) (*DescribeFileSystemsOutput, error) { + req, out := c.DescribeFileSystemsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +// DescribeFileSystemsPages iterates over the pages of a DescribeFileSystems operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See DescribeFileSystems method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a DescribeFileSystems operation. +// pageNum := 0 +// err := client.DescribeFileSystemsPages(params, +// func(page *fsx.DescribeFileSystemsOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *FSx) DescribeFileSystemsPages(input *DescribeFileSystemsInput, fn func(*DescribeFileSystemsOutput, bool) bool) error { + return c.DescribeFileSystemsPagesWithContext(aws.BackgroundContext(), input, fn) +} + +// DescribeFileSystemsPagesWithContext same as DescribeFileSystemsPages except +// it takes a Context and allows setting request options on the pages. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *FSx) DescribeFileSystemsPagesWithContext(ctx aws.Context, input *DescribeFileSystemsInput, fn func(*DescribeFileSystemsOutput, bool) bool, opts ...request.Option) error { + p := request.Pagination{ + NewRequest: func() (*request.Request, error) { + var inCpy *DescribeFileSystemsInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.DescribeFileSystemsRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + + for p.Next() { + if !fn(p.Page().(*DescribeFileSystemsOutput), !p.HasNextPage()) { + break + } + } + + return p.Err() +} + +const opListTagsForResource = "ListTagsForResource" + +// ListTagsForResourceRequest generates a "aws/request.Request" representing the +// client's request for the ListTagsForResource operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See ListTagsForResource for more information on using the ListTagsForResource +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the ListTagsForResourceRequest method. +// req, resp := client.ListTagsForResourceRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/fsx-2018-03-01/ListTagsForResource +func (c *FSx) ListTagsForResourceRequest(input *ListTagsForResourceInput) (req *request.Request, output *ListTagsForResourceOutput) { + op := &request.Operation{ + Name: opListTagsForResource, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ListTagsForResourceInput{} + } + + output = &ListTagsForResourceOutput{} + req = c.newRequest(op, input, output) + return +} + +// ListTagsForResource API operation for Amazon FSx. +// +// Lists tags for an Amazon FSx file systems and backups in the case of Amazon +// FSx for Windows File Server. +// +// When retrieving all tags, you can optionally specify the MaxResults parameter +// to limit the number of tags in a response. If more tags remain, Amazon FSx +// returns a NextToken value in the response. In this case, send a later request +// with the NextToken request parameter set to the value of NextToken from the +// last response. +// +// This action is used in an iterative process to retrieve a list of your tags. +// ListTagsForResource is called first without a NextTokenvalue. Then the action +// continues to be called with the NextToken parameter set to the value of the +// last NextToken value until a response has no NextToken. +// +// When using this action, keep the following in mind: +// +// * The implementation might return fewer than MaxResults file system descriptions +// while still including a NextToken value. +// +// * The order of tags returned in the response of one ListTagsForResource +// call and the order of tags returned across the responses of a multi-call +// iteration is unspecified. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon FSx's +// API operation ListTagsForResource for usage and error information. +// +// Returned Error Codes: +// * ErrCodeBadRequest "BadRequest" +// A generic error indicating a failure with a client request. +// +// * ErrCodeInternalServerError "InternalServerError" +// A generic error indicating a server-side failure. +// +// * ErrCodeResourceNotFound "ResourceNotFound" +// The resource specified by the Amazon Resource Name (ARN) can't be found. +// +// * ErrCodeNotServiceResourceError "NotServiceResourceError" +// The resource specified for the tagging operation is not a resource type owned +// by Amazon FSx. Use the API of the relevant service to perform the operation. +// +// * ErrCodeResourceDoesNotSupportTagging "ResourceDoesNotSupportTagging" +// The resource specified does not support tagging. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/fsx-2018-03-01/ListTagsForResource +func (c *FSx) ListTagsForResource(input *ListTagsForResourceInput) (*ListTagsForResourceOutput, error) { + req, out := c.ListTagsForResourceRequest(input) + return out, req.Send() +} + +// ListTagsForResourceWithContext is the same as ListTagsForResource with the addition of +// the ability to pass a context and additional request options. +// +// See ListTagsForResource for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *FSx) ListTagsForResourceWithContext(ctx aws.Context, input *ListTagsForResourceInput, opts ...request.Option) (*ListTagsForResourceOutput, error) { + req, out := c.ListTagsForResourceRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opTagResource = "TagResource" + +// TagResourceRequest generates a "aws/request.Request" representing the +// client's request for the TagResource operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See TagResource for more information on using the TagResource +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the TagResourceRequest method. +// req, resp := client.TagResourceRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/fsx-2018-03-01/TagResource +func (c *FSx) TagResourceRequest(input *TagResourceInput) (req *request.Request, output *TagResourceOutput) { + op := &request.Operation{ + Name: opTagResource, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &TagResourceInput{} + } + + output = &TagResourceOutput{} + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Swap(jsonrpc.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler) + return +} + +// TagResource API operation for Amazon FSx. +// +// Tags an Amazon FSx resource. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon FSx's +// API operation TagResource for usage and error information. +// +// Returned Error Codes: +// * ErrCodeBadRequest "BadRequest" +// A generic error indicating a failure with a client request. +// +// * ErrCodeInternalServerError "InternalServerError" +// A generic error indicating a server-side failure. +// +// * ErrCodeResourceNotFound "ResourceNotFound" +// The resource specified by the Amazon Resource Name (ARN) can't be found. +// +// * ErrCodeNotServiceResourceError "NotServiceResourceError" +// The resource specified for the tagging operation is not a resource type owned +// by Amazon FSx. Use the API of the relevant service to perform the operation. +// +// * ErrCodeResourceDoesNotSupportTagging "ResourceDoesNotSupportTagging" +// The resource specified does not support tagging. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/fsx-2018-03-01/TagResource +func (c *FSx) TagResource(input *TagResourceInput) (*TagResourceOutput, error) { + req, out := c.TagResourceRequest(input) + return out, req.Send() +} + +// TagResourceWithContext is the same as TagResource with the addition of +// the ability to pass a context and additional request options. +// +// See TagResource for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *FSx) TagResourceWithContext(ctx aws.Context, input *TagResourceInput, opts ...request.Option) (*TagResourceOutput, error) { + req, out := c.TagResourceRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opUntagResource = "UntagResource" + +// UntagResourceRequest generates a "aws/request.Request" representing the +// client's request for the UntagResource operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See UntagResource for more information on using the UntagResource +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the UntagResourceRequest method. +// req, resp := client.UntagResourceRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/fsx-2018-03-01/UntagResource +func (c *FSx) UntagResourceRequest(input *UntagResourceInput) (req *request.Request, output *UntagResourceOutput) { + op := &request.Operation{ + Name: opUntagResource, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &UntagResourceInput{} + } + + output = &UntagResourceOutput{} + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Swap(jsonrpc.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler) + return +} + +// UntagResource API operation for Amazon FSx. +// +// This action removes a tag from an Amazon FSx resource. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon FSx's +// API operation UntagResource for usage and error information. +// +// Returned Error Codes: +// * ErrCodeBadRequest "BadRequest" +// A generic error indicating a failure with a client request. +// +// * ErrCodeInternalServerError "InternalServerError" +// A generic error indicating a server-side failure. +// +// * ErrCodeResourceNotFound "ResourceNotFound" +// The resource specified by the Amazon Resource Name (ARN) can't be found. +// +// * ErrCodeNotServiceResourceError "NotServiceResourceError" +// The resource specified for the tagging operation is not a resource type owned +// by Amazon FSx. Use the API of the relevant service to perform the operation. +// +// * ErrCodeResourceDoesNotSupportTagging "ResourceDoesNotSupportTagging" +// The resource specified does not support tagging. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/fsx-2018-03-01/UntagResource +func (c *FSx) UntagResource(input *UntagResourceInput) (*UntagResourceOutput, error) { + req, out := c.UntagResourceRequest(input) + return out, req.Send() +} + +// UntagResourceWithContext is the same as UntagResource with the addition of +// the ability to pass a context and additional request options. +// +// See UntagResource for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *FSx) UntagResourceWithContext(ctx aws.Context, input *UntagResourceInput, opts ...request.Option) (*UntagResourceOutput, error) { + req, out := c.UntagResourceRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opUpdateFileSystem = "UpdateFileSystem" + +// UpdateFileSystemRequest generates a "aws/request.Request" representing the +// client's request for the UpdateFileSystem operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See UpdateFileSystem for more information on using the UpdateFileSystem +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the UpdateFileSystemRequest method. +// req, resp := client.UpdateFileSystemRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/fsx-2018-03-01/UpdateFileSystem +func (c *FSx) UpdateFileSystemRequest(input *UpdateFileSystemInput) (req *request.Request, output *UpdateFileSystemOutput) { + op := &request.Operation{ + Name: opUpdateFileSystem, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &UpdateFileSystemInput{} + } + + output = &UpdateFileSystemOutput{} + req = c.newRequest(op, input, output) + return +} + +// UpdateFileSystem API operation for Amazon FSx. +// +// Updates a file system configuration. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon FSx's +// API operation UpdateFileSystem for usage and error information. +// +// Returned Error Codes: +// * ErrCodeBadRequest "BadRequest" +// A generic error indicating a failure with a client request. +// +// * ErrCodeUnsupportedOperation "UnsupportedOperation" +// The requested operation is not supported for this resource or API. +// +// * ErrCodeIncompatibleParameterError "IncompatibleParameterError" +// The error returned when a second request is received with the same client +// request token but different parameters settings. A client request token should +// always uniquely identify a single request. +// +// * ErrCodeInternalServerError "InternalServerError" +// A generic error indicating a server-side failure. +// +// * ErrCodeFileSystemNotFound "FileSystemNotFound" +// No Amazon FSx file systems were found based upon supplied parameters. +// +// * ErrCodeMissingFileSystemConfiguration "MissingFileSystemConfiguration" +// File system configuration is required for this operation. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/fsx-2018-03-01/UpdateFileSystem +func (c *FSx) UpdateFileSystem(input *UpdateFileSystemInput) (*UpdateFileSystemOutput, error) { + req, out := c.UpdateFileSystemRequest(input) + return out, req.Send() +} + +// UpdateFileSystemWithContext is the same as UpdateFileSystem with the addition of +// the ability to pass a context and additional request options. +// +// See UpdateFileSystem for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *FSx) UpdateFileSystemWithContext(ctx aws.Context, input *UpdateFileSystemInput, opts ...request.Option) (*UpdateFileSystemOutput, error) { + req, out := c.UpdateFileSystemRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +// The Microsoft AD attributes of the Amazon FSx for Windows File Server file +// system. +type ActiveDirectoryBackupAttributes struct { + _ struct{} `type:"structure"` + + // The ID of the AWS Managed Microsoft Active Directory instance to which the + // file system is joined. + ActiveDirectoryId *string `min:"12" type:"string"` + + // The fully qualified domain name of the self-managed AD directory. + DomainName *string `min:"1" type:"string"` +} + +// String returns the string representation +func (s ActiveDirectoryBackupAttributes) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ActiveDirectoryBackupAttributes) GoString() string { + return s.String() +} + +// SetActiveDirectoryId sets the ActiveDirectoryId field's value. +func (s *ActiveDirectoryBackupAttributes) SetActiveDirectoryId(v string) *ActiveDirectoryBackupAttributes { + s.ActiveDirectoryId = &v + return s +} + +// SetDomainName sets the DomainName field's value. +func (s *ActiveDirectoryBackupAttributes) SetDomainName(v string) *ActiveDirectoryBackupAttributes { + s.DomainName = &v + return s +} + +// A backup of an Amazon FSx for Windows File Server file system. You can create +// a new file system from a backup to protect against data loss. +type Backup struct { + _ struct{} `type:"structure"` + + // The ID of the backup. + // + // BackupId is a required field + BackupId *string `min:"12" type:"string" required:"true"` + + // The time when a particular backup was created. + // + // CreationTime is a required field + CreationTime *time.Time `type:"timestamp" required:"true"` + + // The configuration of the self-managed Microsoft Active Directory (AD) to + // which the Windows File Server instance is joined. + DirectoryInformation *ActiveDirectoryBackupAttributes `type:"structure"` + + // Details explaining any failures that occur when creating a backup. + FailureDetails *BackupFailureDetails `type:"structure"` + + // Metadata of the file system associated with the backup. This metadata is + // persisted even if the file system is deleted. + // + // FileSystem is a required field + FileSystem *FileSystem `type:"structure" required:"true"` + + // The ID of the AWS Key Management Service (AWS KMS) key used to encrypt this + // backup of the Amazon FSx for Windows file system's data at rest. Amazon FSx + // for Lustre does not support KMS encryption. + KmsKeyId *string `min:"1" type:"string"` + + // The lifecycle status of the backup. + // + // Lifecycle is a required field + Lifecycle *string `type:"string" required:"true" enum:"BackupLifecycle"` + + // The current percent of progress of an asynchronous task. + ProgressPercent *int64 `type:"integer"` + + // The Amazon Resource Name (ARN) for the backup resource. + ResourceARN *string `min:"8" type:"string"` + + // Tags associated with a particular file system. + Tags []*Tag `min:"1" type:"list"` + + // The type of the backup. + // + // Type is a required field + Type *string `type:"string" required:"true" enum:"BackupType"` +} + +// String returns the string representation +func (s Backup) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Backup) GoString() string { + return s.String() +} + +// SetBackupId sets the BackupId field's value. +func (s *Backup) SetBackupId(v string) *Backup { + s.BackupId = &v + return s +} + +// SetCreationTime sets the CreationTime field's value. +func (s *Backup) SetCreationTime(v time.Time) *Backup { + s.CreationTime = &v + return s +} + +// SetDirectoryInformation sets the DirectoryInformation field's value. +func (s *Backup) SetDirectoryInformation(v *ActiveDirectoryBackupAttributes) *Backup { + s.DirectoryInformation = v + return s +} + +// SetFailureDetails sets the FailureDetails field's value. +func (s *Backup) SetFailureDetails(v *BackupFailureDetails) *Backup { + s.FailureDetails = v + return s +} + +// SetFileSystem sets the FileSystem field's value. +func (s *Backup) SetFileSystem(v *FileSystem) *Backup { + s.FileSystem = v + return s +} + +// SetKmsKeyId sets the KmsKeyId field's value. +func (s *Backup) SetKmsKeyId(v string) *Backup { + s.KmsKeyId = &v + return s +} + +// SetLifecycle sets the Lifecycle field's value. +func (s *Backup) SetLifecycle(v string) *Backup { + s.Lifecycle = &v + return s +} + +// SetProgressPercent sets the ProgressPercent field's value. +func (s *Backup) SetProgressPercent(v int64) *Backup { + s.ProgressPercent = &v + return s +} + +// SetResourceARN sets the ResourceARN field's value. +func (s *Backup) SetResourceARN(v string) *Backup { + s.ResourceARN = &v + return s +} + +// SetTags sets the Tags field's value. +func (s *Backup) SetTags(v []*Tag) *Backup { + s.Tags = v + return s +} + +// SetType sets the Type field's value. +func (s *Backup) SetType(v string) *Backup { + s.Type = &v + return s +} + +// If backup creation fails, this structure contains the details of that failure. +type BackupFailureDetails struct { + _ struct{} `type:"structure"` + + // A message describing the backup creation failure. + Message *string `min:"1" type:"string"` +} + +// String returns the string representation +func (s BackupFailureDetails) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s BackupFailureDetails) GoString() string { + return s.String() +} + +// SetMessage sets the Message field's value. +func (s *BackupFailureDetails) SetMessage(v string) *BackupFailureDetails { + s.Message = &v + return s +} + +// Cancels a data repository task. +type CancelDataRepositoryTaskInput struct { + _ struct{} `type:"structure"` + + // Specifies the data repository task to cancel. + // + // TaskId is a required field + TaskId *string `min:"12" type:"string" required:"true"` +} + +// String returns the string representation +func (s CancelDataRepositoryTaskInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CancelDataRepositoryTaskInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CancelDataRepositoryTaskInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CancelDataRepositoryTaskInput"} + if s.TaskId == nil { + invalidParams.Add(request.NewErrParamRequired("TaskId")) + } + if s.TaskId != nil && len(*s.TaskId) < 12 { + invalidParams.Add(request.NewErrParamMinLen("TaskId", 12)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetTaskId sets the TaskId field's value. +func (s *CancelDataRepositoryTaskInput) SetTaskId(v string) *CancelDataRepositoryTaskInput { + s.TaskId = &v + return s +} + +type CancelDataRepositoryTaskOutput struct { + _ struct{} `type:"structure"` + + // The lifecycle status of the data repository task, as follows: + // + // * PENDING - Amazon FSx has not started the task. + // + // * EXECUTING - Amazon FSx is processing the task. + // + // * FAILED - Amazon FSx was not able to complete the task. For example, + // there may be files the task failed to process. The DataRepositoryTaskFailureDetails + // property provides more information about task failures. + // + // * SUCCEEDED - FSx completed the task successfully. + // + // * CANCELED - Amazon FSx canceled the task and it did not complete. + // + // * CANCELING - FSx is in process of canceling the task. + Lifecycle *string `type:"string" enum:"DataRepositoryTaskLifecycle"` + + // The ID of the task being canceled. + TaskId *string `min:"12" type:"string"` +} + +// String returns the string representation +func (s CancelDataRepositoryTaskOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CancelDataRepositoryTaskOutput) GoString() string { + return s.String() +} + +// SetLifecycle sets the Lifecycle field's value. +func (s *CancelDataRepositoryTaskOutput) SetLifecycle(v string) *CancelDataRepositoryTaskOutput { + s.Lifecycle = &v + return s +} + +// SetTaskId sets the TaskId field's value. +func (s *CancelDataRepositoryTaskOutput) SetTaskId(v string) *CancelDataRepositoryTaskOutput { + s.TaskId = &v + return s +} + +// Provides a report detailing the data repository task results of the files +// processed that match the criteria specified in the report Scope parameter. +// FSx delivers the report to the file system's linked data repository in Amazon +// S3, using the path specified in the report Path parameter. You can specify +// whether or not a report gets generated for a task using the Enabled parameter. +type CompletionReport struct { + _ struct{} `type:"structure"` + + // Set Enabled to True to generate a CompletionReport when the task completes. + // If set to true, then you need to provide a report Scope, Path, and Format. + // Set Enabled to False if you do not want a CompletionReport generated when + // the task completes. + // + // Enabled is a required field + Enabled *bool `type:"boolean" required:"true"` + + // Required if Enabled is set to true. Specifies the format of the CompletionReport. + // REPORT_CSV_20191124 is the only format currently supported. When Format is + // set to REPORT_CSV_20191124, the CompletionReport is provided in CSV format, + // and is delivered to {path}/task-{id}/failures.csv. + Format *string `type:"string" enum:"ReportFormat"` + + // Required if Enabled is set to true. Specifies the location of the report + // on the file system's linked S3 data repository. An absolute path that defines + // where the completion report will be stored in the destination location. The + // Path you provide must be located within the file system’s ExportPath. An + // example Path value is "s3://myBucket/myExportPath/optionalPrefix". The report + // provides the following information for each file in the report: FilePath, + // FileStatus, and ErrorCode. To learn more about a file system's ExportPath, + // see . + Path *string `min:"3" type:"string"` + + // Required if Enabled is set to true. Specifies the scope of the CompletionReport; + // FAILED_FILES_ONLY is the only scope currently supported. When Scope is set + // to FAILED_FILES_ONLY, the CompletionReport only contains information about + // files that the data repository task failed to process. + Scope *string `type:"string" enum:"ReportScope"` +} + +// String returns the string representation +func (s CompletionReport) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CompletionReport) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CompletionReport) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CompletionReport"} + if s.Enabled == nil { + invalidParams.Add(request.NewErrParamRequired("Enabled")) + } + if s.Path != nil && len(*s.Path) < 3 { + invalidParams.Add(request.NewErrParamMinLen("Path", 3)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetEnabled sets the Enabled field's value. +func (s *CompletionReport) SetEnabled(v bool) *CompletionReport { + s.Enabled = &v + return s +} + +// SetFormat sets the Format field's value. +func (s *CompletionReport) SetFormat(v string) *CompletionReport { + s.Format = &v + return s +} + +// SetPath sets the Path field's value. +func (s *CompletionReport) SetPath(v string) *CompletionReport { + s.Path = &v + return s +} + +// SetScope sets the Scope field's value. +func (s *CompletionReport) SetScope(v string) *CompletionReport { + s.Scope = &v + return s +} + +// The request object for the CreateBackup operation. +type CreateBackupInput struct { + _ struct{} `type:"structure"` + + // (Optional) A string of up to 64 ASCII characters that Amazon FSx uses to + // ensure idempotent creation. This string is automatically filled on your behalf + // when you use the AWS Command Line Interface (AWS CLI) or an AWS SDK. + ClientRequestToken *string `min:"1" type:"string" idempotencyToken:"true"` + + // The ID of the file system to back up. + // + // FileSystemId is a required field + FileSystemId *string `min:"11" type:"string" required:"true"` + + // The tags to apply to the backup at backup creation. The key value of the + // Name tag appears in the console as the backup name. + Tags []*Tag `min:"1" type:"list"` +} + +// String returns the string representation +func (s CreateBackupInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateBackupInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateBackupInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateBackupInput"} + if s.ClientRequestToken != nil && len(*s.ClientRequestToken) < 1 { + invalidParams.Add(request.NewErrParamMinLen("ClientRequestToken", 1)) + } + if s.FileSystemId == nil { + invalidParams.Add(request.NewErrParamRequired("FileSystemId")) + } + if s.FileSystemId != nil && len(*s.FileSystemId) < 11 { + invalidParams.Add(request.NewErrParamMinLen("FileSystemId", 11)) + } + if s.Tags != nil && len(s.Tags) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Tags", 1)) + } + if s.Tags != nil { + for i, v := range s.Tags { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "Tags", i), err.(request.ErrInvalidParams)) + } + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetClientRequestToken sets the ClientRequestToken field's value. +func (s *CreateBackupInput) SetClientRequestToken(v string) *CreateBackupInput { + s.ClientRequestToken = &v + return s +} + +// SetFileSystemId sets the FileSystemId field's value. +func (s *CreateBackupInput) SetFileSystemId(v string) *CreateBackupInput { + s.FileSystemId = &v + return s +} + +// SetTags sets the Tags field's value. +func (s *CreateBackupInput) SetTags(v []*Tag) *CreateBackupInput { + s.Tags = v + return s +} + +// The response object for the CreateBackup operation. +type CreateBackupOutput struct { + _ struct{} `type:"structure"` + + // A description of the backup. + Backup *Backup `type:"structure"` +} + +// String returns the string representation +func (s CreateBackupOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateBackupOutput) GoString() string { + return s.String() +} + +// SetBackup sets the Backup field's value. +func (s *CreateBackupOutput) SetBackup(v *Backup) *CreateBackupOutput { + s.Backup = v + return s +} + +type CreateDataRepositoryTaskInput struct { + _ struct{} `type:"structure"` + + // (Optional) An idempotency token for resource creation, in a string of up + // to 64 ASCII characters. This token is automatically filled on your behalf + // when you use the AWS Command Line Interface (AWS CLI) or an AWS SDK. + ClientRequestToken *string `min:"1" type:"string" idempotencyToken:"true"` + + // The globally unique ID of the file system, assigned by Amazon FSx. + // + // FileSystemId is a required field + FileSystemId *string `min:"11" type:"string" required:"true"` + + // (Optional) The path or paths on the Amazon FSx file system to use when the + // data repository task is processed. The default path is the file system root + // directory. + Paths []*string `type:"list"` + + // Defines whether or not Amazon FSx provides a CompletionReport once the task + // has completed. A CompletionReport provides a detailed report on the files + // that Amazon FSx processed that meet the criteria specified by the Scope parameter. + // + // Report is a required field + Report *CompletionReport `type:"structure" required:"true"` + + // A list of Tag values, with a maximum of 50 elements. + Tags []*Tag `min:"1" type:"list"` + + // Specifies the type of data repository task to create. + // + // Type is a required field + Type *string `type:"string" required:"true" enum:"DataRepositoryTaskType"` +} + +// String returns the string representation +func (s CreateDataRepositoryTaskInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateDataRepositoryTaskInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateDataRepositoryTaskInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateDataRepositoryTaskInput"} + if s.ClientRequestToken != nil && len(*s.ClientRequestToken) < 1 { + invalidParams.Add(request.NewErrParamMinLen("ClientRequestToken", 1)) + } + if s.FileSystemId == nil { + invalidParams.Add(request.NewErrParamRequired("FileSystemId")) + } + if s.FileSystemId != nil && len(*s.FileSystemId) < 11 { + invalidParams.Add(request.NewErrParamMinLen("FileSystemId", 11)) + } + if s.Report == nil { + invalidParams.Add(request.NewErrParamRequired("Report")) + } + if s.Tags != nil && len(s.Tags) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Tags", 1)) + } + if s.Type == nil { + invalidParams.Add(request.NewErrParamRequired("Type")) + } + if s.Report != nil { + if err := s.Report.Validate(); err != nil { + invalidParams.AddNested("Report", err.(request.ErrInvalidParams)) + } + } + if s.Tags != nil { + for i, v := range s.Tags { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "Tags", i), err.(request.ErrInvalidParams)) + } + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetClientRequestToken sets the ClientRequestToken field's value. +func (s *CreateDataRepositoryTaskInput) SetClientRequestToken(v string) *CreateDataRepositoryTaskInput { + s.ClientRequestToken = &v + return s +} + +// SetFileSystemId sets the FileSystemId field's value. +func (s *CreateDataRepositoryTaskInput) SetFileSystemId(v string) *CreateDataRepositoryTaskInput { + s.FileSystemId = &v + return s +} + +// SetPaths sets the Paths field's value. +func (s *CreateDataRepositoryTaskInput) SetPaths(v []*string) *CreateDataRepositoryTaskInput { + s.Paths = v + return s +} + +// SetReport sets the Report field's value. +func (s *CreateDataRepositoryTaskInput) SetReport(v *CompletionReport) *CreateDataRepositoryTaskInput { + s.Report = v + return s +} + +// SetTags sets the Tags field's value. +func (s *CreateDataRepositoryTaskInput) SetTags(v []*Tag) *CreateDataRepositoryTaskInput { + s.Tags = v + return s +} + +// SetType sets the Type field's value. +func (s *CreateDataRepositoryTaskInput) SetType(v string) *CreateDataRepositoryTaskInput { + s.Type = &v + return s +} + +type CreateDataRepositoryTaskOutput struct { + _ struct{} `type:"structure"` + + // The description of the data repository task that you just created. + DataRepositoryTask *DataRepositoryTask `type:"structure"` +} + +// String returns the string representation +func (s CreateDataRepositoryTaskOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateDataRepositoryTaskOutput) GoString() string { + return s.String() +} + +// SetDataRepositoryTask sets the DataRepositoryTask field's value. +func (s *CreateDataRepositoryTaskOutput) SetDataRepositoryTask(v *DataRepositoryTask) *CreateDataRepositoryTaskOutput { + s.DataRepositoryTask = v + return s +} + +// The request object for the CreateFileSystemFromBackup operation. +type CreateFileSystemFromBackupInput struct { + _ struct{} `type:"structure"` + + // The ID of the backup. Specifies the backup to use if you're creating a file + // system from an existing backup. + // + // BackupId is a required field + BackupId *string `min:"12" type:"string" required:"true"` + + // (Optional) A string of up to 64 ASCII characters that Amazon FSx uses to + // ensure idempotent creation. This string is automatically filled on your behalf + // when you use the AWS Command Line Interface (AWS CLI) or an AWS SDK. + ClientRequestToken *string `min:"1" type:"string" idempotencyToken:"true"` + + // A list of IDs for the security groups that apply to the specified network + // interfaces created for file system access. These security groups apply to + // all network interfaces. This value isn't returned in later describe requests. + SecurityGroupIds []*string `type:"list"` + + // A list of IDs for the subnets that the file system will be accessible from. + // Currently, you can specify only one subnet. The file server is also launched + // in that subnet's Availability Zone. + // + // SubnetIds is a required field + SubnetIds []*string `type:"list" required:"true"` + + // The tags to be applied to the file system at file system creation. The key + // value of the Name tag appears in the console as the file system name. + Tags []*Tag `min:"1" type:"list"` + + // The configuration for this Microsoft Windows file system. + WindowsConfiguration *CreateFileSystemWindowsConfiguration `type:"structure"` +} + +// String returns the string representation +func (s CreateFileSystemFromBackupInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateFileSystemFromBackupInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateFileSystemFromBackupInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateFileSystemFromBackupInput"} + if s.BackupId == nil { + invalidParams.Add(request.NewErrParamRequired("BackupId")) + } + if s.BackupId != nil && len(*s.BackupId) < 12 { + invalidParams.Add(request.NewErrParamMinLen("BackupId", 12)) + } + if s.ClientRequestToken != nil && len(*s.ClientRequestToken) < 1 { + invalidParams.Add(request.NewErrParamMinLen("ClientRequestToken", 1)) + } + if s.SubnetIds == nil { + invalidParams.Add(request.NewErrParamRequired("SubnetIds")) + } + if s.Tags != nil && len(s.Tags) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Tags", 1)) + } + if s.Tags != nil { + for i, v := range s.Tags { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "Tags", i), err.(request.ErrInvalidParams)) + } + } + } + if s.WindowsConfiguration != nil { + if err := s.WindowsConfiguration.Validate(); err != nil { + invalidParams.AddNested("WindowsConfiguration", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetBackupId sets the BackupId field's value. +func (s *CreateFileSystemFromBackupInput) SetBackupId(v string) *CreateFileSystemFromBackupInput { + s.BackupId = &v + return s +} + +// SetClientRequestToken sets the ClientRequestToken field's value. +func (s *CreateFileSystemFromBackupInput) SetClientRequestToken(v string) *CreateFileSystemFromBackupInput { + s.ClientRequestToken = &v + return s +} + +// SetSecurityGroupIds sets the SecurityGroupIds field's value. +func (s *CreateFileSystemFromBackupInput) SetSecurityGroupIds(v []*string) *CreateFileSystemFromBackupInput { + s.SecurityGroupIds = v + return s +} + +// SetSubnetIds sets the SubnetIds field's value. +func (s *CreateFileSystemFromBackupInput) SetSubnetIds(v []*string) *CreateFileSystemFromBackupInput { + s.SubnetIds = v + return s +} + +// SetTags sets the Tags field's value. +func (s *CreateFileSystemFromBackupInput) SetTags(v []*Tag) *CreateFileSystemFromBackupInput { + s.Tags = v + return s +} + +// SetWindowsConfiguration sets the WindowsConfiguration field's value. +func (s *CreateFileSystemFromBackupInput) SetWindowsConfiguration(v *CreateFileSystemWindowsConfiguration) *CreateFileSystemFromBackupInput { + s.WindowsConfiguration = v + return s +} + +// The response object for the CreateFileSystemFromBackup operation. +type CreateFileSystemFromBackupOutput struct { + _ struct{} `type:"structure"` + + // A description of the file system. + FileSystem *FileSystem `type:"structure"` +} + +// String returns the string representation +func (s CreateFileSystemFromBackupOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateFileSystemFromBackupOutput) GoString() string { + return s.String() +} + +// SetFileSystem sets the FileSystem field's value. +func (s *CreateFileSystemFromBackupOutput) SetFileSystem(v *FileSystem) *CreateFileSystemFromBackupOutput { + s.FileSystem = v + return s +} + +// The request object used to create a new Amazon FSx file system. +type CreateFileSystemInput struct { + _ struct{} `type:"structure"` + + // (Optional) A string of up to 64 ASCII characters that Amazon FSx uses to + // ensure idempotent creation. This string is automatically filled on your behalf + // when you use the AWS Command Line Interface (AWS CLI) or an AWS SDK. + ClientRequestToken *string `min:"1" type:"string" idempotencyToken:"true"` + + // The type of Amazon FSx file system to create. + // + // FileSystemType is a required field + FileSystemType *string `type:"string" required:"true" enum:"FileSystemType"` + + // The ID of the AWS Key Management Service (AWS KMS) key used to encrypt the + // file system's data for an Amazon FSx for Windows File Server file system + // at rest. Amazon FSx for Lustre does not support KMS encryption. For more + // information, see Encrypt (https://docs.aws.amazon.com/kms/latest/APIReference/API_Encrypt.html) + // in the AWS Key Management Service API Reference. + KmsKeyId *string `min:"1" type:"string"` + + // The Lustre configuration for the file system being created. This value is + // required if FileSystemType is set to LUSTRE. + LustreConfiguration *CreateFileSystemLustreConfiguration `type:"structure"` + + // A list of IDs specifying the security groups to apply to all network interfaces + // created for file system access. This list isn't returned in later requests + // to describe the file system. + SecurityGroupIds []*string `type:"list"` + + // The storage capacity of the file system being created. + // + // For Windows file systems, valid values are 32 GiB - 65,536 GiB. + // + // For Lustre file systems, valid values are 1,200, 2,400, 3,600, then continuing + // in increments of 3600 GiB. + // + // StorageCapacity is a required field + StorageCapacity *int64 `type:"integer" required:"true"` + + // Specifies the IDs of the subnets that the file system will be accessible + // from. For Windows MULTI_AZ_1 file system deployment types, provide exactly + // two subnet IDs, one for the preferred file server and one for the standy + // file server. You specify one of these subnets as the preferred subnet using + // the WindowsConfiguration > PreferredSubnetID property. + // + // For Windows SINGLE_AZ_1 file system deployment types and Lustre file systems, + // provide exactly one subnet ID. The file server is launched in that subnet's + // Availability Zone. + // + // SubnetIds is a required field + SubnetIds []*string `type:"list" required:"true"` + + // The tags to apply to the file system being created. The key value of the + // Name tag appears in the console as the file system name. + Tags []*Tag `min:"1" type:"list"` + + // The Microsoft Windows configuration for the file system being created. This + // value is required if FileSystemType is set to WINDOWS. + WindowsConfiguration *CreateFileSystemWindowsConfiguration `type:"structure"` +} + +// String returns the string representation +func (s CreateFileSystemInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateFileSystemInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateFileSystemInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateFileSystemInput"} + if s.ClientRequestToken != nil && len(*s.ClientRequestToken) < 1 { + invalidParams.Add(request.NewErrParamMinLen("ClientRequestToken", 1)) + } + if s.FileSystemType == nil { + invalidParams.Add(request.NewErrParamRequired("FileSystemType")) + } + if s.KmsKeyId != nil && len(*s.KmsKeyId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("KmsKeyId", 1)) + } + if s.StorageCapacity == nil { + invalidParams.Add(request.NewErrParamRequired("StorageCapacity")) + } + if s.SubnetIds == nil { + invalidParams.Add(request.NewErrParamRequired("SubnetIds")) + } + if s.Tags != nil && len(s.Tags) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Tags", 1)) + } + if s.LustreConfiguration != nil { + if err := s.LustreConfiguration.Validate(); err != nil { + invalidParams.AddNested("LustreConfiguration", err.(request.ErrInvalidParams)) + } + } + if s.Tags != nil { + for i, v := range s.Tags { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "Tags", i), err.(request.ErrInvalidParams)) + } + } + } + if s.WindowsConfiguration != nil { + if err := s.WindowsConfiguration.Validate(); err != nil { + invalidParams.AddNested("WindowsConfiguration", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetClientRequestToken sets the ClientRequestToken field's value. +func (s *CreateFileSystemInput) SetClientRequestToken(v string) *CreateFileSystemInput { + s.ClientRequestToken = &v + return s +} + +// SetFileSystemType sets the FileSystemType field's value. +func (s *CreateFileSystemInput) SetFileSystemType(v string) *CreateFileSystemInput { + s.FileSystemType = &v + return s +} + +// SetKmsKeyId sets the KmsKeyId field's value. +func (s *CreateFileSystemInput) SetKmsKeyId(v string) *CreateFileSystemInput { + s.KmsKeyId = &v + return s +} + +// SetLustreConfiguration sets the LustreConfiguration field's value. +func (s *CreateFileSystemInput) SetLustreConfiguration(v *CreateFileSystemLustreConfiguration) *CreateFileSystemInput { + s.LustreConfiguration = v + return s +} + +// SetSecurityGroupIds sets the SecurityGroupIds field's value. +func (s *CreateFileSystemInput) SetSecurityGroupIds(v []*string) *CreateFileSystemInput { + s.SecurityGroupIds = v + return s +} + +// SetStorageCapacity sets the StorageCapacity field's value. +func (s *CreateFileSystemInput) SetStorageCapacity(v int64) *CreateFileSystemInput { + s.StorageCapacity = &v + return s +} + +// SetSubnetIds sets the SubnetIds field's value. +func (s *CreateFileSystemInput) SetSubnetIds(v []*string) *CreateFileSystemInput { + s.SubnetIds = v + return s +} + +// SetTags sets the Tags field's value. +func (s *CreateFileSystemInput) SetTags(v []*Tag) *CreateFileSystemInput { + s.Tags = v + return s +} + +// SetWindowsConfiguration sets the WindowsConfiguration field's value. +func (s *CreateFileSystemInput) SetWindowsConfiguration(v *CreateFileSystemWindowsConfiguration) *CreateFileSystemInput { + s.WindowsConfiguration = v + return s +} + +// The Lustre configuration for the file system being created. This value is +// required if FileSystemType is set to LUSTRE. +type CreateFileSystemLustreConfiguration struct { + _ struct{} `type:"structure"` + + // (Optional) The path in Amazon S3 where the root of your Amazon FSx file system + // is exported. The path must use the same Amazon S3 bucket as specified in + // ImportPath. You can provide an optional prefix to which new and changed data + // is to be exported from your Amazon FSx for Lustre file system. If an ExportPath + // value is not provided, Amazon FSx sets a default export path, s3://import-bucket/FSxLustre[creation-timestamp]. + // The timestamp is in UTC format, for example s3://import-bucket/FSxLustre20181105T222312Z. + // + // The Amazon S3 export bucket must be the same as the import bucket specified + // by ImportPath. If you only specify a bucket name, such as s3://import-bucket, + // you get a 1:1 mapping of file system objects to S3 bucket objects. This mapping + // means that the input data in S3 is overwritten on export. If you provide + // a custom prefix in the export path, such as s3://import-bucket/[custom-optional-prefix], + // Amazon FSx exports the contents of your file system to that export prefix + // in the Amazon S3 bucket. + ExportPath *string `min:"3" type:"string"` + + // (Optional) The path to the Amazon S3 bucket (including the optional prefix) + // that you're using as the data repository for your Amazon FSx for Lustre file + // system. The root of your FSx for Lustre file system will be mapped to the + // root of the Amazon S3 bucket you select. An example is s3://import-bucket/optional-prefix. + // If you specify a prefix after the Amazon S3 bucket name, only object keys + // with that prefix are loaded into the file system. + ImportPath *string `min:"3" type:"string"` + + // (Optional) For files imported from a data repository, this value determines + // the stripe count and maximum amount of data per file (in MiB) stored on a + // single physical disk. The maximum number of disks that a single file can + // be striped across is limited by the total number of disks that make up the + // file system. + // + // The chunk size default is 1,024 MiB (1 GiB) and can go as high as 512,000 + // MiB (500 GiB). Amazon S3 objects have a maximum size of 5 TB. + ImportedFileChunkSize *int64 `min:"1" type:"integer"` + + // The preferred time to perform weekly maintenance, in the UTC time zone. + WeeklyMaintenanceStartTime *string `min:"7" type:"string"` +} + +// String returns the string representation +func (s CreateFileSystemLustreConfiguration) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateFileSystemLustreConfiguration) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateFileSystemLustreConfiguration) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateFileSystemLustreConfiguration"} + if s.ExportPath != nil && len(*s.ExportPath) < 3 { + invalidParams.Add(request.NewErrParamMinLen("ExportPath", 3)) + } + if s.ImportPath != nil && len(*s.ImportPath) < 3 { + invalidParams.Add(request.NewErrParamMinLen("ImportPath", 3)) + } + if s.ImportedFileChunkSize != nil && *s.ImportedFileChunkSize < 1 { + invalidParams.Add(request.NewErrParamMinValue("ImportedFileChunkSize", 1)) + } + if s.WeeklyMaintenanceStartTime != nil && len(*s.WeeklyMaintenanceStartTime) < 7 { + invalidParams.Add(request.NewErrParamMinLen("WeeklyMaintenanceStartTime", 7)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetExportPath sets the ExportPath field's value. +func (s *CreateFileSystemLustreConfiguration) SetExportPath(v string) *CreateFileSystemLustreConfiguration { + s.ExportPath = &v + return s +} + +// SetImportPath sets the ImportPath field's value. +func (s *CreateFileSystemLustreConfiguration) SetImportPath(v string) *CreateFileSystemLustreConfiguration { + s.ImportPath = &v + return s +} + +// SetImportedFileChunkSize sets the ImportedFileChunkSize field's value. +func (s *CreateFileSystemLustreConfiguration) SetImportedFileChunkSize(v int64) *CreateFileSystemLustreConfiguration { + s.ImportedFileChunkSize = &v + return s +} + +// SetWeeklyMaintenanceStartTime sets the WeeklyMaintenanceStartTime field's value. +func (s *CreateFileSystemLustreConfiguration) SetWeeklyMaintenanceStartTime(v string) *CreateFileSystemLustreConfiguration { + s.WeeklyMaintenanceStartTime = &v + return s +} + +// The response object returned after the file system is created. +type CreateFileSystemOutput struct { + _ struct{} `type:"structure"` + + // The configuration of the file system that was created. + FileSystem *FileSystem `type:"structure"` +} + +// String returns the string representation +func (s CreateFileSystemOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateFileSystemOutput) GoString() string { + return s.String() +} + +// SetFileSystem sets the FileSystem field's value. +func (s *CreateFileSystemOutput) SetFileSystem(v *FileSystem) *CreateFileSystemOutput { + s.FileSystem = v + return s +} + +// The configuration object for the Microsoft Windows file system used in CreateFileSystem +// and CreateFileSystemFromBackup operations. +type CreateFileSystemWindowsConfiguration struct { + _ struct{} `type:"structure"` + + // The ID for an existing AWS Managed Microsoft Active Directory (AD) instance + // that the file system should join when it's created. + ActiveDirectoryId *string `min:"12" type:"string"` + + // The number of days to retain automatic backups. The default is to retain + // backups for 7 days. Setting this value to 0 disables the creation of automatic + // backups. The maximum retention period for backups is 35 days. + AutomaticBackupRetentionDays *int64 `type:"integer"` + + // A boolean flag indicating whether tags for the file system should be copied + // to backups. This value defaults to false. If it's set to true, all tags for + // the file system are copied to all automatic and user-initiated backups where + // the user doesn't specify tags. If this value is true, and you specify one + // or more tags, only the specified tags are copied to backups. + CopyTagsToBackups *bool `type:"boolean"` + + // The preferred time to take daily automatic backups, formatted HH:MM in the + // UTC time zone. + DailyAutomaticBackupStartTime *string `min:"5" type:"string"` + + // Specifies the file system deployment type, valid values are the following: + // + // * MULTI_AZ_1 - Deploys a high availability file system that is configured + // for Multi-AZ redundancy to tolerate temporary Availability Zone (AZ) unavailability. + // You can only deploy a Multi-AZ file system in AWS Regions that have a + // minimum of three Availability Zones. + // + // * SINGLE_AZ_1 - (Default) Choose to deploy a file system that is configured + // for single AZ redundancy. + // + // To learn more about high availability Multi-AZ file systems, see High Availability + // for Amazon FSx for Windows File Server (https://docs.aws.amazon.com/fsx/latest/WindowsGuide/high-availability-multiAZ.html). + DeploymentType *string `type:"string" enum:"WindowsDeploymentType"` + + // Required when DeploymentType is set to MULTI_AZ_1. This specifies the subnet + // in which you want the preferred file server to be located. For in-AWS applications, + // we recommend that you launch your clients in the same Availability Zone (AZ) + // as your preferred file server to reduce cross-AZ data transfer costs and + // minimize latency. + PreferredSubnetId *string `min:"15" type:"string"` + + // The configuration that Amazon FSx uses to join the Windows File Server instance + // to your self-managed (including on-premises) Microsoft Active Directory (AD) + // directory. + SelfManagedActiveDirectoryConfiguration *SelfManagedActiveDirectoryConfiguration `type:"structure"` + + // The throughput of an Amazon FSx file system, measured in megabytes per second, + // in 2 to the nth increments, between 2^3 (8) and 2^11 (2048). + // + // ThroughputCapacity is a required field + ThroughputCapacity *int64 `min:"8" type:"integer" required:"true"` + + // The preferred start time to perform weekly maintenance, formatted d:HH:MM + // in the UTC time zone. + WeeklyMaintenanceStartTime *string `min:"7" type:"string"` +} + +// String returns the string representation +func (s CreateFileSystemWindowsConfiguration) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateFileSystemWindowsConfiguration) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateFileSystemWindowsConfiguration) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateFileSystemWindowsConfiguration"} + if s.ActiveDirectoryId != nil && len(*s.ActiveDirectoryId) < 12 { + invalidParams.Add(request.NewErrParamMinLen("ActiveDirectoryId", 12)) + } + if s.DailyAutomaticBackupStartTime != nil && len(*s.DailyAutomaticBackupStartTime) < 5 { + invalidParams.Add(request.NewErrParamMinLen("DailyAutomaticBackupStartTime", 5)) + } + if s.PreferredSubnetId != nil && len(*s.PreferredSubnetId) < 15 { + invalidParams.Add(request.NewErrParamMinLen("PreferredSubnetId", 15)) + } + if s.ThroughputCapacity == nil { + invalidParams.Add(request.NewErrParamRequired("ThroughputCapacity")) + } + if s.ThroughputCapacity != nil && *s.ThroughputCapacity < 8 { + invalidParams.Add(request.NewErrParamMinValue("ThroughputCapacity", 8)) + } + if s.WeeklyMaintenanceStartTime != nil && len(*s.WeeklyMaintenanceStartTime) < 7 { + invalidParams.Add(request.NewErrParamMinLen("WeeklyMaintenanceStartTime", 7)) + } + if s.SelfManagedActiveDirectoryConfiguration != nil { + if err := s.SelfManagedActiveDirectoryConfiguration.Validate(); err != nil { + invalidParams.AddNested("SelfManagedActiveDirectoryConfiguration", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetActiveDirectoryId sets the ActiveDirectoryId field's value. +func (s *CreateFileSystemWindowsConfiguration) SetActiveDirectoryId(v string) *CreateFileSystemWindowsConfiguration { + s.ActiveDirectoryId = &v + return s +} + +// SetAutomaticBackupRetentionDays sets the AutomaticBackupRetentionDays field's value. +func (s *CreateFileSystemWindowsConfiguration) SetAutomaticBackupRetentionDays(v int64) *CreateFileSystemWindowsConfiguration { + s.AutomaticBackupRetentionDays = &v + return s +} + +// SetCopyTagsToBackups sets the CopyTagsToBackups field's value. +func (s *CreateFileSystemWindowsConfiguration) SetCopyTagsToBackups(v bool) *CreateFileSystemWindowsConfiguration { + s.CopyTagsToBackups = &v + return s +} + +// SetDailyAutomaticBackupStartTime sets the DailyAutomaticBackupStartTime field's value. +func (s *CreateFileSystemWindowsConfiguration) SetDailyAutomaticBackupStartTime(v string) *CreateFileSystemWindowsConfiguration { + s.DailyAutomaticBackupStartTime = &v + return s +} + +// SetDeploymentType sets the DeploymentType field's value. +func (s *CreateFileSystemWindowsConfiguration) SetDeploymentType(v string) *CreateFileSystemWindowsConfiguration { + s.DeploymentType = &v + return s +} + +// SetPreferredSubnetId sets the PreferredSubnetId field's value. +func (s *CreateFileSystemWindowsConfiguration) SetPreferredSubnetId(v string) *CreateFileSystemWindowsConfiguration { + s.PreferredSubnetId = &v + return s +} + +// SetSelfManagedActiveDirectoryConfiguration sets the SelfManagedActiveDirectoryConfiguration field's value. +func (s *CreateFileSystemWindowsConfiguration) SetSelfManagedActiveDirectoryConfiguration(v *SelfManagedActiveDirectoryConfiguration) *CreateFileSystemWindowsConfiguration { + s.SelfManagedActiveDirectoryConfiguration = v + return s +} + +// SetThroughputCapacity sets the ThroughputCapacity field's value. +func (s *CreateFileSystemWindowsConfiguration) SetThroughputCapacity(v int64) *CreateFileSystemWindowsConfiguration { + s.ThroughputCapacity = &v + return s +} + +// SetWeeklyMaintenanceStartTime sets the WeeklyMaintenanceStartTime field's value. +func (s *CreateFileSystemWindowsConfiguration) SetWeeklyMaintenanceStartTime(v string) *CreateFileSystemWindowsConfiguration { + s.WeeklyMaintenanceStartTime = &v + return s +} + +// The data repository configuration object for Lustre file systems returned +// in the response of the CreateFileSystem operation. +type DataRepositoryConfiguration struct { + _ struct{} `type:"structure"` + + // The export path to the Amazon S3 bucket (and prefix) that you are using to + // store new and changed Lustre file system files in S3. + ExportPath *string `min:"3" type:"string"` + + // The import path to the Amazon S3 bucket (and optional prefix) that you're + // using as the data repository for your FSx for Lustre file system, for example + // s3://import-bucket/optional-prefix. If a prefix is specified after the Amazon + // S3 bucket name, only object keys with that prefix are loaded into the file + // system. + ImportPath *string `min:"3" type:"string"` + + // For files imported from a data repository, this value determines the stripe + // count and maximum amount of data per file (in MiB) stored on a single physical + // disk. The maximum number of disks that a single file can be striped across + // is limited by the total number of disks that make up the file system. + // + // The default chunk size is 1,024 MiB (1 GiB) and can go as high as 512,000 + // MiB (500 GiB). Amazon S3 objects have a maximum size of 5 TB. + ImportedFileChunkSize *int64 `min:"1" type:"integer"` +} + +// String returns the string representation +func (s DataRepositoryConfiguration) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DataRepositoryConfiguration) GoString() string { + return s.String() +} + +// SetExportPath sets the ExportPath field's value. +func (s *DataRepositoryConfiguration) SetExportPath(v string) *DataRepositoryConfiguration { + s.ExportPath = &v + return s +} + +// SetImportPath sets the ImportPath field's value. +func (s *DataRepositoryConfiguration) SetImportPath(v string) *DataRepositoryConfiguration { + s.ImportPath = &v + return s +} + +// SetImportedFileChunkSize sets the ImportedFileChunkSize field's value. +func (s *DataRepositoryConfiguration) SetImportedFileChunkSize(v int64) *DataRepositoryConfiguration { + s.ImportedFileChunkSize = &v + return s +} + +// A description of the data repository task. You use data repository tasks +// to perform bulk transfer operations between your Amazon FSx file system and +// its linked data repository. +type DataRepositoryTask struct { + _ struct{} `type:"structure"` + + // The time that the resource was created, in seconds (since 1970-01-01T00:00:00Z), + // also known as Unix time. + // + // CreationTime is a required field + CreationTime *time.Time `type:"timestamp" required:"true"` + + // The time that Amazon FSx completed processing the task, populated after the + // task is complete. + EndTime *time.Time `type:"timestamp"` + + // Failure message describing why the task failed, it is populated only when + // Lifecycle is set to FAILED. + FailureDetails *DataRepositoryTaskFailureDetails `type:"structure"` + + // The globally unique ID of the file system, assigned by Amazon FSx. + // + // FileSystemId is a required field + FileSystemId *string `min:"11" type:"string" required:"true"` + + // The lifecycle status of the data repository task, as follows: + // + // * PENDING - Amazon FSx has not started the task. + // + // * EXECUTING - Amazon FSx is processing the task. + // + // * FAILED - Amazon FSx was not able to complete the task. For example, + // there may be files the task failed to process. The DataRepositoryTaskFailureDetails + // property provides more information about task failures. + // + // * SUCCEEDED - FSx completed the task successfully. + // + // * CANCELED - Amazon FSx canceled the task and it did not complete. + // + // * CANCELING - FSx is in process of canceling the task. + // + // You cannot delete an FSx for Lustre file system if there are data repository + // tasks for the file system in the PENDING or EXECUTING states. Please retry + // when the data repository task is finished (with a status of CANCELED, SUCCEEDED, + // or FAILED). You can use the DescribeDataRepositoryTask action to monitor + // the task status. Contact the FSx team if you need to delete your file system + // immediately. + // + // Lifecycle is a required field + Lifecycle *string `type:"string" required:"true" enum:"DataRepositoryTaskLifecycle"` + + // An array of paths on the Amazon FSx for Lustre file system that specify the + // data for the data repository task to process. For example, in an EXPORT_TO_REPOSITORY + // task, the paths specify which data to export to the linked data repository. + // + // (Default) If Paths is not specified, Amazon FSx uses the file system root + // directory. + Paths []*string `type:"list"` + + // Provides a report detailing the data repository task results of the files + // processed that match the criteria specified in the report Scope parameter. + // FSx delivers the report to the file system's linked data repository in Amazon + // S3, using the path specified in the report Path parameter. You can specify + // whether or not a report gets generated for a task using the Enabled parameter. + Report *CompletionReport `type:"structure"` + + // The Amazon Resource Name (ARN) for a given resource. ARNs uniquely identify + // AWS resources. We require an ARN when you need to specify a resource unambiguously + // across all of AWS. For more information, see Amazon Resource Names (ARNs) + // and AWS Service Namespaces (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) + // in the AWS General Reference. + ResourceARN *string `min:"8" type:"string"` + + // The time that Amazon FSx began processing the task. + StartTime *time.Time `type:"timestamp"` + + // Provides the status of the number of files that the task has processed successfully + // and failed to process. + Status *DataRepositoryTaskStatus `type:"structure"` + + // A list of Tag values, with a maximum of 50 elements. + Tags []*Tag `min:"1" type:"list"` + + // The system-generated, unique 17-digit ID of the data repository task. + // + // TaskId is a required field + TaskId *string `min:"12" type:"string" required:"true"` + + // The type of data repository task; EXPORT_TO_REPOSITORY is the only type currently + // supported. + // + // Type is a required field + Type *string `type:"string" required:"true" enum:"DataRepositoryTaskType"` +} + +// String returns the string representation +func (s DataRepositoryTask) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DataRepositoryTask) GoString() string { + return s.String() +} + +// SetCreationTime sets the CreationTime field's value. +func (s *DataRepositoryTask) SetCreationTime(v time.Time) *DataRepositoryTask { + s.CreationTime = &v + return s +} + +// SetEndTime sets the EndTime field's value. +func (s *DataRepositoryTask) SetEndTime(v time.Time) *DataRepositoryTask { + s.EndTime = &v + return s +} + +// SetFailureDetails sets the FailureDetails field's value. +func (s *DataRepositoryTask) SetFailureDetails(v *DataRepositoryTaskFailureDetails) *DataRepositoryTask { + s.FailureDetails = v + return s +} + +// SetFileSystemId sets the FileSystemId field's value. +func (s *DataRepositoryTask) SetFileSystemId(v string) *DataRepositoryTask { + s.FileSystemId = &v + return s +} + +// SetLifecycle sets the Lifecycle field's value. +func (s *DataRepositoryTask) SetLifecycle(v string) *DataRepositoryTask { + s.Lifecycle = &v + return s +} + +// SetPaths sets the Paths field's value. +func (s *DataRepositoryTask) SetPaths(v []*string) *DataRepositoryTask { + s.Paths = v + return s +} + +// SetReport sets the Report field's value. +func (s *DataRepositoryTask) SetReport(v *CompletionReport) *DataRepositoryTask { + s.Report = v + return s +} + +// SetResourceARN sets the ResourceARN field's value. +func (s *DataRepositoryTask) SetResourceARN(v string) *DataRepositoryTask { + s.ResourceARN = &v + return s +} + +// SetStartTime sets the StartTime field's value. +func (s *DataRepositoryTask) SetStartTime(v time.Time) *DataRepositoryTask { + s.StartTime = &v + return s +} + +// SetStatus sets the Status field's value. +func (s *DataRepositoryTask) SetStatus(v *DataRepositoryTaskStatus) *DataRepositoryTask { + s.Status = v + return s +} + +// SetTags sets the Tags field's value. +func (s *DataRepositoryTask) SetTags(v []*Tag) *DataRepositoryTask { + s.Tags = v + return s +} + +// SetTaskId sets the TaskId field's value. +func (s *DataRepositoryTask) SetTaskId(v string) *DataRepositoryTask { + s.TaskId = &v + return s +} + +// SetType sets the Type field's value. +func (s *DataRepositoryTask) SetType(v string) *DataRepositoryTask { + s.Type = &v + return s +} + +// Provides information about why a data repository task failed. Only populated +// when the task Lifecycle is set to FAILED. +type DataRepositoryTaskFailureDetails struct { + _ struct{} `type:"structure"` + + // A detailed error message. + Message *string `min:"1" type:"string"` +} + +// String returns the string representation +func (s DataRepositoryTaskFailureDetails) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DataRepositoryTaskFailureDetails) GoString() string { + return s.String() +} + +// SetMessage sets the Message field's value. +func (s *DataRepositoryTaskFailureDetails) SetMessage(v string) *DataRepositoryTaskFailureDetails { + s.Message = &v + return s +} + +// (Optional) An array of filter objects you can use to filter the response +// of data repository tasks you will see in the the response. You can filter +// the tasks returned in the response by one or more file system IDs, task lifecycles, +// and by task type. A filter object consists of a filter Name, and one or more +// Values for the filter. +type DataRepositoryTaskFilter struct { + _ struct{} `type:"structure"` + + // Name of the task property to use in filtering the tasks returned in the response. + // + // * Use file-system-id to retrieve data repository tasks for specific file + // systems. + // + // * Use task-lifecycle to retrieve data repository tasks with one or more + // specific lifecycle states, as follows: CANCELED, EXECUTING, FAILED, PENDING, + // and SUCCEEDED. + Name *string `type:"string" enum:"DataRepositoryTaskFilterName"` + + // Use Values to include the specific file system IDs and task lifecycle states + // for the filters you are using. + Values []*string `type:"list"` +} + +// String returns the string representation +func (s DataRepositoryTaskFilter) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DataRepositoryTaskFilter) GoString() string { + return s.String() +} + +// SetName sets the Name field's value. +func (s *DataRepositoryTaskFilter) SetName(v string) *DataRepositoryTaskFilter { + s.Name = &v + return s +} + +// SetValues sets the Values field's value. +func (s *DataRepositoryTaskFilter) SetValues(v []*string) *DataRepositoryTaskFilter { + s.Values = v + return s +} + +// Provides the task status showing a running total of the total number of files +// to be processed, the number successfully processed, and the number of files +// the task failed to process. +type DataRepositoryTaskStatus struct { + _ struct{} `type:"structure"` + + // A running total of the number of files that the task failed to process. + FailedCount *int64 `type:"long"` + + // The time at which the task status was last updated. + LastUpdatedTime *time.Time `type:"timestamp"` + + // A running total of the number of files that the task has successfully processed. + SucceededCount *int64 `type:"long"` + + // The total number of files that the task will process. While a task is executing, + // the sum of SucceededCount plus FailedCount may not equal TotalCount. When + // the task is complete, TotalCount equals the sum of SucceededCount plus FailedCount. + TotalCount *int64 `type:"long"` +} + +// String returns the string representation +func (s DataRepositoryTaskStatus) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DataRepositoryTaskStatus) GoString() string { + return s.String() +} + +// SetFailedCount sets the FailedCount field's value. +func (s *DataRepositoryTaskStatus) SetFailedCount(v int64) *DataRepositoryTaskStatus { + s.FailedCount = &v + return s +} + +// SetLastUpdatedTime sets the LastUpdatedTime field's value. +func (s *DataRepositoryTaskStatus) SetLastUpdatedTime(v time.Time) *DataRepositoryTaskStatus { + s.LastUpdatedTime = &v + return s +} + +// SetSucceededCount sets the SucceededCount field's value. +func (s *DataRepositoryTaskStatus) SetSucceededCount(v int64) *DataRepositoryTaskStatus { + s.SucceededCount = &v + return s +} + +// SetTotalCount sets the TotalCount field's value. +func (s *DataRepositoryTaskStatus) SetTotalCount(v int64) *DataRepositoryTaskStatus { + s.TotalCount = &v + return s +} + +// The request object for DeleteBackup operation. +type DeleteBackupInput struct { + _ struct{} `type:"structure"` + + // The ID of the backup you want to delete. + // + // BackupId is a required field + BackupId *string `min:"12" type:"string" required:"true"` + + // (Optional) A string of up to 64 ASCII characters that Amazon FSx uses to + // ensure idempotent deletion. This is automatically filled on your behalf when + // using the AWS CLI or SDK. + ClientRequestToken *string `min:"1" type:"string" idempotencyToken:"true"` +} + +// String returns the string representation +func (s DeleteBackupInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteBackupInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteBackupInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteBackupInput"} + if s.BackupId == nil { + invalidParams.Add(request.NewErrParamRequired("BackupId")) + } + if s.BackupId != nil && len(*s.BackupId) < 12 { + invalidParams.Add(request.NewErrParamMinLen("BackupId", 12)) + } + if s.ClientRequestToken != nil && len(*s.ClientRequestToken) < 1 { + invalidParams.Add(request.NewErrParamMinLen("ClientRequestToken", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetBackupId sets the BackupId field's value. +func (s *DeleteBackupInput) SetBackupId(v string) *DeleteBackupInput { + s.BackupId = &v + return s +} + +// SetClientRequestToken sets the ClientRequestToken field's value. +func (s *DeleteBackupInput) SetClientRequestToken(v string) *DeleteBackupInput { + s.ClientRequestToken = &v + return s +} + +// The response object for DeleteBackup operation. +type DeleteBackupOutput struct { + _ struct{} `type:"structure"` + + // The ID of the backup deleted. + BackupId *string `min:"12" type:"string"` + + // The lifecycle of the backup. Should be DELETED. + Lifecycle *string `type:"string" enum:"BackupLifecycle"` +} + +// String returns the string representation +func (s DeleteBackupOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteBackupOutput) GoString() string { + return s.String() +} + +// SetBackupId sets the BackupId field's value. +func (s *DeleteBackupOutput) SetBackupId(v string) *DeleteBackupOutput { + s.BackupId = &v + return s +} + +// SetLifecycle sets the Lifecycle field's value. +func (s *DeleteBackupOutput) SetLifecycle(v string) *DeleteBackupOutput { + s.Lifecycle = &v + return s +} + +// The request object for DeleteFileSystem operation. +type DeleteFileSystemInput struct { + _ struct{} `type:"structure"` + + // (Optional) A string of up to 64 ASCII characters that Amazon FSx uses to + // ensure idempotent deletion. This is automatically filled on your behalf when + // using the AWS CLI or SDK. + ClientRequestToken *string `min:"1" type:"string" idempotencyToken:"true"` + + // The ID of the file system you want to delete. + // + // FileSystemId is a required field + FileSystemId *string `min:"11" type:"string" required:"true"` + + // The configuration object for the Microsoft Windows file system used in the + // DeleteFileSystem operation. + WindowsConfiguration *DeleteFileSystemWindowsConfiguration `type:"structure"` +} + +// String returns the string representation +func (s DeleteFileSystemInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteFileSystemInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteFileSystemInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteFileSystemInput"} + if s.ClientRequestToken != nil && len(*s.ClientRequestToken) < 1 { + invalidParams.Add(request.NewErrParamMinLen("ClientRequestToken", 1)) + } + if s.FileSystemId == nil { + invalidParams.Add(request.NewErrParamRequired("FileSystemId")) + } + if s.FileSystemId != nil && len(*s.FileSystemId) < 11 { + invalidParams.Add(request.NewErrParamMinLen("FileSystemId", 11)) + } + if s.WindowsConfiguration != nil { + if err := s.WindowsConfiguration.Validate(); err != nil { + invalidParams.AddNested("WindowsConfiguration", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetClientRequestToken sets the ClientRequestToken field's value. +func (s *DeleteFileSystemInput) SetClientRequestToken(v string) *DeleteFileSystemInput { + s.ClientRequestToken = &v + return s +} + +// SetFileSystemId sets the FileSystemId field's value. +func (s *DeleteFileSystemInput) SetFileSystemId(v string) *DeleteFileSystemInput { + s.FileSystemId = &v + return s +} + +// SetWindowsConfiguration sets the WindowsConfiguration field's value. +func (s *DeleteFileSystemInput) SetWindowsConfiguration(v *DeleteFileSystemWindowsConfiguration) *DeleteFileSystemInput { + s.WindowsConfiguration = v + return s +} + +// The response object for the DeleteFileSystem operation. +type DeleteFileSystemOutput struct { + _ struct{} `type:"structure"` + + // The ID of the file system being deleted. + FileSystemId *string `min:"11" type:"string"` + + // The file system lifecycle for the deletion request. Should be DELETING. + Lifecycle *string `type:"string" enum:"FileSystemLifecycle"` + + // The response object for the Microsoft Windows file system used in the DeleteFileSystem + // operation. + WindowsResponse *DeleteFileSystemWindowsResponse `type:"structure"` +} + +// String returns the string representation +func (s DeleteFileSystemOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteFileSystemOutput) GoString() string { + return s.String() +} + +// SetFileSystemId sets the FileSystemId field's value. +func (s *DeleteFileSystemOutput) SetFileSystemId(v string) *DeleteFileSystemOutput { + s.FileSystemId = &v + return s +} + +// SetLifecycle sets the Lifecycle field's value. +func (s *DeleteFileSystemOutput) SetLifecycle(v string) *DeleteFileSystemOutput { + s.Lifecycle = &v + return s +} + +// SetWindowsResponse sets the WindowsResponse field's value. +func (s *DeleteFileSystemOutput) SetWindowsResponse(v *DeleteFileSystemWindowsResponse) *DeleteFileSystemOutput { + s.WindowsResponse = v + return s +} + +// The configuration object for the Microsoft Windows file system used in the +// DeleteFileSystem operation. +type DeleteFileSystemWindowsConfiguration struct { + _ struct{} `type:"structure"` + + // A set of tags for your final backup. + FinalBackupTags []*Tag `min:"1" type:"list"` + + // By default, Amazon FSx for Windows takes a final backup on your behalf when + // the DeleteFileSystem operation is invoked. Doing this helps protect you from + // data loss, and we highly recommend taking the final backup. If you want to + // skip this backup, use this flag to do so. + SkipFinalBackup *bool `type:"boolean"` +} + +// String returns the string representation +func (s DeleteFileSystemWindowsConfiguration) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteFileSystemWindowsConfiguration) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteFileSystemWindowsConfiguration) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteFileSystemWindowsConfiguration"} + if s.FinalBackupTags != nil && len(s.FinalBackupTags) < 1 { + invalidParams.Add(request.NewErrParamMinLen("FinalBackupTags", 1)) + } + if s.FinalBackupTags != nil { + for i, v := range s.FinalBackupTags { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "FinalBackupTags", i), err.(request.ErrInvalidParams)) + } + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetFinalBackupTags sets the FinalBackupTags field's value. +func (s *DeleteFileSystemWindowsConfiguration) SetFinalBackupTags(v []*Tag) *DeleteFileSystemWindowsConfiguration { + s.FinalBackupTags = v + return s +} + +// SetSkipFinalBackup sets the SkipFinalBackup field's value. +func (s *DeleteFileSystemWindowsConfiguration) SetSkipFinalBackup(v bool) *DeleteFileSystemWindowsConfiguration { + s.SkipFinalBackup = &v + return s +} + +// The response object for the Microsoft Windows file system used in the DeleteFileSystem +// operation. +type DeleteFileSystemWindowsResponse struct { + _ struct{} `type:"structure"` + + // The ID of the final backup for this file system. + FinalBackupId *string `min:"12" type:"string"` + + // The set of tags applied to the final backup. + FinalBackupTags []*Tag `min:"1" type:"list"` +} + +// String returns the string representation +func (s DeleteFileSystemWindowsResponse) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteFileSystemWindowsResponse) GoString() string { + return s.String() +} + +// SetFinalBackupId sets the FinalBackupId field's value. +func (s *DeleteFileSystemWindowsResponse) SetFinalBackupId(v string) *DeleteFileSystemWindowsResponse { + s.FinalBackupId = &v + return s +} + +// SetFinalBackupTags sets the FinalBackupTags field's value. +func (s *DeleteFileSystemWindowsResponse) SetFinalBackupTags(v []*Tag) *DeleteFileSystemWindowsResponse { + s.FinalBackupTags = v + return s +} + +// The request object for DescribeBackups operation. +type DescribeBackupsInput struct { + _ struct{} `type:"structure"` + + // (Optional) IDs of the backups you want to retrieve (String). This overrides + // any filters. If any IDs are not found, BackupNotFound will be thrown. + BackupIds []*string `type:"list"` + + // (Optional) Filters structure. Supported names are file-system-id and backup-type. + Filters []*Filter `type:"list"` + + // (Optional) Maximum number of backups to return in the response (integer). + // This parameter value must be greater than 0. The number of items that Amazon + // FSx returns is the minimum of the MaxResults parameter specified in the request + // and the service's internal maximum number of items per page. + MaxResults *int64 `min:"1" type:"integer"` + + // (Optional) Opaque pagination token returned from a previous DescribeBackups + // operation (String). If a token present, the action continues the list from + // where the returning call left off. + NextToken *string `min:"1" type:"string"` +} + +// String returns the string representation +func (s DescribeBackupsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeBackupsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DescribeBackupsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DescribeBackupsInput"} + if s.MaxResults != nil && *s.MaxResults < 1 { + invalidParams.Add(request.NewErrParamMinValue("MaxResults", 1)) + } + if s.NextToken != nil && len(*s.NextToken) < 1 { + invalidParams.Add(request.NewErrParamMinLen("NextToken", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetBackupIds sets the BackupIds field's value. +func (s *DescribeBackupsInput) SetBackupIds(v []*string) *DescribeBackupsInput { + s.BackupIds = v + return s +} + +// SetFilters sets the Filters field's value. +func (s *DescribeBackupsInput) SetFilters(v []*Filter) *DescribeBackupsInput { + s.Filters = v + return s +} + +// SetMaxResults sets the MaxResults field's value. +func (s *DescribeBackupsInput) SetMaxResults(v int64) *DescribeBackupsInput { + s.MaxResults = &v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *DescribeBackupsInput) SetNextToken(v string) *DescribeBackupsInput { + s.NextToken = &v + return s +} + +// Response object for DescribeBackups operation. +type DescribeBackupsOutput struct { + _ struct{} `type:"structure"` + + // Any array of backups. + Backups []*Backup `type:"list"` + + // This is present if there are more backups than returned in the response (String). + // You can use the NextToken value in the later request to fetch the backups. + NextToken *string `min:"1" type:"string"` +} + +// String returns the string representation +func (s DescribeBackupsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeBackupsOutput) GoString() string { + return s.String() +} + +// SetBackups sets the Backups field's value. +func (s *DescribeBackupsOutput) SetBackups(v []*Backup) *DescribeBackupsOutput { + s.Backups = v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *DescribeBackupsOutput) SetNextToken(v string) *DescribeBackupsOutput { + s.NextToken = &v + return s +} + +type DescribeDataRepositoryTasksInput struct { + _ struct{} `type:"structure"` + + // (Optional) You can use filters to narrow the DescribeDataRepositoryTasks + // response to include just tasks for specific file systems, or tasks in a specific + // lifecycle state. + Filters []*DataRepositoryTaskFilter `type:"list"` + + // The maximum number of resources to return in the response. This value must + // be an integer greater than zero. + MaxResults *int64 `min:"1" type:"integer"` + + // (Optional) Opaque pagination token returned from a previous operation (String). + // If present, this token indicates from what point you can continue processing + // the request, where the previous NextToken value left off. + NextToken *string `min:"1" type:"string"` + + // (Optional) IDs of the tasks whose descriptions you want to retrieve (String). + TaskIds []*string `type:"list"` +} + +// String returns the string representation +func (s DescribeDataRepositoryTasksInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeDataRepositoryTasksInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DescribeDataRepositoryTasksInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DescribeDataRepositoryTasksInput"} + if s.MaxResults != nil && *s.MaxResults < 1 { + invalidParams.Add(request.NewErrParamMinValue("MaxResults", 1)) + } + if s.NextToken != nil && len(*s.NextToken) < 1 { + invalidParams.Add(request.NewErrParamMinLen("NextToken", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetFilters sets the Filters field's value. +func (s *DescribeDataRepositoryTasksInput) SetFilters(v []*DataRepositoryTaskFilter) *DescribeDataRepositoryTasksInput { + s.Filters = v + return s +} + +// SetMaxResults sets the MaxResults field's value. +func (s *DescribeDataRepositoryTasksInput) SetMaxResults(v int64) *DescribeDataRepositoryTasksInput { + s.MaxResults = &v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *DescribeDataRepositoryTasksInput) SetNextToken(v string) *DescribeDataRepositoryTasksInput { + s.NextToken = &v + return s +} + +// SetTaskIds sets the TaskIds field's value. +func (s *DescribeDataRepositoryTasksInput) SetTaskIds(v []*string) *DescribeDataRepositoryTasksInput { + s.TaskIds = v + return s +} + +type DescribeDataRepositoryTasksOutput struct { + _ struct{} `type:"structure"` + + // The collection of data repository task descriptions returned. + DataRepositoryTasks []*DataRepositoryTask `type:"list"` + + // (Optional) Opaque pagination token returned from a previous operation (String). + // If present, this token indicates from what point you can continue processing + // the request, where the previous NextToken value left off. + NextToken *string `min:"1" type:"string"` +} + +// String returns the string representation +func (s DescribeDataRepositoryTasksOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeDataRepositoryTasksOutput) GoString() string { + return s.String() +} + +// SetDataRepositoryTasks sets the DataRepositoryTasks field's value. +func (s *DescribeDataRepositoryTasksOutput) SetDataRepositoryTasks(v []*DataRepositoryTask) *DescribeDataRepositoryTasksOutput { + s.DataRepositoryTasks = v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *DescribeDataRepositoryTasksOutput) SetNextToken(v string) *DescribeDataRepositoryTasksOutput { + s.NextToken = &v + return s +} + +// The request object for DescribeFileSystems operation. +type DescribeFileSystemsInput struct { + _ struct{} `type:"structure"` + + // (Optional) IDs of the file systems whose descriptions you want to retrieve + // (String). + FileSystemIds []*string `type:"list"` + + // (Optional) Maximum number of file systems to return in the response (integer). + // This parameter value must be greater than 0. The number of items that Amazon + // FSx returns is the minimum of the MaxResults parameter specified in the request + // and the service's internal maximum number of items per page. + MaxResults *int64 `min:"1" type:"integer"` + + // (Optional) Opaque pagination token returned from a previous DescribeFileSystems + // operation (String). If a token present, the action continues the list from + // where the returning call left off. + NextToken *string `min:"1" type:"string"` +} + +// String returns the string representation +func (s DescribeFileSystemsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeFileSystemsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DescribeFileSystemsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DescribeFileSystemsInput"} + if s.MaxResults != nil && *s.MaxResults < 1 { + invalidParams.Add(request.NewErrParamMinValue("MaxResults", 1)) + } + if s.NextToken != nil && len(*s.NextToken) < 1 { + invalidParams.Add(request.NewErrParamMinLen("NextToken", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetFileSystemIds sets the FileSystemIds field's value. +func (s *DescribeFileSystemsInput) SetFileSystemIds(v []*string) *DescribeFileSystemsInput { + s.FileSystemIds = v + return s +} + +// SetMaxResults sets the MaxResults field's value. +func (s *DescribeFileSystemsInput) SetMaxResults(v int64) *DescribeFileSystemsInput { + s.MaxResults = &v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *DescribeFileSystemsInput) SetNextToken(v string) *DescribeFileSystemsInput { + s.NextToken = &v + return s +} + +// The response object for DescribeFileSystems operation. +type DescribeFileSystemsOutput struct { + _ struct{} `type:"structure"` + + // An array of file system descriptions. + FileSystems []*FileSystem `type:"list"` + + // Present if there are more file systems than returned in the response (String). + // You can use the NextToken value in the later request to fetch the descriptions. + NextToken *string `min:"1" type:"string"` +} + +// String returns the string representation +func (s DescribeFileSystemsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeFileSystemsOutput) GoString() string { + return s.String() +} + +// SetFileSystems sets the FileSystems field's value. +func (s *DescribeFileSystemsOutput) SetFileSystems(v []*FileSystem) *DescribeFileSystemsOutput { + s.FileSystems = v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *DescribeFileSystemsOutput) SetNextToken(v string) *DescribeFileSystemsOutput { + s.NextToken = &v + return s +} + +// A description of a specific Amazon FSx file system. +type FileSystem struct { + _ struct{} `type:"structure"` + + // The time that the file system was created, in seconds (since 1970-01-01T00:00:00Z), + // also known as Unix time. + CreationTime *time.Time `type:"timestamp"` + + // The DNS name for the file system. + DNSName *string `min:"16" type:"string"` + + // A structure providing details of any failures that occur when creating the + // file system has failed. + FailureDetails *FileSystemFailureDetails `type:"structure"` + + // The system-generated, unique 17-digit ID of the file system. + FileSystemId *string `min:"11" type:"string"` + + // The type of Amazon FSx file system, either LUSTRE or WINDOWS. + FileSystemType *string `type:"string" enum:"FileSystemType"` + + // The ID of the AWS Key Management Service (AWS KMS) key used to encrypt the + // file system's data for an Amazon FSx for Windows File Server file system. + // Amazon FSx for Lustre does not support KMS encryption. + KmsKeyId *string `min:"1" type:"string"` + + // The lifecycle status of the file system, following are the possible values + // and what they mean: + // + // * AVAILABLE - The file system is in a healthy state, and is reachable + // and available for use. + // + // * CREATING - Amazon FSx is creating the new file system. + // + // * DELETING - Amazon FSx is deleting an existing file system. + // + // * FAILED - An existing file system has experienced an unrecoverable failure. + // When creating a new file system, Amazon FSx was unable to create the file + // system. + // + // * MISCONFIGURED indicates that the file system is in a failed but recoverable + // state. + // + // * UPDATING indicates that the file system is undergoing a customer initiated + // update. + Lifecycle *string `type:"string" enum:"FileSystemLifecycle"` + + // The configuration for the Amazon FSx for Lustre file system. + LustreConfiguration *LustreFileSystemConfiguration `type:"structure"` + + // The IDs of the elastic network interface from which a specific file system + // is accessible. The elastic network interface is automatically created in + // the same VPC that the Amazon FSx file system was created in. For more information, + // see Elastic Network Interfaces (https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html) + // in the Amazon EC2 User Guide. + // + // For an Amazon FSx for Windows File Server file system, you can have one network + // interface ID. For an Amazon FSx for Lustre file system, you can have more + // than one. + NetworkInterfaceIds []*string `type:"list"` + + // The AWS account that created the file system. If the file system was created + // by an AWS Identity and Access Management (IAM) user, the AWS account to which + // the IAM user belongs is the owner. + OwnerId *string `min:"12" type:"string"` + + // The Amazon Resource Name (ARN) for the file system resource. + ResourceARN *string `min:"8" type:"string"` + + // The storage capacity of the file system in gigabytes (GB). + StorageCapacity *int64 `type:"integer"` + + // The ID of the subnet to contain the endpoint for the file system. One and + // only one is supported. The file system is launched in the Availability Zone + // associated with this subnet. + SubnetIds []*string `type:"list"` + + // The tags to associate with the file system. For more information, see Tagging + // Your Amazon EC2 Resources (https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Using_Tags.html) + // in the Amazon EC2 User Guide. + Tags []*Tag `min:"1" type:"list"` + + // The ID of the primary VPC for the file system. + VpcId *string `min:"12" type:"string"` + + // The configuration for this Microsoft Windows file system. + WindowsConfiguration *WindowsFileSystemConfiguration `type:"structure"` +} + +// String returns the string representation +func (s FileSystem) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s FileSystem) GoString() string { + return s.String() +} + +// SetCreationTime sets the CreationTime field's value. +func (s *FileSystem) SetCreationTime(v time.Time) *FileSystem { + s.CreationTime = &v + return s +} + +// SetDNSName sets the DNSName field's value. +func (s *FileSystem) SetDNSName(v string) *FileSystem { + s.DNSName = &v + return s +} + +// SetFailureDetails sets the FailureDetails field's value. +func (s *FileSystem) SetFailureDetails(v *FileSystemFailureDetails) *FileSystem { + s.FailureDetails = v + return s +} + +// SetFileSystemId sets the FileSystemId field's value. +func (s *FileSystem) SetFileSystemId(v string) *FileSystem { + s.FileSystemId = &v + return s +} + +// SetFileSystemType sets the FileSystemType field's value. +func (s *FileSystem) SetFileSystemType(v string) *FileSystem { + s.FileSystemType = &v + return s +} + +// SetKmsKeyId sets the KmsKeyId field's value. +func (s *FileSystem) SetKmsKeyId(v string) *FileSystem { + s.KmsKeyId = &v + return s +} + +// SetLifecycle sets the Lifecycle field's value. +func (s *FileSystem) SetLifecycle(v string) *FileSystem { + s.Lifecycle = &v + return s +} + +// SetLustreConfiguration sets the LustreConfiguration field's value. +func (s *FileSystem) SetLustreConfiguration(v *LustreFileSystemConfiguration) *FileSystem { + s.LustreConfiguration = v + return s +} + +// SetNetworkInterfaceIds sets the NetworkInterfaceIds field's value. +func (s *FileSystem) SetNetworkInterfaceIds(v []*string) *FileSystem { + s.NetworkInterfaceIds = v + return s +} + +// SetOwnerId sets the OwnerId field's value. +func (s *FileSystem) SetOwnerId(v string) *FileSystem { + s.OwnerId = &v + return s +} + +// SetResourceARN sets the ResourceARN field's value. +func (s *FileSystem) SetResourceARN(v string) *FileSystem { + s.ResourceARN = &v + return s +} + +// SetStorageCapacity sets the StorageCapacity field's value. +func (s *FileSystem) SetStorageCapacity(v int64) *FileSystem { + s.StorageCapacity = &v + return s +} + +// SetSubnetIds sets the SubnetIds field's value. +func (s *FileSystem) SetSubnetIds(v []*string) *FileSystem { + s.SubnetIds = v + return s +} + +// SetTags sets the Tags field's value. +func (s *FileSystem) SetTags(v []*Tag) *FileSystem { + s.Tags = v + return s +} + +// SetVpcId sets the VpcId field's value. +func (s *FileSystem) SetVpcId(v string) *FileSystem { + s.VpcId = &v + return s +} + +// SetWindowsConfiguration sets the WindowsConfiguration field's value. +func (s *FileSystem) SetWindowsConfiguration(v *WindowsFileSystemConfiguration) *FileSystem { + s.WindowsConfiguration = v + return s +} + +// A structure providing details of any failures that occur when creating the +// file system has failed. +type FileSystemFailureDetails struct { + _ struct{} `type:"structure"` + + // A message describing any failures that occurred during file system creation. + Message *string `min:"1" type:"string"` +} + +// String returns the string representation +func (s FileSystemFailureDetails) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s FileSystemFailureDetails) GoString() string { + return s.String() +} + +// SetMessage sets the Message field's value. +func (s *FileSystemFailureDetails) SetMessage(v string) *FileSystemFailureDetails { + s.Message = &v + return s +} + +// A filter used to restrict the results of describe calls. You can use multiple +// filters to return results that meet all applied filter requirements. +type Filter struct { + _ struct{} `type:"structure"` + + // The name for this filter. + Name *string `type:"string" enum:"FilterName"` + + // The values of the filter. These are all the values for any of the applied + // filters. + Values []*string `type:"list"` +} + +// String returns the string representation +func (s Filter) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Filter) GoString() string { + return s.String() +} + +// SetName sets the Name field's value. +func (s *Filter) SetName(v string) *Filter { + s.Name = &v + return s +} + +// SetValues sets the Values field's value. +func (s *Filter) SetValues(v []*string) *Filter { + s.Values = v + return s +} + +// The request object for ListTagsForResource operation. +type ListTagsForResourceInput struct { + _ struct{} `type:"structure"` + + // (Optional) Maximum number of tags to return in the response (integer). This + // parameter value must be greater than 0. The number of items that Amazon FSx + // returns is the minimum of the MaxResults parameter specified in the request + // and the service's internal maximum number of items per page. + MaxResults *int64 `min:"1" type:"integer"` + + // (Optional) Opaque pagination token returned from a previous ListTagsForResource + // operation (String). If a token present, the action continues the list from + // where the returning call left off. + NextToken *string `min:"1" type:"string"` + + // The ARN of the Amazon FSx resource that will have its tags listed. + // + // ResourceARN is a required field + ResourceARN *string `min:"8" type:"string" required:"true"` +} + +// String returns the string representation +func (s ListTagsForResourceInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListTagsForResourceInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ListTagsForResourceInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ListTagsForResourceInput"} + if s.MaxResults != nil && *s.MaxResults < 1 { + invalidParams.Add(request.NewErrParamMinValue("MaxResults", 1)) + } + if s.NextToken != nil && len(*s.NextToken) < 1 { + invalidParams.Add(request.NewErrParamMinLen("NextToken", 1)) + } + if s.ResourceARN == nil { + invalidParams.Add(request.NewErrParamRequired("ResourceARN")) + } + if s.ResourceARN != nil && len(*s.ResourceARN) < 8 { + invalidParams.Add(request.NewErrParamMinLen("ResourceARN", 8)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetMaxResults sets the MaxResults field's value. +func (s *ListTagsForResourceInput) SetMaxResults(v int64) *ListTagsForResourceInput { + s.MaxResults = &v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *ListTagsForResourceInput) SetNextToken(v string) *ListTagsForResourceInput { + s.NextToken = &v + return s +} + +// SetResourceARN sets the ResourceARN field's value. +func (s *ListTagsForResourceInput) SetResourceARN(v string) *ListTagsForResourceInput { + s.ResourceARN = &v + return s +} + +// The response object for ListTagsForResource operation. +type ListTagsForResourceOutput struct { + _ struct{} `type:"structure"` + + // This is present if there are more tags than returned in the response (String). + // You can use the NextToken value in the later request to fetch the tags. + NextToken *string `min:"1" type:"string"` + + // A list of tags on the resource. + Tags []*Tag `min:"1" type:"list"` +} + +// String returns the string representation +func (s ListTagsForResourceOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListTagsForResourceOutput) GoString() string { + return s.String() +} + +// SetNextToken sets the NextToken field's value. +func (s *ListTagsForResourceOutput) SetNextToken(v string) *ListTagsForResourceOutput { + s.NextToken = &v + return s +} + +// SetTags sets the Tags field's value. +func (s *ListTagsForResourceOutput) SetTags(v []*Tag) *ListTagsForResourceOutput { + s.Tags = v + return s +} + +// The configuration for the Amazon FSx for Lustre file system. +type LustreFileSystemConfiguration struct { + _ struct{} `type:"structure"` + + // The data repository configuration object for Lustre file systems returned + // in the response of the CreateFileSystem operation. + DataRepositoryConfiguration *DataRepositoryConfiguration `type:"structure"` + + // The UTC time that you want to begin your weekly maintenance window. + WeeklyMaintenanceStartTime *string `min:"7" type:"string"` +} + +// String returns the string representation +func (s LustreFileSystemConfiguration) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LustreFileSystemConfiguration) GoString() string { + return s.String() +} + +// SetDataRepositoryConfiguration sets the DataRepositoryConfiguration field's value. +func (s *LustreFileSystemConfiguration) SetDataRepositoryConfiguration(v *DataRepositoryConfiguration) *LustreFileSystemConfiguration { + s.DataRepositoryConfiguration = v + return s +} + +// SetWeeklyMaintenanceStartTime sets the WeeklyMaintenanceStartTime field's value. +func (s *LustreFileSystemConfiguration) SetWeeklyMaintenanceStartTime(v string) *LustreFileSystemConfiguration { + s.WeeklyMaintenanceStartTime = &v + return s +} + +// The configuration of the self-managed Microsoft Active Directory (AD) directory +// to which the Windows File Server instance is joined. +type SelfManagedActiveDirectoryAttributes struct { + _ struct{} `type:"structure"` + + // A list of up to two IP addresses of DNS servers or domain controllers in + // the self-managed AD directory. + DnsIps []*string `min:"1" type:"list"` + + // The fully qualified domain name of the self-managed AD directory. + DomainName *string `min:"1" type:"string"` + + // The name of the domain group whose members have administrative privileges + // for the FSx file system. + FileSystemAdministratorsGroup *string `min:"1" type:"string"` + + // The fully qualified distinguished name of the organizational unit within + // the self-managed AD directory to which the Windows File Server instance is + // joined. + OrganizationalUnitDistinguishedName *string `min:"1" type:"string"` + + // The user name for the service account on your self-managed AD domain that + // FSx uses to join to your AD domain. + UserName *string `min:"1" type:"string"` +} + +// String returns the string representation +func (s SelfManagedActiveDirectoryAttributes) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SelfManagedActiveDirectoryAttributes) GoString() string { + return s.String() +} + +// SetDnsIps sets the DnsIps field's value. +func (s *SelfManagedActiveDirectoryAttributes) SetDnsIps(v []*string) *SelfManagedActiveDirectoryAttributes { + s.DnsIps = v + return s +} + +// SetDomainName sets the DomainName field's value. +func (s *SelfManagedActiveDirectoryAttributes) SetDomainName(v string) *SelfManagedActiveDirectoryAttributes { + s.DomainName = &v + return s +} + +// SetFileSystemAdministratorsGroup sets the FileSystemAdministratorsGroup field's value. +func (s *SelfManagedActiveDirectoryAttributes) SetFileSystemAdministratorsGroup(v string) *SelfManagedActiveDirectoryAttributes { + s.FileSystemAdministratorsGroup = &v + return s +} + +// SetOrganizationalUnitDistinguishedName sets the OrganizationalUnitDistinguishedName field's value. +func (s *SelfManagedActiveDirectoryAttributes) SetOrganizationalUnitDistinguishedName(v string) *SelfManagedActiveDirectoryAttributes { + s.OrganizationalUnitDistinguishedName = &v + return s +} + +// SetUserName sets the UserName field's value. +func (s *SelfManagedActiveDirectoryAttributes) SetUserName(v string) *SelfManagedActiveDirectoryAttributes { + s.UserName = &v + return s +} + +// The configuration that Amazon FSx uses to join the Windows File Server instance +// to your self-managed (including on-premises) Microsoft Active Directory (AD) +// directory. +type SelfManagedActiveDirectoryConfiguration struct { + _ struct{} `type:"structure"` + + // A list of up to two IP addresses of DNS servers or domain controllers in + // the self-managed AD directory. The IP addresses need to be either in the + // same VPC CIDR range as the one in which your Amazon FSx file system is being + // created, or in the private IP version 4 (IPv4) address ranges, as specified + // in RFC 1918 (http://www.faqs.org/rfcs/rfc1918.html): + // + // * 10.0.0.0 - 10.255.255.255 (10/8 prefix) + // + // * 172.16.0.0 - 172.31.255.255 (172.16/12 prefix) + // + // * 192.168.0.0 - 192.168.255.255 (192.168/16 prefix) + // + // DnsIps is a required field + DnsIps []*string `min:"1" type:"list" required:"true"` + + // The fully qualified domain name of the self-managed AD directory, such as + // corp.example.com. + // + // DomainName is a required field + DomainName *string `min:"1" type:"string" required:"true"` + + // (Optional) The name of the domain group whose members are granted administrative + // privileges for the file system. Administrative privileges include taking + // ownership of files and folders, setting audit controls (audit ACLs) on files + // and folders, and administering the file system remotely by using the FSx + // Remote PowerShell. The group that you specify must already exist in your + // domain. If you don't provide one, your AD domain's Domain Admins group is + // used. + FileSystemAdministratorsGroup *string `min:"1" type:"string"` + + // (Optional) The fully qualified distinguished name of the organizational unit + // within your self-managed AD directory that the Windows File Server instance + // will join. Amazon FSx only accepts OU as the direct parent of the file system. + // An example is OU=FSx,DC=yourdomain,DC=corp,DC=com. To learn more, see RFC + // 2253 (https://tools.ietf.org/html/rfc2253). If none is provided, the FSx + // file system is created in the default location of your self-managed AD directory. + // + // Only Organizational Unit (OU) objects can be the direct parent of the file + // system that you're creating. + OrganizationalUnitDistinguishedName *string `min:"1" type:"string"` + + // The password for the service account on your self-managed AD domain that + // Amazon FSx will use to join to your AD domain. + // + // Password is a required field + Password *string `min:"1" type:"string" required:"true" sensitive:"true"` + + // The user name for the service account on your self-managed AD domain that + // Amazon FSx will use to join to your AD domain. This account must have the + // permission to join computers to the domain in the organizational unit provided + // in OrganizationalUnitDistinguishedName, or in the default location of your + // AD domain. + // + // UserName is a required field + UserName *string `min:"1" type:"string" required:"true"` +} + +// String returns the string representation +func (s SelfManagedActiveDirectoryConfiguration) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SelfManagedActiveDirectoryConfiguration) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *SelfManagedActiveDirectoryConfiguration) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "SelfManagedActiveDirectoryConfiguration"} + if s.DnsIps == nil { + invalidParams.Add(request.NewErrParamRequired("DnsIps")) + } + if s.DnsIps != nil && len(s.DnsIps) < 1 { + invalidParams.Add(request.NewErrParamMinLen("DnsIps", 1)) + } + if s.DomainName == nil { + invalidParams.Add(request.NewErrParamRequired("DomainName")) + } + if s.DomainName != nil && len(*s.DomainName) < 1 { + invalidParams.Add(request.NewErrParamMinLen("DomainName", 1)) + } + if s.FileSystemAdministratorsGroup != nil && len(*s.FileSystemAdministratorsGroup) < 1 { + invalidParams.Add(request.NewErrParamMinLen("FileSystemAdministratorsGroup", 1)) + } + if s.OrganizationalUnitDistinguishedName != nil && len(*s.OrganizationalUnitDistinguishedName) < 1 { + invalidParams.Add(request.NewErrParamMinLen("OrganizationalUnitDistinguishedName", 1)) + } + if s.Password == nil { + invalidParams.Add(request.NewErrParamRequired("Password")) + } + if s.Password != nil && len(*s.Password) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Password", 1)) + } + if s.UserName == nil { + invalidParams.Add(request.NewErrParamRequired("UserName")) + } + if s.UserName != nil && len(*s.UserName) < 1 { + invalidParams.Add(request.NewErrParamMinLen("UserName", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDnsIps sets the DnsIps field's value. +func (s *SelfManagedActiveDirectoryConfiguration) SetDnsIps(v []*string) *SelfManagedActiveDirectoryConfiguration { + s.DnsIps = v + return s +} + +// SetDomainName sets the DomainName field's value. +func (s *SelfManagedActiveDirectoryConfiguration) SetDomainName(v string) *SelfManagedActiveDirectoryConfiguration { + s.DomainName = &v + return s +} + +// SetFileSystemAdministratorsGroup sets the FileSystemAdministratorsGroup field's value. +func (s *SelfManagedActiveDirectoryConfiguration) SetFileSystemAdministratorsGroup(v string) *SelfManagedActiveDirectoryConfiguration { + s.FileSystemAdministratorsGroup = &v + return s +} + +// SetOrganizationalUnitDistinguishedName sets the OrganizationalUnitDistinguishedName field's value. +func (s *SelfManagedActiveDirectoryConfiguration) SetOrganizationalUnitDistinguishedName(v string) *SelfManagedActiveDirectoryConfiguration { + s.OrganizationalUnitDistinguishedName = &v + return s +} + +// SetPassword sets the Password field's value. +func (s *SelfManagedActiveDirectoryConfiguration) SetPassword(v string) *SelfManagedActiveDirectoryConfiguration { + s.Password = &v + return s +} + +// SetUserName sets the UserName field's value. +func (s *SelfManagedActiveDirectoryConfiguration) SetUserName(v string) *SelfManagedActiveDirectoryConfiguration { + s.UserName = &v + return s +} + +// The configuration that Amazon FSx uses to join the Windows File Server instance +// to the self-managed Microsoft Active Directory (AD) directory. +type SelfManagedActiveDirectoryConfigurationUpdates struct { + _ struct{} `type:"structure"` + + // A list of up to two IP addresses of DNS servers or domain controllers in + // the self-managed AD directory. + DnsIps []*string `min:"1" type:"list"` + + // The password for the service account on your self-managed AD domain that + // Amazon FSx will use to join to your AD domain. + Password *string `min:"1" type:"string" sensitive:"true"` + + // The user name for the service account on your self-managed AD domain that + // Amazon FSx will use to join to your AD domain. This account must have the + // permission to join computers to the domain in the organizational unit provided + // in OrganizationalUnitDistinguishedName. + UserName *string `min:"1" type:"string"` +} + +// String returns the string representation +func (s SelfManagedActiveDirectoryConfigurationUpdates) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SelfManagedActiveDirectoryConfigurationUpdates) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *SelfManagedActiveDirectoryConfigurationUpdates) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "SelfManagedActiveDirectoryConfigurationUpdates"} + if s.DnsIps != nil && len(s.DnsIps) < 1 { + invalidParams.Add(request.NewErrParamMinLen("DnsIps", 1)) + } + if s.Password != nil && len(*s.Password) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Password", 1)) + } + if s.UserName != nil && len(*s.UserName) < 1 { + invalidParams.Add(request.NewErrParamMinLen("UserName", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDnsIps sets the DnsIps field's value. +func (s *SelfManagedActiveDirectoryConfigurationUpdates) SetDnsIps(v []*string) *SelfManagedActiveDirectoryConfigurationUpdates { + s.DnsIps = v + return s +} + +// SetPassword sets the Password field's value. +func (s *SelfManagedActiveDirectoryConfigurationUpdates) SetPassword(v string) *SelfManagedActiveDirectoryConfigurationUpdates { + s.Password = &v + return s +} + +// SetUserName sets the UserName field's value. +func (s *SelfManagedActiveDirectoryConfigurationUpdates) SetUserName(v string) *SelfManagedActiveDirectoryConfigurationUpdates { + s.UserName = &v + return s +} + +// Specifies a key-value pair for a resource tag. +type Tag struct { + _ struct{} `type:"structure"` + + // A value that specifies the TagKey, the name of the tag. Tag keys must be + // unique for the resource to which they are attached. + Key *string `min:"1" type:"string"` + + // A value that specifies the TagValue, the value assigned to the corresponding + // tag key. Tag values can be null and don't have to be unique in a tag set. + // For example, you can have a key-value pair in a tag set of finances : April + // and also of payroll : April. + Value *string `type:"string"` +} + +// String returns the string representation +func (s Tag) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Tag) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *Tag) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "Tag"} + if s.Key != nil && len(*s.Key) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Key", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetKey sets the Key field's value. +func (s *Tag) SetKey(v string) *Tag { + s.Key = &v + return s +} + +// SetValue sets the Value field's value. +func (s *Tag) SetValue(v string) *Tag { + s.Value = &v + return s +} + +// The request object for the TagResource operation. +type TagResourceInput struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) of the Amazon FSx resource that you want to + // tag. + // + // ResourceARN is a required field + ResourceARN *string `min:"8" type:"string" required:"true"` + + // A list of tags for the resource. If a tag with a given key already exists, + // the value is replaced by the one specified in this parameter. + // + // Tags is a required field + Tags []*Tag `min:"1" type:"list" required:"true"` +} + +// String returns the string representation +func (s TagResourceInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s TagResourceInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *TagResourceInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "TagResourceInput"} + if s.ResourceARN == nil { + invalidParams.Add(request.NewErrParamRequired("ResourceARN")) + } + if s.ResourceARN != nil && len(*s.ResourceARN) < 8 { + invalidParams.Add(request.NewErrParamMinLen("ResourceARN", 8)) + } + if s.Tags == nil { + invalidParams.Add(request.NewErrParamRequired("Tags")) + } + if s.Tags != nil && len(s.Tags) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Tags", 1)) + } + if s.Tags != nil { + for i, v := range s.Tags { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "Tags", i), err.(request.ErrInvalidParams)) + } + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetResourceARN sets the ResourceARN field's value. +func (s *TagResourceInput) SetResourceARN(v string) *TagResourceInput { + s.ResourceARN = &v + return s +} + +// SetTags sets the Tags field's value. +func (s *TagResourceInput) SetTags(v []*Tag) *TagResourceInput { + s.Tags = v + return s +} + +// The response object for the TagResource operation. +type TagResourceOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s TagResourceOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s TagResourceOutput) GoString() string { + return s.String() +} + +// The request object for UntagResource action. +type UntagResourceInput struct { + _ struct{} `type:"structure"` + + // The ARN of the Amazon FSx resource to untag. + // + // ResourceARN is a required field + ResourceARN *string `min:"8" type:"string" required:"true"` + + // A list of keys of tags on the resource to untag. In case the tag key doesn't + // exist, the call will still succeed to be idempotent. + // + // TagKeys is a required field + TagKeys []*string `min:"1" type:"list" required:"true"` +} + +// String returns the string representation +func (s UntagResourceInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UntagResourceInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *UntagResourceInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "UntagResourceInput"} + if s.ResourceARN == nil { + invalidParams.Add(request.NewErrParamRequired("ResourceARN")) + } + if s.ResourceARN != nil && len(*s.ResourceARN) < 8 { + invalidParams.Add(request.NewErrParamMinLen("ResourceARN", 8)) + } + if s.TagKeys == nil { + invalidParams.Add(request.NewErrParamRequired("TagKeys")) + } + if s.TagKeys != nil && len(s.TagKeys) < 1 { + invalidParams.Add(request.NewErrParamMinLen("TagKeys", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetResourceARN sets the ResourceARN field's value. +func (s *UntagResourceInput) SetResourceARN(v string) *UntagResourceInput { + s.ResourceARN = &v + return s +} + +// SetTagKeys sets the TagKeys field's value. +func (s *UntagResourceInput) SetTagKeys(v []*string) *UntagResourceInput { + s.TagKeys = v + return s +} + +// The response object for UntagResource action. +type UntagResourceOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s UntagResourceOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UntagResourceOutput) GoString() string { + return s.String() +} + +// The request object for the UpdateFileSystem operation. +type UpdateFileSystemInput struct { + _ struct{} `type:"structure"` + + // (Optional) A string of up to 64 ASCII characters that Amazon FSx uses to + // ensure idempotent updates. This string is automatically filled on your behalf + // when you use the AWS Command Line Interface (AWS CLI) or an AWS SDK. + ClientRequestToken *string `min:"1" type:"string" idempotencyToken:"true"` + + // The globally unique ID of the file system, assigned by Amazon FSx. + // + // FileSystemId is a required field + FileSystemId *string `min:"11" type:"string" required:"true"` + + // The configuration object for Amazon FSx for Lustre file systems used in the + // UpdateFileSystem operation. + LustreConfiguration *UpdateFileSystemLustreConfiguration `type:"structure"` + + // The configuration update for this Microsoft Windows file system. The only + // supported options are for backup and maintenance and for self-managed Active + // Directory configuration. + WindowsConfiguration *UpdateFileSystemWindowsConfiguration `type:"structure"` +} + +// String returns the string representation +func (s UpdateFileSystemInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UpdateFileSystemInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *UpdateFileSystemInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "UpdateFileSystemInput"} + if s.ClientRequestToken != nil && len(*s.ClientRequestToken) < 1 { + invalidParams.Add(request.NewErrParamMinLen("ClientRequestToken", 1)) + } + if s.FileSystemId == nil { + invalidParams.Add(request.NewErrParamRequired("FileSystemId")) + } + if s.FileSystemId != nil && len(*s.FileSystemId) < 11 { + invalidParams.Add(request.NewErrParamMinLen("FileSystemId", 11)) + } + if s.LustreConfiguration != nil { + if err := s.LustreConfiguration.Validate(); err != nil { + invalidParams.AddNested("LustreConfiguration", err.(request.ErrInvalidParams)) + } + } + if s.WindowsConfiguration != nil { + if err := s.WindowsConfiguration.Validate(); err != nil { + invalidParams.AddNested("WindowsConfiguration", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetClientRequestToken sets the ClientRequestToken field's value. +func (s *UpdateFileSystemInput) SetClientRequestToken(v string) *UpdateFileSystemInput { + s.ClientRequestToken = &v + return s +} + +// SetFileSystemId sets the FileSystemId field's value. +func (s *UpdateFileSystemInput) SetFileSystemId(v string) *UpdateFileSystemInput { + s.FileSystemId = &v + return s +} + +// SetLustreConfiguration sets the LustreConfiguration field's value. +func (s *UpdateFileSystemInput) SetLustreConfiguration(v *UpdateFileSystemLustreConfiguration) *UpdateFileSystemInput { + s.LustreConfiguration = v + return s +} + +// SetWindowsConfiguration sets the WindowsConfiguration field's value. +func (s *UpdateFileSystemInput) SetWindowsConfiguration(v *UpdateFileSystemWindowsConfiguration) *UpdateFileSystemInput { + s.WindowsConfiguration = v + return s +} + +// The configuration object for Amazon FSx for Lustre file systems used in the +// UpdateFileSystem operation. +type UpdateFileSystemLustreConfiguration struct { + _ struct{} `type:"structure"` + + // The preferred time to perform weekly maintenance, in the UTC time zone. + WeeklyMaintenanceStartTime *string `min:"7" type:"string"` +} + +// String returns the string representation +func (s UpdateFileSystemLustreConfiguration) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UpdateFileSystemLustreConfiguration) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *UpdateFileSystemLustreConfiguration) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "UpdateFileSystemLustreConfiguration"} + if s.WeeklyMaintenanceStartTime != nil && len(*s.WeeklyMaintenanceStartTime) < 7 { + invalidParams.Add(request.NewErrParamMinLen("WeeklyMaintenanceStartTime", 7)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetWeeklyMaintenanceStartTime sets the WeeklyMaintenanceStartTime field's value. +func (s *UpdateFileSystemLustreConfiguration) SetWeeklyMaintenanceStartTime(v string) *UpdateFileSystemLustreConfiguration { + s.WeeklyMaintenanceStartTime = &v + return s +} + +// The response object for the UpdateFileSystem operation. +type UpdateFileSystemOutput struct { + _ struct{} `type:"structure"` + + // A description of the file system that was updated. + FileSystem *FileSystem `type:"structure"` +} + +// String returns the string representation +func (s UpdateFileSystemOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UpdateFileSystemOutput) GoString() string { + return s.String() +} + +// SetFileSystem sets the FileSystem field's value. +func (s *UpdateFileSystemOutput) SetFileSystem(v *FileSystem) *UpdateFileSystemOutput { + s.FileSystem = v + return s +} + +// Updates the Microsoft Windows configuration for an existing Amazon FSx for +// Windows File Server file system. Amazon FSx overwrites existing properties +// with non-null values provided in the request. If you don't specify a non-null +// value for a property, that property is not updated. +type UpdateFileSystemWindowsConfiguration struct { + _ struct{} `type:"structure"` + + // The number of days to retain automatic backups. Setting this to 0 disables + // automatic backups. You can retain automatic backups for a maximum of 35 days. + AutomaticBackupRetentionDays *int64 `type:"integer"` + + // The preferred time to take daily automatic backups, in the UTC time zone. + DailyAutomaticBackupStartTime *string `min:"5" type:"string"` + + // The configuration Amazon FSx uses to join the Windows File Server instance + // to the self-managed Microsoft AD directory. + SelfManagedActiveDirectoryConfiguration *SelfManagedActiveDirectoryConfigurationUpdates `type:"structure"` + + // The preferred time to perform weekly maintenance, in the UTC time zone. + WeeklyMaintenanceStartTime *string `min:"7" type:"string"` +} + +// String returns the string representation +func (s UpdateFileSystemWindowsConfiguration) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UpdateFileSystemWindowsConfiguration) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *UpdateFileSystemWindowsConfiguration) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "UpdateFileSystemWindowsConfiguration"} + if s.DailyAutomaticBackupStartTime != nil && len(*s.DailyAutomaticBackupStartTime) < 5 { + invalidParams.Add(request.NewErrParamMinLen("DailyAutomaticBackupStartTime", 5)) + } + if s.WeeklyMaintenanceStartTime != nil && len(*s.WeeklyMaintenanceStartTime) < 7 { + invalidParams.Add(request.NewErrParamMinLen("WeeklyMaintenanceStartTime", 7)) + } + if s.SelfManagedActiveDirectoryConfiguration != nil { + if err := s.SelfManagedActiveDirectoryConfiguration.Validate(); err != nil { + invalidParams.AddNested("SelfManagedActiveDirectoryConfiguration", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetAutomaticBackupRetentionDays sets the AutomaticBackupRetentionDays field's value. +func (s *UpdateFileSystemWindowsConfiguration) SetAutomaticBackupRetentionDays(v int64) *UpdateFileSystemWindowsConfiguration { + s.AutomaticBackupRetentionDays = &v + return s +} + +// SetDailyAutomaticBackupStartTime sets the DailyAutomaticBackupStartTime field's value. +func (s *UpdateFileSystemWindowsConfiguration) SetDailyAutomaticBackupStartTime(v string) *UpdateFileSystemWindowsConfiguration { + s.DailyAutomaticBackupStartTime = &v + return s +} + +// SetSelfManagedActiveDirectoryConfiguration sets the SelfManagedActiveDirectoryConfiguration field's value. +func (s *UpdateFileSystemWindowsConfiguration) SetSelfManagedActiveDirectoryConfiguration(v *SelfManagedActiveDirectoryConfigurationUpdates) *UpdateFileSystemWindowsConfiguration { + s.SelfManagedActiveDirectoryConfiguration = v + return s +} + +// SetWeeklyMaintenanceStartTime sets the WeeklyMaintenanceStartTime field's value. +func (s *UpdateFileSystemWindowsConfiguration) SetWeeklyMaintenanceStartTime(v string) *UpdateFileSystemWindowsConfiguration { + s.WeeklyMaintenanceStartTime = &v + return s +} + +// The configuration for this Microsoft Windows file system. +type WindowsFileSystemConfiguration struct { + _ struct{} `type:"structure"` + + // The ID for an existing Microsoft Active Directory instance that the file + // system should join when it's created. + ActiveDirectoryId *string `min:"12" type:"string"` + + // The number of days to retain automatic backups. Setting this to 0 disables + // automatic backups. You can retain automatic backups for a maximum of 35 days. + AutomaticBackupRetentionDays *int64 `type:"integer"` + + // A boolean flag indicating whether tags on the file system should be copied + // to backups. This value defaults to false. If it's set to true, all tags on + // the file system are copied to all automatic backups and any user-initiated + // backups where the user doesn't specify any tags. If this value is true, and + // you specify one or more tags, only the specified tags are copied to backups. + CopyTagsToBackups *bool `type:"boolean"` + + // The preferred time to take daily automatic backups, in the UTC time zone. + DailyAutomaticBackupStartTime *string `min:"5" type:"string"` + + // Specifies the file system deployment type, valid values are the following: + // + // * MULTI_AZ_1 - Specifies a high availability file system that is configured + // for Multi-AZ redundancy to tolerate temporary Availability Zone (AZ) unavailability. + // + // * SINGLE_AZ_1 - (Default) Specifies a file system that is configured for + // single AZ redundancy. + DeploymentType *string `type:"string" enum:"WindowsDeploymentType"` + + // The list of maintenance operations in progress for this file system. + MaintenanceOperationsInProgress []*string `type:"list"` + + // For MULTI_AZ_1 deployment types, the IP address of the primary, or preferred, + // file server. + // + // Use this IP address when mounting the file system on Linux SMB clients or + // Windows SMB clients that are not joined to a Microsoft Active Directory. + // Applicable for both SINGLE_AZ_1 and MULTI_AZ_1 deployment types. This IP + // address is temporarily unavailable when the file system is undergoing maintenance. + // For Linux and Windows SMB clients that are joined to an Active Directory, + // use the file system's DNSName instead. For more information and instruction + // on mapping and mounting file shares, see https://docs.aws.amazon.com/fsx/latest/WindowsGuide/accessing-file-shares.html + // (https://docs.aws.amazon.com/fsx/latest/WindowsGuide/accessing-file-shares.html). + PreferredFileServerIp *string `min:"7" type:"string"` + + // For MULTI_AZ_1 deployment types, it specifies the ID of the subnet where + // the preferred file server is located. Must be one of the two subnet IDs specified + // in SubnetIds property. Amazon FSx serves traffic from this subnet except + // in the event of a failover to the secondary file server. + // + // For SINGLE_AZ_1 deployment types, this value is the same as that for SubnetIDs. + PreferredSubnetId *string `min:"15" type:"string"` + + // For MULTI_AZ_1 deployment types, use this endpoint when performing administrative + // tasks on the file system using Amazon FSx Remote PowerShell. + // + // For SINGLE_AZ_1 deployment types, this is the DNS name of the file system. + // + // This endpoint is temporarily unavailable when the file system is undergoing + // maintenance. + RemoteAdministrationEndpoint *string `min:"16" type:"string"` + + // The configuration of the self-managed Microsoft Active Directory (AD) directory + // to which the Windows File Server instance is joined. + SelfManagedActiveDirectoryConfiguration *SelfManagedActiveDirectoryAttributes `type:"structure"` + + // The throughput of an Amazon FSx file system, measured in megabytes per second. + ThroughputCapacity *int64 `min:"8" type:"integer"` + + // The preferred time to perform weekly maintenance, in the UTC time zone. + WeeklyMaintenanceStartTime *string `min:"7" type:"string"` +} + +// String returns the string representation +func (s WindowsFileSystemConfiguration) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s WindowsFileSystemConfiguration) GoString() string { + return s.String() +} + +// SetActiveDirectoryId sets the ActiveDirectoryId field's value. +func (s *WindowsFileSystemConfiguration) SetActiveDirectoryId(v string) *WindowsFileSystemConfiguration { + s.ActiveDirectoryId = &v + return s +} + +// SetAutomaticBackupRetentionDays sets the AutomaticBackupRetentionDays field's value. +func (s *WindowsFileSystemConfiguration) SetAutomaticBackupRetentionDays(v int64) *WindowsFileSystemConfiguration { + s.AutomaticBackupRetentionDays = &v + return s +} + +// SetCopyTagsToBackups sets the CopyTagsToBackups field's value. +func (s *WindowsFileSystemConfiguration) SetCopyTagsToBackups(v bool) *WindowsFileSystemConfiguration { + s.CopyTagsToBackups = &v + return s +} + +// SetDailyAutomaticBackupStartTime sets the DailyAutomaticBackupStartTime field's value. +func (s *WindowsFileSystemConfiguration) SetDailyAutomaticBackupStartTime(v string) *WindowsFileSystemConfiguration { + s.DailyAutomaticBackupStartTime = &v + return s +} + +// SetDeploymentType sets the DeploymentType field's value. +func (s *WindowsFileSystemConfiguration) SetDeploymentType(v string) *WindowsFileSystemConfiguration { + s.DeploymentType = &v + return s +} + +// SetMaintenanceOperationsInProgress sets the MaintenanceOperationsInProgress field's value. +func (s *WindowsFileSystemConfiguration) SetMaintenanceOperationsInProgress(v []*string) *WindowsFileSystemConfiguration { + s.MaintenanceOperationsInProgress = v + return s +} + +// SetPreferredFileServerIp sets the PreferredFileServerIp field's value. +func (s *WindowsFileSystemConfiguration) SetPreferredFileServerIp(v string) *WindowsFileSystemConfiguration { + s.PreferredFileServerIp = &v + return s +} + +// SetPreferredSubnetId sets the PreferredSubnetId field's value. +func (s *WindowsFileSystemConfiguration) SetPreferredSubnetId(v string) *WindowsFileSystemConfiguration { + s.PreferredSubnetId = &v + return s +} + +// SetRemoteAdministrationEndpoint sets the RemoteAdministrationEndpoint field's value. +func (s *WindowsFileSystemConfiguration) SetRemoteAdministrationEndpoint(v string) *WindowsFileSystemConfiguration { + s.RemoteAdministrationEndpoint = &v + return s +} + +// SetSelfManagedActiveDirectoryConfiguration sets the SelfManagedActiveDirectoryConfiguration field's value. +func (s *WindowsFileSystemConfiguration) SetSelfManagedActiveDirectoryConfiguration(v *SelfManagedActiveDirectoryAttributes) *WindowsFileSystemConfiguration { + s.SelfManagedActiveDirectoryConfiguration = v + return s +} + +// SetThroughputCapacity sets the ThroughputCapacity field's value. +func (s *WindowsFileSystemConfiguration) SetThroughputCapacity(v int64) *WindowsFileSystemConfiguration { + s.ThroughputCapacity = &v + return s +} + +// SetWeeklyMaintenanceStartTime sets the WeeklyMaintenanceStartTime field's value. +func (s *WindowsFileSystemConfiguration) SetWeeklyMaintenanceStartTime(v string) *WindowsFileSystemConfiguration { + s.WeeklyMaintenanceStartTime = &v + return s +} + +// The type of error relating to Microsoft Active Directory. NOT_FOUND means +// that no directory was found by specifying the given directory. INCOMPATIBLE_MODE +// means that the directory specified is not a Microsoft AD directory. WRONG_VPC +// means that the specified directory isn't accessible from the specified VPC. +// WRONG_STAGE means that the specified directory isn't currently in the ACTIVE +// state. +const ( + // ActiveDirectoryErrorTypeDomainNotFound is a ActiveDirectoryErrorType enum value + ActiveDirectoryErrorTypeDomainNotFound = "DOMAIN_NOT_FOUND" + + // ActiveDirectoryErrorTypeIncompatibleDomainMode is a ActiveDirectoryErrorType enum value + ActiveDirectoryErrorTypeIncompatibleDomainMode = "INCOMPATIBLE_DOMAIN_MODE" + + // ActiveDirectoryErrorTypeWrongVpc is a ActiveDirectoryErrorType enum value + ActiveDirectoryErrorTypeWrongVpc = "WRONG_VPC" + + // ActiveDirectoryErrorTypeInvalidDomainStage is a ActiveDirectoryErrorType enum value + ActiveDirectoryErrorTypeInvalidDomainStage = "INVALID_DOMAIN_STAGE" +) + +// The lifecycle status of the backup. +const ( + // BackupLifecycleAvailable is a BackupLifecycle enum value + BackupLifecycleAvailable = "AVAILABLE" + + // BackupLifecycleCreating is a BackupLifecycle enum value + BackupLifecycleCreating = "CREATING" + + // BackupLifecycleDeleted is a BackupLifecycle enum value + BackupLifecycleDeleted = "DELETED" + + // BackupLifecycleFailed is a BackupLifecycle enum value + BackupLifecycleFailed = "FAILED" +) + +// The type of the backup. +const ( + // BackupTypeAutomatic is a BackupType enum value + BackupTypeAutomatic = "AUTOMATIC" + + // BackupTypeUserInitiated is a BackupType enum value + BackupTypeUserInitiated = "USER_INITIATED" +) + +const ( + // DataRepositoryTaskFilterNameFileSystemId is a DataRepositoryTaskFilterName enum value + DataRepositoryTaskFilterNameFileSystemId = "file-system-id" + + // DataRepositoryTaskFilterNameTaskLifecycle is a DataRepositoryTaskFilterName enum value + DataRepositoryTaskFilterNameTaskLifecycle = "task-lifecycle" +) + +const ( + // DataRepositoryTaskLifecyclePending is a DataRepositoryTaskLifecycle enum value + DataRepositoryTaskLifecyclePending = "PENDING" + + // DataRepositoryTaskLifecycleExecuting is a DataRepositoryTaskLifecycle enum value + DataRepositoryTaskLifecycleExecuting = "EXECUTING" + + // DataRepositoryTaskLifecycleFailed is a DataRepositoryTaskLifecycle enum value + DataRepositoryTaskLifecycleFailed = "FAILED" + + // DataRepositoryTaskLifecycleSucceeded is a DataRepositoryTaskLifecycle enum value + DataRepositoryTaskLifecycleSucceeded = "SUCCEEDED" + + // DataRepositoryTaskLifecycleCanceled is a DataRepositoryTaskLifecycle enum value + DataRepositoryTaskLifecycleCanceled = "CANCELED" + + // DataRepositoryTaskLifecycleCanceling is a DataRepositoryTaskLifecycle enum value + DataRepositoryTaskLifecycleCanceling = "CANCELING" +) + +const ( + // DataRepositoryTaskTypeExportToRepository is a DataRepositoryTaskType enum value + DataRepositoryTaskTypeExportToRepository = "EXPORT_TO_REPOSITORY" +) + +// The lifecycle status of the file system. +const ( + // FileSystemLifecycleAvailable is a FileSystemLifecycle enum value + FileSystemLifecycleAvailable = "AVAILABLE" + + // FileSystemLifecycleCreating is a FileSystemLifecycle enum value + FileSystemLifecycleCreating = "CREATING" + + // FileSystemLifecycleFailed is a FileSystemLifecycle enum value + FileSystemLifecycleFailed = "FAILED" + + // FileSystemLifecycleDeleting is a FileSystemLifecycle enum value + FileSystemLifecycleDeleting = "DELETING" + + // FileSystemLifecycleMisconfigured is a FileSystemLifecycle enum value + FileSystemLifecycleMisconfigured = "MISCONFIGURED" + + // FileSystemLifecycleUpdating is a FileSystemLifecycle enum value + FileSystemLifecycleUpdating = "UPDATING" +) + +// An enumeration specifying the currently ongoing maintenance operation. +const ( + // FileSystemMaintenanceOperationPatching is a FileSystemMaintenanceOperation enum value + FileSystemMaintenanceOperationPatching = "PATCHING" + + // FileSystemMaintenanceOperationBackingUp is a FileSystemMaintenanceOperation enum value + FileSystemMaintenanceOperationBackingUp = "BACKING_UP" +) + +// The type of file system. +const ( + // FileSystemTypeWindows is a FileSystemType enum value + FileSystemTypeWindows = "WINDOWS" + + // FileSystemTypeLustre is a FileSystemType enum value + FileSystemTypeLustre = "LUSTRE" +) + +// The name for a filter. +const ( + // FilterNameFileSystemId is a FilterName enum value + FilterNameFileSystemId = "file-system-id" + + // FilterNameBackupType is a FilterName enum value + FilterNameBackupType = "backup-type" +) + +const ( + // ReportFormatReportCsv20191124 is a ReportFormat enum value + ReportFormatReportCsv20191124 = "REPORT_CSV_20191124" +) + +const ( + // ReportScopeFailedFilesOnly is a ReportScope enum value + ReportScopeFailedFilesOnly = "FAILED_FILES_ONLY" +) + +// The types of limits on your service utilization. Limits include file system +// count, total throughput capacity, total storage, and total user-initiated +// backups. These limits apply for a specific account in a specific AWS Region. +// You can increase some of them by contacting AWS Support. +const ( + // ServiceLimitFileSystemCount is a ServiceLimit enum value + ServiceLimitFileSystemCount = "FILE_SYSTEM_COUNT" + + // ServiceLimitTotalThroughputCapacity is a ServiceLimit enum value + ServiceLimitTotalThroughputCapacity = "TOTAL_THROUGHPUT_CAPACITY" + + // ServiceLimitTotalStorage is a ServiceLimit enum value + ServiceLimitTotalStorage = "TOTAL_STORAGE" + + // ServiceLimitTotalUserInitiatedBackups is a ServiceLimit enum value + ServiceLimitTotalUserInitiatedBackups = "TOTAL_USER_INITIATED_BACKUPS" +) + +const ( + // WindowsDeploymentTypeMultiAz1 is a WindowsDeploymentType enum value + WindowsDeploymentTypeMultiAz1 = "MULTI_AZ_1" + + // WindowsDeploymentTypeSingleAz1 is a WindowsDeploymentType enum value + WindowsDeploymentTypeSingleAz1 = "SINGLE_AZ_1" +) diff --git a/agent/vendor/github.com/aws/aws-sdk-go/service/fsx/doc.go b/agent/vendor/github.com/aws/aws-sdk-go/service/fsx/doc.go new file mode 100644 index 00000000000..0c23c396c48 --- /dev/null +++ b/agent/vendor/github.com/aws/aws-sdk-go/service/fsx/doc.go @@ -0,0 +1,29 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +// Package fsx provides the client and types for making API +// requests to Amazon FSx. +// +// Amazon FSx is a fully managed service that makes it easy for storage and +// application administrators to launch and use shared file storage. +// +// See https://docs.aws.amazon.com/goto/WebAPI/fsx-2018-03-01 for more information on this service. +// +// See fsx package documentation for more information. +// https://docs.aws.amazon.com/sdk-for-go/api/service/fsx/ +// +// Using the Client +// +// To contact Amazon FSx with the SDK use the New function to create +// a new service client. With that client you can make API requests to the service. +// These clients are safe to use concurrently. +// +// See the SDK's documentation for more information on how to use the SDK. +// https://docs.aws.amazon.com/sdk-for-go/api/ +// +// See aws.Config documentation for more information on configuring SDK clients. +// https://docs.aws.amazon.com/sdk-for-go/api/aws/#Config +// +// See the Amazon FSx client FSx for more +// information on creating client for this service. +// https://docs.aws.amazon.com/sdk-for-go/api/service/fsx/#New +package fsx diff --git a/agent/vendor/github.com/aws/aws-sdk-go/service/fsx/errors.go b/agent/vendor/github.com/aws/aws-sdk-go/service/fsx/errors.go new file mode 100644 index 00000000000..8b7c8f6aefc --- /dev/null +++ b/agent/vendor/github.com/aws/aws-sdk-go/service/fsx/errors.go @@ -0,0 +1,138 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +package fsx + +const ( + + // ErrCodeActiveDirectoryError for service response error code + // "ActiveDirectoryError". + // + // An Active Directory error. + ErrCodeActiveDirectoryError = "ActiveDirectoryError" + + // ErrCodeBackupInProgress for service response error code + // "BackupInProgress". + // + // Another backup is already under way. Wait for completion before initiating + // additional backups of this file system. + ErrCodeBackupInProgress = "BackupInProgress" + + // ErrCodeBackupNotFound for service response error code + // "BackupNotFound". + // + // No Amazon FSx backups were found based upon the supplied parameters. + ErrCodeBackupNotFound = "BackupNotFound" + + // ErrCodeBackupRestoring for service response error code + // "BackupRestoring". + // + // You can't delete a backup while it's being used to restore a file system. + ErrCodeBackupRestoring = "BackupRestoring" + + // ErrCodeBadRequest for service response error code + // "BadRequest". + // + // A generic error indicating a failure with a client request. + ErrCodeBadRequest = "BadRequest" + + // ErrCodeDataRepositoryTaskEnded for service response error code + // "DataRepositoryTaskEnded". + // + // The data repository task could not be canceled because the task has already + // ended. + ErrCodeDataRepositoryTaskEnded = "DataRepositoryTaskEnded" + + // ErrCodeDataRepositoryTaskExecuting for service response error code + // "DataRepositoryTaskExecuting". + // + // An existing data repository task is currently executing on the file system. + // Wait until the existing task has completed, then create the new task. + ErrCodeDataRepositoryTaskExecuting = "DataRepositoryTaskExecuting" + + // ErrCodeDataRepositoryTaskNotFound for service response error code + // "DataRepositoryTaskNotFound". + // + // The data repository task or tasks you specified could not be found. + ErrCodeDataRepositoryTaskNotFound = "DataRepositoryTaskNotFound" + + // ErrCodeFileSystemNotFound for service response error code + // "FileSystemNotFound". + // + // No Amazon FSx file systems were found based upon supplied parameters. + ErrCodeFileSystemNotFound = "FileSystemNotFound" + + // ErrCodeIncompatibleParameterError for service response error code + // "IncompatibleParameterError". + // + // The error returned when a second request is received with the same client + // request token but different parameters settings. A client request token should + // always uniquely identify a single request. + ErrCodeIncompatibleParameterError = "IncompatibleParameterError" + + // ErrCodeInternalServerError for service response error code + // "InternalServerError". + // + // A generic error indicating a server-side failure. + ErrCodeInternalServerError = "InternalServerError" + + // ErrCodeInvalidExportPath for service response error code + // "InvalidExportPath". + // + // The path provided for data repository export isn't valid. + ErrCodeInvalidExportPath = "InvalidExportPath" + + // ErrCodeInvalidImportPath for service response error code + // "InvalidImportPath". + // + // The path provided for data repository import isn't valid. + ErrCodeInvalidImportPath = "InvalidImportPath" + + // ErrCodeInvalidNetworkSettings for service response error code + // "InvalidNetworkSettings". + // + // One or more network settings specified in the request are invalid. InvalidVpcId + // means that the ID passed for the virtual private cloud (VPC) is invalid. + // InvalidSubnetIds returns the list of IDs for subnets that are either invalid + // or not part of the VPC specified. InvalidSecurityGroupIds returns the list + // of IDs for security groups that are either invalid or not part of the VPC + // specified. + ErrCodeInvalidNetworkSettings = "InvalidNetworkSettings" + + // ErrCodeMissingFileSystemConfiguration for service response error code + // "MissingFileSystemConfiguration". + // + // File system configuration is required for this operation. + ErrCodeMissingFileSystemConfiguration = "MissingFileSystemConfiguration" + + // ErrCodeNotServiceResourceError for service response error code + // "NotServiceResourceError". + // + // The resource specified for the tagging operation is not a resource type owned + // by Amazon FSx. Use the API of the relevant service to perform the operation. + ErrCodeNotServiceResourceError = "NotServiceResourceError" + + // ErrCodeResourceDoesNotSupportTagging for service response error code + // "ResourceDoesNotSupportTagging". + // + // The resource specified does not support tagging. + ErrCodeResourceDoesNotSupportTagging = "ResourceDoesNotSupportTagging" + + // ErrCodeResourceNotFound for service response error code + // "ResourceNotFound". + // + // The resource specified by the Amazon Resource Name (ARN) can't be found. + ErrCodeResourceNotFound = "ResourceNotFound" + + // ErrCodeServiceLimitExceeded for service response error code + // "ServiceLimitExceeded". + // + // An error indicating that a particular service limit was exceeded. You can + // increase some service limits by contacting AWS Support. + ErrCodeServiceLimitExceeded = "ServiceLimitExceeded" + + // ErrCodeUnsupportedOperation for service response error code + // "UnsupportedOperation". + // + // The requested operation is not supported for this resource or API. + ErrCodeUnsupportedOperation = "UnsupportedOperation" +) diff --git a/agent/vendor/github.com/aws/aws-sdk-go/service/fsx/service.go b/agent/vendor/github.com/aws/aws-sdk-go/service/fsx/service.go new file mode 100644 index 00000000000..e58b9160817 --- /dev/null +++ b/agent/vendor/github.com/aws/aws-sdk-go/service/fsx/service.go @@ -0,0 +1,100 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +package fsx + +import ( + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/client" + "github.com/aws/aws-sdk-go/aws/client/metadata" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/aws/signer/v4" + "github.com/aws/aws-sdk-go/private/protocol/jsonrpc" +) + +// FSx provides the API operation methods for making requests to +// Amazon FSx. See this package's package overview docs +// for details on the service. +// +// FSx methods are safe to use concurrently. It is not safe to +// modify mutate any of the struct's properties though. +type FSx struct { + *client.Client +} + +// Used for custom client initialization logic +var initClient func(*client.Client) + +// Used for custom request initialization logic +var initRequest func(*request.Request) + +// Service information constants +const ( + ServiceName = "FSx" // Name of service. + EndpointsID = "fsx" // ID to lookup a service endpoint with. + ServiceID = "FSx" // ServiceID is a unique identifier of a specific service. +) + +// New creates a new instance of the FSx client with a session. +// If additional configuration is needed for the client instance use the optional +// aws.Config parameter to add your extra config. +// +// Example: +// mySession := session.Must(session.NewSession()) +// +// // Create a FSx client from just a session. +// svc := fsx.New(mySession) +// +// // Create a FSx client with additional configuration +// svc := fsx.New(mySession, aws.NewConfig().WithRegion("us-west-2")) +func New(p client.ConfigProvider, cfgs ...*aws.Config) *FSx { + c := p.ClientConfig(EndpointsID, cfgs...) + return newClient(*c.Config, c.Handlers, c.PartitionID, c.Endpoint, c.SigningRegion, c.SigningName) +} + +// newClient creates, initializes and returns a new service client instance. +func newClient(cfg aws.Config, handlers request.Handlers, partitionID, endpoint, signingRegion, signingName string) *FSx { + svc := &FSx{ + Client: client.New( + cfg, + metadata.ClientInfo{ + ServiceName: ServiceName, + ServiceID: ServiceID, + SigningName: signingName, + SigningRegion: signingRegion, + PartitionID: partitionID, + Endpoint: endpoint, + APIVersion: "2018-03-01", + JSONVersion: "1.1", + TargetPrefix: "AWSSimbaAPIService_v20180301", + }, + handlers, + ), + } + + // Handlers + svc.Handlers.Sign.PushBackNamed(v4.SignRequestHandler) + svc.Handlers.Build.PushBackNamed(jsonrpc.BuildHandler) + svc.Handlers.Unmarshal.PushBackNamed(jsonrpc.UnmarshalHandler) + svc.Handlers.UnmarshalMeta.PushBackNamed(jsonrpc.UnmarshalMetaHandler) + svc.Handlers.UnmarshalError.PushBackNamed(jsonrpc.UnmarshalErrorHandler) + + // Run custom client initialization if present + if initClient != nil { + initClient(svc.Client) + } + + return svc +} + +// newRequest creates a new request for a FSx operation and runs any +// custom request initialization. +func (c *FSx) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) + + // Run custom request initialization if present + if initRequest != nil { + initRequest(req) + } + + return req +}