-
Notifications
You must be signed in to change notification settings - Fork 44
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Question: is it possible to use managed resource result in go-template? #79
Comments
Yes, assuming the SecurityGroup Id is returned by the provider as a status you can retrieve the value and use it in the securityGroupRule. Something like this should work, though you may need to change the path to the ID :) {{ $securityGroupMR := get .observed.resources "security-group" }}
{{ $securityGroupID := dig "resource" "status" "atProvider" "id" "" $securityGroupMR }}
apiVersion: ec2.aws.upbound.io/v1beta1
kind: SecurityGroupRule
metadata:
name: security-group-rule
annotations:
crossplane.io/composition-resource-name: security-group-rule
spec:
forProvider:
region: {{ $xr.spec.region }}
fromPort: {{ $xr.spec.fromPort}}
toPort: {{ $xr.spec.toPort}}
protocol: TCP
type: ingress
securityGroupId: {{ $securityGroupID }} @maplewf Does this answer your question? |
@jtucci I have a similar question and it might fit a here (at least a little): How can I set a value in the status of the claim? F.g. copy the SG ID to
and then tried:
And also variantes of (really not sure about
also with full path |
You have to set the status on the XR itself which will propagate to the claim. Here is an example - lets say I have a composition with an XR kind XStorageAccount and a single MR (account.storage.azure.upbound.io/v1beta1) with a status I want propagated to the claim. To set the status in its entirety I would do the following # composition.yaml
{{ $accountStatus := get .observed.resources.account.resource "status" | default dict }}
apiVersion: storage.api.example/v1alpha1
kind: XStorageAccount
status:
account: {{ $accountStatus | toYaml | nindent 4 }} #definition.yaml
spec:
...
status:
type: object
description: A Status represents the observed state
properties:
account:
type: object
description: FreeForm field containing status information from a azure account instance
x-kubernetes-preserve-unknown-fields: true The above example will copy over the account status in its entirety, so if you only care about a single field you could define that single field in the definition status and then just extract and set the desired field in composition.yaml, same general process though :) |
@jtucci 😞 Sorry I still dont get it. My apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: xcfsetup
spec:
compositeTypeRef:
apiVersion: cloudflare.private/v1alpha1
kind: CFSetup
mode: Pipeline
pipeline:
- step: go-template
functionRef:
name: function-go-templating
input:
apiVersion: gotemplating.fn.crossplane.io/v1beta1
kind: GoTemplate
source: Inline
inline:
template: |
{{ $xr := .observed.composite.resource }}
{{ $name := $xr.metadata.name }}
{{ $spec := $xr.spec }}
---
... mrs ...
- step: automatically-detect-ready-composed-resources
functionRef:
name: function-auto-ready
writeConnectionSecretsToNamespace: crossplane-system
apiVersion: apiextensions.crossplane.io/v1
kind: CompositeResourceDefinition
metadata:
name: cfsetups.cloudflare.private
spec:
group: cloudflare.private
names:
kind: CFSetup
plural: cfsetups
versions:
- name: v1alpha1
served: true
referenceable: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
...
status:
description: Status of the setup
type: object
properties:
atProvider:
type: object
x-kubernetes-preserve-unknown-fields: true I guess you use |
@milkpirate Nope, we are using inline as well. In the below example lets assume that we want the entire status of an MR named 'example1MR' to be patched back into the XR, as well as a single field 'id' from the status of another MR named 'example2MR'. You're composition should look something like this apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: xcfsetup
spec:
compositeTypeRef:
apiVersion: cloudflare.private/v1alpha1
kind: XCFSetup
mode: Pipeline
pipeline:
- step: go-template
functionRef:
name: function-go-templating
input:
apiVersion: gotemplating.fn.crossplane.io/v1beta1
kind: GoTemplate
source: Inline
inline:
template: |
# This will contain the entire status object from the example1MR manaaged resource
{{ $example1MRStatus := get .observed.resources.example1MR.resource "status" | default dict }}
# This will contain just a single string value 'id', from the example2MR status object
{{ $example2MRStatus := get .observed.resources.example2MR.resource.status.atProvider "id" | default dict }}
apiVersion: storage.api.example/v1alpha1
kind: XCFSetup
status:
example1MR: {{ $example1MRStatus | toYaml | nindent 4 }}
example2MR:
id: {{ $example2MRStatus }}
--- apiVersion: apiextensions.crossplane.io/v1
kind: CompositeResourceDefinition
metadata:
name: cfsetups.cloudflare.private
spec:
group: cloudflare.private
names:
kind: XCFSetup
plural: xcfsetups
claimNames:
kind: CFSetup
plural: cfsetups
versions:
- name: v1alpha1
served: true
referenceable: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
...
status:
description: Status of the underlying MR's
type: object
properties:
example1MR:
type: object
x-kubernetes-preserve-unknown-fields: true
example2MR:
type: object
properties:
id:
type: string |
I think this should be reported in the doc and the examples |
@jtucci Hey, ran into the next problem: what you described here: #79 (comment) does not work as expected:
source looks like so: ---
apiVersion: argo.cloudflare.upbound.io/v1alpha1
kind: Tunnel
metadata:
name: {{ $tunnel.name }}.tunnel.of.{{ $name }}
annotations:
gotemplating.fn.crossplane.io/composition-resource-name: tunnel
spec:
...
---
{{ $tunnelMR := get .observed.resources "tunnel" }})
{{ $tunnelID := dig "resource" "status" "atProvider" "id" "" $tunnelMR }}
apiVersion: some.api
kind: OtherResource
... The unsuccessful The same error appears when I want to render the status, like we discussed earlier. Though if I
|
The observed resource isn't always going to be available, so if you are going to reference later in dig you should set a default value to a dict
|
@jtucci ok, I am really sorry for bothering again but I read the thread several times and still dont know why the MR -> MR copy does not work. Here is what I have: apiVersion: apiextensions.crossplane.io/v1
kind: Composition
...
spec:
...
pipeline:
- step: tunnel
...
input:
...
inline:
template: |
{{ $xr := .observed.composite.resource }}
{{ $name := $xr.metadata.name }}
{{ $spec := $xr.spec }}
{{ with $tunnel := $spec.tunnel }}
apiVersion: argo.cloudflare.upbound.io/v1alpha1
kind: Tunnel
metadata:
annotations:
gotemplating.fn.crossplane.io/composition-resource-name: tunnel
spec:
...
---
{{ $tunnelMR := get .observed.resources "tunnel" | default dict }}
{{ $tunnelToken := dig "resource" "status" "atProvider" "tunnelToken" "NOT_A_TOKEN" $tunnelMR }}
apiVersion: helm.crossplane.io/v1beta1
kind: Release
...
spec:
forProvider:
...
values:
cloudflare:
tunnel_token: {{ $tunnelToken }}
{{ end }}
- step: automatically-detect-ready-composed-resources
functionRef:
name: function-auto-ready
- step: status
...
input:
...
inline:
template: |
{{ $tunnelMR := get .observed.resources "tunnel" | default dict }}
{{ $tunnelToken := dig "resource" "status" "atProvider" "tunnelToken" "NOT_A_TOKEN" $tunnelMR }}
---
apiVersion: cloudflare.private/v1alpha1
kind: CFSetup
status:
atProvider:
tunnelToken: {{ $tunnelToken }} The tunnel token successfully ends up in the status: ...
status:
atProvider:
tunnelToken: eyJhIjoi...UdCd2c9In0=
conditions:
- lastTransitionTime: "2024-05-25T19:25:50Z"
reason: ReconcileSuccess
status: "True"
type: Synced
... Thats good 👍🏻 apiVersion: helm.crossplane.io/v1beta1
kind: Release
...
spec:
forProvider:
...
values:
cloudflare:
tunnel_token: NOT_A_TOKEN
status:
atProvider:
releaseDescription: Install complete
revision: 1
state: deployed
conditions:
- lastTransitionTime: "2024-05-25T19:32:04Z"
reason: Available
status: "True"
type: Ready
- lastTransitionTime: "2024-05-25T19:32:04Z"
reason: ReconcileSuccess
status: "True"
type: Synced
synced: true As you said, the observed resource might not always be available, but if it is later, shouldnt the function notice that and re-render, so the release gets updated with the correct value? I really can you hint again, since there is no difference between status and MR in the token retrieval. Whats missing? Whats wrong? Thanks again, you're helping a lot! ❤️ EDIT: {{ $xr := .observed.composite.resource }}
+ {{ $mrs := .observed.resources | default dict }}
{{ $name := $xr.metadata.name }}
{{ $spec := $xr.spec }}
...
---
- {{ $tunnelMR := get .observed.resources "tunnel" | default dict }}
+ {{ $tunnelMR := get $mrs "tunnel" | default dict }}
{{ $tunnelToken := dig "resource" "status" "atProvider" "tunnelToken" "NOT_A_TOKEN" $tunnelMR }} in the tunnel step and now it works. Could you explain why? |
What happened?
I'm pretty new to use
go-templating-function
for composition. What I want to achieve is to pass result of provisioned managed resource to another managed resource in compostion. Let's say I want to create AWS security group and security group rule associated with group I created like:so, I just want to use security group id created by security group in security group rule. If I use patch way, normally I can use
ToCompositeFieldPath
patch in security group resource to write security group id to XR , then useFromCompositeFieldPath
patch in security group rule resource to read security group id from XR.But I don't know how to achieve that in go-templating function?
How can we reproduce it?
No need
What environment did it happen in?
Function version: v0.4.1
The text was updated successfully, but these errors were encountered: