@@ -7,34 +7,9 @@ import (
77 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
88)
99
10- // ResourceQuota holds the quota for a single resource with per-AZ breakdown.
11- // Maps to liquid.ResourceQuotaRequest from the LIQUID API.
12- // See: https://pkg.go.dev/github.com/sapcc/go-api-declarations/liquid#ResourceQuotaRequest
13- type ResourceQuota struct {
14- // Quota is the total quota across all AZs (for compatibility).
15- // Corresponds to liquid.ResourceQuotaRequest.Quota.
16- // +kubebuilder:validation:Required
17- Quota int64 `json:"quota"`
18-
19- // PerAZ holds the per-availability-zone quota breakdown.
20- // Key: availability zone name, Value: quota for that AZ.
21- // Only populated for AZSeparatedTopology resources.
22- // Corresponds to liquid.ResourceQuotaRequest.PerAZ[az].Quota.
23- // See: https://pkg.go.dev/github.com/sapcc/go-api-declarations/liquid#AZResourceQuotaRequest
24- // +kubebuilder:validation:Optional
25- PerAZ map [string ]int64 `json:"perAZ,omitempty"`
26- }
27-
28- // ResourceQuotaUsage holds per-AZ PAYG usage for a single resource.
29- type ResourceQuotaUsage struct {
30- // PerAZ holds per-availability-zone PAYG usage values.
31- // Key: availability zone name, Value: PAYG usage in that AZ.
32- // +kubebuilder:validation:Optional
33- PerAZ map [string ]int64 `json:"perAZ,omitempty"`
34- }
35-
3610// ProjectQuotaSpec defines the desired state of ProjectQuota.
3711// Populated from PUT /v1/projects/:uuid/quota payloads (liquid.ServiceQuotaRequest).
12+ // Each ProjectQuota CRD represents quota for ONE project in ONE availability zone.
3813// See: https://pkg.go.dev/github.com/sapcc/go-api-declarations/liquid#ServiceQuotaRequest
3914type ProjectQuotaSpec struct {
4015 // ProjectID of the OpenStack project this quota belongs to.
@@ -57,12 +32,18 @@ type ProjectQuotaSpec struct {
5732 // +kubebuilder:validation:Optional
5833 DomainName string `json:"domainName,omitempty"`
5934
60- // Quota maps LIQUID resource names to their per-AZ quota.
35+ // AvailabilityZone is the AZ this quota CRD covers (e.g. "qa-de-1a").
36+ // In a multi-cluster setup, this determines which cluster the CRD is routed to.
37+ // +kubebuilder:validation:Required
38+ // +kubebuilder:validation:MinLength=1
39+ AvailabilityZone string `json:"availabilityZone"`
40+
41+ // Quota maps LIQUID resource names to their quota value for THIS availability zone.
6142 // Key: liquid.ResourceName (e.g. "hw_version_hana_v2_ram")
62- // Mirrors liquid.ServiceQuotaRequest.Resources with AZSeparatedTopology.
63- // See: https://pkg.go.dev/github.com/sapcc/go-api-declarations/liquid#ServiceQuotaRequest
43+ // Value: per-AZ quota from liquid.AZResourceQuotaRequest.Quota
44+ // See: https://pkg.go.dev/github.com/sapcc/go-api-declarations/liquid#AZResourceQuotaRequest
6445 // +kubebuilder:validation:Optional
65- Quota map [string ]ResourceQuota `json:"quota,omitempty"`
46+ Quota map [string ]int64 `json:"quota,omitempty"`
6647}
6748
6849// ProjectQuotaStatus defines the observed state of ProjectQuota.
@@ -75,17 +56,17 @@ type ProjectQuotaStatus struct {
7556 // +kubebuilder:validation:Optional
7657 ObservedGeneration int64 `json:"observedGeneration,omitempty"`
7758
78- // TotalUsage tracks per-resource per-AZ total resource consumption (all VMs in this project).
59+ // TotalUsage tracks per-resource total resource consumption in this AZ (all VMs in this project+AZ ).
7960 // Persisted by the quota controller; updated by full reconcile and HV instance diffs.
8061 // Key: liquid.ResourceName
8162 // +kubebuilder:validation:Optional
82- TotalUsage map [string ]ResourceQuotaUsage `json:"totalUsage,omitempty"`
63+ TotalUsage map [string ]int64 `json:"totalUsage,omitempty"`
8364
84- // PaygUsage tracks per-resource per-AZ pay-as-you-go usage.
65+ // PaygUsage tracks per-resource pay-as-you-go usage in this AZ .
8566 // Derived as TotalUsage - CRUsage (clamped >= 0).
8667 // Key: liquid.ResourceName
8768 // +kubebuilder:validation:Optional
88- PaygUsage map [string ]ResourceQuotaUsage `json:"paygUsage,omitempty"`
69+ PaygUsage map [string ]int64 `json:"paygUsage,omitempty"`
8970
9071 // LastReconcileAt is when the controller last reconciled this project's quota (any path).
9172 // +kubebuilder:validation:Optional
@@ -106,13 +87,16 @@ type ProjectQuotaStatus struct {
10687// +kubebuilder:subresource:status
10788// +kubebuilder:resource:scope=Cluster
10889// +kubebuilder:printcolumn:name="Project",type="string",JSONPath=".spec.projectID"
90+ // +kubebuilder:printcolumn:name="AZ",type="string",JSONPath=".spec.availabilityZone"
10991// +kubebuilder:printcolumn:name="Domain",type="string",JSONPath=".spec.domainID"
11092// +kubebuilder:printcolumn:name="LastReconcile",type="date",JSONPath=".status.lastReconcileAt"
11193// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type=='Ready')].status"
11294
11395// ProjectQuota is the Schema for the projectquotas API.
11496// It persists quota values pushed by Limes via the LIQUID quota endpoint
11597// (PUT /v1/projects/:uuid/quota → liquid.ServiceQuotaRequest).
98+ // Each CRD stores quota for one project in one availability zone.
99+ // In a multi-cluster setup, it is routed to the cluster serving that AZ.
116100// See: https://pkg.go.dev/github.com/sapcc/go-api-declarations/liquid#ServiceQuotaRequest
117101type ProjectQuota struct {
118102 metav1.TypeMeta `json:",inline"`
0 commit comments