Skip to content

Commit d581223

Browse files
committed
different refactor
1 parent 0dac345 commit d581223

File tree

1 file changed

+73
-41
lines changed

1 file changed

+73
-41
lines changed

pkg/graph/builder.go

+73-41
Original file line numberDiff line numberDiff line change
@@ -728,60 +728,92 @@ func validateResourceCELExpressions(resources map[string]*Resource, instance *Re
728728
for _, resource := range resources {
729729
// exclude resource from the context
730730
delete(expressionContext, resource.id)
731-
for _, resourceVariable := range resource.variables {
732-
for _, expression := range resourceVariable.Expressions {
733-
_, err = dryRunExpressions(env, expression, resourceIDs, expressionContext)
734-
if err != nil {
735-
return fmt.Errorf("failed to dry-run expression %s: %w", expression, err)
736-
}
737-
}
731+
732+
err := ensureResourceExpressions(env, expressionContext, resource)
733+
if err != nil {
734+
return fmt.Errorf("failed to ensure resource %s expressions: %w", resource.id, err)
738735
}
739-
// validate readyWhen Expressions for resource
740-
// Only accepting expressions accessing the status and spec for now
741-
// and need to evaluate to a boolean type
742-
for _, readyWhenExpression := range resource.readyWhenExpressions {
743-
fieldEnv, err := krocel.DefaultEnvironment(krocel.WithResourceIDs([]string{resource.id}))
744-
if err != nil {
745-
return fmt.Errorf("failed to create CEL environment: %w", err)
746-
}
747736

748-
resourceEmulatedCopy := resource.emulatedObject.DeepCopy()
749-
if resourceEmulatedCopy != nil && resourceEmulatedCopy.Object != nil {
750-
// ignore apiVersion and kind from readyWhenExpression context
751-
delete(resourceEmulatedCopy.Object, "apiVersion")
752-
delete(resourceEmulatedCopy.Object, "kind")
753-
}
754-
context := map[string]*Resource{}
755-
context[resource.id] = &Resource{
756-
emulatedObject: resourceEmulatedCopy,
757-
}
737+
err = ensureReadyWhenExpressions(resource)
738+
if err != nil {
739+
return fmt.Errorf("failed to ensure resource %s readyWhen expressions: %w", resource.id, err)
740+
}
758741

759-
output, err := dryRunExpressions(fieldEnv, readyWhenExpression, []string{resource.id}, context)
760-
if err != nil {
761-
return fmt.Errorf("failed to dry-run expression %s: %w", readyWhenExpression, err)
762-
}
763-
if !krocel.IsBoolType(output) {
764-
return fmt.Errorf("output of readyWhen expression %s can only be of type bool", readyWhenExpression)
765-
}
742+
err = ensureIncludeWhenExpressions(env, includeWhenContext, resource)
743+
if err != nil {
744+
return fmt.Errorf("failed to ensure resource %s includeWhen expressions: %w", resource.id, err)
766745
}
767746

768-
for _, includeWhenExpression := range resource.includeWhenExpressions {
769-
output, err := dryRunExpressions(env, includeWhenExpression, resourceIDs, includeWhenContext)
747+
// include the resource back to the context
748+
expressionContext[resource.id] = resource
749+
}
750+
751+
return nil
752+
}
753+
754+
// ensureResourceExpressions validates the CEL expressions in the resource
755+
// against the resources defined in the resource graph definition.
756+
func ensureResourceExpressions(env *cel.Env, context map[string]*Resource, resource *Resource) error {
757+
// We need to validate the CEL expressions in the resource.
758+
for _, resourceVariable := range resource.variables {
759+
for _, expression := range resourceVariable.Expressions {
760+
_, err := ensureExpression(env, expression, []string{resource.id}, context)
770761
if err != nil {
771-
return fmt.Errorf("failed to dry-run expression %s: %w", includeWhenExpression, err)
772-
}
773-
if !krocel.IsBoolType(output) {
774-
return fmt.Errorf("output of includeWhen expression %s can only be of type bool", includeWhenExpression)
762+
return fmt.Errorf("failed to dry-run expression %s: %w", expression, err)
775763
}
776764
}
777-
// include the resource back to the context
778-
expressionContext[resource.id] = resource
779765
}
766+
return nil
767+
}
768+
769+
// ensureReadyWhenExpressions validates the readyWhen expressions in the resource
770+
// against the resources defined in the resource graph definition.
771+
func ensureReadyWhenExpressions(resource *Resource) error {
772+
env, err := krocel.DefaultEnvironment(krocel.WithResourceIDs([]string{resource.id}))
773+
for _, expression := range resource.readyWhenExpressions {
774+
if err != nil {
775+
return fmt.Errorf("failed to create CEL environment: %w", err)
776+
}
777+
778+
resourceEmulatedCopy := resource.emulatedObject.DeepCopy()
779+
if resourceEmulatedCopy != nil && resourceEmulatedCopy.Object != nil {
780+
// ignore apiVersion and kind from readyWhenExpression context
781+
delete(resourceEmulatedCopy.Object, "apiVersion")
782+
delete(resourceEmulatedCopy.Object, "kind")
783+
}
784+
context := map[string]*Resource{}
785+
context[resource.id] = &Resource{
786+
emulatedObject: resourceEmulatedCopy,
787+
}
780788

789+
output, err := ensureExpression(env, expression, []string{resource.id}, context)
790+
if err != nil {
791+
return fmt.Errorf("failed to dry-run expression %s: %w", expression, err)
792+
}
793+
if !krocel.IsBoolType(output) {
794+
return fmt.Errorf("output of readyWhen expression %s can only be of type bool", expression)
795+
}
796+
}
797+
return nil
798+
}
799+
800+
// ensureIncludeWhenExpressions validates the includeWhen expressions in the resource
801+
func ensureIncludeWhenExpressions(env *cel.Env, context map[string]*Resource, resource *Resource) error {
802+
// We need to validate the CEL expressions in the resource.
803+
for _, expression := range resource.includeWhenExpressions {
804+
output, err := ensureExpression(env, expression, []string{resource.id}, context)
805+
if err != nil {
806+
return fmt.Errorf("failed to dry-run expression %s: %w", expression, err)
807+
}
808+
if !krocel.IsBoolType(output) {
809+
return fmt.Errorf("output of includeWhen expression %s can only be of type bool", expression)
810+
}
811+
}
781812
return nil
782813
}
783814

784-
func dryRunExpressions(env *cel.Env, expression string, resources []string, context map[string]*Resource) (ref.Val, error) {
815+
// ensureExpression validates the CEL expression in the context of the resources
816+
func ensureExpression(env *cel.Env, expression string, resources []string, context map[string]*Resource) (ref.Val, error) {
785817
err := validateCELExpressionContext(env, expression, resources)
786818
if err != nil {
787819
return nil, fmt.Errorf("failed to validate expression %s: %w", expression, err)

0 commit comments

Comments
 (0)