github.com/GoogleCloudPlatform/terraformer@v0.8.18/providers/aws/api_gateway.go (about) 1 // Copyright 2020 The Terraformer Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package aws 16 17 import ( 18 "context" 19 "log" 20 "strings" 21 22 "github.com/GoogleCloudPlatform/terraformer/terraformutils" 23 "github.com/GoogleCloudPlatform/terraformer/terraformutils/terraformerstring" 24 "github.com/aws/aws-sdk-go-v2/service/apigateway" 25 "github.com/aws/aws-sdk-go-v2/service/apigateway/types" 26 ) 27 28 var apiGatewayAllowEmptyValues = []string{"tags.", "parent_id", "path_part"} 29 30 type APIGatewayGenerator struct { 31 AWSService 32 } 33 34 func (g *APIGatewayGenerator) InitResources() error { 35 config, e := g.generateConfig() 36 if e != nil { 37 return e 38 } 39 svc := apigateway.NewFromConfig(config) 40 41 if err := g.loadRestApis(svc); err != nil { 42 return err 43 } 44 if err := g.loadVpcLinks(svc); err != nil { 45 return err 46 } 47 if err := g.loadUsagePlans(svc); err != nil { 48 return err 49 } 50 51 return nil 52 } 53 54 func (g *APIGatewayGenerator) loadRestApis(svc *apigateway.Client) error { 55 p := apigateway.NewGetRestApisPaginator(svc, &apigateway.GetRestApisInput{}) 56 for p.HasMorePages() { 57 page, err := p.NextPage(context.TODO()) 58 if err != nil { 59 return err 60 } 61 for _, restAPI := range page.Items { 62 if g.shouldFilterRestAPI(restAPI.Tags) { 63 continue 64 } 65 g.Resources = append(g.Resources, terraformutils.NewSimpleResource( 66 *restAPI.Id, 67 *restAPI.Name, 68 "aws_api_gateway_rest_api", 69 "aws", 70 apiGatewayAllowEmptyValues)) 71 if err := g.loadStages(svc, restAPI.Id); err != nil { 72 return err 73 } 74 if err := g.loadResources(svc, restAPI.Id); err != nil { 75 return err 76 } 77 if err := g.loadModels(svc, restAPI.Id); err != nil { 78 return err 79 } 80 if err := g.loadResponses(svc, restAPI.Id); err != nil { 81 return err 82 } 83 if err := g.loadDocumentationParts(svc, restAPI.Id); err != nil { 84 return err 85 } 86 if err := g.loadAuthorizers(svc, restAPI.Id); err != nil { 87 return err 88 } 89 } 90 } 91 return nil 92 } 93 94 func (g *APIGatewayGenerator) shouldFilterRestAPI(tags map[string]string) bool { 95 for _, filter := range g.Filter { 96 if strings.HasPrefix(filter.FieldPath, "tags.") && filter.IsApplicable("api_gateway_rest_api") { 97 tagName := strings.Replace(filter.FieldPath, "tags.", "", 1) 98 if val, ok := tags[tagName]; ok { 99 return !terraformerstring.ContainsString(filter.AcceptableValues, val) 100 } 101 return true 102 } 103 } 104 return false 105 } 106 107 func (g *APIGatewayGenerator) loadStages(svc *apigateway.Client, restAPIID *string) error { 108 output, err := svc.GetStages(context.TODO(), &apigateway.GetStagesInput{ 109 RestApiId: restAPIID, 110 }) 111 if err != nil { 112 return err 113 } 114 for _, stage := range output.Item { 115 stageID := *restAPIID + "/" + StringValue(stage.StageName) 116 g.Resources = append(g.Resources, terraformutils.NewResource( 117 stageID, 118 stageID, 119 "aws_api_gateway_stage", 120 "aws", 121 map[string]string{ 122 "rest_api_id": *restAPIID, 123 "stage_name": *stage.StageName, 124 }, 125 apiGatewayAllowEmptyValues, 126 map[string]interface{}{}, 127 )) 128 } 129 return nil 130 } 131 132 func (g *APIGatewayGenerator) loadResources(svc *apigateway.Client, restAPIID *string) error { 133 p := apigateway.NewGetResourcesPaginator(svc, &apigateway.GetResourcesInput{ 134 RestApiId: restAPIID, 135 }) 136 for p.HasMorePages() { 137 page, err := p.NextPage(context.TODO()) 138 if err != nil { 139 return err 140 } 141 for _, resource := range page.Items { 142 resourceID := *resource.Id 143 g.Resources = append(g.Resources, terraformutils.NewResource( 144 resourceID, 145 resourceID, 146 "aws_api_gateway_resource", 147 "aws", 148 map[string]string{ 149 "path": StringValue(resource.Path), 150 "path_part": StringValue(resource.PathPart), 151 "partent_id": StringValue(resource.ParentId), 152 "rest_api_id": StringValue(restAPIID), 153 }, 154 apiGatewayAllowEmptyValues, 155 map[string]interface{}{}, 156 )) 157 err := g.loadResourceMethods(svc, restAPIID, resource) 158 if err != nil { 159 log.Println(err) 160 } 161 } 162 } 163 return nil 164 } 165 166 func (g *APIGatewayGenerator) loadModels(svc *apigateway.Client, restAPIID *string) error { 167 p := apigateway.NewGetModelsPaginator(svc, &apigateway.GetModelsInput{ 168 RestApiId: restAPIID, 169 }) 170 for p.HasMorePages() { 171 page, err := p.NextPage(context.TODO()) 172 if err != nil { 173 return nil 174 } 175 for _, model := range page.Items { 176 resourceID := *model.Id 177 g.Resources = append(g.Resources, terraformutils.NewResource( 178 resourceID, 179 resourceID, 180 "aws_api_gateway_model", 181 "aws", 182 map[string]string{ 183 "name": StringValue(model.Name), 184 "content_type": StringValue(model.ContentType), 185 "schema": StringValue(model.Schema), 186 "rest_api_id": StringValue(restAPIID), 187 }, 188 apiGatewayAllowEmptyValues, 189 map[string]interface{}{}, 190 )) 191 } 192 } 193 return nil 194 } 195 196 func (g *APIGatewayGenerator) loadResourceMethods(svc *apigateway.Client, restAPIID *string, resource types.Resource) error { 197 for httpMethod, method := range resource.ResourceMethods { 198 methodID := *restAPIID + "/" + *resource.Id + "/" + httpMethod 199 authorizationType := "NONE" 200 if method.AuthorizationType != nil { 201 authorizationType = *method.AuthorizationType 202 } 203 204 g.Resources = append(g.Resources, terraformutils.NewResource( 205 methodID, 206 methodID, 207 "aws_api_gateway_method", 208 "aws", 209 map[string]string{ 210 "rest_api_id": *restAPIID, 211 "resource_id": *resource.Id, 212 "http_method": httpMethod, 213 "authorization": authorizationType, 214 }, 215 apiGatewayAllowEmptyValues, 216 map[string]interface{}{}, 217 )) 218 219 methodDetails, err := svc.GetMethod(context.TODO(), &apigateway.GetMethodInput{ 220 HttpMethod: &httpMethod, 221 ResourceId: resource.Id, 222 RestApiId: restAPIID, 223 }) 224 if err != nil { 225 return err 226 } 227 228 if methodDetails.MethodIntegration != nil { 229 typeString := string(methodDetails.MethodIntegration.Type) 230 g.Resources = append(g.Resources, terraformutils.NewResource( 231 methodID, 232 methodID, 233 "aws_api_gateway_integration", 234 "aws", 235 map[string]string{ 236 "rest_api_id": *restAPIID, 237 "resource_id": *resource.Id, 238 "http_method": httpMethod, 239 "type": typeString, 240 }, 241 apiGatewayAllowEmptyValues, 242 map[string]interface{}{}, 243 )) 244 integrationDetails, err := svc.GetIntegration(context.TODO(), &apigateway.GetIntegrationInput{ 245 HttpMethod: &httpMethod, 246 ResourceId: resource.Id, 247 RestApiId: restAPIID, 248 }) 249 if err != nil { 250 return err 251 } 252 253 for responseCode := range integrationDetails.IntegrationResponses { 254 integrationResponseID := *restAPIID + "/" + *resource.Id + "/" + httpMethod + "/" + responseCode 255 g.Resources = append(g.Resources, terraformutils.NewResource( 256 integrationResponseID, 257 integrationResponseID, 258 "aws_api_gateway_integration_response", 259 "aws", 260 map[string]string{ 261 "rest_api_id": *restAPIID, 262 "resource_id": *resource.Id, 263 "http_method": httpMethod, 264 "status_code": responseCode, 265 }, 266 apiGatewayAllowEmptyValues, 267 map[string]interface{}{}, 268 )) 269 } 270 } 271 for responseCode := range methodDetails.MethodResponses { 272 responseID := *restAPIID + "/" + *resource.Id + "/" + httpMethod + "/" + responseCode 273 274 g.Resources = append(g.Resources, terraformutils.NewResource( 275 responseID, 276 responseID, 277 "aws_api_gateway_method_response", 278 "aws", 279 map[string]string{ 280 "rest_api_id": *restAPIID, 281 "resource_id": *resource.Id, 282 "http_method": httpMethod, 283 "status_code": responseCode, 284 }, 285 apiGatewayAllowEmptyValues, 286 map[string]interface{}{}, 287 )) 288 } 289 } 290 return nil 291 } 292 293 func (g *APIGatewayGenerator) loadResponses(svc *apigateway.Client, restAPIID *string) error { 294 var position *string 295 for { 296 response, err := svc.GetGatewayResponses(context.TODO(), &apigateway.GetGatewayResponsesInput{ 297 RestApiId: restAPIID, 298 Position: position, 299 }) 300 if err != nil { 301 return err 302 } 303 for _, response := range response.Items { 304 if response.DefaultResponse { 305 continue 306 } 307 responseTypeString := string(response.ResponseType) 308 responseID := *restAPIID + "/" + responseTypeString 309 g.Resources = append(g.Resources, terraformutils.NewResource( 310 responseID, 311 responseID, 312 "aws_api_gateway_gateway_response", 313 "aws", 314 map[string]string{ 315 "rest_api_id": *restAPIID, 316 "response_type": responseTypeString, 317 }, 318 apiGatewayAllowEmptyValues, 319 map[string]interface{}{}, 320 )) 321 } 322 position = response.Position 323 if position == nil { 324 break 325 } 326 } 327 return nil 328 } 329 330 func (g *APIGatewayGenerator) loadDocumentationParts(svc *apigateway.Client, restAPIID *string) error { 331 var position *string 332 for { 333 response, err := svc.GetDocumentationParts(context.TODO(), &apigateway.GetDocumentationPartsInput{ 334 RestApiId: restAPIID, 335 Position: position, 336 }) 337 if err != nil { 338 return err 339 } 340 for _, documentationPart := range response.Items { 341 documentationPartID := *restAPIID + "/" + *documentationPart.Id 342 g.Resources = append(g.Resources, terraformutils.NewSimpleResource( 343 documentationPartID, 344 documentationPartID, 345 "aws_api_gateway_documentation_part", 346 "aws", 347 apiGatewayAllowEmptyValues, 348 )) 349 } 350 position = response.Position 351 if position == nil { 352 break 353 } 354 } 355 return nil 356 } 357 358 func (g *APIGatewayGenerator) loadAuthorizers(svc *apigateway.Client, restAPIID *string) error { 359 var position *string 360 for { 361 response, err := svc.GetAuthorizers(context.TODO(), &apigateway.GetAuthorizersInput{ 362 RestApiId: restAPIID, 363 Position: position, 364 }) 365 if err != nil { 366 return err 367 } 368 for _, authorizer := range response.Items { 369 g.Resources = append(g.Resources, terraformutils.NewResource( 370 *authorizer.Id, 371 *authorizer.Id, 372 "aws_api_gateway_authorizer", 373 "aws", 374 map[string]string{ 375 "rest_api_id": *restAPIID, 376 "name": StringValue(authorizer.Name), 377 }, 378 apiGatewayAllowEmptyValues, 379 map[string]interface{}{}, 380 )) 381 } 382 position = response.Position 383 if position == nil { 384 break 385 } 386 } 387 return nil 388 } 389 390 func (g *APIGatewayGenerator) loadVpcLinks(svc *apigateway.Client) error { 391 p := apigateway.NewGetVpcLinksPaginator(svc, &apigateway.GetVpcLinksInput{}) 392 for p.HasMorePages() { 393 page, err := p.NextPage(context.TODO()) 394 if err != nil { 395 return err 396 } 397 for _, vpcLink := range page.Items { 398 g.Resources = append(g.Resources, terraformutils.NewSimpleResource( 399 *vpcLink.Id, 400 *vpcLink.Name, 401 "aws_api_gateway_vpc_link", 402 "aws", 403 apiGatewayAllowEmptyValues)) 404 } 405 } 406 return nil 407 } 408 409 func (g *APIGatewayGenerator) loadUsagePlans(svc *apigateway.Client) error { 410 p := apigateway.NewGetUsagePlansPaginator(svc, &apigateway.GetUsagePlansInput{}) 411 for p.HasMorePages() { 412 page, err := p.NextPage(context.TODO()) 413 if err != nil { 414 return err 415 } 416 for _, usagePlan := range page.Items { 417 g.Resources = append(g.Resources, terraformutils.NewSimpleResource( 418 *usagePlan.Id, 419 *usagePlan.Name, 420 "aws_api_gateway_usage_plan", 421 "aws", 422 apiGatewayAllowEmptyValues)) 423 } 424 } 425 return nil 426 }