Skip to content

Commit 76de792

Browse files
committed
add apigateway base path mapping
1 parent a288abe commit 76de792

File tree

3 files changed

+192
-0
lines changed

3 files changed

+192
-0
lines changed
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
package adapters
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"strings"
7+
8+
"github.com/aws/aws-sdk-go-v2/service/apigateway"
9+
"github.com/aws/aws-sdk-go-v2/service/apigateway/types"
10+
"github.com/overmindtech/aws-source/adapterhelpers"
11+
"github.com/overmindtech/sdp-go"
12+
)
13+
14+
func convertGetBasePathMappingOutputToBasePathMapping(output *apigateway.GetBasePathMappingOutput) *types.BasePathMapping {
15+
return &types.BasePathMapping{
16+
BasePath: output.BasePath,
17+
RestApiId: output.RestApiId,
18+
Stage: output.Stage,
19+
}
20+
}
21+
22+
func basePathMappingOutputMapper(query, scope string, awsItem *types.BasePathMapping) (*sdp.Item, error) {
23+
attributes, err := adapterhelpers.ToAttributesWithExclude(awsItem, "tags")
24+
if err != nil {
25+
return nil, err
26+
}
27+
28+
domainName := strings.Split(query, "/")[0]
29+
30+
err = attributes.Set("UniqueAttribute", fmt.Sprintf("%s/%s", domainName, *awsItem.BasePath))
31+
32+
item := sdp.Item{
33+
Type: "apigateway-base-path-mapping",
34+
UniqueAttribute: "BasePath",
35+
Attributes: attributes,
36+
Scope: scope,
37+
}
38+
39+
item.LinkedItemQueries = append(item.LinkedItemQueries, &sdp.LinkedItemQuery{
40+
Query: &sdp.Query{
41+
Type: "apigateway-domain-name",
42+
Method: sdp.QueryMethod_GET,
43+
Query: domainName,
44+
Scope: scope,
45+
},
46+
BlastPropagation: &sdp.BlastPropagation{
47+
// If domain name changes, the base path mapping will be affected
48+
In: true,
49+
// If base path mapping changes, the domain name won't be affected
50+
Out: false,
51+
},
52+
})
53+
54+
if awsItem.RestApiId != nil {
55+
item.LinkedItemQueries = append(item.LinkedItemQueries, &sdp.LinkedItemQuery{
56+
Query: &sdp.Query{
57+
Type: "apigateway-rest-api",
58+
Method: sdp.QueryMethod_GET,
59+
Query: *awsItem.RestApiId,
60+
Scope: scope,
61+
},
62+
BlastPropagation: &sdp.BlastPropagation{
63+
// They are tightly coupled, so we need to propagate the blast to the linked item
64+
In: true,
65+
Out: true,
66+
},
67+
})
68+
}
69+
70+
return &item, nil
71+
}
72+
73+
func NewAPIGatewayBasePathMappingAdapter(client *apigateway.Client, accountID string, region string) *adapterhelpers.GetListAdapter[*types.BasePathMapping, *apigateway.Client, *apigateway.Options] {
74+
return &adapterhelpers.GetListAdapter[*types.BasePathMapping, *apigateway.Client, *apigateway.Options]{
75+
ItemType: "apigateway-base-path-mapping",
76+
Client: client,
77+
AccountID: accountID,
78+
Region: region,
79+
AdapterMetadata: basePathMappingAdapterMetadata,
80+
GetFunc: func(ctx context.Context, client *apigateway.Client, scope, query string) (*types.BasePathMapping, error) {
81+
f := strings.Split(query, "/")
82+
if len(f) != 2 {
83+
return nil, &sdp.QueryError{
84+
ErrorType: sdp.QueryError_NOTFOUND,
85+
ErrorString: fmt.Sprintf("query must be in the format of: the domain-name/base-path, but found: %s", query),
86+
}
87+
}
88+
out, err := client.GetBasePathMapping(ctx, &apigateway.GetBasePathMappingInput{
89+
DomainName: &f[0],
90+
BasePath: &f[1],
91+
})
92+
if err != nil {
93+
return nil, err
94+
}
95+
return convertGetBasePathMappingOutputToBasePathMapping(out), nil
96+
},
97+
DisableList: true,
98+
SearchFunc: func(ctx context.Context, client *apigateway.Client, scope string, query string) ([]*types.BasePathMapping, error) {
99+
out, err := client.GetBasePathMappings(ctx, &apigateway.GetBasePathMappingsInput{
100+
DomainName: &query,
101+
})
102+
if err != nil {
103+
return nil, err
104+
}
105+
106+
var items []*types.BasePathMapping
107+
for _, basePathMapping := range out.Items {
108+
items = append(items, &basePathMapping)
109+
}
110+
111+
return items, nil
112+
},
113+
ItemMapper: func(query, scope string, awsItem *types.BasePathMapping) (*sdp.Item, error) {
114+
return basePathMappingOutputMapper(query, scope, awsItem)
115+
},
116+
}
117+
}
118+
119+
var basePathMappingAdapterMetadata = Metadata.Register(&sdp.AdapterMetadata{
120+
Type: "apigateway-base-path-mapping",
121+
DescriptiveName: "API Gateway Base Path Mapping",
122+
Category: sdp.AdapterCategory_ADAPTER_CATEGORY_CONFIGURATION,
123+
SupportedQueryMethods: &sdp.AdapterSupportedQueryMethods{
124+
Get: true,
125+
Search: true,
126+
GetDescription: "Get an API Gateway Base Path Mapping by its domain name and base path: domain-name/base-path",
127+
SearchDescription: "Search for API Gateway Base Path Mappings by their domain name: domain-name",
128+
},
129+
})
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package adapters
2+
3+
import (
4+
"github.com/overmindtech/sdp-go"
5+
"testing"
6+
"time"
7+
8+
"github.com/aws/aws-sdk-go-v2/aws"
9+
"github.com/aws/aws-sdk-go-v2/service/apigateway"
10+
"github.com/aws/aws-sdk-go-v2/service/apigateway/types"
11+
"github.com/overmindtech/aws-source/adapterhelpers"
12+
)
13+
14+
func TestBasePathMappingOutputMapper(t *testing.T) {
15+
awsItem := &types.BasePathMapping{
16+
BasePath: aws.String("base-path"),
17+
RestApiId: aws.String("rest-api-id"),
18+
Stage: aws.String("stage"),
19+
}
20+
21+
item, err := basePathMappingOutputMapper("domain-name", "scope", awsItem)
22+
if err != nil {
23+
t.Fatalf("unexpected error: %v", err)
24+
}
25+
26+
if err := item.Validate(); err != nil {
27+
t.Error(err)
28+
}
29+
30+
tests := adapterhelpers.QueryTests{
31+
{
32+
ExpectedType: "apigateway-domain-name",
33+
ExpectedMethod: sdp.QueryMethod_GET,
34+
ExpectedQuery: "domain-name",
35+
ExpectedScope: "scope",
36+
},
37+
{
38+
ExpectedType: "apigateway-rest-api",
39+
ExpectedMethod: sdp.QueryMethod_GET,
40+
ExpectedQuery: "rest-api-id",
41+
ExpectedScope: "scope",
42+
},
43+
}
44+
45+
tests.Execute(t, item)
46+
}
47+
48+
func TestNewAPIGatewayBasePathMappingAdapter(t *testing.T) {
49+
config, account, region := adapterhelpers.GetAutoConfig(t)
50+
51+
client := apigateway.NewFromConfig(config)
52+
53+
adapter := NewAPIGatewayBasePathMappingAdapter(client, account, region)
54+
55+
test := adapterhelpers.E2ETest{
56+
Adapter: adapter,
57+
Timeout: 10 * time.Second,
58+
SkipList: true,
59+
}
60+
61+
test.Run(t)
62+
}

proc/proc.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,7 @@ func InitializeAwsSourceEngine(ctx context.Context, ec *discovery.EngineConfig,
488488
adapters.NewAPIGatewayDeploymentAdapter(apigatewayClient, *callerID.Account, cfg.Region),
489489
adapters.NewAPIGatewayStageAdapter(apigatewayClient, *callerID.Account, cfg.Region),
490490
adapters.NewAPIGatewayModelAdapter(apigatewayClient, *callerID.Account, cfg.Region),
491+
adapters.NewAPIGatewayBasePathMappingAdapter(apigatewayClient, *callerID.Account, cfg.Region),
491492

492493
// SSM
493494
adapters.NewSSMParameterAdapter(ssmClient, *callerID.Account, cfg.Region),

0 commit comments

Comments
 (0)