Skip to content

adds using secrets in a python function and cli --function-credentials #902

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

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions content/master/cli/command-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ spec:
| `-c` | `--include-context` | Include the context in the rendered output as a resource of kind: Context. |
| `-x` | `--include-full-xr` | Include a copy of the input Composite Resource spec and metadata fields in the rendered output. |
| | `--timeout=` | Amount of time to wait for a function to finish. (Default 1 minute) |
| | `--function-credentials=PATH` | A YAML file or directory of YAML files specifying credentials to use for Functions to render the XR. |

{{< /table >}}

Expand All @@ -127,6 +128,11 @@ If a function produces Kubernetes events with statuses use the
`--include-function-results` to print them along with the managed resource
outputs.

### Use a secret in a function

If a function needs a secret, use the `--function-credentials=PATH`
where `PATH` is the path to a Kubernetes secret manifest.

### Include the composite resource

Composition functions can only change the `status` field of a composite
Expand Down
69 changes: 69 additions & 0 deletions content/master/guides/write-a-composition-function-in-python.md
Original file line number Diff line number Diff line change
Expand Up @@ -733,3 +733,72 @@ up continuous integration (CI) using
lint, test, and build your function. You can see how the template configures CI
by reading `.github/workflows/ci.yaml`.
{{</hint>}}

## Using credentials in the function

To access a secret, the `composition.yaml` step declares it with:

```yaml
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: create-buckets
spec:
compositeTypeRef:
apiVersion: example.crossplane.io/v1
kind: XBuckets
mode: Pipeline
pipeline:
- step: create-buckets
credentials:
- name: function-credentials
secretRef:
name: secret-name
namespace: crossplane-system
source: Secret
functionRef:
name: function-xbuckets
```

Where `secret-name` is the kubernetes secret name.

Edit the `RunFunction` method to read the credentials using `req.credentials`:

{{<hint "tip">}}
See [apiextensions.fn.proto.v1.RunFunctionRequest](https://buf.build/crossplane/crossplane/docs/main:apiextensions.fn.proto.v1#apiextensions.fn.proto.v1.RunFunctionRequest)
and [protobuf generated Python code ](https://protobuf.dev/reference/python/python-generated/)
to understand what kind of Python code is generated from the protobuf
and how to access the request content
{{</hint>}}

```python
async def RunFunction(self, req: fnv1.RunFunctionRequest, _: grpc.aio.ServicerContext) -> fnv1.RunFunctionResponse:
log = self.log.bind(tag=req.meta.tag)
log.info("Running function")

rsp = response.to(req)

credentials = req.credentials

username = credentials["secret-name"].credential_data.data["username"].decode("utf-8")
password = credentials["secret-name"].credential_data.data["password"].decode("utf-8")
```

To test the function with `crossplane render`, use:

`crossplane render --function-credentials=secret.yaml xr.yaml composition.yaml functions.yaml`

Where `secret.yaml` is a Kubernetes secret manifest:

```yaml
apiVersion: v1
kind: Secret
metadata:
name: secret-name
namespace: crossplane-system
data:
username: bb..bb
password: aa..aa
type: Opaque
```