Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions charts/kubex-automation-engine/templates/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ rules:
- globalconfigurations
- gpuconsolidationpolicies
- gpurebalancingpolicies
- podaffinities
- policyevaluations
- proactivepolicies
- staticpolicies
Expand All @@ -150,6 +151,7 @@ rules:
- globalconfigurations/finalizers
- gpuconsolidationpolicies/finalizers
- gpurebalancingpolicies/finalizers
- podaffinities/finalizers
- policyevaluations/finalizers
- proactivepolicies/finalizers
- staticpolicies/finalizers
Expand All @@ -164,6 +166,7 @@ rules:
- globalconfigurations/status
- gpuconsolidationpolicies/status
- gpurebalancingpolicies/status
- podaffinities/status
- policyevaluations/status
- proactivepolicies/status
- staticpolicies/status
Expand Down
247 changes: 247 additions & 0 deletions charts/kubex-crds/templates/rightsizing.kubex.ai_podaffinities.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,247 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.19.0
name: podaffinities.rightsizing.kubex.ai
spec:
group: rightsizing.kubex.ai
names:
kind: PodAffinity
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

CONTENT OF THIS REVIEW IS AI GENERATED

[Severity: Major] [Confidence: High]

Issue: The CRD kind: PodAffinity (in the rightsizing.kubex.ai group) shadows the well-known core Kubernetes type PodAffinity used inside pod.spec.affinity.

Why it matters: Many Kubernetes tools, admission webhooks, RBAC policy engines, and documentation generators match on Kind alone. This naming collision can cause confusion in audit logs, RBAC policies, and operator tooling. It also makes code and manifests harder to reason about since readers must always qualify the group to distinguish the two.

Suggested fix: Consider a disambiguating name such as NodeAffinityPolicy, WorkloadAffinityPolicy, or PodAffinityPolicy that clearly belongs to the rightsizing.kubex.ai domain and does not clash with the built-in type.

listKind: PodAffinityList
plural: podaffinities
singular: podaffinity
scope: Cluster
versions:
- name: v1alpha1
schema:
openAPIV3Schema:
description: PodAffinity is the Schema for the podaffinities API.
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
spec:
description: spec defines the desired state of PodAffinity
properties:
affinity:
description: affinity describes the preferred node affinity to inject
at pod admission time.
properties:
nodes:
description: nodes lists hostname label values to prefer on replacement
pods.
items:
type: string
minItems: 1
type: array
required:
- nodes
type: object
scope:
description: scope narrows the workloads and namespaces this policy
applies to.
properties:
labelSelector:
description: labelSelector limits the workload objects (e.g.,
Deployments, CronJobs) this policy applies to.
properties:
matchExpressions:
description: matchExpressions is a list of label selector
requirements. The requirements are ANDed.
items:
description: |-
A label selector requirement is a selector that contains values, a key, and an operator that
relates the key and values.
properties:
key:
description: key is the label key that the selector
applies to.
type: string
operator:
description: |-
operator represents a key's relationship to a set of values.
Valid operators are In, NotIn, Exists and DoesNotExist.
type: string
values:
description: |-
values is an array of string values. If the operator is In or NotIn,
the values array must be non-empty. If the operator is Exists or DoesNotExist,
the values array must be empty. This array is replaced during a strategic
merge patch.
items:
type: string
type: array
x-kubernetes-list-type: atomic
required:
- key
- operator
type: object
type: array
x-kubernetes-list-type: atomic
matchLabels:
additionalProperties:
type: string
description: |-
matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
map is equivalent to an element of matchExpressions, whose key field is "key", the
operator is "In", and the values array contains only "value". The requirements are ANDed.
type: object
type: object
x-kubernetes-map-type: atomic
namespaceSelector:
description: namespaceSelector restricts the namespaces this policy
applies to.
properties:
operator:
description: operator determines how the listed values are
evaluated.
enum:
- In
- NotIn
type: string
values:
description: values contains the namespace name patterns to
match.
items:
type: string
minItems: 1
type: array
required:
- operator
- values
type: object
workloadTypes:
default:
- Deployment
- StatefulSet
- CronJob
- Rollout
- Job
- AnalysisRun
- DaemonSet
description: workloadTypes limits the workload kinds this policy
applies to. When omitted, all supported workload types are targeted.
items:
description: WorkloadType enumerates the workload kinds a policy
can target.
enum:
- Deployment
- StatefulSet
- DaemonSet
- CronJob
- Rollout
- Job
- AnalysisRun
type: string
type: array
required:
- namespaceSelector
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

CONTENT OF THIS REVIEW IS AI GENERATED

[Severity: Minor] [Confidence: High]

Issue: namespaceSelector is required inside spec.scope, but the CRD is scope: Cluster (line 15). A cluster-scoped resource has no owning namespace, so requiring a namespace filter on every instance may be surprising.

Why it matters: Users creating a truly cluster-wide PodAffinity policy must still supply a namespaceSelector, which is non-obvious. If the intent is to always restrict by namespace, a comment in the description would help; if the intent is optionality for cluster-wide coverage, namespaceSelector should be removed from required.

Suggested fix: Either add an explanatory description clarifying that namespaceSelector is mandatory even for the cluster-scoped resource, or remove it from required and handle the nil case in the controller.

type: object
weight:
default: 0
description: |-
weight determines which policy wins when multiple PodAffinity policies match.
Higher weights take precedence. When weights are equal, older policies win.
format: int32
minimum: 0
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

CONTENT OF THIS REVIEW IS AI GENERATED

[Severity: Minor] [Confidence: Medium]

Issue: weight has minimum: 0 but no maximum constraint.

Why it matters: Without an upper bound, a user could set an arbitrarily large value (e.g. MaxInt32 = 2147483647). While the controller may handle this gracefully, documenting an expected ceiling (e.g. maximum: 1000) makes the tie-breaking semantics explicit and prevents accidental misuse of the priority scheme.

Suggested fix: Add a maximum that matches the controller's intended range, e.g.:

minimum: 0
maximum: 1000

type: integer
required:
- affinity
- scope
type: object
status:
description: status defines the observed state of PodAffinity
properties:
conditions:
description: |-
conditions represent the current state of the StaticPolicy resource.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

CONTENT OF THIS REVIEW IS AI GENERATED

[Severity: Major] [Confidence: High]

Issue: Copy-paste error — conditions description says "StaticPolicy resource" instead of "PodAffinity resource".

Why it matters: This is the machine-readable description surfaced by kubectl describe and tooling dashboards. Pointing to the wrong resource type is confusing for operators debugging PodAffinity objects and indicates the file was templated from StaticPolicy without a full search-and-replace.

Suggested fix:

conditions represent the current state of the PodAffinity resource.

Each condition has a unique type and reflects the status of a specific aspect of the resource.

Standard condition types include:
- "Available": the resource is fully functional
- "Progressing": the resource is being created or updated
- "Degraded": the resource failed to reach or maintain its desired state

The status of each condition is one of True, False, or Unknown.
items:
description: Condition contains details for one aspect of the current
state of this API Resource.
properties:
lastTransitionTime:
description: |-
lastTransitionTime is the last time the condition transitioned from one status to another.
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
format: date-time
type: string
message:
description: |-
message is a human readable message indicating details about the transition.
This may be an empty string.
maxLength: 32768
type: string
observedGeneration:
description: |-
observedGeneration represents the .metadata.generation that the condition was set based upon.
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
with respect to the current state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: |-
reason contains a programmatic identifier indicating the reason for the condition's last transition.
Producers of specific condition types may define expected values and meanings for this field,
and whether the values are considered a guaranteed API.
The value should be a CamelCase string.
This field may not be empty.
maxLength: 1024
minLength: 1
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False, Unknown.
enum:
- "True"
- "False"
- Unknown
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
required:
- lastTransitionTime
- message
- reason
- status
- type
type: object
type: array
x-kubernetes-list-map-keys:
- type
x-kubernetes-list-type: map
type: object
required:
- spec
type: object
served: true
storage: true
subresources:
status: {}