Skip to content

SRVOCF-979: return union of repo and cluster functions - #133

Open
pmeida wants to merge 3 commits into
openshift:masterfrom
pmeida:SRVOCF-979-github-func-union
Open

SRVOCF-979: return union of repo and cluster functions#133
pmeida wants to merge 3 commits into
openshift:masterfrom
pmeida:SRVOCF-979-github-func-union

Conversation

@pmeida

@pmeida pmeida commented Aug 14, 2026

Copy link
Copy Markdown

Summary

  • /func/list now returns the union of GitHub repo-discovered functions and cluster-deployed functions, each tagged with a source (repo or cluster); when a function exists in both, repo wins. Cluster-deployed functions with no source repository now appear in the UI.
  • Split cluster access by intent: new functions package (unified knative/func facade: the growable functions.Client for cluster queries, plus offline source/CI scaffold generation - the former scaffold package folded in so all knative/func usage sits behind one boundary) and new kube package (shared REST config: host resolution, TLS, JSON content type, request timeout). cluster is now provisioning-only (RBAC, service accounts, tokens) instead of a god-client.
  • Frontend threads source through the table, disables Edit for cluster-only functions with a tooltip ("No source repository to edit"), and renders empty runtime as a dash.
  • Bumped knative/func to include fix(list): populate RUNTIME column in func list knative/func#4010 so cluster-deployed functions report their runtime and refactor(listers): inject k8s.Client via DI knative/func#4003 so that we can inject rest configs into the lister.
  • Added backend specs for the union/merge and the functions package; added frontend tests for cluster-only rows and the disabled-Edit behavior.
  • Documented the kube/functions packages and the cluster-access split.
  • Dropped the redundant direct go.yaml.in/yaml/v3 dependency, using sigs.k8s.io/yaml for func.yaml parsing

Fixes SRVOCF-979

Checklist

  • Updated docs/ARCHITECTURE.md (if there are relevant changes to our layered architecture)

Additional Info

Reasoning for the design decisions:

  • cluster (write: provisioning) and functions (function lifecycle) answer different questions, so they are separate packages rather than one shared client interface. functions.Client is an interface (not a bare lister) because deploy/delete/describe may be expected next.
  • Shared connection logic lives in kube.RESTConfig, a leaf package (depends only on client-go/rest), so both domain packages build connections identically without a dependency cycle. It intentionally does not live in config, which is the wiring layer imported only by handler/main.
  • Graceful degradation on cluster list failure: repo-discovered functions are the required result; cluster-deployed functions are an enrichment. If connecting to the cluster or listing functions fails (knative not installed, RBAC forbidden, API unreachable), the handler logs a warning and returns the repo-sourced list rather than failing the request. Only a repo/SCM failure is fatal (401 on an invalid token, 502 otherwise). Cluster results add to the picture; they do not gate it.

@openshift-ci openshift-ci Bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Aug 14, 2026
@openshift-ci

openshift-ci Bot commented Aug 14, 2026

Copy link
Copy Markdown

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@openshift-ci

openshift-ci Bot commented Aug 14, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: pmeida

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Aug 14, 2026
@pmeida pmeida changed the title feat: return union of repo and cluster functions SRVOCF-979: return union of repo and cluster functions Aug 14, 2026
@openshift-ci-robot

openshift-ci-robot commented Aug 14, 2026

Copy link
Copy Markdown

@pmeida: This pull request references SRVOCF-979 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "5.1.0" version, but no target version was set.

Details

In response to this:

What

/func/list now returns the union of GitHub repo-discovered functions and cluster-deployed functions, instead of sourcing the list from GitHub repositories alone. Each item carries a source (repo or cluster); when a function exists in both, the repo source wins.

Jira: SRVOCF-979

Why

Functions deployed to the cluster without a discoverable source repository never showed up in the UI. This makes the list reflect what is actually deployed as well as what is editable from source.

Backend

  • New functions package exposing a growable functions.Client facade over knative/func (only List today; deploy/delete/describe expected next).
  • New kube package owning the shared REST config (host resolution, TLS, JSON content type, default request timeout); both cluster and functions build connections through it.
  • cluster is now provisioning-only (RBAC, service accounts, tokens); function querying moved out of the cluster client so it is no longer a god-client.
  • List handler merges repo + cluster results, keeping repo when a function is present in both.
  • Bumped knative/func to include fix(list): populate RUNTIME column in func list knative/func#4010 so cluster-deployed functions report their runtime.

Frontend

  • Added FunctionSource type, threaded source through the table.
  • Edit is disabled for cluster-only functions, with a tooltip explaining there is no source repository to edit.
  • Empty runtime now renders as a dash, matching url/namespace.

Docs

  • docs/ARCHITECTURE.md documents the kube/functions packages and the cluster-access split.

Testing

  • Backend: go build, go vet, go test ./..., golangci-lint all green.
  • Frontend: vitest function-list suites pass (38 tests).

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Aug 14, 2026
@pmeida
pmeida force-pushed the SRVOCF-979-github-func-union branch from c4d9732 to 2968a47 Compare August 17, 2026 11:14
@pmeida

pmeida commented Aug 17, 2026

Copy link
Copy Markdown
Author

Edge cases in the repo/cluster function union - worth discussing

This PR merges repo-discovered and cluster-deployed functions, which surfaces two states we should be intentional about:

  1. Function on the cluster but no repo (source: cluster)
    The function is listed but not editable, since we don't have its source. This can happen when:

    • the user deployed it directly with the func CLI
    • the backing repo was deleted
    • the repo exists but isn't visible to the provided token.
      Current behavior: Edit is disabled with a generic "No source repository to edit" tooltip. That's reasonable, and from the console's vantage point these three sub-causes are indistinguishable, so I don't think we can do better here.
  2. Function has a repo but isn't on the cluster (source: repo)
    The row shows NotDeployed. But that single badge collapses several different situations:

    • not deployed yet
    • the deploy workflow failed
    • it's deployed on a different cluster and only shows up here because the same SCM token for both clusters

    Should we distinguish these? The "workflow failed" case is detectable (we already hold the SCM token and could query the GitHub Actions run status) - I think we have a ticket for it. "Deployed on another cluster" is not reliably detectable from the current cluster. At minimum, wording like "Not deployed on this cluster" would be more honest than "NotDeployed".
    Deploy action: there's currently no way to deploy a repo-only function from the console. Do we want one (e.g. triggering the existing CI workflow via workflow_dispatch)? Probably out of scope for this PR.

@pmeida
pmeida marked this pull request as ready for review August 17, 2026 11:34
@openshift-ci openshift-ci Bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Aug 17, 2026
@openshift-ci
openshift-ci Bot requested review from dsimansk and matejvasek August 17, 2026 11:35
@pmeida

pmeida commented Aug 17, 2026

Copy link
Copy Markdown
Author

/test e2e-aws

@pmeida
pmeida force-pushed the SRVOCF-979-github-func-union branch from 2968a47 to 7107e94 Compare August 17, 2026 16:33
@pmeida

pmeida commented Aug 17, 2026

Copy link
Copy Markdown
Author

/test e2e-aws

1 similar comment
@pmeida

pmeida commented Aug 18, 2026

Copy link
Copy Markdown
Author

/test e2e-aws

Comment thread backend/go.mod Outdated
github.com/google/go-github/v72 v72.0.0
github.com/onsi/ginkgo/v2 v2.32.0
github.com/onsi/gomega v1.42.1
go.yaml.in/yaml/v3 v3.0.5

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove, we have sigs.k8s.io/yaml v1.6.0 in line 16

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Notice that sigs.k8s.io/yaml is itself a wrapper around go.yaml.in/yaml/v3. So by switching to it, we still pull that package in transitively (indirect section)

@twoGiants twoGiants Aug 18, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It makes sense to have an adapter for functions pkg.

I think scaffold could be merged into here. The scaffold package is basically the C in CRUD for function management and the functions package is now the R.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function list was sourced only from GitHub repositories, so
functions deployed to the cluster without a discoverable repo never
appeared in the UI. /func/list now returns the union of repo-discovered
and cluster-deployed functions, tagging each with a source (repo or
cluster) and keeping the repo source when a function exists in both.

Cluster-only functions have no repository to edit, so the frontend
disables their Edit action and explains why on hover. Empty runtime now
renders as a dash, matching url and namespace.

Function querying is split out of the cluster client, which is now
provisioning-only (RBAC, service accounts, tokens). A new functions
package exposes a growable Client facade over knative/func, and a new
kube package owns the shared REST config (host resolution, TLS, JSON
content type, request timeout) that both cluster and functions build on.
This keeps each cluster concern focused and avoids a god-client.

knative/func is bumped to pick up knative/func#4010 so cluster-deployed
functions report their runtime.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@pmeida
pmeida force-pushed the SRVOCF-979-github-func-union branch from 7107e94 to e44895c Compare August 18, 2026 11:17
func.yaml parsing pulled in go.yaml.in/yaml/v3 as a second direct
YAML library, while sigs.k8s.io/yaml was already a dependency. Switch
the func.yaml unmarshal to sigs.k8s.io/yaml and retag the struct with
json tags (which sigs.k8s.io/yaml honors), removing the redundant
direct dependency.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@pmeida

pmeida commented Aug 18, 2026

Copy link
Copy Markdown
Author

/test e2e-aws

@twoGiants twoGiants removed the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Aug 18, 2026
The scaffold and functions packages were both thin facades over
knative/func: scaffold generated a new function's source and CI files,
while functions queried deployed functions. Keeping them apart split
knative/func usage across two boundaries for no real gain.

Fold scaffold into functions so a single package owns all knative/func
usage, while keeping its two responsibilities distinct:

- client.go holds the cluster-connected facade (Client, NewClient,
  List); deploy/undeploy/describe are expected next, hence an interface.
- scaffold.go holds offline generation (Generate, ScaffoldConfig,
  EnvVar), which writes to a temp dir and returns scm.FileEntry blobs.
  It never touches the cluster, so it stays a package function rather
  than a Client method.

Renames for clarity now that both concerns share the namespace:
functions.New -> functions.NewClient, functions.Config ->
functions.ScaffoldConfig. The knative/func import is aliased fn since
the package is itself named functions.

docs/ARCHITECTURE.md updated to drop the scaffold package and record
why offline scaffolding stays separate from the cluster CRUD facade.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@pmeida
pmeida force-pushed the SRVOCF-979-github-func-union branch from 284263f to 72b4609 Compare August 19, 2026 07:49
@openshift-ci openshift-ci Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Aug 19, 2026
@openshift-ci

openshift-ci Bot commented Aug 19, 2026

Copy link
Copy Markdown

@pmeida: all tests passed!

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants