Skip to content

Commit

Permalink
Merge pull request #3 from stevendborrelli/refactor-conditional
Browse files Browse the repository at this point in the history
change fields from condition/expression to condition
  • Loading branch information
stevendborrelli authored Nov 14, 2023
2 parents f221df1 + 6c1285a commit ea49546
Show file tree
Hide file tree
Showing 13 changed files with 61 additions and 72 deletions.
9 changes: 8 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,17 @@ GO := go

GOLANGCI_VERSION := 1.55.2

generate:
$(GO) generate ./...

test:
$(GO) test ./...

lint:
$(DOCKER) run --rm -v $(CURDIR):/app -v ~/.cache/golangci-lint/v$(GOLANGCI_VERSION):/root/.cache -w /app golangci/golangci-lint:v$(GOLANGCI_VERSION) golangci-lint run --fix

reviewable: test lint
reviewable: generate test lint

# run a local process for crossplane render
run-local:
$(GO) run . --debug --insecure
10 changes: 4 additions & 6 deletions condition.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ import (
"github.com/crossplane/crossplane-runtime/pkg/errors"

fnv1beta1 "github.com/crossplane/function-sdk-go/proto/v1beta1"

"github.com/stevendborrelli/function-conditional-patch-and-transform/input/v1beta1"
)

// NewCELEnvironment sets up the CEL Environment
Expand All @@ -30,8 +28,8 @@ func ToCELVars(req *fnv1beta1.RunFunctionRequest) map[string]any {
}

// EvaluateCondition will evaluate a CEL expression
func EvaluateCondition(cs v1beta1.ConditionSpec, req *fnv1beta1.RunFunctionRequest) (bool, error) {
if cs.Expression == "" {
func EvaluateCondition(expression *string, req *fnv1beta1.RunFunctionRequest) (bool, error) {
if expression == nil {
return false, nil
}

Expand All @@ -40,7 +38,7 @@ func EvaluateCondition(cs v1beta1.ConditionSpec, req *fnv1beta1.RunFunctionReque
return false, errors.Wrap(err, "CEL Env error")
}

ast, iss := env.Parse(cs.Expression)
ast, iss := env.Parse(*expression)
if iss.Err() != nil {
return false, errors.Wrap(iss.Err(), "CEL Parse error")
}
Expand All @@ -56,7 +54,7 @@ func EvaluateCondition(cs v1beta1.ConditionSpec, req *fnv1beta1.RunFunctionReque
if !reflect.DeepEqual(checked.OutputType(), cel.BoolType) {
return false, errors.Errorf(
"CEL Type error: expression '%s' must return a boolean, got %v instead",
cs.Expression,
*expression,
checked.OutputType())
}

Expand Down
30 changes: 17 additions & 13 deletions condition_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ func TestEvaluateCondition(t *testing.T) {
oxr := `{"apiVersion":"nopexample.org/v1alpha1","kind":"XNopResource","metadata":{"name":"test-resource"},"spec":{"env":"dev","render":true},"status":{"id":"123","ready":false} }`

type args struct {
cs v1beta1.ConditionSpec
req *fnv1beta1.RunFunctionRequest
condition v1beta1.Condition
req *fnv1beta1.RunFunctionRequest
}
type want struct {
ret bool
Expand All @@ -35,7 +35,7 @@ func TestEvaluateCondition(t *testing.T) {
}{
"CELParseError": {
args: args{
cs: v1beta1.ConditionSpec{Expression: "field = value"},
condition: strPtr("field = value"),
req: &fnv1beta1.RunFunctionRequest{
Input: resource.MustStructObject(&v1beta1.Resources{
Resources: []v1beta1.ComposedTemplate{
Expand Down Expand Up @@ -64,7 +64,7 @@ func TestEvaluateCondition(t *testing.T) {
},
"CELTypeError": {
args: args{
cs: v1beta1.ConditionSpec{Expression: "size(desired.resources)"},
condition: strPtr("size(desired.resources)"),
req: &fnv1beta1.RunFunctionRequest{
Input: resource.MustStructObject(&v1beta1.Resources{
Resources: []v1beta1.ComposedTemplate{
Expand Down Expand Up @@ -93,7 +93,7 @@ func TestEvaluateCondition(t *testing.T) {
},
"KeyError": {
args: args{
cs: v1beta1.ConditionSpec{Expression: "badkey"},
condition: strPtr("badkey"),
req: &fnv1beta1.RunFunctionRequest{
Input: resource.MustStructObject(&v1beta1.Resources{
Resources: []v1beta1.ComposedTemplate{
Expand Down Expand Up @@ -122,7 +122,7 @@ func TestEvaluateCondition(t *testing.T) {
},
"TrueDesired": {
args: args{
cs: v1beta1.ConditionSpec{Expression: "desired.composite.resource.spec.env == \"dev\" "},
condition: strPtr("desired.composite.resource.spec.env == \"dev\" "),
req: &fnv1beta1.RunFunctionRequest{
Input: resource.MustStructObject(&v1beta1.Resources{
Resources: []v1beta1.ComposedTemplate{
Expand Down Expand Up @@ -151,7 +151,7 @@ func TestEvaluateCondition(t *testing.T) {
},
"TrueDesiredBool": {
args: args{
cs: v1beta1.ConditionSpec{Expression: "desired.composite.resource.spec.render == true"},
condition: strPtr("desired.composite.resource.spec.render == true"),
req: &fnv1beta1.RunFunctionRequest{
Input: resource.MustStructObject(&v1beta1.Resources{
Resources: []v1beta1.ComposedTemplate{
Expand Down Expand Up @@ -180,7 +180,7 @@ func TestEvaluateCondition(t *testing.T) {
},
"FalseDesiredBool": {
args: args{
cs: v1beta1.ConditionSpec{Expression: "desired.composite.resource.spec.render == false"},
condition: strPtr("desired.composite.resource.spec.render == false"),
req: &fnv1beta1.RunFunctionRequest{
Input: resource.MustStructObject(&v1beta1.Resources{
Resources: []v1beta1.ComposedTemplate{
Expand Down Expand Up @@ -209,7 +209,7 @@ func TestEvaluateCondition(t *testing.T) {
},
"FalseObservedBool": {
args: args{
cs: v1beta1.ConditionSpec{Expression: "observed.composite.resource.status.ready == true"},
condition: strPtr("observed.composite.resource.status.ready == true"),
req: &fnv1beta1.RunFunctionRequest{
Input: resource.MustStructObject(&v1beta1.Resources{
Resources: []v1beta1.ComposedTemplate{
Expand Down Expand Up @@ -238,7 +238,7 @@ func TestEvaluateCondition(t *testing.T) {
},
"FalseLengthResources": {
args: args{
cs: v1beta1.ConditionSpec{Expression: "size(desired.resources) == 0"},
condition: strPtr("size(desired.resources) == 0"),
req: &fnv1beta1.RunFunctionRequest{
Input: resource.MustStructObject(&v1beta1.Resources{
Resources: []v1beta1.ComposedTemplate{
Expand Down Expand Up @@ -272,7 +272,7 @@ func TestEvaluateCondition(t *testing.T) {
},
"TrueResourceMapKeyExists": {
args: args{
cs: v1beta1.ConditionSpec{Expression: "\"test-resource\" in desired.resources"},
condition: strPtr("\"test-resource\" in desired.resources"),
req: &fnv1beta1.RunFunctionRequest{
Input: resource.MustStructObject(&v1beta1.Resources{
Resources: []v1beta1.ComposedTemplate{
Expand Down Expand Up @@ -306,7 +306,7 @@ func TestEvaluateCondition(t *testing.T) {
},
"FalseResourceMapKeyExists": {
args: args{
cs: v1beta1.ConditionSpec{Expression: "\"bad-resource\" in desired.resources"},
condition: strPtr("\"bad-resource\" in desired.resources"),
req: &fnv1beta1.RunFunctionRequest{
Input: resource.MustStructObject(&v1beta1.Resources{
Resources: []v1beta1.ComposedTemplate{
Expand Down Expand Up @@ -342,7 +342,7 @@ func TestEvaluateCondition(t *testing.T) {

for name, tc := range cases {
t.Run(name, func(t *testing.T) {
ret, err := EvaluateCondition(tc.args.cs, tc.args.req)
ret, err := EvaluateCondition(tc.args.condition, tc.args.req)

if diff := cmp.Diff(tc.want.ret, ret); diff != "" {
t.Errorf("%s\nEvaluateCondition(...): -want ret, +got ret:\n%s", tc.reason, diff)
Expand All @@ -357,3 +357,7 @@ func TestEvaluateCondition(t *testing.T) {
})
}
}

func strPtr(str string) *string {
return &str
}
4 changes: 2 additions & 2 deletions example/functions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
apiVersion: pkg.crossplane.io/v1beta1
kind: Function
metadata:
name: function-patch-and-transform
name: function-conditional-patch-and-transform
spec:
package: xpkg.upbound.io/crossplane-contrib/function-patch-and-transform:v0.1.4
package: xpkg.upbound.io/crossplane-contrib/function-conditional-patch-and-transform:v0.1.4
2 changes: 1 addition & 1 deletion examples/conditional-rendering/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ will not run.

## Running this example

- Until 1.14 is released, install a development version of Crossplane. See [install Crossplane master](https://docs.crossplane.io/latest/software/install/#install-the-crossplane-master-helm-chart)
- Install Crossplane version 1.14 or newer. See <https://docs.crossplane.io/v1.14/software/install/>
- Install the nop provider in `kubectl apply -f provider.yaml`
- Install the XRD & Composition in `kubectl apply -f definition.yaml -f composition.yaml`
- Install the Function `kubectl apply -f function.yaml`
Expand Down
7 changes: 3 additions & 4 deletions examples/conditional-rendering/composition.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,11 @@ spec:
pipeline:
- step: conditional-patch-and-transform
functionRef:
name: function-patch-and-transform
name: function-conditional-patch-and-transform
input:
apiVersion: pt.fn.crossplane.io/v1beta1
apiVersion: conditional-pt.fn.crossplane.io/v1beta1
kind: Resources
condition:
expression: observed.composite.resource.spec.env == "dev" && observed.composite.resource.spec.render == true
condition: observed.composite.resource.spec.env == "dev" && observed.composite.resource.spec.render == true
resources:
- name: test-resource
base:
Expand Down
6 changes: 3 additions & 3 deletions examples/conditional-rendering/function.yaml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
apiVersion: pkg.crossplane.io/v1beta1
kind: Function
metadata:
name: function-patch-and-transform
name: function-conditional-patch-and-transform
annotations:
xrender.crossplane.io/runtime: Development
render.crossplane.io/runtime: Development
spec:
package: index.docker.io/steve/function-patch-and-transform:v0.2.0
package: index.docker.io/steve/function-conditional-patch-and-transform:v0.2.0
packagePullPolicy: Always
4 changes: 2 additions & 2 deletions fn.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func (f *Function) RunFunction(ctx context.Context, req *fnv1beta1.RunFunctionRe
// Evaluate any Conditions using the values from the Observed XR
if input.Condition != nil {
// Evaluate the condition to see if we should run
run, err := EvaluateCondition(*input.Condition, req)
run, err := EvaluateCondition(input.Condition, req)
if err != nil {
response.Fatal(rsp, errors.Wrap(err, conditionError))
return rsp, nil
Expand Down Expand Up @@ -159,7 +159,7 @@ func (f *Function) RunFunction(ctx context.Context, req *fnv1beta1.RunFunctionRe

if t.Condition != nil {
// Evaluate the condition to see if we should skip this template.
run, err := EvaluateCondition(*t.Condition, req)
run, err := EvaluateCondition(t.Condition, req)
if err != nil {
log.Info(err.Error())
response.Fatal(rsp, errors.Wrap(err, conditionError))
Expand Down
8 changes: 2 additions & 6 deletions input/v1beta1/conditions.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
package v1beta1

// ConditionSpec defines the condition for rendering.
// Condition defines the condition for rendering.
// Conditions are defined using the Common Expression Language
// For more information refer to https://github.com/google/cel-spec
type ConditionSpec struct {
// Expression is the CEL expression to be evaluated. If the Expression
// returns a true value, the function will render the resources
Expression string `json:"expression"`
}
type Condition *string
6 changes: 3 additions & 3 deletions input/v1beta1/resources.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Package v1beta1 contains the input type for the P&T Composition Function.
// +kubebuilder:object:generate=true
// +groupName=pt.fn.crossplane.io
// +groupName=conditional-pt.fn.crossplane.io
// +versionName=v1beta1
package v1beta1

Expand All @@ -20,8 +20,8 @@ type Resources struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

// Condition defines a CEL condition whether this function will render
Condition *ConditionSpec `json:"condition,omitempty"`
// If defines a CEL condition whether this function will render
Condition Condition `json:"condition,omitempty"`

// PatchSets define a named set of patches that may be included by any
// resource. PatchSets cannot themselves refer to other PatchSets.
Expand Down
4 changes: 2 additions & 2 deletions input/v1beta1/resources_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ type ComposedTemplate struct {
// +optional
Base *runtime.RawExtension `json:"base,omitempty"`

// Condition defines a CEL condition whether this function will render
Condition *ConditionSpec `json:"condition,omitempty"`
// Condition defines a CEL condition whether this managed resource will render
Condition Condition `json:"condition,omitempty"`

// Patches to and from the composed resource.
// +optional
Expand Down
22 changes: 6 additions & 16 deletions input/v1beta1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.13.0
name: resources.pt.fn.crossplane.io
name: resources.conditional-pt.fn.crossplane.io
spec:
group: pt.fn.crossplane.io
group: conditional-pt.fn.crossplane.io
names:
categories:
- crossplane
Expand All @@ -27,17 +27,8 @@ spec:
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
condition:
description: Condition defines a CEL condition whether this function will
render
properties:
expression:
description: Expression is the CEL expression to be evaluated. If
the Expression returns a true value, the function will render the
resources
type: string
required:
- expression
type: object
description: If defines a CEL condition whether this function will render
type: string
environment:
description: "Environment represents the Composition environment. \n THIS
IS AN ALPHA FIELD. Do not use it in production. It may be changed or
Expand Down Expand Up @@ -682,6 +673,10 @@ spec:
type: object
x-kubernetes-embedded-resource: true
x-kubernetes-preserve-unknown-fields: true
condition:
description: Condition defines a CEL condition whether this managed
resource will render
type: string
connectionDetails:
description: ConnectionDetails lists the propagation secret keys
from this composed resource to the composition instance connection
Expand Down

0 comments on commit ea49546

Please sign in to comment.