Skip to content

B3+B4+B13: cluster index, placeholders, MC admission validators#1034

Draft
anandsyncs wants to merge 14 commits intomc-search-b14-distributionfrom
mc-search-b3-b4-cluster-index-placeholders
Draft

B3+B4+B13: cluster index, placeholders, MC admission validators#1034
anandsyncs wants to merge 14 commits intomc-search-b14-distributionfrom
mc-search-b3-b4-cluster-index-placeholders

Conversation

@anandsyncs
Copy link
Copy Markdown
Contributor

@anandsyncs anandsyncs commented Apr 29, 2026

Summary

Consolidates B3 (per-cluster index annotation), B4 ({clusterName}/{clusterIndex} placeholder resolution), and B13 (residual MC admission validators) into one PR — they're all CRD-level admission/validation work for the multi-cluster MongoDBSearch MVP, and reviewing them together catches inter-rule overlap.

Changes

B3 — cluster index annotation

  • AssignClusterIndices(existing, currentClusterNames) map[string]int — preserves existing assignments, monotonic-only, never reuses on remove/re-add
  • ClusterIndex(search, clusterName) accessor for downstream consumers
  • Annotation mongodb.com/v1.last-cluster-num-mapping persisted on the MongoDBSearch CR at reconcile entry
  • Admission rule: rejects clusterName rename in a single Update (rename = recreate)

B4 — placeholder resolution

  • {clusterName} and {clusterIndex} resolvers in loadBalancer.managed.externalHostname
  • Cross-product (cluster × shard) hostname resolver for sharded MC
  • Admission requires {clusterName} or {clusterIndex} when len(spec.clusters) > 1
  • Sharded MC additionally requires {shardName}
  • Cross-product DNS-length validation (RFC 1123 label ≤ 63, FQDN ≤ 253)

B13 — MC admission residuals (4 new validators)

  • validateMCRejectsUnmanagedLB — Q3/Q4-MC reject (len(clusters) > 1 + unmanaged LB)
  • validateMCRequiresLoadBalancerManaged — Q5/Q6-MC reject (len(clusters) > 1 + no LB)
  • validateClustersClusterNameNonEmpty — explicit empty-string rejection with clear error
  • validateMCMatchTagsNonEmpty — empty MatchTags map rejected (operator can't autodetect from external replSetConfig)

(MongoDBCommunity-source MC rejection is already covered by B2's validateMCRequiresExternalSource.)

Stack

  • Base: #1030 (B14+B18 — spec.clusters[] types + defaulting)
  • Bottom: #1027 (B1 — cluster client plumbing)

Replaces

  • #1031 — closed in favour of this consolidated PR

Out of scope

  • Per-cluster status surface (B9 / #1033)
  • Reconcile loop consumption of placeholder resolution (B16 / readPrefTags)

Testing

  • Unit: go test ./api/v1/search/... ./controllers/searchcontroller/... ./controllers/operator/... passes
  • Lint: golangci-lint run ./api/v1/search/... clean

@anandsyncs anandsyncs added the skip-changelog Use this label in Pull Request to not require new changelog entry file label Apr 29, 2026
@anandsyncs
Copy link
Copy Markdown
Contributor Author

@anandsyncs anandsyncs changed the title B3+B4: cluster-index annotation + clusterName/clusterIndex placeholders B3+B4+B13: cluster index, placeholders, MC admission validators Apr 29, 2026
@anandsyncs
Copy link
Copy Markdown
Contributor Author

B13 admission residuals folded in (4 new validators). Re-triggered Evergreen: https://evergreen.mongodb.com/patch/69f1ed87e9e6d9000787d7eb (supersedes the earlier B3+B4-only patch)

Multi-cluster MongoDBSearch at GA = Q1 or Q2 (managed LB only). Q3-MC and
Q4-MC are deferred post-GA per spec §4.4 / §B0.2. Single-cluster unmanaged
LB stays unchanged.
len(spec.clusters) > 1 with spec.loadBalancer == nil is Q5-MC / Q6-MC and
permanently rejected per spec §4.4 / §B0.2 — MC requires Envoy. Combined
with the unmanaged-LB rejection from the prior commit, MC at GA is
enforced symbolically as "managed LB only" without per-cluster replica
introspection.
Per spec §4.4, clusters[].clusterName must be non-empty when MC. Single-
cluster degenerate case (len <= 1) keeps allowing an empty clusterName.
Ordered before validateClustersUniqueClusterName so the dedicated
"is required" message fires instead of "duplicate" for the two-empty-
names case.
An explicitly-set-but-empty matchTags in spec.clusters[].syncSourceSelector
is meaningless when MC: the operator cannot peek at the external
replSetConfig to autodetect tags. nil (omitted) is fine — inherits. Pairs
with B14's validateClustersSyncSourceSelector (matchTags-vs-hosts mutual
exclusion).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

skip-changelog Use this label in Pull Request to not require new changelog entry file

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant