diff --git a/pkg/engine2/operational_rule/operational_action.go b/pkg/engine2/operational_rule/operational_action.go index 8d6636d2e..0083648f3 100644 --- a/pkg/engine2/operational_rule/operational_action.go +++ b/pkg/engine2/operational_rule/operational_action.go @@ -6,6 +6,7 @@ import ( "sort" "github.com/dominikbraun/graph" + "github.com/google/uuid" "github.com/klothoplatform/klotho/pkg/collectionutil" construct "github.com/klothoplatform/klotho/pkg/construct2" "github.com/klothoplatform/klotho/pkg/engine2/solution_context" @@ -408,13 +409,21 @@ func (action *operationalResourceAction) generateResourceName(resourceToSet *con if err != nil { return err } - matcher := construct.ResourceId{Provider: resourceToSet.Provider, Type: resourceToSet.Type, Namespace: resourceToSet.Namespace} + currNames := make(set.Set[string]) + // we cannot consider things only in the namespace because when creating a resource for an operational action + // it likely has not been namespaced yet and we dont know where it will be namespaced to + matcher := construct.ResourceId{Provider: resourceToSet.Provider, Type: resourceToSet.Type} for _, id := range ids { if matcher.Matches(id) { + currNames.Add(id.Name) numResources++ } } + // check if the current name based on the digit conflicts with an existing name and if so create a random uuid suffix resourceToSet.Name = fmt.Sprintf("%s-%d", resourceToSet.Type, numResources) - + if currNames.Contains(resourceToSet.Name) { + suffix := uuid.NewString()[:8] + resourceToSet.Name = fmt.Sprintf("%s-%s", resourceToSet.Type, suffix) + } return nil } diff --git a/pkg/engine2/testdata/2_routes.expect.yaml b/pkg/engine2/testdata/2_routes.expect.yaml index 89a2ef1c7..b56085630 100755 --- a/pkg/engine2/testdata/2_routes.expect.yaml +++ b/pkg/engine2/testdata/2_routes.expect.yaml @@ -6,10 +6,10 @@ resources: aws:api_deployment:rest_api_1:api_deployment-0: RestApi: aws:rest_api:rest_api_1 Triggers: - api_method-0: api_method-0 - api_method-1: api_method-1 integ0: integ0 + integ0-api_method: integ0-api_method integ1: integ1 + integ1-api_method: integ1-api_method aws:rest_api:rest_api_1: BinaryMediaTypes: - application/octet-stream @@ -34,13 +34,13 @@ resources: ParentResource: aws:api_resource:rest_api_1:lambda1 PathPart: api RestApi: aws:rest_api:rest_api_1 - aws:api_method:rest_api_1:api_method-0: + aws:api_method:rest_api_1:integ0-api_method: Authorization: NONE HttpMethod: ANY RequestParameters: {} Resource: aws:api_resource:rest_api_1:api_resource-0 RestApi: aws:rest_api:rest_api_1 - aws:api_method:rest_api_1:api_method-1: + aws:api_method:rest_api_1:integ1-api_method: Authorization: NONE HttpMethod: ANY RequestParameters: {} @@ -48,7 +48,7 @@ resources: RestApi: aws:rest_api:rest_api_1 aws:api_integration:rest_api_1:integ0: IntegrationHttpMethod: POST - Method: aws:api_method:rest_api_1:api_method-0 + Method: aws:api_method:rest_api_1:integ0-api_method RequestParameters: {} Resource: aws:api_resource:rest_api_1:api_resource-0 RestApi: aws:rest_api:rest_api_1 @@ -58,7 +58,7 @@ resources: Uri: aws:lambda_function:lambda_function_0#LambdaIntegrationUri aws:api_integration:rest_api_1:integ1: IntegrationHttpMethod: POST - Method: aws:api_method:rest_api_1:api_method-1 + Method: aws:api_method:rest_api_1:integ1-api_method RequestParameters: {} Resource: aws:api_resource:rest_api_1:api_resource-1 RestApi: aws:rest_api:rest_api_1 @@ -134,13 +134,13 @@ edges: aws:api_stage:rest_api_1:api_stage-0 -> aws:rest_api:rest_api_1: aws:api_deployment:rest_api_1:api_deployment-0 -> aws:api_integration:rest_api_1:integ0: aws:api_deployment:rest_api_1:api_deployment-0 -> aws:api_integration:rest_api_1:integ1: - aws:api_deployment:rest_api_1:api_deployment-0 -> aws:api_method:rest_api_1:api_method-0: - aws:api_deployment:rest_api_1:api_deployment-0 -> aws:api_method:rest_api_1:api_method-1: + aws:api_deployment:rest_api_1:api_deployment-0 -> aws:api_method:rest_api_1:integ0-api_method: + aws:api_deployment:rest_api_1:api_deployment-0 -> aws:api_method:rest_api_1:integ1-api_method: aws:api_deployment:rest_api_1:api_deployment-0 -> aws:rest_api:rest_api_1: aws:rest_api:rest_api_1 -> aws:api_integration:rest_api_1:integ0: aws:rest_api:rest_api_1 -> aws:api_integration:rest_api_1:integ1: - aws:rest_api:rest_api_1 -> aws:api_method:rest_api_1:api_method-0: - aws:rest_api:rest_api_1 -> aws:api_method:rest_api_1:api_method-1: + aws:rest_api:rest_api_1 -> aws:api_method:rest_api_1:integ0-api_method: + aws:rest_api:rest_api_1 -> aws:api_method:rest_api_1:integ1-api_method: aws:rest_api:rest_api_1 -> aws:api_resource:rest_api_1:api_resource-0: aws:rest_api:rest_api_1 -> aws:api_resource:rest_api_1:api_resource-1: aws:rest_api:rest_api_1 -> aws:api_resource:rest_api_1:lambda0: @@ -148,11 +148,11 @@ edges: aws:api_resource:rest_api_1:lambda0 -> aws:api_resource:rest_api_1:api_resource-0: aws:api_resource:rest_api_1:lambda1 -> aws:api_resource:rest_api_1:api_resource-1: aws:api_resource:rest_api_1:api_resource-0 -> aws:api_integration:rest_api_1:integ0: - aws:api_resource:rest_api_1:api_resource-0 -> aws:api_method:rest_api_1:api_method-0: + aws:api_resource:rest_api_1:api_resource-0 -> aws:api_method:rest_api_1:integ0-api_method: aws:api_resource:rest_api_1:api_resource-1 -> aws:api_integration:rest_api_1:integ1: - aws:api_resource:rest_api_1:api_resource-1 -> aws:api_method:rest_api_1:api_method-1: - aws:api_method:rest_api_1:api_method-0 -> aws:api_integration:rest_api_1:integ0: - aws:api_method:rest_api_1:api_method-1 -> aws:api_integration:rest_api_1:integ1: + aws:api_resource:rest_api_1:api_resource-1 -> aws:api_method:rest_api_1:integ1-api_method: + aws:api_method:rest_api_1:integ0-api_method -> aws:api_integration:rest_api_1:integ0: + aws:api_method:rest_api_1:integ1-api_method -> aws:api_integration:rest_api_1:integ1: aws:api_integration:rest_api_1:integ0 -> aws:lambda_permission:integ0-lambda_function_0: aws:api_integration:rest_api_1:integ1 -> aws:lambda_permission:integ1-lambda_function_1: aws:lambda_permission:integ0-lambda_function_0 -> aws:lambda_function:lambda_function_0: diff --git a/pkg/engine2/testdata/2_routes.iac-viz.yaml b/pkg/engine2/testdata/2_routes.iac-viz.yaml index a134775b5..a1922a068 100755 --- a/pkg/engine2/testdata/2_routes.iac-viz.yaml +++ b/pkg/engine2/testdata/2_routes.iac-viz.yaml @@ -42,28 +42,28 @@ resources: lambda_function/lambda_function_1 -> ecr_image/lambda_function_1-image: lambda_function/lambda_function_1 -> iam_role/lambda_function_1-executionrole: - aws:api_method:rest_api_1/api_method-0: - aws:api_method:rest_api_1/api_method-0 -> aws:api_resource:rest_api_1/api_resource-0: - aws:api_method:rest_api_1/api_method-0 -> rest_api/rest_api_1: + aws:api_method:rest_api_1/integ0-api_method: + aws:api_method:rest_api_1/integ0-api_method -> aws:api_resource:rest_api_1/api_resource-0: + aws:api_method:rest_api_1/integ0-api_method -> rest_api/rest_api_1: lambda_permission/integ0-lambda_function_0: lambda_permission/integ0-lambda_function_0 -> lambda_function/lambda_function_0: - aws:api_method:rest_api_1/api_method-1: - aws:api_method:rest_api_1/api_method-1 -> aws:api_resource:rest_api_1/api_resource-1: - aws:api_method:rest_api_1/api_method-1 -> rest_api/rest_api_1: + aws:api_method:rest_api_1/integ1-api_method: + aws:api_method:rest_api_1/integ1-api_method -> aws:api_resource:rest_api_1/api_resource-1: + aws:api_method:rest_api_1/integ1-api_method -> rest_api/rest_api_1: lambda_permission/integ1-lambda_function_1: lambda_permission/integ1-lambda_function_1 -> lambda_function/lambda_function_1: aws:api_integration:rest_api_1/integ0: - aws:api_integration:rest_api_1/integ0 -> aws:api_method:rest_api_1/api_method-0: + aws:api_integration:rest_api_1/integ0 -> aws:api_method:rest_api_1/integ0-api_method: aws:api_integration:rest_api_1/integ0 -> aws:api_resource:rest_api_1/api_resource-0: aws:api_integration:rest_api_1/integ0 -> lambda_permission/integ0-lambda_function_0: aws:api_integration:rest_api_1/integ0 -> rest_api/rest_api_1: aws:api_integration:rest_api_1/integ1: - aws:api_integration:rest_api_1/integ1 -> aws:api_method:rest_api_1/api_method-1: + aws:api_integration:rest_api_1/integ1 -> aws:api_method:rest_api_1/integ1-api_method: aws:api_integration:rest_api_1/integ1 -> aws:api_resource:rest_api_1/api_resource-1: aws:api_integration:rest_api_1/integ1 -> lambda_permission/integ1-lambda_function_1: aws:api_integration:rest_api_1/integ1 -> rest_api/rest_api_1: @@ -71,8 +71,8 @@ resources: aws:api_deployment:rest_api_1/api_deployment-0: aws:api_deployment:rest_api_1/api_deployment-0 -> aws:api_integration:rest_api_1/integ0: aws:api_deployment:rest_api_1/api_deployment-0 -> aws:api_integration:rest_api_1/integ1: - aws:api_deployment:rest_api_1/api_deployment-0 -> aws:api_method:rest_api_1/api_method-0: - aws:api_deployment:rest_api_1/api_deployment-0 -> aws:api_method:rest_api_1/api_method-1: + aws:api_deployment:rest_api_1/api_deployment-0 -> aws:api_method:rest_api_1/integ0-api_method: + aws:api_deployment:rest_api_1/api_deployment-0 -> aws:api_method:rest_api_1/integ1-api_method: aws:api_deployment:rest_api_1/api_deployment-0 -> rest_api/rest_api_1: aws:api_stage:rest_api_1/api_stage-0: diff --git a/pkg/templates/aws/resources/api_integration.yaml b/pkg/templates/aws/resources/api_integration.yaml index 24bc6348e..9d3bdf969 100644 --- a/pkg/templates/aws/resources/api_integration.yaml +++ b/pkg/templates/aws/resources/api_integration.yaml @@ -31,9 +31,9 @@ properties: direction: upstream resources: - selector: aws:api_method - properties: + properties: RestApi: '{{ fieldValue "RestApi" .Self }}' - Resource: '{{ fieldValue "Resource" .Self }}' + unique: true # Each Integration must have its own method RequestParameters: type: map(string,string) operational_rule: