Skip to content

Commit

Permalink
move merge logic out of main function
Browse files Browse the repository at this point in the history
Signed-off-by: Steven Borrelli <[email protected]>
  • Loading branch information
stevendborrelli committed Oct 3, 2024
1 parent 7ea0dd4 commit 9f88fb6
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 19 deletions.
30 changes: 30 additions & 0 deletions context.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package main

import (
"dario.cat/mergo"
"github.com/crossplane/function-sdk-go/errors"
fnv1beta1 "github.com/crossplane/function-sdk-go/proto/v1beta1"
"github.com/crossplane/function-sdk-go/request"
"github.com/crossplane/function-sdk-go/resource"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)

type Context map[string]any

// MergeContextKey merges existing Context at a key with context data val
func (f *Function) MergeContextKey(key string, val map[string]interface{}, req *fnv1beta1.RunFunctionRequest) (*unstructured.Unstructured, error) {
// Check if key is already defined in the context and merge fields
var mergedContext *unstructured.Unstructured
if v, ok := request.GetContextKey(req, key); ok {
mergedContext = &unstructured.Unstructured{}
if err := resource.AsObject(v.GetStructValue(), mergedContext); err != nil {
return mergedContext, errors.Wrapf(err, "cannot get Composition environment from %T context key %q", req, key)
}
f.log.Debug("Loaded Existing Function Context", "context-key", key)
if err := mergo.Merge(&mergedContext.Object, val); err != nil {
return mergedContext, errors.Wrapf(err, "cannot merge data %T at context key %q", req, key)
}
return mergedContext, nil
}
return &unstructured.Unstructured{Object: val}, nil
}
27 changes: 8 additions & 19 deletions fn.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ func (f *Function) RunFunction(_ context.Context, req *fnv1beta1.RunFunctionRequ
case "Context":
contextData := make(map[string]any)
if err = cd.Resource.GetValueInto("data", &contextData); err != nil {
response.Fatal(rsp, errors.Wrap(err, "cannot get contexts"))
response.Fatal(rsp, errors.Wrap(err, "cannot get Contexts from input"))
return rsp, nil
}
for key, data := range contextData {
Expand All @@ -203,27 +203,16 @@ func (f *Function) RunFunction(_ context.Context, req *fnv1beta1.RunFunctionRequ
response.Fatal(rsp, errors.Wrapf(err, "cannot convert Context from %T context key %q", req, key))
return rsp, nil
}
// Check if key is already defined in the context
var inputEnv *unstructured.Unstructured
if v, ok := request.GetContextKey(req, key); ok {
inputEnv = &unstructured.Unstructured{}
if err := resource.AsObject(v.GetStructValue(), inputEnv); err != nil {
response.Fatal(rsp, errors.Wrapf(err, "cannot get Composition environment from %T context key %q", req, key))
return rsp, nil
}
f.log.Debug("Loaded Existing Composition environment from Function context", "context-key", key)
if err := mergo.Merge(&inputEnv.Object, val); err != nil {
response.Fatal(rsp, errors.Wrapf(err, "cannot merge data %T at context key %q", req, key))
return rsp, nil
}
} else {
inputEnv = &unstructured.Unstructured{Object: val}
mergedCtx, err := f.MergeContextKey(key, val, req)
if err != nil {
response.Fatal(rsp, errors.Wrapf(err, "cannot merge Context"))
return rsp, nil
}

if inputEnv.GroupVersionKind().Empty() {
inputEnv.SetGroupVersionKind(schema.GroupVersionKind{Group: "internal.crossplane.io", Kind: "Environment", Version: "v1alpha1"})
if mergedCtx.GroupVersionKind().Empty() {
mergedCtx.SetGroupVersionKind(schema.GroupVersionKind{Group: "internal.crossplane.io", Kind: "Environment", Version: "v1alpha1"})
}
v, err := resource.AsStruct(inputEnv)
v, err := resource.AsStruct(mergedCtx)
if err != nil {
response.Fatal(rsp, errors.Wrap(err, "cannot convert Context to protobuf Struct well-known type"))
return rsp, nil
Expand Down

0 comments on commit 9f88fb6

Please sign in to comment.