[WIP] Add func-operator integration to deploy command #3657
[WIP] Add func-operator integration to deploy command #3657creydr wants to merge 6 commits intoknative:mainfrom
Conversation
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: creydr The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #3657 +/- ##
==========================================
- Coverage 56.69% 56.42% -0.27%
==========================================
Files 181 183 +2
Lines 20732 21096 +364
==========================================
+ Hits 11753 11904 +151
- Misses 7768 7958 +190
- Partials 1211 1234 +23
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
When deploying a function, automatically create or update a Function CR (functions.dev/v1alpha1) if the func-operator CRD is installed on the cluster. On first deploy, the CR is created with the git repository URL, branch, and path. On subsequent deploys, only the functions.knative.dev/last-deployed annotation is updated. - Add pkg/git/ with go-git based resolution of remote URL and branch - Add pkg/operator/ with Function CR sync logic and k8s client setup - Add WithPostDeploy client option to run post-deploy hooks - Add --manage flag (default true) to opt out with --manage=false - Wire operator sync via WithPostDeploy in deploy command - Git URL cascade: --git-url > tracking remote > origin - Branch cascade: --git-branch > current branch > "main" - Silently skip if CRD not installed; warn if no git remote found
Add TestInt_OperatorSync to the shared deployer integration test helper. The test deploys a function with WithPostDeploy wired to operator.SyncFunctionCR, verifies the Function CR is created with the correct spec on first deploy, and confirms only the last-deployed annotation is updated on subsequent deploys. CR verification is skipped gracefully when the Function CRD is not installed.
Add func-operator v0.2.1 to the cluster setup script so the Function CRD is available for integration tests. The operator is installed in parallel with other components during cluster allocation.
ResolveRemoteURL now removes userinfo (username and password) from HTTP/HTTPS remote URLs before returning them, preventing credentials from being stored in the Function CR spec.
When deploying to a private registry, resolve credentials via the existing CredentialsProvider, create a docker-registry K8s Secret, and set .spec.registry.authSecretRef on the Function CR so the func-operator can authenticate with the registry.
- Check return value of AddToScheme (errcheck lint) - Make registry secret creation injectable for unit tests - Add git commit author in resolver tests for CI - Add FuncOperator to component-versions test expectations
6bd73c4 to
ba2e1c9
Compare
|
PR needs rebase. DetailsInstructions 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. |
lkingland
left a comment
There was a problem hiding this comment.
Looks great! My only substantive suggestion is that this be integrated more deeply into core instead of an ad-hoc post-deploy hook 👍🏻
| module knative.dev/func | ||
|
|
||
| go 1.25.9 | ||
| go 1.26 |
There was a problem hiding this comment.
I presume this was necessary due to controller-runtime dependency? Maybe just add to the commit description this PR also bumps to Go 1.26
| } | ||
|
|
||
| if cfg.RepoURL == "" { | ||
| fmt.Fprintln(os.Stderr, "Function CR not created: no git remote found. Set --git-url to enable operator management.") |
There was a problem hiding this comment.
This warning will fire on every deploy without a configured git remote, given --manage=true is the default. I think that there are actually two preconditions for a Function to be "managed": The operator is installed AND they're using git.
The base case: A user just initializes a function and deployes it directly to a vanilla cluster, shouldn't really even print a warning (it's an expected base case).
| } | ||
|
|
||
| if existing != nil { | ||
| existing.Spec = desiredSpec |
There was a problem hiding this comment.
Just double-checking: without using a merge, this will always overwrite the spec, even if changed in some different way. I think that's what we want (again encouraging declarative config), but just want to flag this to be sure.
| func hasFunctionCRD(disc discovery.DiscoveryInterface) (bool, error) { | ||
| resources, err := disc.ServerResourcesForGroupVersion("functions.dev/v1alpha1") | ||
| if err != nil { | ||
| return false, nil |
There was a problem hiding this comment.
This swallows any error from ServerResourcesForGroupVersion and treats it identically to "CRD not present." If there's a legitimate reason, we probably want to raise an error. Perhaps something like:
resources, err := disc.ServerResourcesForGroupVersion("functions.dev/v1alpha1")
if err != nil {
if apierrors.IsNotFound(err) || meta.IsNoMatchError(err) {
return false, nil
}
return false, fmt.Errorf("checking for Function CRD: %w", err)
}(I haven't fully traced the call path here; just an example)
| if list.Items[i].Status.Name == funcName { | ||
| return &list.Items[i], nil | ||
| } | ||
| } | ||
|
|
||
| for i := range list.Items { | ||
| if list.Items[i].Name == funcName { |
There was a problem hiding this comment.
Minor nit: these two loops over list.Items made me double-check to see if it was an error. maybe just put both if statements in one for-loop for clarity that this was intended.
| if c.Manage { | ||
| o = append(o, fn.WithPostDeploy(func(ctx context.Context, f fn.Function) error { | ||
| if err := syncFunctionCR(ctx, f, c, creds); err != nil { | ||
| fmt.Fprintf(os.Stderr, "Warning: failed to sync Function CR: %v\n", err) | ||
| } | ||
| return nil | ||
| })) | ||
| } |
There was a problem hiding this comment.
This should probably be part of core rather than in the CLI. Adding a boolean to the Function structh which states this is a "managed" Function, and a CR should be created (if the operator is installed).
| pipelinesProvider PipelinesProvider // CI/CD pipelines management | ||
| mcpServer MCPServer // MCP Server | ||
| startTimeout time.Duration // default start timeout for all runs | ||
| postDeploy func(context.Context, Function) error |
There was a problem hiding this comment.
No need for a post-deploy hook if we just extend the core's "deploy" logic to do the CR work if the given function is a "managed" function.
To make it even simpler, the flag could be "ManagementDisabled", such that the deafult will always be to create the CR if the system detects the operator is installed.
Changes
func deploywhen func-operator is installedfunc deploy --manage=false/kind enhancement
Release Note