Skip to content

Commit

Permalink
Merge pull request hashicorp#40447 from DrFaust92/apigw-domain-base
Browse files Browse the repository at this point in the history
r/apigateway_base_path_mapping - add support `domain_name_id`
  • Loading branch information
ewbankkit authored Dec 5, 2024
2 parents fbc0ab8 + 26fe1c6 commit 74707c7
Show file tree
Hide file tree
Showing 7 changed files with 265 additions and 62 deletions.
3 changes: 3 additions & 0 deletions .changelog/40447.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
resource/aws_api_gateway_base_path_mapping: Add `domain_name_id` argument
```
128 changes: 78 additions & 50 deletions internal/service/apigateway/base_path_mapping.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ func resourceBasePathMapping() *schema.Resource {
Required: true,
ForceNew: true,
},
"domain_name_id": {
Type: schema.TypeString,
Optional: true,
},
"stage_name": {
Type: schema.TypeString,
Optional: true,
Expand All @@ -64,14 +68,22 @@ func resourceBasePathMappingCreate(ctx context.Context, d *schema.ResourceData,
conn := meta.(*conns.AWSClient).APIGatewayClient(ctx)

domainName, basePath := d.Get(names.AttrDomainName).(string), d.Get("base_path").(string)
id := basePathMappingCreateResourceID(domainName, basePath)
input := &apigateway.CreateBasePathMappingInput{
RestApiId: aws.String(d.Get("api_id").(string)),
DomainName: aws.String(domainName),
BasePath: aws.String(basePath),
Stage: aws.String(d.Get("stage_name").(string)),
}

var id string
if v, ok := d.GetOk("domain_name_id"); ok {
domainNameID := v.(string)
input.DomainNameId = aws.String(domainNameID)
id = basePathMappingCreateResourceID(domainName, basePath, domainNameID)
} else {
id = basePathMappingCreateResourceID(domainName, basePath, "")
}

const (
timeout = 30 * time.Second
)
Expand All @@ -92,12 +104,12 @@ func resourceBasePathMappingRead(ctx context.Context, d *schema.ResourceData, me
var diags diag.Diagnostics
conn := meta.(*conns.AWSClient).APIGatewayClient(ctx)

domainName, basePath, err := basePathMappingParseResourceID(d.Id())
domainName, basePath, domainNameID, err := basePathMappingParseResourceID(d.Id())
if err != nil {
return sdkdiag.AppendFromErr(diags, err)
}

mapping, err := findBasePathMappingByTwoPartKey(ctx, conn, domainName, basePath)
mapping, err := findBasePathMappingByThreePartKey(ctx, conn, domainName, basePath, domainNameID)

if !d.IsNewResource() && tfresource.NotFound(err) {
log.Printf("[WARN] API Gateway Base Path Mapping (%s) not found, removing from state", d.Id())
Expand All @@ -109,14 +121,14 @@ func resourceBasePathMappingRead(ctx context.Context, d *schema.ResourceData, me
return sdkdiag.AppendErrorf(diags, "reading API Gateway Base Path Mapping (%s): %s", d.Id(), err)
}

d.Set("api_id", mapping.RestApiId)
mappingBasePath := aws.ToString(mapping.BasePath)
if mappingBasePath == emptyBasePathMappingValue {
mappingBasePath = ""
}

d.Set("api_id", mapping.RestApiId)
d.Set("base_path", mappingBasePath)
d.Set(names.AttrDomainName, domainName)
d.Set("domain_name_id", domainNameID)
d.Set("stage_name", mapping.Stage)

return diags
Expand All @@ -126,21 +138,13 @@ func resourceBasePathMappingUpdate(ctx context.Context, d *schema.ResourceData,
var diags diag.Diagnostics
conn := meta.(*conns.AWSClient).APIGatewayClient(ctx)

domainName, basePath, err := basePathMappingParseResourceID(d.Id())
domainName, basePath, domainNameID, err := basePathMappingParseResourceID(d.Id())
if err != nil {
return sdkdiag.AppendFromErr(diags, err)
}

operations := make([]types.PatchOperation, 0)

if d.HasChange("stage_name") {
operations = append(operations, types.PatchOperation{
Op: types.Op("replace"),
Path: aws.String("/stage"),
Value: aws.String(d.Get("stage_name").(string)),
})
}

if d.HasChange("api_id") {
operations = append(operations, types.PatchOperation{
Op: types.Op("replace"),
Expand All @@ -157,11 +161,22 @@ func resourceBasePathMappingUpdate(ctx context.Context, d *schema.ResourceData,
})
}

if d.HasChange("stage_name") {
operations = append(operations, types.PatchOperation{
Op: types.Op("replace"),
Path: aws.String("/stage"),
Value: aws.String(d.Get("stage_name").(string)),
})
}

input := apigateway.UpdateBasePathMappingInput{
BasePath: aws.String(basePath),
DomainName: aws.String(domainName),
PatchOperations: operations,
}
if domainNameID != "" {
input.DomainNameId = aws.String(domainNameID)
}

_, err = conn.UpdateBasePathMapping(ctx, &input)

Expand All @@ -170,7 +185,7 @@ func resourceBasePathMappingUpdate(ctx context.Context, d *schema.ResourceData,
}

if d.HasChange("base_path") {
id := basePathMappingCreateResourceID(d.Get(names.AttrDomainName).(string), d.Get("base_path").(string))
id := basePathMappingCreateResourceID(d.Get(names.AttrDomainName).(string), d.Get("base_path").(string), domainNameID)
d.SetId(id)
}

Expand All @@ -181,16 +196,21 @@ func resourceBasePathMappingDelete(ctx context.Context, d *schema.ResourceData,
var diags diag.Diagnostics
conn := meta.(*conns.AWSClient).APIGatewayClient(ctx)

domainName, basePath, err := basePathMappingParseResourceID(d.Id())
domainName, basePath, domainNameID, err := basePathMappingParseResourceID(d.Id())
if err != nil {
return sdkdiag.AppendFromErr(diags, err)
}

log.Printf("[INFO] Deleting API Gateway Base Path Mapping: %s", d.Id())
_, err = conn.DeleteBasePathMapping(ctx, &apigateway.DeleteBasePathMappingInput{
input := &apigateway.DeleteBasePathMappingInput{
DomainName: aws.String(domainName),
BasePath: aws.String(basePath),
})
}
if domainNameID != "" {
input.DomainNameId = aws.String(domainNameID)
}

_, err = conn.DeleteBasePathMapping(ctx, input)

if errs.IsA[*types.NotFoundException](err) {
return diags
Expand All @@ -203,11 +223,50 @@ func resourceBasePathMappingDelete(ctx context.Context, d *schema.ResourceData,
return diags
}

func findBasePathMappingByTwoPartKey(ctx context.Context, conn *apigateway.Client, domainName, basePath string) (*apigateway.GetBasePathMappingOutput, error) {
const basePathMappingResourceIDSeparator = "/"

func basePathMappingCreateResourceID(domainName, basePath, domainNameID string) string {
var id string
parts := []string{domainName, basePath}

if domainNameID != "" {
parts = append(parts, domainNameID)
}

id = strings.Join(parts, basePathMappingResourceIDSeparator)

return id
}

func basePathMappingParseResourceID(id string) (string, string, string, error) {
switch parts := strings.SplitN(id, basePathMappingResourceIDSeparator, 3); len(parts) {
case 2:
if domainName, basePath := parts[0], parts[1]; domainName != "" {
if basePath == "" {
basePath = emptyBasePathMappingValue
}
return domainName, basePath, "", nil
}
case 3:
if domainName, basePath, domainNameID := parts[0], parts[1], parts[2]; domainName != "" && domainNameID != "" {
if basePath == "" {
basePath = emptyBasePathMappingValue
}
return domainName, basePath, domainNameID, nil
}
}

return "", "", "", fmt.Errorf("unexpected format of ID (%[1]s), expected DOMAIN-NAME%[2]sBASEPATH or DOMAIN-NAME%[2]sBASEPATH%[2]sDOMAIN-NAME-ID", id, basePathMappingResourceIDSeparator)
}

func findBasePathMappingByThreePartKey(ctx context.Context, conn *apigateway.Client, domainName, basePath, domainNameID string) (*apigateway.GetBasePathMappingOutput, error) {
input := &apigateway.GetBasePathMappingInput{
BasePath: aws.String(basePath),
DomainName: aws.String(domainName),
}
if domainNameID != "" {
input.DomainNameId = aws.String(domainNameID)
}

output, err := conn.GetBasePathMapping(ctx, input)

Expand All @@ -228,34 +287,3 @@ func findBasePathMappingByTwoPartKey(ctx context.Context, conn *apigateway.Clien

return output, nil
}

const basePathMappingResourceIDSeparator = "/"

func basePathMappingCreateResourceID(domainName, basePath string) string {
parts := []string{domainName, basePath}
id := strings.Join(parts, basePathMappingResourceIDSeparator)

return id
}

func basePathMappingParseResourceID(id string) (string, string, error) {
err := fmt.Errorf("Unexpected format of ID (%[1]s), expected DOMAIN%[2]sBASEPATH", id, basePathMappingResourceIDSeparator)

parts := strings.SplitN(id, basePathMappingResourceIDSeparator, 2)
if len(parts) != 2 {
return "", "", err
}

domainName := parts[0]
basePath := parts[1]

if domainName == "" {
return "", "", err
}

if basePath == "" {
basePath = emptyBasePathMappingValue
}

return domainName, basePath, nil
}
Loading

0 comments on commit 74707c7

Please sign in to comment.