Skip to content

Commit

Permalink
add possibiltiy to set fully qualified field references (e.g. desired…
Browse files Browse the repository at this point in the history
….composite.resource., .desired.resources. or context.) (#33)
  • Loading branch information
anessi authored Sep 3, 2024
1 parent 2d56777 commit bd291de
Show file tree
Hide file tree
Showing 15 changed files with 581 additions and 66 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,6 @@ go.work
.golangci.yml
*.xpkg
function-cidr
.vscode
.idea
.vscode
*__debug_bin*
18 changes: 18 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
generate:
go generate ./...

build:
docker build . --quiet --platform=linux/amd64 --tag runtime-amd64
crossplane xpkg build --package-root=package --embed-runtime-image=runtime-amd64 --package-file=function-amd64.xpkg

render:
@for file in examples/xr-*.yaml; do \
echo ""; \
Expand All @@ -8,5 +15,16 @@ render:
examples/functions.yaml; \
done

render-pipeline:
crossplane beta render examples/xr-cidrsubnet.yaml \
apis/composition-pipeline.yaml \
examples/functions.yaml

render-pipeline-context:
crossplane beta render examples/xr-cidrsubnet.yaml \
apis/composition-pipeline-context.yaml \
examples/functions-pipeline-context.yaml \
--extra-resources=examples/extraResources.yaml

debug:
go run . --insecure --debug
19 changes: 12 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,21 +70,26 @@ Valid values are as follows:
- multiprefixloop
```
Specify a custom `outputfield` in the function input parameters when the output
Specify a custom `outputField` in the function input parameters when the output
should appear at a different path than the respective `status.atFunction.cidr`
sub field default path.
All `cidrfunc` IP Network Functions require a CIDR `prefix` as input.
Provide the `prefix` directly in the function input or specify a `prefixfield`
Provide the `prefix` directly in the function input or specify a `prefixField`
in the XR where the function shall pick up the `prefix` value.
Function input field names ending in `field` indicate that the function shall
Function input field names ending in `Field` indicate that the function shall
read the field path value from the specified field path in the XR.
You can also provide `desired.composite.resource.` and `desired.resources.` in the `prefixField` value to reference
the resource attribute from where to read the prefix value. See [apis/composition-pipeline.yaml](apis/composition-pipeline.yaml).
In addition, referencing the pipeline `context` is supported. You can use [gjson](https://github.com/tidwall/gjson)
for selecting context values. See [apis/composition-pipeline-context.yaml](apis/composition-pipeline-context.yaml).
### cidrhost
The `cidrhost cidrfunc` requires a `hostnum` or `hostnumfield` as
The `cidrhost cidrfunc` requires a `hostnum` or `hostnumField` as
function input. `hostnum` is an integer.
### cidrnetmask
Expand Down Expand Up @@ -115,7 +120,7 @@ The `cidrhost cidrsubnetloop` requires the following input fields.
- `newBits` (integer array) or `newBitsField`
- `netNumCount` (integer) or `netNumCountField`
- `netNumItems` (string array) or `netNumItemsField`
- `offset` or `offsetfield`
- `offset` or `offsetField`
**`netNumCount` and `netNumItems` are mutually exclusive**
Expand Down Expand Up @@ -148,5 +153,5 @@ before calculations and then removed after the calculation is completed.
## Testing The Function
Clone the repo. Run `make debug` and in a second terminal run `make render`
and examine the output. Corresponding compositions and XR yaml can be found in
the `examples` folder.
or `make render-pipeline` and examine the output. Corresponding compositions and XR
yaml can be found in the `examples` folder.
100 changes: 100 additions & 0 deletions apis/composition-pipeline-context.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: xcidrs.platform.upbound.io
spec:
compositeTypeRef:
apiVersion: platform.upbound.io/v1alpha1
kind: XCIDR
mode: Pipeline
pipeline:
- step: pull-extra-resources
functionRef:
name: function-extra-resources
input:
apiVersion: extra-resources.fn.crossplane.io/v1beta1
kind: Input
spec:
extraResources:
- kind: XCluster
into: XCluster
apiVersion: example.crossplane.io/v1
type: Selector
selector:
maxMatch: 2
minMatch: 1
matchLabels:
- key: type
type: Value
value: cluster
- step: debug-context
functionRef:
name: function-go-templating
input:
apiVersion: gotemplate.fn.crossplane.io/v1beta1
kind: GoTemplate
source: Inline
inline:
template: |
apiVersion: test.my-domain.com/v1alpha1
kind: DebugContext
metadata:
annotations:
gotemplating.fn.crossplane.io/composition-resource-name: debug-context
debug:
{{ . | toYaml | nindent 2 }}
- step: cidr-subnets-partitions
functionRef:
name: upbound-function-cidr
input:
apiVersion: cidr.fn.crossplane.io/v1beta1
kind: Parameters
cidrFunc: cidrsubnets
prefixField: context.apiextensions\.crossplane\.io/extra-resources.XCluster.0.spec.cidrBlock
newBits:
- 1
- 1
outputField: status.atFunction.cidr.partitions
- step: cidr-subnets-private
functionRef:
name: upbound-function-cidr
input:
apiVersion: cidr.fn.crossplane.io/v1beta1
kind: Parameters
cidrFunc: cidrsubnets
prefixField: desired.composite.resource.status.atFunction.cidr.partitions[0]
newBits:
- 1
- 1
outputField: status.atFunction.cidr.private.subnets
- step: cidr-subnets-public
functionRef:
name: upbound-function-cidr
input:
apiVersion: cidr.fn.crossplane.io/v1beta1
kind: Parameters
cidrFunc: cidrsubnets
prefixField: desired.composite.resource.status.atFunction.cidr.partitions[1]
newBits:
- 1
- 1
outputField: status.atFunction.cidr.public.subnets
# To debug the pipeline output you can generate a new resource which contains all attributes. Make sure to add function-go-templating to functions.yaml.
- step: render-templates
functionRef:
name: function-go-templating
input:
apiVersion: gotemplate.fn.crossplane.io/v1beta1
kind: GoTemplate
source: Inline
inline:
template: |
apiVersion: test.my-domain.com/v1alpha1
kind: DebugResource
metadata:
annotations:
gotemplating.fn.crossplane.io/composition-resource-name: debug
debug:
{{ . | toYaml | nindent 2 }}
debugValue:
{{ index .desired.composite.resource.status.atFunction.cidr.public.subnets 0 | nindent 2 }}
65 changes: 65 additions & 0 deletions apis/composition-pipeline.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: xcidrs.platform.upbound.io
spec:
compositeTypeRef:
apiVersion: platform.upbound.io/v1alpha1
kind: XCIDR
mode: Pipeline
pipeline:
- step: cidr-subnets-partitions
functionRef:
name: upbound-function-cidr
input:
apiVersion: cidr.fn.crossplane.io/v1beta1
kind: Parameters
cidrFunc: cidrsubnets
prefixField: spec.parameters.cidrBlock
newBits:
- 1
- 1
outputField: status.atFunction.cidr.partitions
- step: cidr-subnets-private
functionRef:
name: upbound-function-cidr
input:
apiVersion: cidr.fn.crossplane.io/v1beta1
kind: Parameters
cidrFunc: cidrsubnets
prefixField: desired.composite.resource.status.atFunction.cidr.partitions[0]
newBits:
- 1
- 1
outputField: status.atFunction.cidr.private.subnets
- step: cidr-subnets-public
functionRef:
name: upbound-function-cidr
input:
apiVersion: cidr.fn.crossplane.io/v1beta1
kind: Parameters
cidrFunc: cidrsubnets
prefixField: desired.composite.resource.status.atFunction.cidr.partitions[1]
newBits:
- 1
- 1
outputField: status.atFunction.cidr.public.subnets
## To debug the pipeline output you can generate a new resource which contains all attributes. Make sure to add function-go-templating to functions.yaml.
# - step: render-templates
# functionRef:
# name: function-go-templating
# input:
# apiVersion: gotemplate.fn.crossplane.io/v1beta1
# kind: GoTemplate
# source: Inline
# inline:
# template: |
# apiVersion: test.my-domain.com/v1alpha1
# kind: DebugResource
# metadata:
# annotations:
# gotemplating.fn.crossplane.io/composition-resource-name: debug
# debug:
# {{ . | toYaml | nindent 2 }}
# debugValue:
# {{ index .desired.composite.resource.status.atFunction.cidr.public.subnets 0 | nindent 2 }}
2 changes: 1 addition & 1 deletion apis/definition.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ spec:
type: integer
offset:
type: integer
output:
outputField:
type: string
required:
- parameters
Expand Down
8 changes: 8 additions & 0 deletions examples/extraResources.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
apiVersion: example.crossplane.io/v1
kind: XCluster
metadata:
name: net-staging-blue
labels:
type: cluster
spec:
cidrBlock: 10.0.0.0/20
29 changes: 29 additions & 0 deletions examples/functions-pipeline-context.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
apiVersion: pkg.crossplane.io/v1beta1
kind: Function
metadata:
name: upbound-function-cidr
annotations:
render.crossplane.io/runtime: Development
# spec:
# package: xpkg.upbound.io/upbound/function-cidr:v0.3.0
---
apiVersion: pkg.crossplane.io/v1beta1
kind: Function
metadata:
name: function-go-templating
annotations:
render.crossplane.io/runtime-docker-cleanup: "Orphan"
spec:
package: xpkg.upbound.io/crossplane-contrib/function-go-templating:v0.5.0
---
apiVersion: pkg.crossplane.io/v1beta1
kind: Function
metadata:
name: function-extra-resources
annotations:
render.crossplane.io/runtime-docker-cleanup: "Orphan"
# This tells crossplane beta render to connect to the function locally.
#render.crossplane.io/runtime: Development
spec:
# This is ignored when using the Development runtime.
package: xpkg.upbound.io/crossplane-contrib/function-extra-resources:v0.0.3
4 changes: 2 additions & 2 deletions fn.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func (f *Function) RunFunction(_ context.Context, req *fnv1beta1.RunFunctionRequ
return rsp, nil
}

if err := ValidateParameters(input, oxr); err != nil {
if err := ValidateParameters(input, oxr, req); err != nil {
response.Fatal(rsp, errors.Wrap(err, "invalid Function input"))
return rsp, nil
}
Expand Down Expand Up @@ -68,7 +68,7 @@ func (f *Function) RunFunction(_ context.Context, req *fnv1beta1.RunFunctionRequ

var prefix string = input.Prefix
if cidrFunc != "multiprefixloop" && len(input.PrefixField) > 0 {
prefix, err = oxr.Resource.GetString(input.PrefixField)
prefix, err = GetPrefixField(input.PrefixField, oxr, req)
if err != nil {
response.Fatal(rsp, errors.Wrapf(err, "cannot get prefix from field %s for %s", input.PrefixField, oxr.Resource.GetKind()))
return rsp, nil
Expand Down
Loading

0 comments on commit bd291de

Please sign in to comment.