diff --git a/example/composition.yaml b/example/composition.yaml index da197e7..09cdc9d 100644 --- a/example/composition.yaml +++ b/example/composition.yaml @@ -14,4 +14,4 @@ spec: input: apiVersion: template.fn.crossplane.io/v1beta1 kind: Input - example: "Hello world" + version: v1beta2 diff --git a/function/fn.py b/function/fn.py index 705121b..7cf8c25 100644 --- a/function/fn.py +++ b/function/fn.py @@ -1,7 +1,7 @@ """A Crossplane composition function.""" import grpc -from crossplane.function import logging, response +from crossplane.function import logging, resource, response from crossplane.function.proto.v1 import run_function_pb2 as fnv1 from crossplane.function.proto.v1 import run_function_pb2_grpc as grpcv1 @@ -22,12 +22,18 @@ class FunctionRunner(grpcv1.FunctionRunnerService): rsp = response.to(req) - example = "" - if "example" in req.input: - example = req.input["example"] + version = req.input["version"] + region = req.observed.composite.resource["spec"]["region"] - # TODO: Add your function logic here! - response.normal(rsp, f"I was run with input {example}!") - log.info("I was run!", input=example) + resource.update( + rsp.desired.resources["bucket"], + { + "apiVersion": f"s3.aws.upbound.io/{version}", + "kind": "Bucket", + "spec": { + "forProvider": {"region": region}, + }, + }, + ) return rsp diff --git a/package/input/template.fn.crossplane.io_inputs.yaml b/package/input/template.fn.crossplane.io_inputs.yaml index f10d927..7889880 100644 --- a/package/input/template.fn.crossplane.io_inputs.yaml +++ b/package/input/template.fn.crossplane.io_inputs.yaml @@ -24,9 +24,8 @@ spec: of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' type: string - example: - description: Example is an example field. Replace it with whatever input - you need. :) + version: + description: The bucket version to compose (e.g. v1beta2). type: string kind: description: 'Kind is a string value representing the REST resource this @@ -36,7 +35,7 @@ spec: metadata: type: object required: - - example + - version type: object served: true storage: true diff --git a/tests/test_fn.py b/tests/test_fn.py index 0c111ee..35e5333 100644 --- a/tests/test_fn.py +++ b/tests/test_fn.py @@ -28,17 +28,36 @@ class TestFunctionRunner(unittest.IsolatedAsyncioTestCase): TestCase( reason="The function should return the input as a result.", req=fnv1.RunFunctionRequest( - input=resource.dict_to_struct({"example": "Hello, world"}) + input=resource.dict_to_struct({"version": "v1beta2"}), + observed=fnv1.State( + composite=fnv1.Resource( + resource=resource.dict_to_struct( + { + "apiVersion": "example.crossplane.io/v1", + "kind": "XR", + "spec": {"region": "us-west-2"}, + } + ), + ), + ), ), want=fnv1.RunFunctionResponse( meta=fnv1.ResponseMeta(ttl=durationpb.Duration(seconds=60)), - desired=fnv1.State(), - results=[ - fnv1.Result( - severity=fnv1.SEVERITY_NORMAL, - message="I was run with input Hello, world!", - ) - ], + desired=fnv1.State( + resources={ + "bucket": fnv1.Resource( + resource=resource.dict_to_struct( + { + "apiVersion": "s3.aws.upbound.io/v1beta2", + "kind": "Bucket", + "spec": { + "forProvider": {"region": "us-west-2"}, + }, + } + ), + ), + }, + ), context=structpb.Struct(), ), ),