From e1d1edec7daadffcaf40a990c2b8851f13a0f64b Mon Sep 17 00:00:00 2001 From: ppapishe <46689524+ppapishe@users.noreply.github.com> Date: Tue, 1 Feb 2022 10:06:45 -0800 Subject: [PATCH] (MINOR) Add new AWS IAM Role method ## ADDS * Added the `AssertIAMRoleMaxSessionDuration method to assert the MaxDurationSession attribute value for a given AWS IAM Role. --- Makefile | 2 ++ go.mod | 4 +-- go.sum | 9 ++++-- mock/iam.go | 56 ++++++++++++++++++++++++++++++++++++ pkg/aws/iam.go | 33 ++++++++++++++++++++++ pkg/aws/iam_test.go | 69 +++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 169 insertions(+), 4 deletions(-) create mode 100644 mock/iam.go diff --git a/Makefile b/Makefile index 031e544..a49bc48 100644 --- a/Makefile +++ b/Makefile @@ -29,9 +29,11 @@ tools: mock: tools mockgen -source pkg/aws/dax.go -destination mock/dax.go -package mock mockgen -source pkg/aws/ec2.go -destination mock/ec2.go -package mock + mockgen -source pkg/aws/iam.go -destination mock/iam.go -package mock mockgen -source pkg/aws/eks.go -destination mock/eks.go -package mock mockgen -source pkg/k8s/jobs.go -destination mock/k8s_jobs.go -package mock mockgen -source pkg/k8s/util.go -destination mock/k8s_util.go -package mock + .PHONY: mock .PHONY: k8s-integration-test diff --git a/go.mod b/go.mod index dd9e721..162e2d8 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ module github.com/hbocodelabs/infratest go 1.17 require ( + github.com/aws/aws-sdk-go v1.42.43 // indirect github.com/aws/aws-sdk-go-v2/service/dax v1.6.0 github.com/aws/aws-sdk-go-v2/service/ec2 v1.12.0 github.com/aws/aws-sdk-go-v2/service/eks v1.18.0 @@ -25,7 +26,6 @@ require ( cloud.google.com/go v0.83.0 // indirect github.com/BurntSushi/toml v0.3.1 // indirect github.com/alessio/shellescape v1.4.1 // indirect - github.com/aws/aws-sdk-go v1.40.56 // indirect github.com/aws/aws-sdk-go-v2 v1.13.0 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.4 // indirect github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.2.0 // indirect @@ -69,7 +69,7 @@ require ( github.com/urfave/cli v1.22.2 // indirect golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect golang.org/x/mod v0.4.2 // indirect - golang.org/x/net v0.0.0-20211209124913-491a49abca63 // indirect + golang.org/x/net v0.0.0-20211216030914-fe4d6282115f // indirect golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f // indirect golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e // indirect golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b // indirect diff --git a/go.sum b/go.sum index 59eda91..dfe9604 100644 --- a/go.sum +++ b/go.sum @@ -120,8 +120,9 @@ github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQ github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= github.com/aws/aws-sdk-go v1.15.78/go.mod h1:E3/ieXAlvM0XWO57iftYVDLLvQ824smPP3ATZkfNZeM= github.com/aws/aws-sdk-go v1.37.1/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= -github.com/aws/aws-sdk-go v1.40.56 h1:FM2yjR0UUYFzDTMx+mH9Vyw1k1EUUxsAFzk+BjkzANA= github.com/aws/aws-sdk-go v1.40.56/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q= +github.com/aws/aws-sdk-go v1.42.43 h1:rLcxH9YgI3zN7TnjBn1Z6V62GPjOEW1IQd0m11Y/nXE= +github.com/aws/aws-sdk-go v1.42.43/go.mod h1:OGr6lGMAKGlG9CVrYnWYDKIyb829c6EVBRjxqjmPepc= github.com/aws/aws-sdk-go-v2 v1.7.1/go.mod h1:L5LuPC1ZgDr2xQS7AmIec/Jlc7O/Y1u2KxJyNVab250= github.com/aws/aws-sdk-go-v2 v1.10.0/go.mod h1:U/EyyVvKtzmFeQQcca7eBotKdlpcP2zzU6bXBYcf7CE= github.com/aws/aws-sdk-go-v2 v1.11.0/go.mod h1:SQfA+m2ltnu1cA0soUkj4dRSsmITiVQUJvBIZjzfPyQ= @@ -725,6 +726,7 @@ github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -1020,8 +1022,9 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211209124913-491a49abca63 h1:iocB37TsdFuN6IBRZ+ry36wrkoV51/tl5vOWqkcPGvY= golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211216030914-fe4d6282115f h1:hEYJvxw1lSnWIl8X9ofsYMklzaDs90JI2az5YMd4fPM= +golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1135,6 +1138,7 @@ golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1153,6 +1157,7 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/mock/iam.go b/mock/iam.go new file mode 100644 index 0000000..cc8b262 --- /dev/null +++ b/mock/iam.go @@ -0,0 +1,56 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: pkg/aws/iam.go + +// Package mock is a generated GoMock package. +package mock + +import ( + context "context" + reflect "reflect" + + iam "github.com/aws/aws-sdk-go-v2/service/iam" + gomock "github.com/golang/mock/gomock" +) + +// MockIAMClient is a mock of IAMClient interface. +type MockIAMClient struct { + ctrl *gomock.Controller + recorder *MockIAMClientMockRecorder +} + +// MockIAMClientMockRecorder is the mock recorder for MockIAMClient. +type MockIAMClientMockRecorder struct { + mock *MockIAMClient +} + +// NewMockIAMClient creates a new mock instance. +func NewMockIAMClient(ctrl *gomock.Controller) *MockIAMClient { + mock := &MockIAMClient{ctrl: ctrl} + mock.recorder = &MockIAMClientMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockIAMClient) EXPECT() *MockIAMClientMockRecorder { + return m.recorder +} + +// GetRole mocks base method. +func (m *MockIAMClient) GetRole(arg0 context.Context, arg1 *iam.GetRoleInput, arg2 ...func(*iam.Options)) (*iam.GetRoleOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetRole", varargs...) + ret0, _ := ret[0].(*iam.GetRoleOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetRole indicates an expected call of GetRole. +func (mr *MockIAMClientMockRecorder) GetRole(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRole", reflect.TypeOf((*MockIAMClient)(nil).GetRole), varargs...) +} diff --git a/pkg/aws/iam.go b/pkg/aws/iam.go index 182dbc8..8053e4f 100644 --- a/pkg/aws/iam.go +++ b/pkg/aws/iam.go @@ -8,11 +8,17 @@ import ( "reflect" "github.com/aws/aws-sdk-go-v2/service/iam" + "github.com/stretchr/testify/assert" "gopkg.in/square/go-jose.v2/json" "testing" ) +// IAMClient serves as a stub client interface for the AWS SDK [IAM client](https://pkg.go.dev/github.com/aws/aws-sdk-go/service/iam#hdr-Using_the_Client). +type IAMClient interface { + GetRole(context.Context, *iam.GetRoleInput, ...func(*iam.Options)) (*iam.GetRoleOutput, error) +} + type PolicyDocument struct { Version string Statement []StatementEntry @@ -190,3 +196,30 @@ func unMarshallPolicyDocument(document string) (*PolicyDocument, error) { } return &policyDocument, nil } + +// getIAMRole returns the role object struct that has attributes of a given role +func getIAMRole(ctx context.Context, client IAMClient, roleName string) (output *iam.GetRoleOutput, err error) { + input := &iam.GetRoleInput{ + RoleName: &roleName, + } + + output, err = client.GetRole(ctx, input) + if err != nil { + return + } + + return +} + +// Asserts the MaxSessionDuration attribute of a given IAM Role +func AssertIAMRoleMaxSessionDuration(t *testing.T, ctx context.Context, client IAMClient, roleName string, maxDuration int32) { + output, err := getIAMRole(ctx, client, roleName) + if err != nil { + t.Error(err) + + return + } + + assert.Equal(t, *output.Role.MaxSessionDuration, maxDuration, "Role %s Has an incorrect max session duration value", roleName) + +} diff --git a/pkg/aws/iam_test.go b/pkg/aws/iam_test.go index 842c3a4..ddfac9b 100644 --- a/pkg/aws/iam_test.go +++ b/pkg/aws/iam_test.go @@ -3,10 +3,16 @@ package aws import ( + "context" "encoding/json" "net/url" "testing" + "github.com/aws/aws-sdk-go-v2/service/iam" + "github.com/aws/aws-sdk-go-v2/service/iam/types" + gomock "github.com/golang/mock/gomock" + "github.com/hbocodelabs/infratest/mock" + "github.com/stretchr/testify/assert" ) @@ -219,3 +225,66 @@ func TestUnMarshallPolicyDocument_DecodeJson(t *testing.T) { } assert.Equal(t, policyDocument, *policyDocumentResult) } + +func TestAssertIamRoleComponent_MaxDuration_Success(t *testing.T) { + fakeTest := &testing.T{} + + ctrl := gomock.NewController(t) + client := mock.NewMockIAMClient(ctrl) + + var roleMaxDuration int32 = 5200 + roleName := "testIam" + input := &iam.GetRoleInput{ + RoleName: &roleName, + } + + role := types.Role{ + RoleName: &roleName, + MaxSessionDuration: &roleMaxDuration, + } + output := &iam.GetRoleOutput{ + Role: &role, + } + ctx := context.Background() + client.EXPECT(). + GetRole(ctx, input). + Times(1). + Return(output, nil) + + AssertIAMRoleMaxSessionDuration(fakeTest, ctx, client, roleName, roleMaxDuration) + ctrl.Finish() + assert.False(t, fakeTest.Failed()) + +} + +func TestAssertIamRoleComponent_MaxDuration_Fail(t *testing.T) { + fakeTest := &testing.T{} + + ctrl := gomock.NewController(t) + client := mock.NewMockIAMClient(ctrl) + + var actualRoleMaxDuration int32 = 5200 + var expectedRoleMaxDuration int32 = 2000 + roleName := "testIam" + input := &iam.GetRoleInput{ + RoleName: &roleName, + } + + role := types.Role{ + RoleName: &roleName, + MaxSessionDuration: &actualRoleMaxDuration, + } + output := &iam.GetRoleOutput{ + Role: &role, + } + ctx := context.Background() + client.EXPECT(). + GetRole(ctx, input). + Times(1). + Return(output, nil) + + AssertIAMRoleMaxSessionDuration(fakeTest, ctx, client, roleName, expectedRoleMaxDuration) + ctrl.Finish() + assert.True(t, fakeTest.Failed()) + +}