diff --git a/pkg/engine2/operational_eval/graph.go b/pkg/engine2/operational_eval/graph.go index 083a6d5ce..bd13e0b6d 100644 --- a/pkg/engine2/operational_eval/graph.go +++ b/pkg/engine2/operational_eval/graph.go @@ -141,7 +141,7 @@ func (eval *Evaluator) resourceVertices( changes := newChanges() var errs error - addProp := func(prop *knowledgebase.Property) { + addProp := func(prop *knowledgebase.Property) error { vertex := &propertyVertex{ Ref: construct.PropertyRef{Resource: res.ID, Property: prop.Path}, Template: prop, @@ -149,8 +149,9 @@ func (eval *Evaluator) resourceVertices( } errs = errors.Join(errs, changes.AddVertexAndDeps(eval, vertex)) + return nil } - tmpl.LoopProperties(res, addProp) + errs = errors.Join(errs, tmpl.LoopProperties(res, addProp)) return changes, errs } diff --git a/pkg/engine2/path_selection/edge_validity.go b/pkg/engine2/path_selection/edge_validity.go new file mode 100644 index 000000000..eafcaadcb --- /dev/null +++ b/pkg/engine2/path_selection/edge_validity.go @@ -0,0 +1,253 @@ +package path_selection + +import ( + "errors" + "fmt" + "reflect" + + "github.com/dominikbraun/graph" + "github.com/klothoplatform/klotho/pkg/collectionutil" + construct "github.com/klothoplatform/klotho/pkg/construct2" + "github.com/klothoplatform/klotho/pkg/engine2/solution_context" + knowledgebase "github.com/klothoplatform/klotho/pkg/knowledge_base2" +) + +// checkUniquenessValidity checks if the candidate is valid based on if it is intended to be created as unique resource +// for another resource. If the resource was created by an operational rule with the unique flag, we wont consider it as valid +func checkUniquenessValidity( + ctx solution_context.SolutionContext, + src, trgt construct.ResourceId, +) (bool, error) { + // check if the node is a phantom node + source, err := ctx.RawView().Vertex(src) + switch { + case errors.Is(err, graph.ErrVertexNotFound): + source = &construct.Resource{ID: src} + case err != nil: + return false, err + } + + target, err := ctx.RawView().Vertex(trgt) + switch { + case errors.Is(err, graph.ErrVertexNotFound): + target = &construct.Resource{ID: trgt} + case err != nil: + return false, err + } + + // check if the upstream resource has a unique rule for the matched resource type + valid, err := checkProperties(ctx, target, source, knowledgebase.DirectionUpstream) + if err != nil { + return false, err + } + if !valid { + return false, nil + } + + // check if the downstream resource has a unique rule for the matched resource type + valid, err = checkProperties(ctx, source, target, knowledgebase.DirectionDownstream) + if err != nil { + return false, err + } + if !valid { + return false, nil + } + + return true, nil +} + +// check properties checks the resource's properties to make sure its not supposed to have a unique toCheck type +// if it is, it makes sure that the toCheck is not used elsewhere or already being used as its unique type +func checkProperties(ctx solution_context.SolutionContext, resource, toCheck *construct.Resource, direction knowledgebase.Direction) (bool, error) { + //check if the upstream resource has a unique rule for the matched resource type + template, err := ctx.KnowledgeBase().GetResourceTemplate(resource.ID) + if err != nil || template == nil { + return false, fmt.Errorf("error getting resource template for resource %s: %w", resource.ID, err) + } + explicitlyNotValid := false + explicitlyValid := false + err = template.LoopProperties(resource, func(prop *knowledgebase.Property) error { + if prop.OperationalRule == nil { + return nil + } + for _, step := range prop.OperationalRule.Steps { + if !step.Unique || step.Direction != direction { + continue + } + //check if the upstream resource is the same type as the matched resource type + for _, selector := range step.Resources { + match, err := selector.CanUse(solution_context.DynamicCtx(ctx), knowledgebase.DynamicValueData{Resource: resource.ID}, + toCheck) + if err != nil { + return fmt.Errorf("error checking if resource %s matches selector %s: %w", toCheck, selector, err) + } + // if its a match for the selectors, lets ensure that it has a dependency and exists in the properties of the rul + if !match { + continue + } + property, err := resource.GetProperty(prop.Path) + if err != nil { + return fmt.Errorf("error getting property %s for resource %s: %w", prop.Path, toCheck, err) + } + if property != nil { + if checkIfPropertyContainsResource(property, toCheck.ID) { + explicitlyValid = true + return knowledgebase.ErrStopWalk + } + } else { + loneDep, err := checkIfLoneDependency(ctx, resource.ID, toCheck.ID, direction) + if err != nil { + return err + } + if loneDep { + explicitlyValid = true + return knowledgebase.ErrStopWalk + } + } + explicitlyNotValid = true + return knowledgebase.ErrStopWalk + } + } + return nil + }) + if err != nil { + return false, err + } + if explicitlyValid { + return true, nil + } else if explicitlyNotValid { + return false, nil + } + + // if we cant validate uniqueness off of properties we then need to see if the resource was created to be unique + // check if the upstream resource was created as a unique resource by any of its direct dependents + valid, err := checkIfCreatedAsUniqueValidity(ctx, resource, toCheck, direction) + if err != nil { + return false, err + } + if !valid { + return false, nil + } + return true, nil +} + +// checkIfPropertyContainsResource checks if the property contains the resource id passed in +func checkIfPropertyContainsResource(property interface{}, resource construct.ResourceId) bool { + switch reflect.ValueOf(property).Kind() { + case reflect.Slice, reflect.Array: + for _, p := range property.([]construct.ResourceId) { + if p.Matches(resource) { + return true + } + } + case reflect.Struct: + if id, ok := property.(construct.ResourceId); ok && id.Matches(resource) { + return true + } + if pref, ok := property.(construct.PropertyRef); ok && pref.Resource.Matches(resource) { + return true + } + } + return false +} + +func checkIfLoneDependency(ctx solution_context.SolutionContext, resource, toCheck construct.ResourceId, direction knowledgebase.Direction) (bool, error) { + var resources []construct.ResourceId + var err error + // we are going to check if the resource was created as a unique resource by any of its direct dependents. if it was and that + // dependent is not the other id, its not a valid candidate for this edge + + // here the direction matches because we are checking the resource for being used by another resource similar to other + if direction == knowledgebase.DirectionDownstream { + resources, err = solution_context.Upstream(ctx, resource, knowledgebase.ResourceDirectLayer) + if err != nil { + return false, err + } + } else { + resources, err = solution_context.Downstream(ctx, resource, knowledgebase.ResourceDirectLayer) + if err != nil { + return false, err + } + } + if len(resources) == 0 { + return true, nil + } else if len(resources) == 1 && resources[0].Matches(toCheck) { + return true, nil + } + return false, nil +} + +// checkIfCreatedAsUnique checks if the resource was created as a unique resource by any of its direct dependents. if it was and that +// dependent is not the other id, its not a valid candidate for this edge +func checkIfCreatedAsUniqueValidity(ctx solution_context.SolutionContext, resource, other *construct.Resource, direction knowledgebase.Direction) (bool, error) { + var resources []construct.ResourceId + var foundMatch bool + var err error + // we are going to check if the resource was created as a unique resource by any of its direct dependents. if it was and that + // dependent is not the other id, its not a valid candidate for this edge + + // here the direction matches because we are checking the resource for being used by another resource similar to other + if direction == knowledgebase.DirectionUpstream { + resources, err = solution_context.Upstream(ctx, resource.ID, knowledgebase.ResourceDirectLayer) + if err != nil { + return false, err + } + } else { + resources, err = solution_context.Downstream(ctx, resource.ID, knowledgebase.ResourceDirectLayer) + if err != nil { + return false, err + } + } + // if the dependencies contains the other resource, dont run any checks as we assume its valid + if collectionutil.Contains(resources, other.ID) { + return true, nil + } + + for _, res := range resources { + + // check if the upstream resource has a unique rule for the matched resource type + template, err := ctx.KnowledgeBase().GetResourceTemplate(res) + if err != nil || template == nil { + return false, fmt.Errorf("error getting resource template for resource %s: %w", res, err) + } + currRes, err := ctx.RawView().Vertex(res) + if err != nil { + return false, err + } + err = template.LoopProperties(currRes, func(prop *knowledgebase.Property) error { + if prop.OperationalRule == nil { + return nil + } + for _, step := range prop.OperationalRule.Steps { + // we want the step to be the opposite of the direction passed in so we know its creating the resource in the direction of the resource + // since we are looking at the resources dependencies + if !step.Unique || step.Direction == direction { + continue + } + //check if the upstream resource is the same type as the matched resource type + for _, selector := range step.Resources { + match, err := selector.CanUse(solution_context.DynamicCtx(ctx), knowledgebase.DynamicValueData{Resource: currRes.ID}, + resource) + if err != nil { + return fmt.Errorf("error checking if resource %s matches selector %s: %w", other, selector, err) + } + // if its a match for the selectors, lets ensure that it has a dependency and exists in the properties of the rul + if !match { + continue + } + + foundMatch = true + return knowledgebase.ErrStopWalk + } + } + return nil + }) + if err != nil { + return false, err + } + if foundMatch { + return false, nil + } + } + return true, nil +} diff --git a/pkg/engine2/path_selection/path_expansion.go b/pkg/engine2/path_selection/path_expansion.go index 530c7e929..df206ba2f 100644 --- a/pkg/engine2/path_selection/path_expansion.go +++ b/pkg/engine2/path_selection/path_expansion.go @@ -182,7 +182,7 @@ func handleProperties( continue } - handleProp := func(prop *knowledgebase.Property) { + handleProp := func(prop *knowledgebase.Property) error { oldId := res.ID opRuleCtx := operational_rule.OperationalRuleContext{ Solution: ctx, @@ -190,7 +190,7 @@ func handleProperties( Data: knowledgebase.DynamicValueData{Resource: res.ID}, } if prop.OperationalRule == nil { - return + return nil } for _, step := range prop.OperationalRule.Steps { for _, selector := range step.Resources { @@ -219,8 +219,9 @@ func handleProperties( if prop.Namespace && oldId.Namespace != res.ID.Namespace { errs = errors.Join(errs, construct.ReplaceResource(g, oldId, res)) } + return nil } - rt.LoopProperties(res, handleProp) + errs = errors.Join(errs, rt.LoopProperties(res, handleProp)) } return errs } @@ -334,6 +335,7 @@ func ExpandPath( construct.SimpleEdge{Source: input.Dep.Source.ID, Target: input.Dep.Target.ID}, source.id, target.id, source.divideWeightBy, target.divideWeightBy, + input.Classification, ctx.KnowledgeBase()) tmpl := ctx.KnowledgeBase().GetEdgeTemplate(source.id, target.id) @@ -358,7 +360,15 @@ func ExpandPath( } } - err := input.TempGraph.AddEdge(source.id, target.id, graph.EdgeWeight(weight)) + valid, err := checkUniquenessValidity(ctx, source.id, target.id) + if err != nil { + errs = errors.Join(errs, err) + } + if !valid { + return + } + + err = input.TempGraph.AddEdge(source.id, target.id, graph.EdgeWeight(weight)) if err != nil && !errors.Is(err, graph.ErrEdgeAlreadyExists) && !errors.Is(err, graph.ErrEdgeCreatesCycle) { errs = errors.Join(errs, err) } diff --git a/pkg/engine2/path_selection/path_selection.go b/pkg/engine2/path_selection/path_selection.go index c03960432..429e99737 100644 --- a/pkg/engine2/path_selection/path_selection.go +++ b/pkg/engine2/path_selection/path_selection.go @@ -54,7 +54,7 @@ func BuildPathSelectionGraph( if err != nil && !errors.Is(err, graph.ErrVertexAlreadyExists) { return nil, fmt.Errorf("failed to add target vertex to path selection graph for %s: %w", dep, err) } - err = tempGraph.AddEdge(dep.Source, dep.Target, graph.EdgeWeight(calculateEdgeWeight(dep, dep.Source, dep.Target, 0, 0, kb))) + err = tempGraph.AddEdge(dep.Source, dep.Target, graph.EdgeWeight(calculateEdgeWeight(dep, dep.Source, dep.Target, 0, 0, classification, kb))) if err != nil { return nil, err } @@ -103,7 +103,7 @@ func BuildPathSelectionGraph( if !prevRes.IsZero() { edgeTemplate := kb.GetEdgeTemplate(prevRes, id) if edgeTemplate != nil && !edgeTemplate.DirectEdgeOnly { - err := tempGraph.AddEdge(prevRes, id, graph.EdgeWeight(calculateEdgeWeight(dep, prevRes, id, 0, 0, kb))) + err := tempGraph.AddEdge(prevRes, id, graph.EdgeWeight(calculateEdgeWeight(dep, prevRes, id, 0, 0, classification, kb))) if err != nil { return nil, err } @@ -162,6 +162,7 @@ func calculateEdgeWeight( dep construct.SimpleEdge, source, target construct.ResourceId, divideSourceBy, divideTargetBy int, + classification string, kb knowledgebase.TemplateKB, ) int { if divideSourceBy == 0 { @@ -170,6 +171,21 @@ func calculateEdgeWeight( if divideTargetBy == 0 { divideTargetBy = 1 } + + // check to see if the resources match the classification being solved and account for their weights accordingly + sourceTemplate, err := kb.GetResourceTemplate(source) + if err == nil || sourceTemplate != nil { + if collectionutil.Contains(sourceTemplate.Classification.Is, classification) { + divideSourceBy += 10 + } + } + targetTemplate, err := kb.GetResourceTemplate(target) + if err == nil || targetTemplate != nil { + if collectionutil.Contains(targetTemplate.Classification.Is, classification) { + divideTargetBy += 10 + } + } + // We start with a weight of 10 for glue and 10000 for functionality for newly created edges of "phantom" resources // We do so to allow for the preference of existing resources since we can multiply these weights by a decimal // This will achieve priority for existing resources over newly created ones diff --git a/pkg/infra/iac3/templates/aws/eks_cluster/factory.ts b/pkg/infra/iac3/templates/aws/eks_cluster/factory.ts index 9fa964978..165a82f41 100644 --- a/pkg/infra/iac3/templates/aws/eks_cluster/factory.ts +++ b/pkg/infra/iac3/templates/aws/eks_cluster/factory.ts @@ -25,5 +25,6 @@ function properties(object: aws.eks.Cluster, args: Args) { Name: object.name, ClusterEndpoint: object.endpoint, CertificateAuthorityData: object.certificateAuthorities[0].data, + ClusterSecurityGroup: object.vpcConfig.clusterSecurityGroupId, } } \ No newline at end of file diff --git a/pkg/infra/iac3/templates/aws/security_group_rule/factory.ts b/pkg/infra/iac3/templates/aws/security_group_rule/factory.ts new file mode 100644 index 000000000..c33e0f9a2 --- /dev/null +++ b/pkg/infra/iac3/templates/aws/security_group_rule/factory.ts @@ -0,0 +1,30 @@ +import * as aws from '@pulumi/aws' +import * as pulumi from '@pulumi/pulumi' + +interface Args { + Name: string + Description: string + FromPort: number + ToPort: number + Protocol: string + CidrBlocks: pulumi.Input[] + SecurityGroupId: pulumi.Input + Type: string +} + +function create(args: Args): aws.ec2.SecurityGroupRule { + return new aws.ec2.SecurityGroupRule(args.Name, { + description: args.Description, + type: args.Type, + cidrBlocks: pulumi + .all(args.CidrBlocks) + .apply( + (cidrBlocks) => + cidrBlocks.filter((cidrBlock) => cidrBlock !== undefined) as string[] + ), + fromPort: args.FromPort, + protocol: args.Protocol, + toPort: args.ToPort, + securityGroupId: args.SecurityGroupId, + }) +} diff --git a/pkg/infra/iac3/templates/aws/security_group_rule/package.json b/pkg/infra/iac3/templates/aws/security_group_rule/package.json new file mode 100644 index 000000000..079d99ebf --- /dev/null +++ b/pkg/infra/iac3/templates/aws/security_group_rule/package.json @@ -0,0 +1,7 @@ +{ + "name": "security_group_rule", + "dependencies": { + "@pulumi/pulumi": "^3.69.0", + "@pulumi/aws": "^5.37.0" + } +} diff --git a/pkg/knowledge_base2/resource_template.go b/pkg/knowledge_base2/resource_template.go index bfffc7d6b..2d3fdcd68 100644 --- a/pkg/knowledge_base2/resource_template.go +++ b/pkg/knowledge_base2/resource_template.go @@ -3,6 +3,7 @@ package knowledgebase2 import ( "bytes" "crypto/sha256" + "errors" "fmt" "reflect" "regexp" @@ -381,13 +382,23 @@ func (template ResourceTemplate) GetProperty(name string) *Property { return nil } -func (tmpl ResourceTemplate) LoopProperties(res *construct.Resource, addProp func(*Property)) { +var ErrStopWalk = errors.New("stop walk") + +func (tmpl ResourceTemplate) LoopProperties(res *construct.Resource, addProp func(*Property) error) error { queue := []Properties{tmpl.Properties} var props Properties + var errs error for len(queue) > 0 { props, queue = queue[0], queue[1:] for _, prop := range props { - addProp(prop) + err := addProp(prop) + if err != nil { + if errors.Is(err, ErrStopWalk) { + return nil + } + errs = errors.Join(errs, err) + continue + } if strings.HasPrefix(prop.Type, "list") || strings.HasPrefix(prop.Type, "set") { p, err := res.GetProperty(prop.Path) @@ -430,4 +441,5 @@ func (tmpl ResourceTemplate) LoopProperties(res *construct.Resource, addProp fun } } } + return errs } diff --git a/pkg/templates/aws/edges/ecs_task_definition-efs_mount_target.yaml b/pkg/templates/aws/edges/ecs_task_definition-efs_mount_target.yaml new file mode 100644 index 000000000..cf02f290b --- /dev/null +++ b/pkg/templates/aws/edges/ecs_task_definition-efs_mount_target.yaml @@ -0,0 +1,2 @@ +source: aws:ecs_task_definition +target: aws:efs_mount_target diff --git a/pkg/templates/aws/edges/eks_cluster-vpc.yaml b/pkg/templates/aws/edges/eks_cluster-vpc.yaml index 1e65914ef..153e504cb 100644 --- a/pkg/templates/aws/edges/eks_cluster-vpc.yaml +++ b/pkg/templates/aws/edges/eks_cluster-vpc.yaml @@ -18,3 +18,11 @@ operational_rules: - selector: aws:eks_add_on:vpc-cni properties: AddOnName: vpc-cni + - steps: + - resource: '{{ .Target }}' + direction: upstream + resources: + - selector: aws:security_group_rule + properties: + SecurityGroupId: '{{ fieldRef "ClusterSecurityGroup" .Source }}' + Type: ingress \ No newline at end of file diff --git a/pkg/templates/aws/edges/eks_fargate_profile-eks_cluster.yaml b/pkg/templates/aws/edges/eks_fargate_profile-eks_cluster.yaml index 6539dfc14..8aefd497d 100644 --- a/pkg/templates/aws/edges/eks_fargate_profile-eks_cluster.yaml +++ b/pkg/templates/aws/edges/eks_fargate_profile-eks_cluster.yaml @@ -35,7 +35,7 @@ operational_rules: - if: | # check if the config map is in place {{ $configMaps := allUpstream "kubernetes:config_map" .Target }} {{ range $index, $cm := $configMaps }} - {{- if eq (fieldValue "ObjectMeta.Name" $cm) "aws-logging" }} + {{- if eq (fieldValue "Object.metadata.name" $cm) "aws-logging" }} false {{break}} {{- end }} @@ -52,7 +52,8 @@ operational_rules: - selector: kubernetes:namespace properties: Object: - name: aws-observability + metadata: + name: aws-observability configuration_rules: - resource: kubernetes:config_map:aws-logging configuration: diff --git a/pkg/templates/aws/edges/kubernetes_pod-eks_fargate_profile.yaml b/pkg/templates/aws/edges/kubernetes_pod-eks_fargate_profile.yaml index 1883da191..8949ce5a3 100644 --- a/pkg/templates/aws/edges/kubernetes_pod-eks_fargate_profile.yaml +++ b/pkg/templates/aws/edges/kubernetes_pod-eks_fargate_profile.yaml @@ -1,2 +1,4 @@ source: kubernetes:pod target: aws:eks_fargate_profile + +edge_weight_multiplier: 1.1 \ No newline at end of file diff --git a/pkg/templates/aws/edges/kubernetes_pod-eks_node_group.yaml b/pkg/templates/aws/edges/kubernetes_pod-eks_node_group.yaml index 545a1bc8a..2445e5fff 100644 --- a/pkg/templates/aws/edges/kubernetes_pod-eks_node_group.yaml +++ b/pkg/templates/aws/edges/kubernetes_pod-eks_node_group.yaml @@ -1,2 +1,3 @@ source: kubernetes:pod target: aws:eks_node_group + diff --git a/pkg/templates/aws/edges/kubernetes_service_account-iam_role.yaml b/pkg/templates/aws/edges/kubernetes_service_account-iam_role.yaml index ceceb9d79..63f409e06 100644 --- a/pkg/templates/aws/edges/kubernetes_service_account-iam_role.yaml +++ b/pkg/templates/aws/edges/kubernetes_service_account-iam_role.yaml @@ -10,7 +10,7 @@ operational_rules: - if: | {{ $needsCreation := false}} - {{ $charts := allDownstream "kubernetes:helm_chart" .Source }} + {{ $charts := allUpstream "kubernetes:helm_chart" .Source }} {{ range $index, $chart := $charts }} {{- if and (eq (fieldValue "Repo" $chart) "https://aws.github.io/eks-charts") (eq (fieldValue "Chart" $chart) "aws-load-balancer-controller") }} {{ $needsCreation = true }} diff --git a/pkg/templates/aws/edges/security_group-eks_cluster.yaml b/pkg/templates/aws/edges/security_group-eks_cluster.yaml index f4c9cdf4d..55dd5b289 100644 --- a/pkg/templates/aws/edges/security_group-eks_cluster.yaml +++ b/pkg/templates/aws/edges/security_group-eks_cluster.yaml @@ -9,7 +9,7 @@ operational_rules: value: - Description: Allows ingress traffic from the EKS control plane CidrBlocks: - - Property: 0.0.0.0/0 + - 0.0.0.0/0 FromPort: 9443 Protocol: TCP ToPort: 9443 diff --git a/pkg/templates/aws/edges/security_group_rule-security_group.yaml b/pkg/templates/aws/edges/security_group_rule-security_group.yaml new file mode 100644 index 000000000..3ccf2584d --- /dev/null +++ b/pkg/templates/aws/edges/security_group_rule-security_group.yaml @@ -0,0 +1,9 @@ +source: aws:security_group_rule +target: aws:security_group +deployment_order_reversed: true +operational_rules: + - configuration_rules: + - resource: '{{ .Source }}' + configuration: + field: SecurityGroup + value: '{{ .Target }}' diff --git a/pkg/templates/aws/edges/security_group_rule-vpc.yaml b/pkg/templates/aws/edges/security_group_rule-vpc.yaml new file mode 100644 index 000000000..16b03d280 --- /dev/null +++ b/pkg/templates/aws/edges/security_group_rule-vpc.yaml @@ -0,0 +1,25 @@ +source: aws:security_group_rule +target: aws:vpc +operational_rules: + - configuration_rules: + - resource: '{{ .Source }}' + configuration: + field: Description + value: Allow ingress traffic from within the vpc + - resource: '{{ .Source }}' + configuration: + field: FromPort + value: 0 + - resource: '{{ .Source }}' + configuration: + field: Protocol + value: '-1' + - resource: '{{ .Source }}' + configuration: + field: ToPort + value: 0 + - resource: '{{ .Source }}' + configuration: + field: CidrBlocks + value: + - '{{ fieldValue "CidrBlock" .Target }}' \ No newline at end of file diff --git a/pkg/templates/aws/edges/service_api.yaml b/pkg/templates/aws/edges/service_api.yaml index a2be42710..e1a89b10f 100644 --- a/pkg/templates/aws/edges/service_api.yaml +++ b/pkg/templates/aws/edges/service_api.yaml @@ -3,10 +3,6 @@ resource: aws:SERVICE_API sources: - aws:lambda_function - aws:app_runner_service - - aws:ecs_service - - kubernetes:deployment - - kubernetes:pod - - aws:ec2_instance - aws:subnet targets: - aws:lambda_function diff --git a/pkg/templates/aws/resources/eks_cluster.yaml b/pkg/templates/aws/resources/eks_cluster.yaml index a2707d9e1..1f4b92af5 100644 --- a/pkg/templates/aws/resources/eks_cluster.yaml +++ b/pkg/templates/aws/resources/eks_cluster.yaml @@ -62,6 +62,10 @@ properties: type: string configuration_disabled: true deploy_time: true + ClusterSecurityGroup: + type: string + configuration_disabled: true + deploy_time: true classification: is: diff --git a/pkg/templates/aws/resources/security_group_rule.yaml b/pkg/templates/aws/resources/security_group_rule.yaml new file mode 100644 index 000000000..c821a846f --- /dev/null +++ b/pkg/templates/aws/resources/security_group_rule.yaml @@ -0,0 +1,19 @@ +qualified_type_name: aws:security_group_rule +description: Security Group Rule + +properties: + Description: + type: string + CidrBlocks: + type: list(string) + FromPort: + type: int + ToPort: + type: int + Protocol: + type: string + SecurityGroupId: + type: string # Not resource type because we need deploy time properties to be able to exist here + default_value: '{{ upstream "aws:security_group" .Self }}#Id' + Type: + type: string \ No newline at end of file diff --git a/pkg/templates/kubernetes/resources/deployment.yaml b/pkg/templates/kubernetes/resources/deployment.yaml index df76650b4..fc6dd6f12 100644 --- a/pkg/templates/kubernetes/resources/deployment.yaml +++ b/pkg/templates/kubernetes/resources/deployment.yaml @@ -54,6 +54,11 @@ properties: maxSurge: type: any default_value: 1 + +path_satisfaction: + as_target: + - network#Cluster#Subnets + classification: is: - compute diff --git a/pkg/templates/kubernetes/resources/pod.yaml b/pkg/templates/kubernetes/resources/pod.yaml index 61e5ab982..191edda29 100644 --- a/pkg/templates/kubernetes/resources/pod.yaml +++ b/pkg/templates/kubernetes/resources/pod.yaml @@ -34,6 +34,10 @@ properties: spec: type: model(kubernetes:PodSpec) +path_satisfaction: + as_target: + - network#Cluster#Subnets + classification: is: - compute diff --git a/pkg/templates/kubernetes/resources/service.yaml b/pkg/templates/kubernetes/resources/service.yaml index b37213e50..0d096bd1f 100644 --- a/pkg/templates/kubernetes/resources/service.yaml +++ b/pkg/templates/kubernetes/resources/service.yaml @@ -58,6 +58,10 @@ properties: sessionAffinity: type: string +path_satisfaction: + as_target: + - network#Cluster#Subnets + delete_context: requires_no_upstream_or_downstream: true views: diff --git a/pkg/templates/kubernetes/resources/service_account.yaml b/pkg/templates/kubernetes/resources/service_account.yaml index 2fe170ccb..6556016cf 100644 --- a/pkg/templates/kubernetes/resources/service_account.yaml +++ b/pkg/templates/kubernetes/resources/service_account.yaml @@ -39,6 +39,8 @@ classification: is: - role - kubernetes + - permissions + delete_context: require_no_upstream: true views: