|
1 | 1 | # OCI Functions Operator |
2 | 2 |
|
3 | | -Kubernetes-native management and job-style invocation of OCI Functions from OKE. |
| 3 | +Kubernetes-native APIs for managing and invoking OCI Functions from OKE. |
4 | 4 |
|
5 | | -MVP controller image: |
| 5 | +Current controller image: |
6 | 6 |
|
7 | 7 | ```text |
8 | | -ghcr.io/ronsevet/oci-functions-operator/controller:mvp-events-functionevents-v1 |
| 8 | +ghcr.io/ronsevetoci/oci-functions-operator/controller:v0.1.7 |
9 | 9 | ``` |
10 | 10 |
|
11 | | -## MVP Feature Summary |
| 11 | +## What This Operator Provides |
12 | 12 |
|
13 | | -The MVP adds four namespaced CRDs: |
| 13 | +The operator exposes five namespaced CRDs in `functions.oci.oracle.com/v1alpha1`: |
14 | 14 |
|
15 | | -- `Function`: references an existing OCI Function or manages an OCI Functions application/function. |
16 | | -- `FunctionJob`: invokes a referenced `Function`, fans out inline JSON payloads, retries failed invocations, and records aggregate/per-payload status. |
17 | | -- `FunctionEventTrigger`: creates OCI Events Rules for OCI service events such as Object Storage events, or routes Kubernetes-native `functionevent.*` events to a referenced `Function`. |
18 | | -- `FunctionEvent`: Kubernetes-native event object for direct operator-routed invocation through `functionevent.*` event types. |
| 15 | +- `FunctionApplication`: maps to an OCI Functions Application. It owns app-level settings such as compartment, region, subnets, NSGs, application config, and invocation log settings. |
| 16 | +- `Function`: maps to an OCI Function. It can reference an existing OCI Function or manage one inside a `FunctionApplication`. |
| 17 | +- `FunctionJob`: invokes a referenced `Function` with one or more inline JSON payloads, parallelism, retry limits, and per-payload status. |
| 18 | +- `FunctionEventTrigger`: routes an OCI Events rule or a Kubernetes-native `functionevent.*` event type to a `Function`. |
| 19 | +- `FunctionEvent`: an in-cluster event envelope that the operator matches against `FunctionEventTrigger` resources. |
| 20 | + |
| 21 | +`FunctionJob` and `FunctionEvent` both end in a Function invocation, but they are not the same resource. Use `FunctionJob` when a user or system wants to submit explicit invocation work and track that work as a job. Use `FunctionEvent` when an application emits an event and wants the operator to route it through matching triggers. |
| 22 | + |
| 23 | +## Resource Flow |
| 24 | + |
| 25 | +```mermaid |
| 26 | +flowchart TB |
| 27 | + APPCR[FunctionApplication CR] |
| 28 | + APP[OCI Functions Application] |
| 29 | + FNCR[Function CR] |
| 30 | + FN[OCI Function] |
| 31 | + INVOKE[Function Invocation] |
| 32 | +
|
| 33 | + APPCR --> APP |
| 34 | + APP --> FNCR |
| 35 | + FNCR --> FN |
| 36 | + FN --> INVOKE |
| 37 | +
|
| 38 | + JOB[FunctionJob CR] |
| 39 | + TRIGGER[FunctionEventTrigger CR] |
| 40 | + EVENT[FunctionEvent CR] |
| 41 | + OCIEVENT[OCI service event] |
| 42 | + RULE[OCI Events Rule] |
| 43 | +
|
| 44 | + JOB --> INVOKE |
| 45 | + EVENT --> TRIGGER |
| 46 | + OCIEVENT --> RULE |
| 47 | + RULE --> TRIGGER |
| 48 | + TRIGGER --> INVOKE |
| 49 | +``` |
| 50 | + |
| 51 | +Read it top to bottom: a `FunctionApplication` is the application wrapper, a `Function` lives inside it, and every invocation path eventually invokes that function. `FunctionJob` is direct work submission. `FunctionEventTrigger` routes either OCI service events through an OCI Events Rule or in-cluster `FunctionEvent` objects. |
| 52 | + |
| 53 | +The important boundary is that the operator does not turn OCI Functions into Pods. It keeps OCI Functions as OCI resources and gives Kubernetes users a clear control plane for application setup, function setup, invocation, event routing, status, and events. |
19 | 54 |
|
20 | 55 | ## Two Images |
21 | 56 |
|
22 | | -The operator image and function runtime image are different artifacts: |
| 57 | +The operator image and function runtime image are separate artifacts: |
23 | 58 |
|
24 | 59 | - Operator/controller image: runs as a Kubernetes Deployment in OKE. It can be in GHCR, OCIR, or any registry OKE can pull from. |
25 | 60 | - Function runtime image: runs in OCI Functions. It must be an OCI Functions-compatible Fn image in same-region OCIR, for example `jed.ocir.io/<TENANCY_NAMESPACE>/hello-function:fn-v1` for Jeddah. |
26 | 61 |
|
27 | | -Do not use GHCR for the OCI Functions runtime image. OCI Functions pulls the runtime image from the Functions application network during invocation, so the application subnet/NSG must have egress to Oracle Services Network/OCIR even when the OCIR repository is public. |
| 62 | +Do not use GHCR for the OCI Functions runtime image. OCI Functions pulls the runtime image from the Functions application network during invocation, so the application subnet and any attached NSGs must allow egress to Oracle Services Network/OCIR even when the OCIR repository is public. |
28 | 63 |
|
29 | 64 | ## Start Here |
30 | 65 |
|
31 | | -- [Helm install](docs/helm-install.md): recommended OKE installation and upgrade path. |
32 | | -- [MVP demo flow](docs/demo/mvp-demo-flow.md): primary concise handoff/demo guide for the final MVP image. |
33 | | -- [MVP checklist](docs/demo/mvp-checklist.md): short secondary pre-demo checklist. |
34 | | -- [MVP video script](docs/demo/mvp-video-script.md): short secondary narration outline. |
35 | | -- [Managed Function demo](docs/managed-function-demo.md): primary OKE walkthrough for managed application/function creation and invocation. |
36 | | -- [Function events](docs/function-events.md): Kubernetes-native `functionevent.*` events routed directly by the operator. |
37 | | -- [Function event triggers](docs/event-triggers.md): OCI Events Rule and FunctionEvent trigger setup. |
38 | | -- [OKE deployment](docs/oke-deployment.md): supported Helm deployment, Workload Identity, IAM, and network setup. |
39 | | -- [Design overview](docs/design.md): CRDs, controllers, lifecycle, invoker contracts, and limitations. |
40 | | -- [Local existing Function demo](docs/oci-mode-demo.md): local `OCI_AUTH_MODE=config` path against an already-created OCI Function. |
| 66 | +- [Helm install](docs/helm-install.md): supported OKE installation and upgrade path. |
| 67 | +- [OKE deployment](docs/oke-deployment.md): Workload Identity, IAM, networking, and the core resource sequence. |
| 68 | +- [Function event triggers](docs/event-triggers.md): OCI Events and `functionevent.*` routing. |
| 69 | +- [Function events](docs/function-events.md): Kubernetes-native event emission. |
41 | 70 | - [Debugging Functions](docs/debugging-functions.md): image, CRD, Workload Identity, NSG, and invocation failure checks. |
42 | | -- [Validation notes](docs/validation-notes.md): template for recording real OCI-mode runs. |
43 | | -- [Sample function image](examples/hello-function/README.md): Fn-compatible Python function runtime image for the managed demo. |
| 71 | +- [Design overview](docs/design.md): controller architecture, resource behavior, and current limitations. |
| 72 | +- [Sample function image](examples/hello-function/README.md): Fn-compatible Python function runtime image. |
| 73 | + |
| 74 | +Tracked files under `config/samples/` are generic examples with placeholders. Live walkthrough manifests with OCIDs, tenancy namespaces, bucket names, or temporary cleanup settings should live in the ignored `local/` directory, not in the repository history. |
| 75 | + |
| 76 | +## Helm CRDs |
| 77 | + |
| 78 | +The Helm chart includes CRDs for `FunctionApplication`, `Function`, `FunctionJob`, `FunctionEventTrigger`, and `FunctionEvent`. |
| 79 | + |
| 80 | +Fresh Helm installs install CRDs from `charts/oci-functions-operator/crds/`, but existing Helm upgrades do not add or update CRDs from that directory. Before installing or upgrading after API changes, apply the chart CRDs first: |
| 81 | + |
| 82 | +```sh |
| 83 | +kubectl apply -f charts/oci-functions-operator/crds/ |
| 84 | +``` |
| 85 | + |
| 86 | +Then run `helm upgrade --install`. |
44 | 87 |
|
45 | 88 | ## Modes |
46 | 89 |
|
47 | | -`INVOKER_MODE=fake` is the default. It requires no OCI auth, creates no OCI resources, and is useful only for CRD/controller/status demos. |
| 90 | +`INVOKER_MODE=fake` is the default for local controller development and tests. It requires no OCI auth and creates no OCI resources. |
48 | 91 |
|
49 | 92 | `INVOKER_MODE=oci` uses the OCI Go SDK: |
50 | 93 |
|
51 | 94 | - On OKE, the Helm chart configures Workload Identity with `oci.authMode=workload`. |
52 | 95 | - For local development only, use `OCI_AUTH_MODE=config` with `OCI_CONFIG_FILE` and `OCI_CONFIG_PROFILE`. |
53 | 96 |
|
54 | | -Existing mode requires `spec.functionId` and `spec.invokeEndpoint` on the `Function`. Managed mode uses `spec.config` to create/update the OCI Functions application and function, then writes `status.applicationId`, `status.functionId`, and `status.invokeEndpoint`. |
| 97 | +The Helm chart is the supported way to deploy the operator on OKE. Kustomize under `config/` is kept for Kubebuilder-generated manifests and local development only. Do not mix Helm and Kustomize for the same cluster install. |
| 98 | + |
| 99 | +## Resource Model |
| 100 | + |
| 101 | +Preferred managed mode is explicit: |
| 102 | + |
| 103 | +1. Create a `FunctionApplication` for the shared OCI Functions Application. |
| 104 | +2. Create one or more managed `Function` resources with `spec.applicationRef.name`. |
| 105 | +3. Wait for `Function.status.functionId` and `Function.status.invokeEndpoint`. |
| 106 | +4. Invoke through `FunctionJob`, OCI Events-backed `FunctionEventTrigger`, or Kubernetes-native `FunctionEvent`. |
| 107 | + |
| 108 | +Legacy managed `Function` manifests that put app-level settings under `spec.config` still work for compatibility, but new manifests should use `FunctionApplication`. |
55 | 109 |
|
56 | | -## Local Fake Demo |
| 110 | +`Function.spec.deletionPolicy` defaults to `Retain`. Deleting a managed `Function` with `Retain` leaves OCI resources untouched. Set `deletionPolicy: Delete` only when Kubernetes deletion should also delete the managed OCI Function. `FunctionApplication.spec.deletionPolicy` controls OCI Application cleanup separately; `Delete` is honored only for managed applications and only when no functions remain. Existing-mode resources never delete OCI resources. |
57 | 111 |
|
58 | | -Install or refresh generated manifests: |
| 112 | +## Local Development |
| 113 | + |
| 114 | +Install or refresh generated CRDs: |
59 | 115 |
|
60 | 116 | ```sh |
61 | 117 | make generate |
62 | 118 | make manifests |
63 | 119 | kubectl apply -k config/crd |
64 | 120 | ``` |
65 | 121 |
|
66 | | -Run the manager against your current kubeconfig: |
| 122 | +Run the manager in fake mode: |
67 | 123 |
|
68 | 124 | ```sh |
69 | 125 | INVOKER_MODE=fake go run ./cmd |
70 | 126 | ``` |
71 | 127 |
|
72 | | -In another terminal: |
| 128 | +Apply the safe sample resources: |
73 | 129 |
|
74 | 130 | ```sh |
75 | | -scripts/check-demo-prereqs.sh |
76 | | -scripts/demo-fake.sh |
| 131 | +kubectl apply -k config/samples |
| 132 | +kubectl get functions,functionjobs |
| 133 | +kubectl describe functionjob hello-job |
77 | 134 | ``` |
78 | 135 |
|
79 | | -Fake mode proves only the Kubernetes reconciliation/status path. It does not prove OCI auth, OCI Functions network egress, OCIR image access, or function image compatibility. |
80 | | - |
81 | | -## Primary OKE Path |
82 | | - |
83 | | -For OKE managed mode: |
84 | | - |
85 | | -1. Build and push the operator/controller image to a registry OKE can pull. |
86 | | -2. Build a Fn-compatible function runtime image and push it to same-region OCIR. |
87 | | -3. Deploy the operator with Helm. The chart is the supported OKE path and defaults to OCI mode with Workload Identity. |
88 | | -4. Apply a managed `Function` with `spec.config.region`, `compartmentId`, `applicationName`, `subnetIds`, optional `nsgIds`, and same-region OCIR `image`. |
89 | | -5. Submit a `FunctionJob`, create a `FunctionEventTrigger`, or emit a `FunctionEvent` after the `Function` is Ready. |
90 | | - |
91 | | -See [docs/helm-install.md](docs/helm-install.md) for installation and [docs/managed-function-demo.md](docs/managed-function-demo.md) for the full Function sequence. |
92 | | - |
93 | | -Kustomize under `config/` is kept for Kubebuilder-generated manifests and local controller development only. Do not mix Helm and Kustomize for the same OKE operator install. |
| 136 | +Fake mode proves only Kubernetes reconciliation and status behavior. It does not prove OCI auth, OCI Functions network egress, OCIR image access, or function image compatibility. |
0 commit comments