github.com/webdestroya/awsmocker@v0.2.6/imds_mocks.go (about) 1 package awsmocker 2 3 import ( 4 "fmt" 5 "net/http" 6 "time" 7 8 "github.com/aws/aws-sdk-go-v2/feature/ec2/imds" 9 ) 10 11 // Override the default settings when using a default IMDS mock 12 type IMDSMockOptions struct { 13 // The identity document to return 14 IdentityDocument imds.InstanceIdentityDocument 15 16 // any custom user data 17 UserData string 18 19 // if you want to override the role name that is used for EC2 creds 20 RoleName string 21 22 // Override the instance profile name 23 InstanceProfileName string 24 } 25 26 func getDefaultImdsIdentityDocument() imds.InstanceIdentityDocument { 27 return imds.InstanceIdentityDocument{ 28 Version: "2017-09-30", 29 InstanceID: "i-000deadbeef", 30 AccountID: DefaultAccountId, 31 Region: DefaultRegion, 32 AvailabilityZone: DefaultRegion + "a", 33 InstanceType: "t3.medium", 34 } 35 } 36 37 // Provides an array of mocks that will provide a decent replication of the 38 // EC2 Instance Metadata Service 39 func Mock_IMDS_Common(optFns ...func(*IMDSMockOptions)) []*MockedEndpoint { 40 41 cfg := IMDSMockOptions{ 42 IdentityDocument: getDefaultImdsIdentityDocument(), 43 UserData: "# awsmocker", 44 RoleName: "awsmocker_role", 45 InstanceProfileName: "awsmocker-instance-profile", 46 } 47 48 for _, f := range optFns { 49 f(&cfg) 50 } 51 52 mocks := make([]*MockedEndpoint, 0, 10) 53 54 mocks = append(mocks, Mock_IMDS_IdentityDocument(func(iid *imds.InstanceIdentityDocument) { 55 *iid = cfg.IdentityDocument 56 })) 57 58 for k, v := range map[string]string{ 59 "instance-id": cfg.IdentityDocument.InstanceID, 60 "instance-type": cfg.IdentityDocument.InstanceType, 61 "instance-life-cycle": "on-demand", 62 } { 63 mocks = append(mocks, Mock_IMDS_MetaData_KeyValue(k, v)) 64 } 65 66 mocks = append(mocks, Mock_IMDS_UserData(cfg.UserData)) 67 mocks = append(mocks, Mock_IMDS_IAM_Info(cfg.InstanceProfileName)) 68 mocks = append(mocks, Mock_IMDS_IAM_RoleList(cfg.RoleName)) 69 mocks = append(mocks, Mock_IMDS_IAM_Credentials(cfg.RoleName)) 70 mocks = append(mocks, Mock_IMDS_API_Token()) 71 72 return mocks 73 } 74 75 // Provide a document to be returned, or nil to use a default one 76 func Mock_IMDS_IdentityDocument(optFns ...func(*imds.InstanceIdentityDocument)) *MockedEndpoint { 77 doc := getDefaultImdsIdentityDocument() 78 79 for _, f := range optFns { 80 f(&doc) 81 } 82 83 return &MockedEndpoint{ 84 Request: &MockedRequest{ 85 Method: http.MethodGet, 86 Path: "/latest/dynamic/instance-identity/document", 87 IsEc2IMDS: true, 88 }, 89 Response: &MockedResponse{ 90 Encoding: ResponseEncodingJSON, 91 Body: doc, 92 }, 93 } 94 } 95 96 func Mock_IMDS_MetaData_KeyValue(k, v string) *MockedEndpoint { 97 return &MockedEndpoint{ 98 Request: &MockedRequest{ 99 Method: http.MethodGet, 100 Path: "/latest/meta-data/" + k, 101 IsEc2IMDS: true, 102 }, 103 Response: &MockedResponse{ 104 Encoding: ResponseEncodingText, 105 Body: v, 106 }, 107 } 108 } 109 110 func Mock_IMDS_UserData(userData string) *MockedEndpoint { 111 return &MockedEndpoint{ 112 Request: &MockedRequest{ 113 Method: http.MethodGet, 114 Path: "/latest/user-data", 115 IsEc2IMDS: true, 116 }, 117 Response: &MockedResponse{ 118 Encoding: ResponseEncodingText, 119 Body: userData, 120 }, 121 } 122 } 123 124 func Mock_IMDS_API_Token() *MockedEndpoint { 125 return &MockedEndpoint{ 126 Request: &MockedRequest{ 127 Path: "/latest/api/token", 128 IsEc2IMDS: true, 129 }, 130 Response: &MockedResponse{ 131 Encoding: ResponseEncodingText, 132 Body: "AwsMockerImdsToken", 133 }, 134 } 135 } 136 137 func Mock_IMDS_IAM_Info(profileName string) *MockedEndpoint { 138 return &MockedEndpoint{ 139 Request: &MockedRequest{ 140 Method: http.MethodGet, 141 Path: "/latest/meta-data/iam/info", 142 IsEc2IMDS: true, 143 }, 144 Response: &MockedResponse{ 145 Encoding: ResponseEncodingJSON, 146 Body: map[string]interface{}{ 147 "Code": "Success", 148 "LastUpdated": time.Now().UTC().Format(time.RFC3339), 149 "InstanceProfileArn": fmt.Sprintf("arn:aws:iam::%s:instance-profile/%s", DefaultAccountId, profileName), 150 "InstanceProfileId": "AIPAABCDEFGHIJKLMN123", 151 }, 152 }, 153 } 154 } 155 156 func Mock_IMDS_IAM_RoleList(roleName string) *MockedEndpoint { 157 return &MockedEndpoint{ 158 Request: &MockedRequest{ 159 Method: http.MethodGet, 160 Path: "/latest/meta-data/iam/security-credentials/", 161 IsEc2IMDS: true, 162 }, 163 Response: &MockedResponse{ 164 Encoding: ResponseEncodingText, 165 Body: roleName, 166 }, 167 } 168 } 169 170 func Mock_IMDS_IAM_Credentials(roleName string) *MockedEndpoint { 171 return &MockedEndpoint{ 172 Request: &MockedRequest{ 173 Method: http.MethodGet, 174 Path: "/latest/meta-data/iam/security-credentials/" + roleName, 175 }, 176 Response: &MockedResponse{ 177 Encoding: ResponseEncodingJSON, 178 Body: map[string]interface{}{ 179 "Code": "Success", 180 "Type": "AWS-HMAC", 181 "LastUpdated": time.Now().UTC().Format(time.RFC3339), 182 "Expiration": time.Now().UTC().Add(1 * time.Hour).Format(time.RFC3339), 183 "AccessKeyID": "FAKEKEY", 184 "SecretAccessKey": "fakeSecretKEY", 185 "Token": "FAKETOKEN", 186 }, 187 }, 188 } 189 }