1package awsat 2 3import ( 4 "io/ioutil" 5 "os" 6 "path/filepath" 7 "testing" 8 9 "github.com/aws/aws-sdk-go/service/iam" 10 "github.com/wallix/awless/aws/config" 11 "github.com/wallix/awless/aws/spec" 12 "github.com/wallix/awless/cloud/properties" 13 "github.com/wallix/awless/graph" 14 "github.com/wallix/awless/graph/resourcetest" 15) 16 17func TestAccesskey(t *testing.T) { 18 t.Run("create", func(t *testing.T) { 19 defer redirectStdErrToDevNull()() 20 21 t.Run("no-prompt", func(t *testing.T) { 22 23 Template("create accesskey user=jdoe no-prompt=true"). 24 Mock(&iamMock{ 25 CreateAccessKeyFunc: func(*iam.CreateAccessKeyInput) (*iam.CreateAccessKeyOutput, error) { 26 return &iam.CreateAccessKeyOutput{AccessKey: &iam.AccessKey{AccessKeyId: String("new-keypair-id")}}, nil 27 }, 28 }).ExpectInput("CreateAccessKey", &iam.CreateAccessKeyInput{UserName: String("jdoe")}). 29 ExpectCommandResult("new-keypair-id").ExpectCalls("CreateAccessKey").Run(t) 30 }) 31 32 t.Run("save credentials", func(t *testing.T) { 33 awsFolder, err := ioutil.TempDir("", "") 34 if err != nil { 35 t.Fatal(err) 36 } 37 defer os.RemoveAll(awsFolder) 38 awsconfig.AWSHomeDir = func() string { 39 return awsFolder 40 } 41 awsspec.AWSCredFilepath = filepath.Join(awsFolder, "credentials") 42 Template("create accesskey user=jdoe save=true"). 43 Mock(&iamMock{ 44 CreateAccessKeyFunc: func(*iam.CreateAccessKeyInput) (*iam.CreateAccessKeyOutput, error) { 45 return &iam.CreateAccessKeyOutput{AccessKey: &iam.AccessKey{AccessKeyId: String("0123456EXAMPLE0123456EXAMPLE"), SecretAccessKey: String("MYSECRETKEYMYSECRETKEYMYSECRETKEYMYSECRETKEY")}}, nil 46 }, 47 }).ExpectInput("CreateAccessKey", &iam.CreateAccessKeyInput{UserName: String("jdoe")}). 48 ExpectCommandResult("0123456EXAMPLE0123456EXAMPLE").ExpectCalls("CreateAccessKey").Run(t) 49 cred, err := ioutil.ReadFile(awsspec.AWSCredFilepath) 50 if err != nil { 51 t.Fatal(err) 52 } 53 expected := ` 54[jdoe] 55aws_access_key_id = 0123456EXAMPLE0123456EXAMPLE 56aws_secret_access_key = MYSECRETKEYMYSECRETKEYMYSECRETKEYMYSECRETKEY 57` 58 if got, want := string(cred), expected; got != want { 59 t.Fatalf("got %s, want %s", got, want) 60 } 61 }) 62 }) 63 64 t.Run("delete", func(t *testing.T) { 65 t.Run("with user", func(t *testing.T) { 66 Template("delete accesskey id=ACCESSKEYID user=jdoe"). 67 Mock(&iamMock{ 68 DeleteAccessKeyFunc: func(param0 *iam.DeleteAccessKeyInput) (*iam.DeleteAccessKeyOutput, error) { 69 return nil, nil 70 }, 71 }).ExpectInput("DeleteAccessKey", &iam.DeleteAccessKeyInput{ 72 UserName: String("jdoe"), 73 AccessKeyId: String("ACCESSKEYID"), 74 }).ExpectCalls("DeleteAccessKey").Run(t) 75 }) 76 t.Run("without user and id in local graph", func(t *testing.T) { 77 g := graph.NewGraph() 78 g.AddResource(resourcetest.AccessKey("ACCESSKEYID").Prop(properties.Username, "myusername").Build()) 79 g.AddResource(resourcetest.AccessKey("OTHERACCESSKEYID").Prop(properties.Username, "notthis").Build()) 80 Template("delete accesskey id=ACCESSKEYID"). 81 Mock(&iamMock{ 82 DeleteAccessKeyFunc: func(param0 *iam.DeleteAccessKeyInput) (*iam.DeleteAccessKeyOutput, error) { 83 return nil, nil 84 }, 85 }).Graph(g).ExpectInput("DeleteAccessKey", &iam.DeleteAccessKeyInput{ 86 UserName: String("myusername"), 87 AccessKeyId: String("ACCESSKEYID"), 88 }).ExpectCalls("DeleteAccessKey").Run(t) 89 }) 90 t.Run("without user and id not in local graph", func(t *testing.T) { 91 Template("delete accesskey id=ACCESSKEYID"). 92 Mock(&iamMock{ 93 DeleteAccessKeyFunc: func(param0 *iam.DeleteAccessKeyInput) (*iam.DeleteAccessKeyOutput, error) { 94 return nil, nil 95 }, 96 }).ExpectInput("DeleteAccessKey", &iam.DeleteAccessKeyInput{ 97 AccessKeyId: String("ACCESSKEYID"), 98 }).ExpectCalls("DeleteAccessKey").Run(t) 99 }) 100 t.Run("with user without id", func(t *testing.T) { 101 Template("delete accesskey user=myusername"). 102 Mock(&iamMock{ 103 DeleteAccessKeyFunc: func(param0 *iam.DeleteAccessKeyInput) (*iam.DeleteAccessKeyOutput, error) { 104 return nil, nil 105 }, 106 ListAccessKeysFunc: func(param0 *iam.ListAccessKeysInput) (*iam.ListAccessKeysOutput, error) { 107 return &iam.ListAccessKeysOutput{AccessKeyMetadata: []*iam.AccessKeyMetadata{{AccessKeyId: String("ACCESSKEYID")}}}, nil 108 }, 109 }).ExpectInput("DeleteAccessKey", &iam.DeleteAccessKeyInput{ 110 UserName: String("myusername"), 111 AccessKeyId: String("ACCESSKEYID"), 112 }).ExpectInput("ListAccessKeys", &iam.ListAccessKeysInput{ 113 UserName: String("myusername"), 114 }).ExpectCalls("ListAccessKeys", "DeleteAccessKey").Run(t) 115 }) 116 }) 117} 118 119func redirectStdErrToDevNull() func() { 120 originalStdErr := os.Stderr 121 toDefer := func() { 122 os.Stderr = originalStdErr 123 } 124 devNull, err := os.OpenFile(os.DevNull, os.O_RDWR, 0777) 125 if err != nil { 126 panic(err) 127 } 128 os.Stderr = devNull 129 return toDefer 130} 131