Skip to content

Add a startup extension so main stops calling into pkg/enterprise - #5237

Open
caseydavenport wants to merge 1 commit into
tigera:masterfrom
caseydavenport:casey-operator-shim
Open

Add a startup extension so main stops calling into pkg/enterprise#5237
caseydavenport wants to merge 1 commit into
tigera:masterfrom
caseydavenport:casey-operator-shim

Conversation

@caseydavenport

@caseydavenport caseydavenport commented Aug 21, 2026

Copy link
Copy Markdown
Member

Description

The operator's startup path calls into the Enterprise package directly for several things. Those go through the extensions boundary here instead, via a new startup slot that no-ops when nothing registers.

  • checking that the variant's CRDs are served before any controller starts
  • verifying the cluster's Elasticsearch certificates match the configured internal or external mode
  • listing the namespaces the operator manages and so must not run in itself
  • discovering the tenancy mode, which only ever comes back true for Enterprise or Cloud
  • interpreting the cloud build flag, which the Makefile bakes in through linker flags

The extensions now arrive as a factory rather than a built registry, since the variant is not known until the operator has a client and has read the Installation. That leaves cmd/main.go naming a variant in exactly one place, the factory it starts with, which is what a variant's own entry point replaces.

Behavior is unchanged with two exceptions worth calling out. The protected namespaces were already applied whatever the variant, so the startup extension registers for every variant and skips the checks that only apply to Enterprise. The version banner prints the build variant it was given rather than a hardcoded product name, so a cloud build reports "cloud"; the line the release tooling parses for the operator version is untouched.

Related: CORE-13420

None

Comment thread cmd/main.go
}
// buildExtensions is the variant's extensions factory, and the only place this binary
// names a variant. A variant's own main supplies its own once main becomes a shim.
var buildExtensions extensions.Factory = enterprise.Build

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

As this PR stands the factory methodology here seems uneccessary (might be missing something though).

I could understand this though if the follow up work / goal is that this factory is defaulted in OS and then overwritten in enterprise, although I might still have some questions if that's the case.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yeah, it might be overkill - the idea is that we're preparing for a future where we have an "operator as a library" structure, and enterprise imports it.

Something like this:

  • calico:
    • lib/operator/
    • cmd/main.go - imports lib/operator/ and calls New() without an extension.
  • calico-private
    • cmd/main.go - imports calico/lib/operator/ and calls New() with this extension factory.

The reason for a factory is that the context needed to build the extension is queried from the cluster in main

It mostly just removes the need to duplicate that context gathering to build the extension - perhaps overkill, perhaps not. But happy to hear either way.

Otherwise, we'll just need to copy lines 424-449 below in both places.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think in this mono repo merged world we'd might still have separate main files for calico versus calico-private, so the buildExtensions variable that's overwritten in main.go doesn't seem like it would even be something that's viable to use in that future.

The common lines you referenced will have to go into some common invocable library if you want to share it between the main OS and EE main files.

The main functions just call whatever they need to get the extension registry and pass it to the common tooling so the "factories" don't even have to have the same function definition between the two variants.

I might just advocate for taking out that factory variable / type because whether or not that's needed is very much dependent on the final step we take to merge this into the mono repo.

The variant's API checks, cluster state verification, protected namespaces,
tenancy and cloud build flag now register through pkg/extensions, and the
extensions arrive as a factory the operator calls once it resolves the variant.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants