Skip to content

Add spec.groups field with typed group memberships#292

Merged
PhilippMatthes merged 3 commits intomainfrom
feat/spec-groups
Apr 30, 2026
Merged

Add spec.groups field with typed group memberships#292
PhilippMatthes merged 3 commits intomainfrom
feat/spec-groups

Conversation

@PhilippMatthes
Copy link
Copy Markdown
Member

@PhilippMatthes PhilippMatthes commented Apr 27, 2026

The Cortex Placement Shim replaces OpenStack Placement for kvm and reads scheduling information directly from the Hypervisor CRD. This is an opportunity to rethink how traits and aggregates are modeled on the CRD.

Today, trait and aggregate data is split across spec and status. Controllers reconcile between the two, merging sources and pushing state to OpenStack Placement. With the shim reading the CRD directly, there is no external system to observe or merge from, making this indirection unnecessary. The existing spec fields are also flat string lists tied to OpenStack naming, unable to carry the structured data like UUIDs and metadata that the shim needs to serve a compatible Placement API.

Both traits and aggregates are forms of grouping: traits group hypervisors by capability, aggregates group them by administrative assignment. This proposal unifies them under a new spec.groups field as the single source of truth. Rather than using Kubernetes labels, which are flat key-value strings without schema validation, spec.groups models each group kind as a well-typed substruct that can carry structured data such as UUIDs and metadata.

The field is a list of typed group entries following the field-presence union pattern from core Kubernetes, as used by PodSpec.volumes. Each entry populates exactly one type-specific sub-field:

spec:
  groups:
    - trait: {name: COMPUTE_STATUS_DISABLED}
    - trait: {name: CUSTOM_TRAIT_FOO}
    - aggregate:
        name: fast-storage
        uuid: abc-123
        metadata:
          ssd: "true"

Each group type has its own struct with only the fields relevant to it. A CEL validation rule enforces that exactly one sub-field is populated per entry. The existing spec.customTraits and spec.aggregates fields remain untouched to not interfere with existing controller logic, separating this api change from the controller refactor. They can be deprecated and removed in a future release once the shim is fully integrated.

Library helper functions like HasTrait, GetTraits, HasAggregate, and GetAggregates follow the meta.IsStatusConditionTrue pattern and are reusable across the shim, operator, and scheduler.

The design is extensible: adding a new grouping concept means adding one optional pointer field to the Group struct and a corresponding type-specific struct. No changes to existing fields or consumers are required.

Introduce a new spec.groups field on the Hypervisor CRD that unifies
traits and aggregates as typed group entries using the field-presence
union pattern. Each entry populates exactly one type-specific sub-field
(trait or aggregate), enforced by a CEL validation rule.

Includes library helper functions (HasTrait, GetTraits, HasAggregate,
GetAggregates) following the meta.IsStatusConditionTrue pattern,
reusable across the shim, operator, and scheduler.

Existing spec.customTraits and spec.aggregates fields remain untouched.
@coderabbitai

This comment was marked as spam.

@PhilippMatthes
Copy link
Copy Markdown
Member Author

See cobaltcore-dev/cortex#766

coderabbitai[bot]

This comment was marked as resolved.

- Replace MinLength=1 with RFC 4122 UUID pattern validation on
  AggregateGroup.UUID to reject malformed UUIDs at the CRD level.
- Tighten negative validation test assertions to check specific
  field paths in error messages (trait.name, aggregate.name,
  aggregate.uuid).
- Add round-trip assertion verifying aggregate metadata survives
  serialization after creation.
- Update all test UUIDs to valid RFC 4122 format.
The "union rule" tests still used "abc-123" which doesn't match the
new RFC 4122 pattern validation. Replace with valid UUIDs.
@github-actions

This comment was marked as low quality.

@PhilippMatthes PhilippMatthes merged commit 9e3466f into main Apr 30, 2026
7 checks passed
@PhilippMatthes PhilippMatthes deleted the feat/spec-groups branch April 30, 2026 06:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants