-
Notifications
You must be signed in to change notification settings - Fork 40
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
allow imported resources to be path expanded and more state reading #979
Changes from 1 commit
df9526b
1c60591
5ed9ded
437fe51
c8682c5
82fc05c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,7 @@ import ( | |
"fmt" | ||
"strings" | ||
|
||
"github.com/dominikbraun/graph" | ||
"github.com/klothoplatform/klotho/pkg/collectionutil" | ||
construct "github.com/klothoplatform/klotho/pkg/construct" | ||
"github.com/klothoplatform/klotho/pkg/engine/solution_context" | ||
|
@@ -20,6 +21,58 @@ type ( | |
} | ||
) | ||
|
||
// checkDoesNotModifyImportedResource checks if there is an imported resource that would be modified due to the edge | ||
// If there is an edge rule modifying the resource then we consider the edge to be invalid | ||
func checkDoesNotModifyImportedResource( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: the "does not" kinda throws me for a loop - usually I like to keep functions in the positive (and properties, when the default value isn't important) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i can change the naming and make it return the inverse then |
||
source, target construct.ResourceId, | ||
ctx solution_context.SolutionContext, | ||
et *knowledgebase.EdgeTemplate, | ||
) (bool, error) { | ||
// see if the source resource exists in the graph | ||
sourceResource, srcErr := ctx.RawView().Vertex(source) | ||
// see if the target resource exists in the graph | ||
targetResource, trgtErr := ctx.RawView().Vertex(target) | ||
if errors.Is(srcErr, graph.ErrVertexNotFound) && errors.Is(trgtErr, graph.ErrVertexNotFound) { | ||
return true, nil | ||
} | ||
|
||
if et == nil { | ||
et = ctx.KnowledgeBase().GetEdgeTemplate(source, target) | ||
} | ||
|
||
checkRules := func(resources construct.ResourceList) (bool, error) { | ||
if len(resources) == 0 { | ||
return true, nil | ||
} | ||
for _, rule := range et.OperationalRules { | ||
for _, config := range rule.ConfigurationRules { | ||
dynamicCtx := solution_context.DynamicCtx(ctx) | ||
id := construct.ResourceId{} | ||
// we ignore the error since phantom resources will cause errors in the decoding of templates | ||
_ = dynamicCtx.ExecuteDecode(config.Resource, knowledgebase.DynamicValueData{ | ||
Edge: &construct.Edge{ | ||
Source: source, | ||
Target: target, | ||
}}, &id) | ||
|
||
if resources.MatchesAny(id) { | ||
return false, nil | ||
} | ||
} | ||
} | ||
return true, nil | ||
} | ||
|
||
importedResources := construct.ResourceList{} | ||
if sourceResource != nil && sourceResource.Imported { | ||
importedResources = append(importedResources, source) | ||
} | ||
if targetResource != nil && targetResource.Imported { | ||
importedResources = append(importedResources, target) | ||
} | ||
return checkRules(importedResources) | ||
} | ||
|
||
// checkCandidatesValidity checks if the candidate is valid based on the validity of its own path satisfaction rules and namespace | ||
func checkCandidatesValidity( | ||
ctx solution_context.SolutionContext, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -308,8 +308,18 @@ func expandPath( | |
path construct.Path, | ||
resultGraph construct.Graph, | ||
) error { | ||
|
||
if len(path) == 2 { | ||
return nil | ||
doesNotModifyImport, err := checkDoesNotModifyImportedResource(input.SatisfactionEdge.Source.ID, | ||
input.SatisfactionEdge.Target.ID, ctx, nil) | ||
if err != nil { | ||
return err | ||
} | ||
if !doesNotModifyImport { | ||
// Because the direct edge will cause modifications to an imported resource, we need to remove the direct edge | ||
return input.TempGraph.RemoveEdge(input.SatisfactionEdge.Source.ID, | ||
input.SatisfactionEdge.Target.ID) | ||
} | ||
} | ||
zap.S().Debugf("Resolving path %s", path) | ||
|
||
|
@@ -434,10 +444,17 @@ func expandPath( | |
if !tmpl.Unique.CanAdd(edges, source.id, target.id) { | ||
return | ||
} | ||
|
||
doesNotModifyImport, err := checkDoesNotModifyImportedResource(source.id, target.id, ctx, tmpl) | ||
if err != nil { | ||
errs = errors.Join(errs, err) | ||
return | ||
} | ||
if !doesNotModifyImport { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit continued: this further leans me towards the function should be |
||
return | ||
} | ||
// if the edge doesnt exist in the actual graph and there is any uniqueness constraint, | ||
// then we need to check uniqueness validity | ||
_, err := ctx.RawView().Edge(source.id, target.id) | ||
_, err = ctx.RawView().Edge(source.id, target.id) | ||
if errors.Is(err, graph.ErrEdgeNotFound) { | ||
if tmpl.Unique.Source || tmpl.Unique.Target { | ||
valid, err := checkUniquenessValidity(ctx, source.id, target.id) | ||
|
@@ -527,7 +544,7 @@ func connectThroughNamespace(src, target *construct.Resource, ctx solution_conte | |
continue | ||
} | ||
// if we have a namespace resource that is not the same as the target namespace resource | ||
tg, err := BuildPathSelectionGraph(construct.SimpleEdge{Source: res, Target: target.ID}, kb, "") | ||
tg, err := BuildPathSelectionGraph(construct.SimpleEdge{Source: res, Target: target.ID}, kb, "", true) | ||
if err != nil { | ||
continue | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: If neither of these are template resource ids (ones without names), then IMO
==
is much clearer.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the selector may not have a name
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Which is the selector?
uids
comes from downstream so they're real resources. Ifresource.ID
is the selector, then it needs to be the receiver (per the godoc)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah youre right neither of these is the selector, i can change it to ==