Skip to content

Un-fork operator-cloud: bring cloud differences behind a runtime Cloud gate - #4980

Merged
Brian-McM merged 15 commits into
tigera:masterfrom
Brian-McM:bm-upstream-cloud-differences
Jul 29, 2026
Merged

Un-fork operator-cloud: bring cloud differences behind a runtime Cloud gate#4980
Brian-McM merged 15 commits into
tigera:masterfrom
Brian-McM:bm-upstream-cloud-differences

Conversation

@Brian-McM

Copy link
Copy Markdown
Contributor

Description

Type of change: new feature (Calico Cloud support / un-fork of tigera/operator-cloud).

This brings the differences carried by the long-lived tigera/operator-cloud fork back into
tigera/operator, so the fork can be retired. All cloud behavior is gated behind the CALICO_CLOUD
environment variable
(cloud.EnableCloudEnvVar), set on the operator Deployment by the cloud
installer. When the gate is off (every Calico / Calico Enterprise install), behavior is unchanged —
the cloud code paths are inert.

Why merge this: it removes the maintenance burden of a separate fork that had to be continually
re-synced with this repo, and makes Calico Cloud a first-class, gated mode of the upstream operator.

How it works:

  • pkg/cloud parses CALICO_CLOUD at startup and returns Cloud=false (no-op) unless it is set,
    threading options.ControllerOptions.Cloud to controllers.
  • Controllers populate typed per-component cloud extension structs (e.g. render.ManagerCloudResources)
    only when opts.Cloud is true; render decorators are no-ops otherwise.
  • Cloud version pins are generated from config/cloud_versions.yml into pkg/components/cloud.go via a
    new standalone make gen-versions-cloud target (not part of the default gen-versions aggregate, so
    enterprise generated output is byte-identical).

Components affected (all gated): manager, logstorage (linseed / esgateway / kibana / elastic /
external-elastic / dashboards / kube-controllers + ES ILM), api-server RBAC, compliance, fluentd, tiers,
intrusion-detection, policy-recommendation, monitor, packet-capture. Intrusion-detection additionally
cleans up orphaned Image Assurance resources.

Testing:

  • make build / go build ./pkg/... ./cmd/... succeed.
  • Unit tests pass for every touched package, including new cloud-path tests (manager / fluentd / kibana /
    esgateway / linseed render and elastic / compliance / manager controllers), each with cloud-on and
    cloud-off (negative) cases confirming enterprise output is unchanged.
  • Branch rebased cleanly on master; cloud version generation is idempotent.

A full migration map and rationale is in docs/cloud-unfork-migration-plan.md.

Prerequisite context: tigera/operator-cloud#1059 (removal of dead Image Assurance / runtime security)
landed in the fork first.

Release Note

NONE

For PR author

  • Tests for change.
  • If changing pkg/apis/, run make gen-files (no api/v1 / CRD changes in this PR)
  • If changing versions, run make gen-versions (make gen-versions-cloudpkg/components/cloud.go)

For PR reviewers

A note for code reviewers - all pull requests must have the following:

  • Milestone set according to targeted release.
  • Appropriate labels:
    • kind/bug if this is a bugfix.
    • kind/enhancement if this is a a new feature.
    • enterprise if this PR applies to Calico Enterprise only.

🤖 Generated with Claude Code

Comment thread cmd/main.go Outdated
})
}

if cloudOpts.Cloud {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is this real? I'm a bit surprised this would be needed for CC and not for everyone else who uses the operator 🤷

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It probably wouldn't hurt to use it for everybody.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think it would potentially slow down rolling update?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Ohh right, ya it would. It seems like there's a better solution to this issue, how long is the apiserver taking that we need this sort of duration?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

how long is the apiserver taking that we need this sort of duration?

Indeed, that's basically my question. This smells a lot like code that was added to fix a symptom rather than a root cause and that might not be needed any more.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@Brian-McM bumping this one - did you get a chance to dig into the apiserver latency numbers? Still want to make sure these longer durations aren't just papering over a slow apiserver rather than fixing the actual cause.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Just looking into this now, this was something added a long time ago so might not be relevant anymore, cc @tmjd.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Chatted with @tmjd and I'm going to remove the hard coded override but put in flags to update these values in case we need to quickly override these again in cloud.

Sound good @caseydavenport ?

Comment thread cmd/main.go Outdated
Comment thread cmd/main.go Outdated
Comment thread docs/cloud-unfork-migration-plan.md Outdated
Comment thread hack/gen-versions/main.go
Comment thread hack/hashrelease/management_cluster_updater.py Outdated
Comment thread pkg/cloud/watch.go Outdated
Comment thread pkg/cloud/watch.go Outdated
KeyValidatorConfig: keyValidatorConfig,
KubernetesVersion: r.opts.KubernetesVersion,
ClusterDomain: r.opts.ClusterDomain,
Cloud: r.opts.Cloud,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I've already started doing this in other places - I'll handle it in my own refactoring but worth calling out that I'm moving to just having the ControllerOptions as a field on the controller instead of copying each var individually.

Comment thread pkg/controller/compliance/compliance_controller.go Outdated
Comment thread pkg/controller/compliance/compliance_controller.go Outdated
Comment thread pkg/controller/logstorage/dashboards/dashboards_controller.go Outdated
Comment thread pkg/controller/logstorage/elastic/elastic_controller.go Outdated
Comment thread pkg/controller/logstorage/elastic/external_elastic_controller.go Outdated
Comment thread pkg/controller/logstorage/linseed/linseed_controller.go Outdated
var mcr render.ManagerCloudResources
if r.opts.Cloud {
var reconcileResult *reconcile.Result
bundleMaker, mcr, tenant, reconcileResult, err = r.handleCloudReconcile(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is probably fine, but I think we probably only structure the code this way because it used to be a fork and we didn't want to interleave merge conflicts - we should probably unpack this as a follow on to clean it up instead of overwriting / recalculating what was done above.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Oh I fully intend on doing that right now, this is the initial pass.

Comment thread pkg/controller/options/options.go Outdated
Comment thread pkg/controller/tiers/tiers_controller_cloud.go Outdated

// GetCloudConfig retrieves the config map containing the configuration values needed to set up communications with
// external Elasticsearch and Kibana, such as the externalESDomain and externalKibanaDomain.
func GetCloudConfig(ctx context.Context, cli client.Client) (*cloudconfig.CloudConfig, error) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Does it make sense for this to be separate from the other utility functions in pkg/cloud/ ?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@Brian-McM any thoughts here? Feels like it'd sit more naturally alongside the other helpers in pkg/cloud/.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Might be splitting hairs here but this logic is pretty controller centric, while the pkg/cloud is used for initial setup.

Comment thread pkg/render/common/test/testing.go
Comment thread pkg/render/kubecontrollers/kube-controllers.go Outdated
Comment thread pkg/render/logstorage/esgateway/cloud.go Outdated
Brian-McM added a commit to Brian-McM/operator that referenced this pull request Jul 20, 2026
…val, cloud release version fix

Follow-up to review comments from @radTuti and @tmjd:

- CI registry cred isolation (radTuti): each job now authenticates only to
  the registry it pushes to — quay login in the enterprise Build/Publish
  Release jobs, gcloud/GCR in the Build Cloud/Publish Cloud Release jobs —
  instead of both in the shared block prologue (push_images.yml, release.yml).

- Remove dead cloud version/image machinery (tmjd): the operator does not
  deploy cc-rbac-api, and ComponentCloudRBACAPI / CloudImages / CloudRegistry
  were never consumed. Drop config/cloud_versions.yml, pkg/components/cloud.go,
  pkg/components/cloud_images.go, and the gen-versions-cloud target +
  CLOUD_VERSIONS. CalicoCloudImage() (used by kube-controllers) is unrelated
  and stays.

- Reference TSLA-11650 for possible removal of CalicoCloudImage() (tmjd).

- Fix the cloud tagged-release path (radTuti): the cloud image/version keeps a
  -cloud suffix (vX.Y.Z-cloud) but rides the enterprise git tag (vX.Y.Z), so
  the version no longer matches git describe. checkVersionMatchesGitVersion now
  strips -cloud before matching, and the release tool passes GIT_VERSION=VERSION
  for cloud so the Makefile's VERSION==GIT_VERSION guard passes and the binary
  reports the -cloud version.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Brian-McM added a commit to Brian-McM/operator that referenced this pull request Jul 20, 2026
…val, cloud release version fix

Follow-up to review comments from @radTuti and @tmjd:

- CI registry cred isolation (radTuti): each job now authenticates only to
  the registry it pushes to — quay login in the enterprise Build/Publish
  Release jobs, gcloud/GCR in the Build Cloud/Publish Cloud Release jobs —
  instead of both in the shared block prologue (push_images.yml, release.yml).

- Remove dead cloud version/image machinery (tmjd): the operator does not
  deploy cc-rbac-api, and ComponentCloudRBACAPI / CloudImages / CloudRegistry
  were never consumed. Drop config/cloud_versions.yml, pkg/components/cloud.go,
  pkg/components/cloud_images.go, and the gen-versions-cloud target +
  CLOUD_VERSIONS. CalicoCloudImage() (used by kube-controllers) is unrelated
  and stays.

- Reference TSLA-11650 for possible removal of CalicoCloudImage() (tmjd).

- Fix the cloud tagged-release path (radTuti): the cloud image/version keeps a
  -cloud suffix (vX.Y.Z-cloud) but rides the enterprise git tag (vX.Y.Z), so
  the version no longer matches git describe. checkVersionMatchesGitVersion now
  strips -cloud before matching, and the release tool passes GIT_VERSION=VERSION
  for cloud so the Makefile's VERSION==GIT_VERSION guard passes and the binary
  reports the -cloud version.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Brian-McM
Brian-McM force-pushed the bm-upstream-cloud-differences branch from a262857 to d10356a Compare July 20, 2026 22:15
Brian-McM added a commit to Brian-McM/operator that referenced this pull request Jul 20, 2026
… is known

Resolves the cloud trusted-bundle TODO (PR tigera#4980 review, @caseydavenport).
Previously the bundle was created early, then re-created for Calico Cloud
management clusters once the authenticationCR was available. Since the bundle
isn't consumed until later in Reconcile, move its creation down past the
authenticationCR fetch and build it once — standard, multi-tenant, or the
Calico Cloud system-root variant (for external OIDC verification) — dropping
the re-creation. The auth-gating order is unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Comment thread pkg/controller/logstorage/elastic/elastic_controller.go
Comment thread pkg/render/logstorage/kibana/kibana.go Outdated
Comment thread pkg/cloud/cloud.go Outdated
Comment thread cmd/main.go Outdated
})
}

if cloudOpts.Cloud {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@Brian-McM bumping this one - did you get a chance to dig into the apiserver latency numbers? Still want to make sure these longer durations aren't just papering over a slow apiserver rather than fixing the actual cause.

Comment thread pkg/controller/logstorage/dashboards/dashboards_controller.go Outdated
Comment thread pkg/controller/logstorage/linseed/linseed_controller.go Outdated

// GetCloudConfig retrieves the config map containing the configuration values needed to set up communications with
// external Elasticsearch and Kibana, such as the externalESDomain and externalKibanaDomain.
func GetCloudConfig(ctx context.Context, cli client.Client) (*cloudconfig.CloudConfig, error) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@Brian-McM any thoughts here? Feels like it'd sit more naturally alongside the other helpers in pkg/cloud/.

Brian-McM added a commit to Brian-McM/operator that referenced this pull request Jul 27, 2026
…na global, consolidate cloud startup

Review follow-ups:
- kibana: thread the Calico Cloud Kibana config overrides through Configuration
  (CloudConfigOverrides) instead of a package global. The map is now a per-reconcile
  local, so a deleted cloud-kibana-config ConfigMap no longer leaves stale overrides.
- logstorage dashboards/linseed: document that the `!cloud` clause is load-bearing —
  for any non-cloud install it collapses to the original pre-cloud check, so EE
  behavior is unchanged.
- main.go: replace the cloud-only 4x leader-election overrides with
  --leader-election-{lease-duration,renew-deadline,retry-period} flags defaulting to
  the controller-runtime (and EE) values. No separate cloud code path.

Dismantle pkg/cloud:
- Fold the build-variant stamp (buildVariant/isCloudBuild) and cloud startup into
  cmd (package main); delete the pkg/cloud package and the dead ToPtr helper.
- Cloud startup now reads the operator bootstrap ConfigMap (ELASTIC_EXTERNAL /
  ELASTIC_MIGRATION) via discovery and reuses utils.MonitorConfigMap, removing the
  duplicate cloud-operator-config load and bespoke config watch. Use %w when wrapping
  the startup errors.
- Makefile: CLOUD_LDFLAGS becomes `-X main.buildVariant=cloud` (the linker addresses
  package main as "main", not by import path).

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

@caseydavenport caseydavenport left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Just a few more thoughts / questions. Probably the last round though!

Comment thread cmd/main.go Outdated
// buildVariant is injected at build time via -ldflags "-X main.buildVariant=cloud" when building the
// Calico Cloud operator image (see CLOUD_LDFLAGS in the Makefile). It is empty for the regular
// Calico/Calico Enterprise image. Baking it into the binary means cloud mode is immutable: it cannot
// be disabled by editing the operator Deployment's environment.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Baking it into the binary means cloud mode is immutable: it cannot be disabled by editing the operator Deployment's environment.

Just a bit of a pressure test... why is this important?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I don't want us to somehow have some weird backdoor of setting a operator cloud image into EE mode.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'm generally against having two builds of this code if we can avoid it.

I don't see there being a huge risk of someone having a backdoor, and if they do it's not actually a problem? It just won't work, right?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The risk is that a cloud environment gets turned into an ee environment and cloud production cluster is hosed, even worse if it's a multi tenant one.

I don't like uneccessarily having multiple builds, but I'll stand by it being worth it in this case.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Yeah, I just don't see why that's a risk worth propagating into our build + code, rather than just having CI that catches misconfigurations before merging manifest changes. A CLI argument would be pretty hard to mess up, especially if we had some pre-flight checks that caught a misconfiguration and prevented the operator from taking action.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I sort of think the opposite, why push it to testing when you can just make it not possible. I'm not sure this is huge burden having two builds here tbh, but I'd just like to roll with this for my peace of mind and if it is for some reason actual issue then maybe we can just revisit then.

Comment thread cmd/main.go Outdated
Comment thread cmd/main.go Outdated
Comment thread pkg/controller/logstorage/dashboards/dashboards_controller.go Outdated
Comment thread pkg/controller/logstorage/linseed/linseed_controller.go Outdated
Brian-McM added a commit to Brian-McM/operator that referenced this pull request Jul 28, 2026
…als, trim comments

Restructure the external-ES tenant-source conditional in the dashboards and
linseed controllers to `if multiTenant { } else if cloud { }`. EE single-tenant
external ES does not exist, so the previously-handled third state is
unreachable; this drops the load-bearing explainer comment.

Trim verbose comments across cmd/main.go, the release setup package, and the
kibana/elastic logstorage code.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Brian-McM and others added 14 commits July 29, 2026 10:40
…d gate

Migrate the tigera/operator-cloud fork's differences into tigera/operator,
gated by the CALICO_CLOUD env var so enterprise/OSS behavior is unchanged
unless cloud mode is active.

- Foundation: pkg/cloud (CALICO_CLOUD gate, tolerant Load), render/common/cloudconfig,
  controller/utils/cloudconfig, options.{Cloud,ESMigration}, cmd/main wiring.
- Shared helpers: key_validator cloud tenancy claim (self-gating), auth_cloud,
  GetKeyValidatorConfig addTenancyClaim param, meta.DefaultCertificateDuration,
  elasticsearch.AddTenantId.
- Per-component cloud paths (all gated): manager, logstorage (linseed/esgateway/
  kibana/elastic/external-elastic/dashboards/kubecontrollers + ES ILM), compliance,
  fluentd, tiers, intrusiondetection, policyrecommendation, monitor, packetcapture.
- apiserver + kube-controllers RBAC divergences gated behind Cloud.
- Intrusion detection: clean up orphaned Image Assurance resources.
- Cloud version-gen wiring: -cloud-versions flag, cloud.go.tpl, gen-versions-cloud
  target, generated pkg/components/cloud.go.
- Cloud-path tests for manager/fluentd/kibana render and elastic/compliance/manager
  controllers. Plan + status in docs/cloud-unfork-migration-plan.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add the Calico Cloud release tooling, gated by the `cloud` build tag so the
enterprise/OSS release tool is unaffected.

- hack/release/cloud.go + internal/versions/cloud.go (//go:build cloud): init()
  wraps the OSS release commands (GCR/tesla image defaults, cloud-vX.Y.Z version
  format, hashrelease support, CI output files). checks.go/flags.go are NOT changed
  (cloud.go reassigns isValidReleaseVersion at init).
- Makefile: `make release-cloud` / `release-publish-cloud` build with -tags cloud;
  a gated `ifeq ($(VARIANT),cloud)` block switches image identity to
  gcr.io/tigera-tesla/operator-cloud (amd64) without affecting enterprise builds.
- hack/release/CLOUD.md documents the flow.

Verified: untagged release tool builds + tests unchanged; tagged build + cloud
test pass; Makefile VARIANT gating switches vars correctly.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Bring the Calico Cloud CI from the fork, adapted to tigera/operator and made to
coexist with the enterprise CI.

Semaphore (additive — enterprise pipelines untouched):
- push_images_cloud.yml / release_cloud.yml: new pipelines that push the
  operator-cloud image to GCR via VARIANT=cloud (amd64 only); release triggers on
  cloud-v* tags.
- semaphore.yml: two additive promotions (Push Cloud Images, Release Cloud); the
  enterprise promotions and multi-arch build are unchanged.
- Makefile: release-tag-cloud target (uses the -tags cloud release tool).

ArgoCI (.argoci/, new to this repo): build-hashrelease + update-cluster-with-
hashrelease workflows and hack/hashrelease/*.py cluster updaters. Source-repo
references retargeted operator-cloud -> tigera/operator (clone URL/dir, labels,
branch param, build command -> make release-cloud release-publish-cloud); the
published image name (operator-cloud), GCR project, secrets, Slack and cluster
infra are kept as-is.

Fork-maintenance machinery (fork-sync crons/templates, update_fork.sh,
approve_check.yml) is intentionally dropped.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Cloud-only changes that landed on operator-cloud after the initial un-fork
snapshot (or were missed by it), all behind the runtime Cloud gate so
enterprise/OSS behavior is unchanged:

- TSLA-11182: disable ui-apis Kibana login for all Calico Cloud (not just
  multi-tenant) via a cloud-gated decorateCloudUIAPIsContainer decorator.
- TSLA-11580 (tigera#1111): run cloud kube-controllers from the tesla-tagged
  calico image (components.CalicoCloudImage); gated on Config.Cloud, plumbed
  into both the calico- and es-kube-controllers render configs.
- TSLA-11553 (tigera#1103): pin the policy-activity index base name only for
  single-tenant external-ES (Tenant.SingleTenant()), not all tenants.
- TSLA-11547: point enterprise images at the cloud registry in the
  build-hashrelease ArgoCI template so hashrelease images resolve.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Casey flagged that ElasticExternal (cloud) and discovery.UseExternalElastic
(enterprise bootstrap configmap) are the same knob read from two configmaps,
OR'd together in main.go. Collapse to a single source: the operator now reads
external-ES only from operator-bootstrap-config via discovery.UseExternalElastic.

Calico Cloud provisions ELASTIC_EXTERNAL into operator-bootstrap-config too (in
addition to cloud-operator-config, which cloud.Load still reads for its own
startup verify), so cloud and enterprise share one downstream gate. Requires the
cc-mgmt-config helm chart to populate operator-bootstrap-config (separate change).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
setupLog.Info takes key/value pairs, not printf verbs; passing a lone err
after a "%v" message string is an odd argument count that trips zap's dpanic
("odd number of arguments passed as key-value pairs for logging"). Use a
proper "error", err pair.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Master replaced fluentd with fluent-bit, which dropped the DISABLE_ES_*_LOG
env toggles the un-fork's cloud path used (they died with the fluentd ES
output; fluent-bit ships to Linseed). Reimplement the same cloud/enterprise
split natively: a Cloud gate omits the Linseed outputs for the log types cloud
does not store — DNS, EE/kube audit and BGP always, and flow logs unless this
is a multi-tenant management cluster (matching the old
DISABLE_ES_{DNS,AUDIT_EE,AUDIT_KUBE,BGP,FLOW}_LOG behavior). Non-cluster host
variants follow their base tag. Enterprise behavior is unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…handling

Make the Calico Cloud variant easy to tell apart from enterprise and
collapse the cloud release/CI machinery down to the minimal set of
runtime-resolved differences.

Binary / version markers:
- Build the cloud operator binary as operator-cloud-<arch> via a new
  BINARY_NAME make var (VARIANT=cloud); Dockerfile copies it by name.
- --version (and the startup log) print "Variant: Calico Cloud" for a
  cloud build, as a separate line so hack/release parsing is unaffected.

Release tool:
- Replace hack/release/cloud.go (and the -tags-style overrides) with a
  single internal/setup package that resolves the variant-dependent
  defaults (registry, image, release-version validator, github-release
  default) once at init, keyed off VARIANT. This runs before the main
  package's flag vars initialize, so flag defaults capture the correct
  cloud/enterprise values with no fix-up.
- Cloud releases use the operator's own version scheme with a -cloud
  suffix (vX.Y.Z-cloud) instead of a bespoke format.
- Drop the Argo hashrelease flow and its pinned-components/cloud-registry
  machinery (build-hashrelease.yaml, internal/versions/cloud.go).
- Remove CLOUD.md; document the variant briefly in README instead.

Semaphore CI:
- Fold cloud build/publish into the enterprise pipelines as parallel
  jobs (Build Cloud in push_images.yml, Publish Cloud Release in
  release.yml) off the same branches/tags, differing only by
  VARIANT=cloud and the -cloud image/version. GCR auth is added to the
  shared block prologues (required for the operator-cloud GCR push).
- Delete the separate release_cloud.yml / push_images_cloud.yml
  pipelines and their promotions.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…val, cloud release version fix

Follow-up to review comments from @radTuti and @tmjd:

- CI registry cred isolation (radTuti): each job now authenticates only to
  the registry it pushes to — quay login in the enterprise Build/Publish
  Release jobs, gcloud/GCR in the Build Cloud/Publish Cloud Release jobs —
  instead of both in the shared block prologue (push_images.yml, release.yml).

- Remove dead cloud version/image machinery (tmjd): the operator does not
  deploy cc-rbac-api, and ComponentCloudRBACAPI / CloudImages / CloudRegistry
  were never consumed. Drop config/cloud_versions.yml, pkg/components/cloud.go,
  pkg/components/cloud_images.go, and the gen-versions-cloud target +
  CLOUD_VERSIONS. CalicoCloudImage() (used by kube-controllers) is unrelated
  and stays.

- Reference TSLA-11650 for possible removal of CalicoCloudImage() (tmjd).

- Fix the cloud tagged-release path (radTuti): the cloud image/version keeps a
  -cloud suffix (vX.Y.Z-cloud) but rides the enterprise git tag (vX.Y.Z), so
  the version no longer matches git describe. checkVersionMatchesGitVersion now
  strips -cloud before matching, and the release tool passes GIT_VERSION=VERSION
  for cloud so the Makefile's VERSION==GIT_VERSION guard passes and the binary
  reports the -cloud version.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… is known

Resolves the cloud trusted-bundle TODO (PR tigera#4980 review, @caseydavenport).
Previously the bundle was created early, then re-created for Calico Cloud
management clusters once the authenticationCR was available. Since the bundle
isn't consumed until later in Reconcile, move its creation down past the
authenticationCR fetch and build it once — standard, multi-tenant, or the
Calico Cloud system-root variant (for external OIDC verification) — dropping
the re-creation. The auth-gating order is unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…na global, consolidate cloud startup

Review follow-ups:
- kibana: thread the Calico Cloud Kibana config overrides through Configuration
  (CloudConfigOverrides) instead of a package global. The map is now a per-reconcile
  local, so a deleted cloud-kibana-config ConfigMap no longer leaves stale overrides.
- logstorage dashboards/linseed: document that the `!cloud` clause is load-bearing —
  for any non-cloud install it collapses to the original pre-cloud check, so EE
  behavior is unchanged.
- main.go: replace the cloud-only 4x leader-election overrides with
  --leader-election-{lease-duration,renew-deadline,retry-period} flags defaulting to
  the controller-runtime (and EE) values. No separate cloud code path.

Dismantle pkg/cloud:
- Fold the build-variant stamp (buildVariant/isCloudBuild) and cloud startup into
  cmd (package main); delete the pkg/cloud package and the dead ToPtr helper.
- Cloud startup now reads the operator bootstrap ConfigMap (ELASTIC_EXTERNAL /
  ELASTIC_MIGRATION) via discovery and reuses utils.MonitorConfigMap, removing the
  duplicate cloud-operator-config load and bespoke config watch. Use %w when wrapping
  the startup errors.
- Makefile: CLOUD_LDFLAGS becomes `-X main.buildVariant=cloud` (the linker addresses
  package main as "main", not by import path).

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

Consolidates release-version format checks onto setup.IsValidReleaseVersion and
removes the now-redundant local isReleaseVersionFormat helper (radTuti review
comment on hack/release/utils.go). In the default (non-cloud) variant the setup
validator uses the identical ^vX.Y.Z regex, so behavior is unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The Calico version is validated on the cloud path (the build command sets
CALICO_VERSION with VARIANT=cloud), but setup.IsValidReleaseVersion is
variant-aware and requires a -cloud suffix in cloud mode — which the Calico
version never carries. Add setup.IsValidCalicoReleaseVersion (always plain
vX.Y.Z) and use it for the Calico version flag and release-prep, leaving the
variant-aware validator for the operator version. Also drop the now-unused
releaseFormat const from utils.go (superseded by setup's formats).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…als, trim comments

Restructure the external-ES tenant-source conditional in the dashboards and
linseed controllers to `if multiTenant { } else if cloud { }`. EE single-tenant
external ES does not exist, so the previously-handled third state is
unreachable; this drops the load-bearing explainer comment.

Trim verbose comments across cmd/main.go, the release setup package, and the
kibana/elastic logstorage code.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Brian-McM
Brian-McM force-pushed the bm-upstream-cloud-differences branch from f2f0b40 to 4030b58 Compare July 29, 2026 17:42
Comment thread hack/release/README.md
Comment thread pkg/render/apiserver.go
// Calico Cloud additionally grants access to runtime logs.
resourceNames := []string{"flows", "audit*", "l7", "events", "dns", "waf", "kibana_login", "recommendations"}
if c.cfg.Cloud {
resourceNames = append([]string{"runtime"}, resourceNames...)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Do we even need to include this anymore?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

ooof, I'm not sure, I would think not....

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Brian-McM
Brian-McM merged commit 8874924 into tigera:master Jul 29, 2026
6 checks passed
@Brian-McM
Brian-McM deleted the bm-upstream-cloud-differences branch July 29, 2026 21:37
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.

6 participants