Skip to content

[release-v1.44] fix(apiserver): allow queryserver egress to Linseed via guardian on managed clusters - #5263

Merged
rene-dekker merged 2 commits into
tigera:release-v1.44from
tianfeng92:CI-2048-apiserver-guardian-egress-v1.44
Aug 28, 2026
Merged

[release-v1.44] fix(apiserver): allow queryserver egress to Linseed via guardian on managed clusters#5263
rene-dekker merged 2 commits into
tigera:release-v1.44from
tianfeng92:CI-2048-apiserver-guardian-egress-v1.44

Conversation

@tianfeng92

@tianfeng92 tianfeng92 commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Description

Clean cherry-pick of #5240, no adaptation needed — this branch carries the
pkg/enterprise/apiserver extension mechanism (#4871), so the commit applies as-is.

A managed cluster runs no local Linseed, so the query server reaches it through guardian —
the URL LinseedEndpoint returns as LINSEED_URL. The calico-system.apiserver-access
policy permitted only the local Linseed pods, whose selector matches nothing on a managed
cluster, so the connection fell through to the policy's trailing Pass. The calico-system
tier's default-deny excludes calico-apiserver by design, so the traffic is then evaluated
against the customer's tiers, where any default-deny drops it. The Manager policy board
renders empty and policy activity requests return 500.

The rule is branched in modifyAPIServerPolicy on managementClusterConnection, which is the
same condition the LINSEED_URL env var already uses in that file.

Addresses CI-2048.

Testing

Verified on a live managed cluster on the master change (#5240): with the customer's
default-deny in a tier after calico-system, the original operator returned the reported 500
on GET /policies after a 19.5s guardian timeout, and the fixed operator returned 200 in
0.58s with the calico-system tier present. The deny stayed applied across both runs and only
the operator image changed.

On this branch: pkg/enterprise/apiserver suite green, including the specs covering the rule
being rendered ahead of the trailing Pass on a managed cluster and absent otherwise.

Release Note

Fixed the Manager policy board rendering empty on managed clusters, where the query server was not permitted egress to Linseed through guardian.

For PR author

  • Tests for change.
  • If changing pkg/apis/, run make gen-files
  • If changing versions, run make gen-versions

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



Second commit — CRD regeneration. make gen-versions produces changes against the
committed CRDs on this branch, so dirty-check fails. A separate chore(crds) commit carries
the regenerated output; it is isolated so it can be reviewed or dropped on its own.

FV is red on this branch regardless of this change#5211 and #5229 both fail FV with no
CRD change at all. Note that the regenerated IPPool CRD is rejected by the API server on CEL
cost (x-kubernetes-validations[9].rule: estimated rule cost exceeds budget by factor of more than 100x), so FV now fails at deploy-crds rather than on individual specs. That rule needs
bounding with maxItems/maxLength where the CRD is generated upstream; fixing it there is
what turns FV green for this branch and for #5211 and #5229.

…anaged clusters

A managed cluster runs no local Linseed, so the queryserver reaches it
through guardian. The apiserver-access policy only permitted the local
Linseed pods, which select nothing on a managed cluster, so the request
fell through to the trailing Pass and was denied by whatever the
customer's tiers enforce.

Branch the rule the same way LINSEED_URL is already branched in this
file: guardian when a ManagementClusterConnection is present, local
Linseed otherwise.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@marvin-tigera marvin-tigera added this to the v1.44.0 milestone Aug 26, 2026
@tianfeng92
tianfeng92 force-pushed the CI-2048-apiserver-guardian-egress-v1.44 branch 2 times, most recently from 75949d7 to 9a3542b Compare August 27, 2026 16:54
@tianfeng92
tianfeng92 marked this pull request as ready for review August 27, 2026 16:55
Copilot AI lite review requested due to automatic review settings August 27, 2026 16:55
@tianfeng92
tianfeng92 requested a review from a team as a code owner August 27, 2026 16:55

Copilot AI left a comment

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.

Pull request overview

This PR fixes managed-cluster Manager policy board failures by ensuring the API server’s network policy allows the query server to reach Linseed via Guardian when ManagementClusterConnection is present, and includes a separate CRD regeneration commit (from make gen-versions) that updates several Calico/Enterprise CRD schemas.

Changes:

  • Add a managed-cluster-specific egress allow rule to Guardian in the API server enterprise policy modifier (inserted before the trailing Pass rule).
  • Add unit tests covering presence/absence of the Guardian egress rule depending on whether the cluster is managed.
  • Regenerate imported CRD YAMLs (FelixConfiguration/BGPConfiguration docs/enums, plus additional IPPool CEL validations and description updates).

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
pkg/enterprise/apiserver/extension.go Adds helper to insert egress rules before Pass and adds Guardian egress allow on managed clusters.
pkg/enterprise/apiserver/extension_test.go Adds tests asserting Guardian egress rule is inserted before trailing Pass only on managed clusters.
pkg/imports/crds/enterprise/v3.projectcalico.org/projectcalico.org_felixconfigurations.yaml CRD regen: updates bpfAttachType docs/enums and expands programClusterRoutes docs/enums/default text.
pkg/imports/crds/enterprise/v3.projectcalico.org/projectcalico.org_bgpconfigurations.yaml CRD regen: expands programClusterRoutes docs/enums/default text.
pkg/imports/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_felixconfigurations.yaml CRD regen: same FelixConfiguration schema/doc updates as v3.
pkg/imports/crds/enterprise/v1.crd.projectcalico.org/crd.projectcalico.org_bgpconfigurations.yaml CRD regen: same BGPConfiguration schema/doc updates as v1.
pkg/imports/crds/calico/v3.projectcalico.org/projectcalico.org_ippools.yaml CRD regen: updates IPPool blockSize description and adds additional CEL validations.
pkg/imports/crds/calico/v3.projectcalico.org/projectcalico.org_felixconfigurations.yaml CRD regen: updates bpfAttachType docs/enums/default text to include Netkit.
pkg/imports/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_ippools.yaml CRD regen: same IPPool blockSize description and CEL validation updates as v3.
pkg/imports/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_felixconfigurations.yaml CRD regen: same bpfAttachType docs/enums/default text to include Netkit.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines 93 to +97
blockSize:
description: |-
The block size to use for IP address assignments from this pool. Defaults to 26 for IPv4 and 122 for IPv6.
The block size must be between 0 and 32 for IPv4 and between 0 and 128 for IPv6. It must also be smaller than
or equal to the size of the pool CIDR.
The block size must be between 20 and 32 for IPv4 and between 116 and 128 for IPv6. It must also be smaller
than or equal to the size of the pool CIDR.
Comment on lines 68 to +72
blockSize:
description: |-
The block size to use for IP address assignments from this pool. Defaults to 26 for IPv4 and 122 for IPv6.
The block size must be between 0 and 32 for IPv4 and between 0 and 128 for IPv6. It must also be smaller than
or equal to the size of the pool CIDR.
The block size must be between 20 and 32 for IPv4 and between 116 and 128 for IPv6. It must also be smaller
than or equal to the size of the pool CIDR.
make gen-versions produces changes against the committed CRDs on this
branch, so validate-gen-versions fails dirty-check for every PR opened
against it. Commit the regenerated output.

The drift is upstream CRD movement, not a change of ours, across
FelixConfiguration, IPPool and BGPConfiguration for both calico and
enterprise.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@tianfeng92
tianfeng92 force-pushed the CI-2048-apiserver-guardian-egress-v1.44 branch from 9a3542b to 2d2b32e Compare August 27, 2026 17:29
Copilot AI review requested due to automatic review settings August 27, 2026 17:29

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated 1 comment.

Suppressed comments (2)

pkg/imports/crds/calico/v3.projectcalico.org/projectcalico.org_ippools.yaml:97

  • The updated blockSize description says it must be between 20–32 (IPv4) / 116–128 (IPv6), but the schema still allows 0 and the CEL validation explicitly allows blockSize==0. The description should mention that 0 is permitted (and what it means) to avoid confusing users.
                blockSize:
                  description: |-
                    The block size to use for IP address assignments from this pool. Defaults to 26 for IPv4 and 122 for IPv6.
                    The block size must be between 20 and 32 for IPv4 and between 116 and 128 for IPv6. It must also be smaller
                    than or equal to the size of the pool CIDR.

pkg/imports/crds/calico/v1.crd.projectcalico.org/crd.projectcalico.org_ippools.yaml:72

  • The updated blockSize description says it must be between 20–32 (IPv4) / 116–128 (IPv6), but the schema still allows 0 and the CEL validation explicitly allows blockSize==0. The description should mention that 0 is permitted (and what it means) to avoid confusing users.
                blockSize:
                  description: |-
                    The block size to use for IP address assignments from this pool. Defaults to 26 for IPv4 and 122 for IPv6.
                    The block size must be between 20 and 32 for IPv4 and between 116 and 128 for IPv6. It must also be smaller
                    than or equal to the size of the pool CIDR.

Comment on lines +766 to +767
// insertEgressBeforePass inserts rule ahead of the policy's trailing Pass rule, so that it is
// evaluated before the tier hands the traffic to subsequent tiers.
@tianfeng92 tianfeng92 changed the title fix(apiserver): allow queryserver egress to Linseed via guardian on managed clusters [release-v1.44] fix(apiserver): allow queryserver egress to Linseed via guardian on managed clusters Aug 27, 2026
@rene-dekker
rene-dekker merged commit 055d403 into tigera:release-v1.44 Aug 28, 2026
3 of 4 checks passed
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.

5 participants