github.com/aavshr/aws-sdk-go@v1.41.3/service/s3control/endpoint_test.go (about) 1 //go:build go1.7 2 // +build go1.7 3 4 package s3control 5 6 import ( 7 "bytes" 8 "fmt" 9 "io/ioutil" 10 "net/http" 11 "strings" 12 "testing" 13 14 "github.com/aavshr/aws-sdk-go/aws" 15 "github.com/aavshr/aws-sdk-go/aws/endpoints" 16 "github.com/aavshr/aws-sdk-go/aws/request" 17 "github.com/aavshr/aws-sdk-go/awstesting/unit" 18 ) 19 20 type testParams struct { 21 bucket string 22 config *aws.Config 23 expectedEndpoint string 24 expectedSigningName string 25 expectedSigningRegion string 26 expectedHeaderForOutpostID string 27 expectedHeaderForAccountID bool 28 expectedErr string 29 } 30 31 // Test endpoint from outpost access point 32 func TestEndpoint_OutpostAccessPointARN(t *testing.T) { 33 cases := map[string]testParams{ 34 "Outpost AccessPoint with no S3UseARNRegion flag set": { 35 bucket: "arn:aws:s3-outposts:us-west-2:123456789012:outpost:op-01234567890123456:accesspoint:myaccesspoint", 36 config: &aws.Config{ 37 Region: aws.String("us-west-2"), 38 }, 39 expectedEndpoint: "https://s3-outposts.us-west-2.amazonaws.com", 40 expectedSigningName: "s3-outposts", 41 expectedSigningRegion: "us-west-2", 42 expectedHeaderForAccountID: true, 43 expectedHeaderForOutpostID: "op-01234567890123456", 44 }, 45 "Outpost AccessPoint Cross-Region Enabled": { 46 bucket: "arn:aws:s3-outposts:us-east-1:123456789012:outpost:op-01234567890123456:accesspoint:myaccesspoint", 47 config: &aws.Config{ 48 Region: aws.String("us-west-2"), 49 S3UseARNRegion: aws.Bool(true), 50 }, 51 expectedEndpoint: "https://s3-outposts.us-east-1.amazonaws.com", 52 expectedSigningName: "s3-outposts", 53 expectedSigningRegion: "us-east-1", 54 expectedHeaderForAccountID: true, 55 expectedHeaderForOutpostID: "op-01234567890123456", 56 }, 57 "Outpost AccessPoint Cross-Region Disabled": { 58 bucket: "arn:aws:s3-outposts:us-east-1:123456789012:outpost:op-01234567890123456:accesspoint:myaccesspoint", 59 config: &aws.Config{ 60 Region: aws.String("us-west-2"), 61 }, 62 expectedErr: "client region does not match provided ARN region", 63 }, 64 "Outpost AccessPoint other partition": { 65 bucket: "arn:aws-cn:s3-outposts:cn-north-1:123456789012:outpost:op-01234567890123456:accesspoint:myaccesspoint", 66 config: &aws.Config{ 67 Region: aws.String("us-west-2"), 68 S3UseARNRegion: aws.Bool(true), 69 }, 70 expectedErr: "ConfigurationError: client partition does not match provided ARN partition", 71 }, 72 "Outpost AccessPoint us-gov region": { 73 bucket: "arn:aws-us-gov:s3-outposts:us-gov-east-1:123456789012:outpost:op-01234567890123456:accesspoint:myaccesspoint", 74 config: &aws.Config{ 75 Region: aws.String("us-gov-east-1"), 76 S3UseARNRegion: aws.Bool(true), 77 }, 78 expectedEndpoint: "https://s3-outposts.us-gov-east-1.amazonaws.com", 79 expectedSigningName: "s3-outposts", 80 expectedSigningRegion: "us-gov-east-1", 81 expectedHeaderForAccountID: true, 82 expectedHeaderForOutpostID: "op-01234567890123456", 83 }, 84 "Outpost AccessPoint with client region as FIPS": { 85 bucket: "arn:aws-us-gov:s3-outposts:us-gov-east-1:123456789012:outpost:op-01234567890123456:accesspoint:myaccesspoint", 86 config: &aws.Config{ 87 EndpointResolver: endpoints.AwsUsGovPartition(), 88 Region: aws.String("us-gov-east-1-fips"), 89 }, 90 expectedErr: "use of ARN is not supported when client or request is configured for FIPS", 91 }, 92 "Outpost AccessPoint with client FIPS region and cross-region ARN": { 93 bucket: "arn:aws-us-gov:s3-outposts:us-gov-west-1:123456789012:outpost:op-01234567890123456:accesspoint:myaccesspoint", 94 config: &aws.Config{ 95 EndpointResolver: endpoints.AwsUsGovPartition(), 96 Region: aws.String("us-gov-east-1-fips"), 97 S3UseARNRegion: aws.Bool(true), 98 }, 99 expectedErr: "use of ARN is not supported when client or request is configured for FIPS", 100 }, 101 "Outpost AccessPoint FIPS client region with matching ARN region": { 102 bucket: "arn:aws-us-gov:s3-outposts:us-gov-east-1:123456789012:outpost:op-01234567890123456:accesspoint:myaccesspoint", 103 config: &aws.Config{ 104 EndpointResolver: endpoints.AwsUsGovPartition(), 105 Region: aws.String("fips-us-gov-east-1"), 106 S3UseARNRegion: aws.Bool(true), 107 }, 108 expectedErr: "use of ARN is not supported when client or request is configured for FIPS", 109 }, 110 "Outpost AccessPoint with DualStack": { 111 bucket: "arn:aws:s3-outposts:us-west-2:123456789012:outpost:op-01234567890123456:accesspoint:myaccesspoint", 112 config: &aws.Config{ 113 Region: aws.String("us-west-2"), 114 UseDualStack: aws.Bool(true), 115 }, 116 expectedErr: "ConfigurationError: client configured for S3 Dual-stack but is not supported with resource ARN", 117 }, 118 "Outpost AccessPoint with Accelerate": { 119 bucket: "arn:aws:s3-outposts:us-west-2:123456789012:outpost:op-01234567890123456:accesspoint:myaccesspoint", 120 config: &aws.Config{ 121 Region: aws.String("us-west-2"), 122 S3UseAccelerate: aws.Bool(true), 123 }, 124 expectedErr: "ConfigurationError: client configured for S3 Accelerate but is not supported with resource ARN", 125 }, 126 "Invalid outpost resource format": { 127 bucket: "arn:aws:s3-outposts:us-west-2:123456789012:outpost", 128 config: &aws.Config{ 129 Region: aws.String("us-west-2"), 130 }, 131 expectedErr: "outpost resource-id not set", 132 }, 133 "Missing access point for outpost resource": { 134 bucket: "arn:aws:s3-outposts:us-west-2:123456789012:outpost:op-01234567890123456", 135 config: &aws.Config{ 136 Region: aws.String("us-west-2"), 137 }, 138 expectedErr: "incomplete outpost resource type", 139 }, 140 "access point": { 141 bucket: "myaccesspoint", 142 config: &aws.Config{ 143 Region: aws.String("us-west-2"), 144 }, 145 expectedEndpoint: "https://123456789012.s3-control.us-west-2.amazonaws.com", 146 expectedHeaderForAccountID: true, 147 expectedSigningRegion: "us-west-2", 148 expectedSigningName: "s3", 149 }, 150 "outpost access point with unsupported sub-resource": { 151 bucket: "arn:aws:s3-outposts:us-west-2:123456789012:outpost:op-01234567890123456:accesspoint:mybucket:object:foo", 152 config: &aws.Config{ 153 Region: aws.String("us-west-2"), 154 }, 155 expectedErr: "sub resource not supported", 156 }, 157 "Missing outpost identifiers in outpost access point arn": { 158 bucket: "arn:aws:s3-outposts:us-west-2:123456789012:accesspoint:myendpoint", 159 config: &aws.Config{ 160 Region: aws.String("us-west-2"), 161 }, 162 expectedErr: "invalid Amazon s3-outposts ARN", 163 }, 164 "Invalid Outpost AccessPoint ARN with FIPS pseudo-region (prefix)": { 165 bucket: "arn:aws-us-gov:s3-outposts:fips-us-east-1:123456789012:outpost:op-01234567890123456:accesspoint:myaccesspoint", 166 config: &aws.Config{ 167 Region: aws.String("us-west-2"), 168 S3UseARNRegion: aws.Bool(true), 169 }, 170 expectedErr: "FIPS region not allowed in ARN", 171 }, 172 "Invalid Outpost AccessPoint ARN with FIPS pseudo-region (suffix)": { 173 bucket: "arn:aws-us-gov:s3-outposts:us-east-1-fips:123456789012:outpost:op-01234567890123456:accesspoint:myaccesspoint", 174 config: &aws.Config{ 175 Region: aws.String("us-west-2"), 176 S3UseARNRegion: aws.Bool(true), 177 }, 178 expectedErr: "FIPS region not allowed in ARN", 179 }, 180 } 181 182 runValidations(t, cases) 183 } 184 185 // Test endpoint from outpost bucket arn 186 func TestEndpoint_OutpostBucketARN(t *testing.T) { 187 cases := map[string]testParams{ 188 "Outpost Bucket with no S3UseARNRegion flag set": { 189 bucket: "arn:aws:s3-outposts:us-west-2:123456789012:outpost:op-01234567890123456:bucket:mybucket", 190 config: &aws.Config{ 191 Region: aws.String("us-west-2"), 192 }, 193 expectedEndpoint: "https://s3-outposts.us-west-2.amazonaws.com", 194 expectedSigningName: "s3-outposts", 195 expectedSigningRegion: "us-west-2", 196 expectedHeaderForOutpostID: "op-01234567890123456", 197 expectedHeaderForAccountID: true, 198 }, 199 "Outpost Bucket Cross-Region Enabled": { 200 bucket: "arn:aws:s3-outposts:us-east-1:123456789012:outpost:op-01234567890123456:bucket:mybucket", 201 config: &aws.Config{ 202 Region: aws.String("us-west-2"), 203 S3UseARNRegion: aws.Bool(true), 204 }, 205 expectedEndpoint: "https://s3-outposts.us-east-1.amazonaws.com", 206 expectedSigningName: "s3-outposts", 207 expectedSigningRegion: "us-east-1", 208 expectedHeaderForOutpostID: "op-01234567890123456", 209 expectedHeaderForAccountID: true, 210 }, 211 "Outpost Bucket Cross-Region Disabled": { 212 bucket: "arn:aws:s3-outposts:us-east-1:123456789012:outpost:op-01234567890123456:bucket:mybucket", 213 config: &aws.Config{ 214 Region: aws.String("us-west-2"), 215 }, 216 expectedErr: "client region does not match provided ARN region", 217 }, 218 "Outpost Bucket other partition": { 219 bucket: "arn:aws-cn:s3-outposts:cn-north-1:123456789012:outpost:op-01234567890123456:bucket:mybucket", 220 config: &aws.Config{ 221 Region: aws.String("us-west-2"), 222 S3UseARNRegion: aws.Bool(true), 223 }, 224 expectedErr: "ConfigurationError: client partition does not match provided ARN partition", 225 }, 226 "Outpost Bucket us-gov region": { 227 bucket: "arn:aws-us-gov:s3-outposts:us-gov-east-1:123456789012:outpost:op-01234567890123456:bucket:mybucket", 228 config: &aws.Config{ 229 Region: aws.String("us-gov-east-1"), 230 S3UseARNRegion: aws.Bool(true), 231 }, 232 expectedEndpoint: "https://s3-outposts.us-gov-east-1.amazonaws.com", 233 expectedSigningName: "s3-outposts", 234 expectedSigningRegion: "us-gov-east-1", 235 expectedHeaderForOutpostID: "op-01234567890123456", 236 expectedHeaderForAccountID: true, 237 }, 238 "Outpost Bucket FIPS client region": { 239 bucket: "arn:aws-us-gov:s3-outposts:us-gov-east-1:123456789012:outpost:op-01234567890123456:bucket:mybucket", 240 config: &aws.Config{ 241 EndpointResolver: endpoints.AwsUsGovPartition(), 242 Region: aws.String("fips-us-gov-east-1"), 243 }, 244 expectedErr: "ConfigurationError: client region does not match provided ARN region", 245 }, 246 "Outpost Bucket FIPS client region with match ARN region": { 247 bucket: "arn:aws-us-gov:s3-outposts:us-gov-east-1:123456789012:outpost:op-01234567890123456:bucket:mybucket", 248 config: &aws.Config{ 249 EndpointResolver: endpoints.AwsUsGovPartition(), 250 Region: aws.String("fips-us-gov-east-1"), 251 S3UseARNRegion: aws.Bool(true), 252 }, 253 expectedErr: "use of ARN is not supported when client or request is configured for FIPS", 254 }, 255 "Outpost Bucket FIPS client region with cross-region ARN": { 256 bucket: "arn:aws-us-gov:s3-outposts:us-gov-west-1:123456789012:outpost:op-01234567890123456:bucket:mybucket", 257 config: &aws.Config{ 258 EndpointResolver: endpoints.AwsUsGovPartition(), 259 Region: aws.String("fips-us-gov-east-1"), 260 S3UseARNRegion: aws.Bool(true), 261 }, 262 expectedErr: "use of ARN is not supported when client or request is configured for FIPS", 263 }, 264 "Outpost Bucket with DualStack": { 265 bucket: "arn:aws:s3-outposts:us-west-2:123456789012:outpost:op-01234567890123456:bucket:mybucket", 266 config: &aws.Config{ 267 Region: aws.String("us-west-2"), 268 UseDualStack: aws.Bool(true), 269 }, 270 expectedErr: "ConfigurationError: client configured for S3 Dual-stack but is not supported with resource ARN", 271 }, 272 "Outpost Bucket with Accelerate": { 273 bucket: "arn:aws:s3-outposts:us-west-2:123456789012:outpost:op-01234567890123456:accesspoint:myaccesspoint", 274 config: &aws.Config{ 275 Region: aws.String("us-west-2"), 276 S3UseAccelerate: aws.Bool(true), 277 }, 278 expectedErr: "ConfigurationError: client configured for S3 Accelerate but is not supported with resource ARN", 279 }, 280 "Missing bucket id": { 281 bucket: "arn:aws:s3-outposts:us-west-2:123456789012:outpost:op-01234567890123456:bucket", 282 config: &aws.Config{ 283 Region: aws.String("us-west-2"), 284 S3UseAccelerate: aws.Bool(true), 285 }, 286 expectedErr: "invalid Amazon s3-outposts ARN", 287 }, 288 "Invalid ARN": { 289 bucket: "arn:aws:s3-outposts:us-west-2:123456789012:bucket:mybucket", 290 config: &aws.Config{ 291 Region: aws.String("us-west-2"), 292 }, 293 expectedErr: "invalid Amazon s3-outposts ARN, unknown resource type", 294 }, 295 "Invalid Outpost Bucket ARN with FIPS pseudo-region (prefix)": { 296 bucket: "arn:aws:s3-outposts:fips-us-east-1:123456789012:outpost:op-01234567890123456:bucket:mybucket", 297 config: &aws.Config{ 298 Region: aws.String("us-west-2"), 299 S3UseARNRegion: aws.Bool(true), 300 }, 301 expectedErr: "FIPS region not allowed in ARN", 302 }, 303 "Invalid Outpost Bucket ARN with FIPS pseudo-region (suffix)": { 304 bucket: "arn:aws:s3-outposts:us-east-1-fips:123456789012:outpost:op-01234567890123456:bucket:mybucket", 305 config: &aws.Config{ 306 Region: aws.String("us-west-2"), 307 S3UseARNRegion: aws.Bool(true), 308 }, 309 expectedErr: "FIPS region not allowed in ARN", 310 }, 311 } 312 313 runValidations(t, cases) 314 } 315 316 // Runs the test validation 317 func runValidations(t *testing.T, cases map[string]testParams) { 318 for name, c := range cases { 319 t.Run(name, func(t *testing.T) { 320 sess := unit.Session.Copy(c.config) 321 322 svc := New(sess) 323 req, _ := svc.GetBucketRequest(&GetBucketInput{ 324 Bucket: &c.bucket, 325 AccountId: aws.String("123456789012"), 326 }) 327 328 req.Handlers.Send.Clear() 329 req.Handlers.Send.PushBack(func(r *request.Request) { 330 defer func() { 331 r.HTTPResponse = &http.Response{ 332 StatusCode: 200, 333 ContentLength: 0, 334 Body: ioutil.NopCloser(bytes.NewReader(nil)), 335 } 336 }() 337 if len(c.expectedErr) != 0 { 338 return 339 } 340 341 endpoint := fmt.Sprintf("%s://%s", r.HTTPRequest.URL.Scheme, r.HTTPRequest.URL.Host) 342 if e, a := c.expectedEndpoint, endpoint; e != a { 343 t.Errorf("expected %v, got %v", e, a) 344 } 345 346 if e, a := c.expectedSigningName, r.ClientInfo.SigningName; e != a { 347 t.Errorf("expected %v, got %v", e, a) 348 } 349 if e, a := c.expectedSigningRegion, r.ClientInfo.SigningRegion; e != a { 350 t.Errorf("expected %v, got %v", e, a) 351 } 352 353 if e, a := c.expectedHeaderForOutpostID, r.HTTPRequest.Header.Get("x-amz-outpost-id"); e != a { 354 if len(e) == 0 { 355 t.Errorf("expected no outpost id header set, got %v", a) 356 } else if len(a) == 0 { 357 t.Errorf("expected outpost id header set as %v, got none", e) 358 } else { 359 t.Errorf("expected %v as Outpost id header value, got %v", e, a) 360 } 361 } 362 363 if c.expectedHeaderForAccountID { 364 if e, a := "123456789012", r.HTTPRequest.Header.Get("x-amz-account-id"); e != a { 365 t.Errorf("expected x-amz-account-id header value to be %v, got %v", e, a) 366 } 367 } 368 }) 369 370 err := req.Send() 371 if len(c.expectedErr) == 0 && err != nil { 372 t.Errorf("expected no error but got: %v", err) 373 } else if len(c.expectedErr) != 0 && err == nil { 374 t.Errorf("expected err %q, but got nil", c.expectedErr) 375 } else if len(c.expectedErr) != 0 && err != nil && !strings.Contains(err.Error(), c.expectedErr) { 376 t.Errorf("expected %v, got %v", c.expectedErr, err.Error()) 377 } 378 }) 379 } 380 } 381 382 type testParamsWithRequestFn struct { 383 bucket string 384 outpostID string 385 config *aws.Config 386 requestFn func(c *S3Control) *request.Request 387 expectedEndpoint string 388 expectedSigningName string 389 expectedSigningRegion string 390 expectedHeaderForOutpostID string 391 expectedErr string 392 } 393 394 func TestCustomEndpoint_SpecialOperations(t *testing.T) { 395 cases := map[string]testParamsWithRequestFn{ 396 "CreateBucketOperation": { 397 bucket: "mockBucket", 398 outpostID: "op-01234567890123456", 399 config: &aws.Config{ 400 Region: aws.String("us-west-2"), 401 }, 402 requestFn: func(svc *S3Control) *request.Request { 403 req, _ := svc.CreateBucketRequest(&CreateBucketInput{ 404 Bucket: aws.String("mockBucket"), 405 OutpostId: aws.String("op-01234567890123456"), 406 }) 407 return req 408 }, 409 expectedEndpoint: "https://s3-outposts.us-west-2.amazonaws.com", 410 expectedSigningName: "s3-outposts", 411 expectedSigningRegion: "us-west-2", 412 expectedHeaderForOutpostID: "op-01234567890123456", 413 }, 414 "ListRegionalBucketsOperation": { 415 bucket: "mockBucket", 416 outpostID: "op-01234567890123456", 417 config: &aws.Config{ 418 Region: aws.String("us-west-2"), 419 }, 420 requestFn: func(svc *S3Control) *request.Request { 421 req, _ := svc.ListRegionalBucketsRequest(&ListRegionalBucketsInput{ 422 OutpostId: aws.String("op-01234567890123456"), 423 AccountId: aws.String("123456789012"), 424 }) 425 return req 426 }, 427 expectedEndpoint: "https://s3-outposts.us-west-2.amazonaws.com", 428 expectedSigningName: "s3-outposts", 429 expectedSigningRegion: "us-west-2", 430 expectedHeaderForOutpostID: "op-01234567890123456", 431 }, 432 "CreateAccessPoint bucket arn": { 433 config: &aws.Config{ 434 Region: aws.String("us-west-2"), 435 }, 436 requestFn: func(svc *S3Control) *request.Request { 437 req, _ := svc.CreateAccessPointRequest(&CreateAccessPointInput{ 438 AccountId: aws.String("123456789012"), 439 Bucket: aws.String("arn:aws:s3:us-west-2:123456789012:bucket:mockBucket"), 440 Name: aws.String("mockName"), 441 }) 442 return req 443 }, 444 expectedErr: "invalid Amazon s3 ARN, unknown resource type", 445 }, 446 "CreateAccessPoint outpost bucket arn": { 447 config: &aws.Config{ 448 Region: aws.String("us-west-2"), 449 }, 450 requestFn: func(svc *S3Control) *request.Request { 451 req, _ := svc.CreateAccessPointRequest(&CreateAccessPointInput{ 452 AccountId: aws.String("123456789012"), 453 Bucket: aws.String("arn:aws:s3-outposts:us-west-2:123456789012:outpost:op-01234567890123456:bucket:mockBucket"), 454 Name: aws.String("mockName"), 455 }) 456 return req 457 }, 458 expectedEndpoint: "https://s3-outposts.us-west-2.amazonaws.com", 459 expectedSigningName: "s3-outposts", 460 expectedSigningRegion: "us-west-2", 461 expectedHeaderForOutpostID: "op-01234567890123456", 462 }, 463 } 464 465 for name, c := range cases { 466 t.Run(name, func(t *testing.T) { 467 runValidationsWithRequestFn(t, c) 468 }) 469 } 470 } 471 472 func TestCustomEndpointURL(t *testing.T) { 473 account := "123456789012" 474 cases := map[string]testParamsWithRequestFn{ 475 "standard GetAccesspoint with custom endpoint url": { 476 config: &aws.Config{ 477 Endpoint: aws.String("beta.example.com"), 478 Region: aws.String("us-west-2"), 479 }, 480 requestFn: func(c *S3Control) *request.Request { 481 req, _ := c.GetAccessPointRequest(&GetAccessPointInput{ 482 AccountId: aws.String(account), 483 Name: aws.String("apname"), 484 }) 485 return req 486 }, 487 expectedEndpoint: "https://123456789012.beta.example.com", 488 expectedSigningName: "s3", 489 expectedSigningRegion: "us-west-2", 490 }, 491 "Outpost Accesspoint ARN with GetAccesspoint and custom endpoint url": { 492 config: &aws.Config{ 493 Endpoint: aws.String("beta.example.com"), 494 Region: aws.String("us-west-2"), 495 }, 496 requestFn: func(c *S3Control) *request.Request { 497 req, _ := c.GetAccessPointRequest(&GetAccessPointInput{ 498 AccountId: aws.String(account), 499 Name: aws.String("arn:aws:s3-outposts:us-west-2:123456789012:outpost:op-01234567890123456:accesspoint:myaccesspoint"), 500 }) 501 return req 502 }, 503 expectedEndpoint: "https://beta.example.com", 504 expectedSigningName: "s3-outposts", 505 expectedSigningRegion: "us-west-2", 506 expectedHeaderForOutpostID: "op-01234567890123456", 507 }, 508 "standard CreateBucket with custom endpoint url": { 509 config: &aws.Config{ 510 Endpoint: aws.String("beta.example.com"), 511 Region: aws.String("us-west-2"), 512 }, 513 requestFn: func(c *S3Control) *request.Request { 514 req, _ := c.CreateBucketRequest(&CreateBucketInput{ 515 Bucket: aws.String("bucketname"), 516 OutpostId: aws.String("op-123"), 517 }) 518 return req 519 }, 520 expectedEndpoint: "https://beta.example.com", 521 expectedSigningName: "s3-outposts", 522 expectedSigningRegion: "us-west-2", 523 expectedHeaderForOutpostID: "op-123", 524 }, 525 "Outpost Accesspoint for GetBucket with custom endpoint url": { 526 config: &aws.Config{ 527 Endpoint: aws.String("beta.example.com"), 528 Region: aws.String("us-west-2"), 529 }, 530 requestFn: func(c *S3Control) *request.Request { 531 req, _ := c.GetBucketRequest(&GetBucketInput{ 532 Bucket: aws.String("arn:aws:s3-outposts:us-west-2:123456789012:outpost:op-01234567890123456:bucket:mybucket"), 533 }) 534 return req 535 }, 536 expectedEndpoint: "https://beta.example.com", 537 expectedSigningName: "s3-outposts", 538 expectedSigningRegion: "us-west-2", 539 expectedHeaderForOutpostID: "op-01234567890123456", 540 }, 541 "GetAccesspoint with dualstack and custom endpoint url": { 542 config: &aws.Config{ 543 Endpoint: aws.String("beta.example.com"), 544 Region: aws.String("us-west-2"), 545 UseDualStack: aws.Bool(true), 546 }, 547 requestFn: func(c *S3Control) *request.Request { 548 req, _ := c.GetAccessPointRequest(&GetAccessPointInput{ 549 AccountId: aws.String(account), 550 Name: aws.String("apname"), 551 }) 552 return req 553 }, 554 expectedEndpoint: "https://123456789012.beta.example.com", 555 expectedSigningName: "s3", 556 expectedSigningRegion: "us-west-2", 557 }, 558 "GetAccesspoint with Outposts accesspoint ARN and dualstack": { 559 config: &aws.Config{ 560 Endpoint: aws.String("beta.example.com"), 561 UseDualStack: aws.Bool(true), 562 Region: aws.String("us-west-2"), 563 }, 564 requestFn: func(c *S3Control) *request.Request { 565 req, _ := c.GetAccessPointRequest(&GetAccessPointInput{ 566 AccountId: aws.String(account), 567 Name: aws.String("arn:aws:s3-outposts:us-west-2:123456789012:outpost:op-01234567890123456:accesspoint:myaccesspoint"), 568 }) 569 return req 570 }, 571 expectedErr: "client configured for S3 Dual-stack but is not supported with resource ARN", 572 }, 573 "standard CreateBucket with dualstack": { 574 config: &aws.Config{ 575 Endpoint: aws.String("beta.example.com"), 576 UseDualStack: aws.Bool(true), 577 Region: aws.String("us-west-2"), 578 }, 579 requestFn: func(c *S3Control) *request.Request { 580 req, _ := c.CreateBucketRequest(&CreateBucketInput{ 581 Bucket: aws.String("bucketname"), 582 OutpostId: aws.String("op-1234567890123456"), 583 }) 584 return req 585 }, 586 expectedEndpoint: "https://beta.example.com", 587 expectedSigningName: "s3-outposts", 588 expectedSigningRegion: "us-west-2", 589 expectedHeaderForOutpostID: "op-1234567890123456", 590 }, 591 "GetBucket with Outpost bucket ARN": { 592 config: &aws.Config{ 593 Endpoint: aws.String("beta.example.com"), 594 Region: aws.String("us-west-2"), 595 UseDualStack: aws.Bool(true), 596 }, 597 requestFn: func(c *S3Control) *request.Request { 598 req, _ := c.GetBucketRequest(&GetBucketInput{ 599 Bucket: aws.String("arn:aws:s3-outposts:us-west-2:123456789012:outpost:op-01234567890123456:bucket:mybucket"), 600 }) 601 return req 602 }, 603 expectedErr: "client configured for S3 Dual-stack but is not supported with resource ARN", 604 }, 605 } 606 607 for name, c := range cases { 608 t.Run(name, func(t *testing.T) { 609 runValidationsWithRequestFn(t, c) 610 }) 611 } 612 } 613 614 func runValidationsWithRequestFn(t *testing.T, c testParamsWithRequestFn) { 615 sess := unit.Session.Copy(c.config) 616 svc := New(sess) 617 618 req := c.requestFn(svc) 619 req.Handlers.Send.Clear() 620 req.Handlers.Send.PushBack(func(r *request.Request) { 621 defer func() { 622 r.HTTPResponse = &http.Response{ 623 StatusCode: 200, 624 ContentLength: 0, 625 Body: ioutil.NopCloser(bytes.NewReader(nil)), 626 } 627 }() 628 if len(c.expectedErr) != 0 { 629 return 630 } 631 632 endpoint := fmt.Sprintf("%s://%s", r.HTTPRequest.URL.Scheme, r.HTTPRequest.URL.Host) 633 if e, a := c.expectedEndpoint, endpoint; e != a { 634 t.Errorf("expected %v, got %v", e, a) 635 } 636 637 if e, a := c.expectedSigningName, r.ClientInfo.SigningName; e != a { 638 t.Errorf("expected %v, got %v", e, a) 639 } 640 if e, a := c.expectedSigningRegion, r.ClientInfo.SigningRegion; e != a { 641 t.Errorf("expected %v, got %v", e, a) 642 } 643 644 if e, a := c.expectedHeaderForOutpostID, r.HTTPRequest.Header.Get("x-amz-outpost-id"); e != a { 645 if len(e) == 0 { 646 t.Errorf("expected no outpost id header set, got %v", a) 647 } else if len(a) == 0 { 648 t.Errorf("expected outpost id header set as %v, got none", e) 649 } else { 650 t.Errorf("expected %v as Outpost id header value, got %v", e, a) 651 } 652 } 653 }) 654 655 err := req.Send() 656 if len(c.expectedErr) == 0 && err != nil { 657 t.Errorf("expected no error but got: %v", err) 658 } else if len(c.expectedErr) != 0 && err == nil { 659 t.Errorf("expected err %q, but got nil", c.expectedErr) 660 } else if len(c.expectedErr) != 0 && err != nil && !strings.Contains(err.Error(), c.expectedErr) { 661 t.Errorf("expected %v, got %v", c.expectedErr, err.Error()) 662 } 663 } 664 665 func TestInputIsNotModified(t *testing.T) { 666 inputBucket := "arn:aws:s3-outposts:us-east-1:123456789012:outpost:op-01234567890123456:bucket:mybucket" 667 expectedAccountID := "123456789012" 668 sess := unit.Session.Copy(&aws.Config{ 669 Region: aws.String("us-west-2"), 670 S3UseARNRegion: aws.Bool(true), 671 }) 672 673 svc := New(sess) 674 params := &DeleteBucketInput{ 675 Bucket: aws.String(inputBucket), 676 } 677 req, _ := svc.DeleteBucketRequest(params) 678 679 req.Handlers.Send.Clear() 680 req.Handlers.Send.PushBack(func(r *request.Request) { 681 defer func() { 682 r.HTTPResponse = &http.Response{ 683 StatusCode: 200, 684 ContentLength: 0, 685 Body: ioutil.NopCloser(bytes.NewReader(nil)), 686 } 687 }() 688 }) 689 690 err := req.Send() 691 if err != nil { 692 t.Fatalf("expected no error, got %v", err) 693 } 694 695 // check if req params were modified 696 if e, a := *params.Bucket, inputBucket; !strings.EqualFold(e, a) { 697 t.Fatalf("expected no modification for operation input, "+ 698 "expected %v, got %v as bucket input", e, a) 699 } 700 701 if params.AccountId != nil { 702 t.Fatalf("expected original input to be unmodified, but account id was backfilled") 703 } 704 705 modifiedInput, ok := req.Params.(*DeleteBucketInput) 706 if !ok { 707 t.Fatalf("expected modified input of type *DeleteBucketInput") 708 } 709 710 if modifiedInput.AccountId == nil { 711 t.Fatalf("expected AccountID value to be backfilled, was not") 712 } 713 714 if e, a := expectedAccountID, *modifiedInput.AccountId; !strings.EqualFold(e, a) { 715 t.Fatalf("expected account id backfilled on request params to be %v, got %v", e, a) 716 } 717 718 if modifiedInput.Bucket == nil { 719 t.Fatalf("expected Bucket value to be set, was not") 720 } 721 722 if e, a := "mybucket", *modifiedInput.Bucket; !strings.EqualFold(e, a) { 723 t.Fatalf("expected modified input bucket name to be %v, got %v", e, a) 724 } 725 }