-
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
Constraints satisfication checks #674
Changes from 1 commit
ba0a446
cbf731b
f11e3d9
68dbc1d
49e11db
7088070
5bb4d36
1e979f3
5dc86ec
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 |
---|---|---|
|
@@ -8,64 +8,71 @@ import ( | |
|
||
type ( | ||
// ApplicationConstraint is a struct that represents constraints that can be applied on the entire resource graph | ||
// | ||
// Example | ||
// | ||
// To specify a constraint detailing application level intents in yaml | ||
// | ||
//- scope: application | ||
// operator: add | ||
// node: klotho:execution_unit:my_compute | ||
// | ||
// The end result of this should be that the execution unit construct is added to the construct graph for processing | ||
ApplicationConstraint struct { | ||
Operator ConstraintOperator `yaml:"operator"` | ||
Node core.ResourceId `yaml:"node"` | ||
ReplacementNode core.ResourceId `yaml:"replacement_node"` | ||
} | ||
) | ||
|
||
func (b *ApplicationConstraint) Scope() ConstraintScope { | ||
return EdgeConstraintScope | ||
func (constraint *ApplicationConstraint) Scope() ConstraintScope { | ||
return ApplicationConstraintScope | ||
} | ||
|
||
func (b *ApplicationConstraint) IsSatisfied(dag *core.ResourceGraph) bool { | ||
switch b.Operator { | ||
func (constraint *ApplicationConstraint) IsSatisfied(dag *core.ResourceGraph) bool { | ||
switch constraint.Operator { | ||
case AddConstraintOperator: | ||
// If the add was for a construct, we need to check if any resource references the construct | ||
if b.Node.Provider == core.AbstractConstructProvider { | ||
return len(dag.FindResourcesWithRef(b.Node)) > 0 | ||
if constraint.Node.Provider == core.AbstractConstructProvider { | ||
return len(dag.FindResourcesWithRef(constraint.Node)) > 0 | ||
} | ||
return dag.GetResource(b.Node) != nil | ||
return dag.GetResource(constraint.Node) != nil | ||
case RemoveConstraintOperator: | ||
// If the remove was for a construct, we need to check if any resource references the construct | ||
if b.Node.Provider == core.AbstractConstructProvider { | ||
return len(dag.FindResourcesWithRef(b.Node)) == 0 | ||
if constraint.Node.Provider == core.AbstractConstructProvider { | ||
return len(dag.FindResourcesWithRef(constraint.Node)) == 0 | ||
} | ||
return dag.GetResource(b.Node) == nil | ||
return dag.GetResource(constraint.Node) == nil | ||
case ReplaceConstraintOperator: | ||
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. Shouldn't 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. well for replace my thought is that we will want to check that we copied the edges over soon, so thats why it is separate. If we recieved a remove + add we wouldnt copy edges 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 just figured that'd be a node or construct constraint not an application one. |
||
// We should entail edges are copied from the original source to the new replacement node in the dag | ||
// Ignoring for now, but will be an optimization we can make | ||
|
||
// We should ensure edges are copied from the original source to the new replacement node in the dag | ||
// Ignoring for now, but will be an extra check we can make later to ensure that the Replace constraint is fully satisfied | ||
|
||
// If any of the nodes are abstract constructs, we need to check if any resource references the construct | ||
if b.Node.Provider == core.AbstractConstructProvider && b.ReplacementNode.Provider == core.AbstractConstructProvider { | ||
return len(dag.FindResourcesWithRef(b.Node)) == 0 && len(dag.FindResourcesWithRef(b.ReplacementNode)) > 0 | ||
} else if b.Node.Provider == core.AbstractConstructProvider && b.ReplacementNode.Provider != core.AbstractConstructProvider { | ||
return len(dag.FindResourcesWithRef(b.Node)) == 0 && dag.GetResource(b.ReplacementNode) != nil | ||
} else if b.Node.Provider != core.AbstractConstructProvider && b.ReplacementNode.Provider == core.AbstractConstructProvider { | ||
return dag.GetResource(b.Node) == nil && len(dag.FindResourcesWithRef(b.Node)) > 0 | ||
if constraint.Node.Provider == core.AbstractConstructProvider && constraint.ReplacementNode.Provider == core.AbstractConstructProvider { | ||
return len(dag.FindResourcesWithRef(constraint.Node)) == 0 && len(dag.FindResourcesWithRef(constraint.ReplacementNode)) > 0 | ||
} else if constraint.Node.Provider == core.AbstractConstructProvider && constraint.ReplacementNode.Provider != core.AbstractConstructProvider { | ||
return len(dag.FindResourcesWithRef(constraint.Node)) == 0 && dag.GetResource(constraint.ReplacementNode) != nil | ||
} else if constraint.Node.Provider != core.AbstractConstructProvider && constraint.ReplacementNode.Provider == core.AbstractConstructProvider { | ||
return dag.GetResource(constraint.Node) == nil && len(dag.FindResourcesWithRef(constraint.Node)) > 0 | ||
} | ||
return dag.GetResource(b.Node) == nil && dag.GetResource(b.ReplacementNode) != nil | ||
return dag.GetResource(constraint.Node) == nil && dag.GetResource(constraint.ReplacementNode) != nil | ||
} | ||
return false | ||
} | ||
|
||
func (b *ApplicationConstraint) Conflict(other Constraint) bool { | ||
return false | ||
} | ||
|
||
func (b *ApplicationConstraint) Validate() error { | ||
if b.Operator == ReplaceConstraintOperator && (b.Node == core.ResourceId{} || b.ReplacementNode == core.ResourceId{}) { | ||
func (constraint *ApplicationConstraint) Validate() error { | ||
if constraint.Operator == ReplaceConstraintOperator && (constraint.Node == core.ResourceId{} || constraint.ReplacementNode == core.ResourceId{}) { | ||
return errors.New("replace constraint must have a node and replacement node defined") | ||
} | ||
if b.Operator == ReplaceConstraintOperator && b.Node.Provider != core.AbstractConstructProvider && b.ReplacementNode.Provider == core.AbstractConstructProvider { | ||
if constraint.Operator == ReplaceConstraintOperator && constraint.Node.Provider != core.AbstractConstructProvider && constraint.ReplacementNode.Provider == core.AbstractConstructProvider { | ||
return errors.New("replace constraint cannot replace a resource with an abstract construct") | ||
} | ||
if b.Operator == AddConstraintOperator && (b.Node == core.ResourceId{}) { | ||
if constraint.Operator == AddConstraintOperator && (constraint.Node == core.ResourceId{}) { | ||
return errors.New("add constraint must have a node defined") | ||
} | ||
|
||
if b.Operator == RemoveConstraintOperator && (b.Node == core.ResourceId{}) { | ||
if constraint.Operator == RemoveConstraintOperator && (constraint.Node == core.ResourceId{}) { | ||
return errors.New("remove constraint must have a node defined") | ||
} | ||
return nil | ||
|
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.
I'd like to see some examples with descriptions of what they mean for all these constraints.
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.
im going to do a large documentation pass towards the end of this if thats ok, but can toss in some samples quick for now.
Just avoiding doing too much in case it changes