Skip to content

🌱 sync: forward-port v4.17.1 into v5 with ancestry - #6060

Merged
clubanderson merged 12 commits into
v5from
sync/v4-into-v5-ancestry-2026-09-05
Sep 5, 2026
Merged

🌱 sync: forward-port v4.17.1 into v5 with ancestry#6060
clubanderson merged 12 commits into
v5from
sync/v4-into-v5-ancestry-2026-09-05

Conversation

@clubanderson

Copy link
Copy Markdown
Member

Summary

Conflict resolutions

  • CHANGELOG.md: kept v5 generated changelog; retained changelog fragments instead of importing v4 release-generated sections.
  • src/cmd/hive/main.go: kept v5 decomposed entrypoint; moved structured GitHub App failure and output-freshness helpers into split cmd/hive files and wired hubwire payload fields.
  • src/pkg/hub/saas.go: kept v5 split router/static layout; wildcard TLS health and provider-limit behavior were applied to split hub files.
  • src/pkg/agent/manager.go: kept v5 split snapshot implementation and added v4.17 start-failure detail fields to the split snapshot.
  • src/pkg/hub/agent_capability.go / heartbeat.go: combined restart-reset support from v5 with v4.17 provider-limit/start-failure telemetry.
  • src/docs/README.md: kept existing v5 docs entries and added the v4→v5 sync policy link.

Validation

  • cd src && go build ./...
  • cd src && go vet ./...
  • cd src && go test ./cmd/hive ./pkg/agent ./pkg/hub ./pkg/dashboard ./pkg/tokens
  • cd src && bash scripts/test-publish-image-tags.sh
  • python3 src/scripts/check-docs-links.py

clubanderson and others added 12 commits September 5, 2026 00:42
Closes #6030
Closes #6032

Signed-off-by: Andy Anderson <andy@clubanderson.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Closes #6036

Signed-off-by: Andy Anderson <andy@clubanderson.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Automated release commit. Compiles changelog.d/ fragments and moves
the CHANGELOG.md Unreleased section into a dated v4.17.0 entry.
See src/docs/releases.md.

Signed-off-by: hive-release-bot <actions@github.com>
Closes #6031.
Closes #6035.
Closes #6037.

Signed-off-by: Andy Anderson <andy@clubanderson.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Automated release commit. Compiles changelog.d/ fragments and moves
the CHANGELOG.md Unreleased section into a dated v4.17.1 entry.
See src/docs/releases.md.

Signed-off-by: hive-release-bot <actions@github.com>
…ke (#5977) (#6010)

* 🌱 feat(hub): watch the wildcard certificate that now serves every spoke (#5977)

#5981 landed item 2: on a cluster that opts in with wildcard_tls_secret,
provisioned spoke Ingresses omit their per-host tls: block and the ingress
controller's --default-ssl-certificate serves them instead.

That trades ~60 certificates for one, and it trades the blast radius with them.
A per-host certificate that failed to renew took down ONE dashboard. The
wildcard stands behind every hosted spoke on the cluster — ~263 hostnames
across the two clusters in the issue — so a renewal that fails silently takes
all of them at once. Nothing was watching. The issue named that as the
"renewal consideration", and src/docs/spoke-wildcard-tls.md named monitoring as
a prerequisite for enabling the opt-in fleet-wide.

wildcard_tls_health.go reads the asserted secret once per cluster-health build
and reports it as PerClusterHealth.WildcardTLS. Statuses: ok, expiring,
expired, missing, domain_mismatch, unreadable. Non-ok renders on the cluster
row of the fleet-health panel and logs a warning; ok renders nothing, so a
healthy fleet stays quiet.

## It is also the first check on the opt-in itself

wildcard_tls_secret is an operator ASSERTION, and wildcard_tls.go is explicit
that the provisioner cannot verify it — it has to decide without a cluster
round-trip, and guessing wrong takes the cluster down. That is right at
provision time and is not a reason never to check. The health build already
talks to every cluster on a timer, where being wrong costs a warning rather
than an outage, so the assertion is verified there. Two statuses are exactly
that assertion turning out to be false, and neither is visible from
clusters.json:

- missing: the flag is set and the secret is not there. Every wildcard-served
  spoke on the cluster is being handed ingress-nginx's built-in self-signed
  certificate right now.
- domain_mismatch: the secret is there and does not carry "*.<cluster domain>".
  servesHostFromWildcard decides coverage from the domain in clusters.json;
  this is the only place the CERTIFICATE gets a say.

Coverage is judged on the WILDCARD SAN, not on whether today's hosts happen to
be listed: the hub omits the tls: block for every single-label host under the
domain including hives that do not exist yet, so a certificate enumerating
today's hosts would pass a per-host check and break the next hive provisioned.

## Thresholds and failure directions

- expiring fires under 21 days, which means renewal is OVERDUE rather than
  upcoming. cert-manager's default renewBefore starts renewing a 90-day Let's
  Encrypt certificate at 30 days out, so warning at 30 would fire on every
  healthy renewal, every quarter, on every opted-in cluster.
- A cluster the hub cannot reach reports NOTHING, never a reassuring ok — the
  same unknown-is-not-healthy contract StuckPods and LeakedNamespaces carry on
  this surface. kubectlSaysNotFound separates "the secret is gone" from "the
  cluster was unreachable" on kubectl's stderr and fails toward unknown, so an
  RBAC denial or a network blip is never reported as a vanished certificate.
- Read-only, and only on opted-in clusters: one `kubectl get secret`. Clusters
  without the opt-in still carry per-host certificates and issue no request.
- Coverage is judged before expiry: a certificate that cannot serve the domain
  is already failing every request, and calling it "expiring" would send an
  operator to renew a certificate that would still be wrong.

## Tests

Every pure function at 100%: the parse (7 fail-closed shapes plus a chain,
where taking the last block instead of the leaf would report the CA's expiry
years out and never warn), coverage, every status with its boundary (30 days
quiet, exactly 21 quiet, a minute inside noisy, exactly at notAfter expired),
the not-found/unreachable split, and the JSON keys the dashboard switches on.
collectWildcardTLSHealth is covered end to end against a scripted kubectl,
including the missing-secret finding. pkg/hub coverage 91.7% against the
gate's floor of 87.

Items 1 and 3 of the issue remain operator work; this does not touch them.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016gdK4wp8g7YFfiatUzdbgj
Signed-off-by: Danathar <doug.baggett@gmail.com>

* 🐛 verify wildcard ingress default

Report opted-in clusters where ingress-nginx is not configured to serve the asserted wildcard secret as its default SSL certificate.

Refs #5977

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Andy Anderson <andy@clubanderson.com>

---------

Signed-off-by: Danathar <doug.baggett@gmail.com>
Signed-off-by: Andy Anderson <andy@clubanderson.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Andy Anderson <andy@clubanderson.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Capture request watcher directories for the lifetime of each loop and join the issue watcher in tests before restoring package-level test seams.

Closes #6045

v5 note: pkg/github/requestwatch needs the same fix after the v4→v5 sync.

Signed-off-by: Andy Anderson <andy@clubanderson.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…nc-policy.md) (#6052)

* [strategist] planning: document v4→v5 forward-port sync policy

Adds src/docs/v5-sync-policy.md proposing cadence (v4 minor release or
50-commit drift), single-owner rotation, the merge-commit top-up
procedure already used by #5845/#6046, DCO expectations, and explicit
PR-body and review contracts for sync PRs. Links it from the docs index.

Refs #6051

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: sec-check <sec-check@hive.kubestellar.io>

* 📖 document active v5 sync policy

Align the v4-to-v5 sync policy with the current merge-commit top-up process, weekly/release cadence, maintainer ownership, verification checklist, and zero-delta check.

Closes #6051

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Andy Anderson <andy@clubanderson.com>

---------

Signed-off-by: sec-check <sec-check@hive.kubestellar.io>
Signed-off-by: Andy Anderson <andy@clubanderson.com>
Co-authored-by: sec-check <sec-check@hive.kubestellar.io>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Andy Anderson <andy@clubanderson.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Andy Anderson <andy@clubanderson.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Andy Anderson <andy@clubanderson.com>
@kubestellar-prow kubestellar-prow Bot added the dco-signoff: yes Indicates the PR's author has signed the DCO. label Sep 5, 2026
@clubanderson clubanderson added no-changelog No changelog fragment required approved Indicates a PR has been approved by an approver from all required OWNERS files. labels Sep 5, 2026
@kubestellar-prow

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

Approval requirements bypassed by manually added approval.

This pull-request has been approved by:

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

@kubestellar-prow kubestellar-prow Bot added the size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. label Sep 5, 2026
@clubanderson
clubanderson merged commit fe28f8b into v5 Sep 5, 2026
56 of 60 checks passed
@clubanderson
clubanderson deleted the sync/v4-into-v5-ancestry-2026-09-05 branch September 5, 2026 05:47
@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Thank you for your contribution! Your PR has been merged.

We'd love to hear how your experience was: share feedback

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. dco-signoff: yes Indicates the PR's author has signed the DCO. no-changelog No changelog fragment required size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants