Skip to content

Add ORC API linter to enforce ORC specific rules#677

Open
mandre wants to merge 5 commits intok-orc:mainfrom
shiftstack:orc-lint
Open

Add ORC API linter to enforce ORC specific rules#677
mandre wants to merge 5 commits intok-orc:mainfrom
shiftstack:orc-lint

Conversation

@mandre
Copy link
Collaborator

@mandre mandre commented Feb 6, 2026

This adds a custom noopenstackidref linter to kube-api-lint that enforces ORC's API design philosophy: spec and filter fields should reference ORC Kubernetes objects using *KubernetesNameRef with a Ref suffix rather than OpenStack resources directly by UUID.

Add a custom golangci-lint plugin that flags OpenStack ID references in
spec structs, enforcing ORC's API design philosophy that spec fields
should only reference ORC Kubernetes objects, not OpenStack resources
directly by UUID.

The noopenstackidref linter flags fields like 'ProjectID *string' in
spec/filter structs and suggests using '*KubernetesNameRef' with a 'Ref'
suffix instead (e.g., 'ProjectRef *KubernetesNameRef').

Status structs are exempt, as they are expected to report OpenStack UUIDs.

See: https://k-orc.cloud/development/architecture/#api-design-philosophy
Fields like NetworkIDs, SubnetIDs should use NetworkRefs, SubnetRefs instead.
This ensures consistency with the singular form (NetworkID -> NetworkRef).
Fields ending in Ref or Refs should use KubernetesNameRef type to reference
ORC objects. This catches cases where the naming convention is correct but
the type is wrong (e.g., SecurityGroupRefs []OpenStackName should be
[]KubernetesNameRef).

CloudCredentialsRef is excluded as it intentionally uses a different type.
- HostID.ID: Allows raw hypervisor host ID as alternative to ServerRef
- PortResourceSpec.HostID: The HostID struct intentionally provides both options
- SecurityGroupRefs: Known issue k-orc#438, breaking change planned for next API version
Update API design documentation to align with ssatags linter behavior:
listType=set is discouraged for object arrays due to SSA merge issues,
so recommend listType=map for structs and listType=set only for primitives.
Copy link
Contributor

@winiciusallan winiciusallan left a comment

Choose a reason for hiding this comment

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

I didn't know that we could create a custom linter; that's cool. There is a lot to learn.

The code looks good to me overall, just left a small observation.

// not OpenStack resource references.
var excludedIDPatterns = []string{
"SegmentationID", // VLAN segmentation ID, not an OpenStack resource
"SegmentationIDs", // Plural form of the above
Copy link
Contributor

Choose a reason for hiding this comment

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

Having this one here does not hurt, but we don't have a reference for this word throughout the code. Do we really need to exclude this pattern?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

semver:patch No API change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants