// Copyright 2015-2018 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 regcredio import ( "io/ioutil" "os" "testing" "github.com/stretchr/testify/assert" ) func TestReadCredsInput(t *testing.T) { credsInputString := `version: 1 registry_credentials: registry.io: username: some_user_name password: myl337p4$$w0rd!<bz* kms_key_id: aws:arn:kms:key/iuytre-jhgfd container_names: - nginx-custom - logging other-registry.net: secrets_manager_arn: aws:arn:secretsmanager:secret/repocreds-776ytg container_names: - metrics` tmpfile, err := ioutil.TempFile("", "test") assert.NoError(t, err, "Unexpected error in creating test file") defer os.Remove(tmpfile.Name()) _, err = tmpfile.Write([]byte(credsInputString)) assert.NoError(t, err, "Unexpected error writing file") err = tmpfile.Close() assert.NoError(t, err, "Unexpected error closing file") credsResult, err := ReadCredsInput(tmpfile.Name()) assert.NoError(t, err, "Unexpected error reading file") // assert expected values match assert.Equal(t, "1", credsResult.Version) assert.Equal(t, 2, len(credsResult.RegistryCredentials)) firstRegResult := credsResult.RegistryCredentials["registry.io"] assert.NotEmpty(t, firstRegResult) assert.Equal(t, "some_user_name", firstRegResult.Username) assert.Equal(t, "myl337p4$$w0rd!<bz*", firstRegResult.Password) assert.Equal(t, "aws:arn:kms:key/iuytre-jhgfd", firstRegResult.KmsKeyID) assert.Equal(t, 2, len(firstRegResult.ContainerNames)) otherRegResult := credsResult.RegistryCredentials["other-registry.net"] assert.NotEmpty(t, otherRegResult) assert.Equal(t, "aws:arn:secretsmanager:secret/repocreds-776ytg", otherRegResult.SecretManagerARN) assert.Equal(t, 1, len(otherRegResult.ContainerNames)) } func TestReadCredsInputWithEnvVarsFromShell(t *testing.T) { // setup test env vars secretEnvKey := "MY_SECRET_ARN" secretEnvVal := "aws:arn:secretmanager:secret/regsecret-1" usrnameEnvKey := "MY_REG_USRNAME" usrnameEnvVal := "myname@example.net" passwrdEnvKey := "MY_REG_PASSWORD" passwrdEnvVal := "ne4t04905e867uyrdtoilfgkj" kmsEnvKey := "MY_KEY_ARN" kmsEnvVal := "aws:arn:kms:key/iuytre-yhe4" os.Setenv(usrnameEnvKey, usrnameEnvVal) os.Setenv(passwrdEnvKey, passwrdEnvVal) os.Setenv(kmsEnvKey, kmsEnvVal) os.Setenv(secretEnvKey, secretEnvVal) defer func() { os.Unsetenv(usrnameEnvKey) os.Unsetenv(passwrdEnvKey) os.Unsetenv(kmsEnvKey) os.Unsetenv(secretEnvKey) }() inputFileString := `version: 1 registry_credentials: myrepo.someregistry.io: secrets_manager_arn: ${MY_SECRET_ARN} username: ${MY_REG_USRNAME} password: ${MY_REG_PASSWORD} kms_key_id: ${MY_KEY_ARN} container_names: - test` tmpfile, err := ioutil.TempFile("", "test") assert.NoError(t, err, "Unexpected error in creating test file") defer os.Remove(tmpfile.Name()) _, err = tmpfile.Write([]byte(inputFileString)) assert.NoError(t, err, "Unexpected error writing file") err = tmpfile.Close() assert.NoError(t, err, "Unexpected error closing file") credsResult, err := ReadCredsInput(tmpfile.Name()) assert.NoError(t, err, "Unexpected error reading file") // assert expected values match assert.Equal(t, "1", credsResult.Version) assert.Equal(t, 1, len(credsResult.RegistryCredentials)) credEntry := credsResult.RegistryCredentials["myrepo.someregistry.io"] assert.NotEmpty(t, credEntry) assert.Equal(t, usrnameEnvVal, credEntry.Username) assert.Equal(t, passwrdEnvVal, credEntry.Password) assert.Equal(t, kmsEnvVal, credEntry.KmsKeyID) assert.Equal(t, secretEnvVal, credEntry.SecretManagerARN) assert.Equal(t, 1, len(credEntry.ContainerNames)) } func TestReadCredsInput_ErrorFileNotFound(t *testing.T) { var fakeFileName = "/missingFile" _, err := ReadCredsInput(fakeFileName) assert.Error(t, err, "Expected error on missing file") } func TestReadCredsInput_ErrorBadYaml(t *testing.T) { badCredEntryFileString := `version: 1 registry_credentials: myrepo.someregistry.io: secrets_manager_arn: arn:aws:secretmanager:some-secret container_names: - test` tmpfile, err := ioutil.TempFile("", "test") assert.NoError(t, err, "Unexpected error in creating test file") defer os.Remove(tmpfile.Name()) _, err = tmpfile.Write([]byte(badCredEntryFileString)) assert.NoError(t, err, "Unexpected error writing file") err = tmpfile.Close() assert.NoError(t, err, "Unexpected error closing file") _, err = ReadCredsInput(tmpfile.Name()) assert.Error(t, err, "Expected error on bad file YAML") } func TestReadCredsOutput(t *testing.T) { credsOutputString := `version: "1" registry_credential_outputs: task_execution_role: someTestRole container_credentials: my.example.registry.net: credentials_parameter: arn:aws:secretsmanager::secret:amazon-ecs-cli-setup-my.example.registry.net container_names: - web another.example.io: credentials_parameter: arn:aws:secretsmanager::secret:amazon-ecs-cli-setup-another.example.io kms_key_id: arn:aws:kms::key/some-key-57yrt container_names: - test` tmpfile, err := ioutil.TempFile("", "test") assert.NoError(t, err, "Unexpected error in creating test file") defer os.Remove(tmpfile.Name()) _, err = tmpfile.Write([]byte(credsOutputString)) assert.NoError(t, err, "Unexpected error writing file") err = tmpfile.Close() assert.NoError(t, err, "Unexpected error closing file") credsOutput, err := ReadCredsOutput(tmpfile.Name()) assert.NoError(t, err, "Unexpected error reading creds output file") // assert expected values match assert.Equal(t, "1", credsOutput.Version) assert.Equal(t, "someTestRole", credsOutput.CredentialResources.TaskExecutionRole) assert.Equal(t, 2, len(credsOutput.CredentialResources.ContainerCredentials)) firstOutputEntry := credsOutput.CredentialResources.ContainerCredentials["my.example.registry.net"] assert.NotEmpty(t, firstOutputEntry) assert.Equal(t, "arn:aws:secretsmanager::secret:amazon-ecs-cli-setup-my.example.registry.net", firstOutputEntry.CredentialARN) assert.Equal(t, "", firstOutputEntry.KMSKeyID) assert.ElementsMatch(t, []string{"web"}, firstOutputEntry.ContainerNames) secondOutputEntry := credsOutput.CredentialResources.ContainerCredentials["another.example.io"] assert.NotEmpty(t, secondOutputEntry) assert.Equal(t, "arn:aws:secretsmanager::secret:amazon-ecs-cli-setup-another.example.io", secondOutputEntry.CredentialARN) assert.Equal(t, "arn:aws:kms::key/some-key-57yrt", secondOutputEntry.KMSKeyID) assert.ElementsMatch(t, []string{"test"}, secondOutputEntry.ContainerNames) } func TestReadCredsOutput_ErrorOnBadYaml(t *testing.T) { badCredsOutputFileString := `version: 1 registry_credential_outputs: task_execution_role: someTestRole container_credentials: myrepo.someregistry.io: credentials_parameter: arn:aws:secretmanager:some-secret container_names: - test` tmpfile, err := ioutil.TempFile("", "test") assert.NoError(t, err, "Unexpected error in creating test file") defer os.Remove(tmpfile.Name()) _, err = tmpfile.Write([]byte(badCredsOutputFileString)) assert.NoError(t, err, "Unexpected error writing file") err = tmpfile.Close() assert.NoError(t, err, "Unexpected error closing file") _, err = ReadCredsOutput(tmpfile.Name()) assert.Error(t, err, "Expected error on bad file YAML") } func TestReadCredsOutput_ErrorFileNotFound(t *testing.T) { var fakeFileName = "/missingFile" _, err := ReadCredsOutput(fakeFileName) assert.Error(t, err, "Expected error on missing file") } func TestFindLatestRegCredsOutputFile(t *testing.T) { testCases := []struct { description string inputFileNames []string expectedLatest string }{ {"Find latest of 3 valid output files", []string{"ecs-registry-creds_20171117T125102Z.yml", "ecs-registry-creds_20181012T215145Z.yml", "ecs-registry-creds_20181017T125102Z.yml"}, "ecs-registry-creds_20181017T125102Z.yml"}, {"Find latest valid file out of mixed valid/invalid output files", []string{"ecs-registry-creds_3.yml", "ecs-registry-creds_20181013T125105Z.yml"}, "ecs-registry-creds_20181013T125105Z.yml"}, {"Return no file if no valid file found", []string{"ecs-registry-creds_3.yml", "ecs-registry-creds_TEST.yml"}, ""}, {"Return no file if no files found", []string{}, ""}, } for _, test := range testCases { t.Run(test.description, func(t *testing.T) { // setup test dir & file testOutputDir, err := ioutil.TempDir("", "test") assert.NoError(t, err, "Unexpected error creating temp directory") defer os.RemoveAll(testOutputDir) for _, fileName := range test.inputFileNames { err := ioutil.WriteFile(testOutputDir+string(os.PathSeparator)+fileName, []byte("creds go here"), os.ModeTemporary) assert.NoError(t, err, "Unexpected error creating test file") } expectedLatestFile := "" if test.expectedLatest != "" { expectedLatestFile = testOutputDir + string(os.PathSeparator) + test.expectedLatest } actualLatestFile, err := FindLatestRegCredsOutputFile(testOutputDir) assert.NoError(t, err, "Unexpected error finding latest creds file") assert.Equal(t, expectedLatestFile, actualLatestFile) }) } }