Skip to content

Commit 4e540ff

Browse files
authored
Add storage attribute fields + remove storageTier field (#185)
* Add storage attribute fields + remove storageTier field * Add test * Fix test
1 parent 9fd9bad commit 4e540ff

File tree

7 files changed

+226
-65
lines changed

7 files changed

+226
-65
lines changed

api/v1/qdrantcluster_types.go

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -55,17 +55,6 @@ const (
5555
ByCountAndSize RebalanceStrategy = "by_count_and_size"
5656
)
5757

58-
// StorageTier specifies the performance profile for the disk to use.
59-
// +kubebuilder:validation:Enum=budget;balanced;performance
60-
type StorageTier string
61-
62-
//goland:noinspection GoUnusedConst
63-
const (
64-
StorageTierBudget StorageTier = "budget"
65-
StorageTierBalanced StorageTier = "balanced"
66-
StorageTierPerformance StorageTier = "performance"
67-
)
68-
6958
// QdrantClusterSpec defines the desired state of QdrantCluster
7059
// +kubebuilder:pruning:PreserveUnknownFields
7160
type QdrantClusterSpec struct {
@@ -128,10 +117,9 @@ type QdrantClusterSpec struct {
128117
// StorageClassNames specifies the storage class names for db and snapshots.
129118
// +optional
130119
StorageClassNames *StorageClassNames `json:"storageClassNames,omitempty"`
131-
// StorageTier specifies the performance tier to use for the disk
132-
// +kubebuilder:validation:Enum=budget;balanced;performance
120+
// Storage specifies the storage specification for the PVCs of the cluster. If the field is not set, no configuration will be applied.
133121
// +optional
134-
StorageTier *StorageTier `json:"storageTier,omitempty"`
122+
Storage *Storage `json:"storage,omitempty"`
135123
// TopologySpreadConstraints specifies the topology spread constraints for the cluster.
136124
// +optional
137125
TopologySpreadConstraints *[]corev1.TopologySpreadConstraint `json:"topologySpreadConstraints,omitempty"`
@@ -169,6 +157,10 @@ func (s QdrantClusterSpec) Validate() error {
169157
if err := s.Resources.Validate("Spec.Resources"); err != nil {
170158
return err
171159
}
160+
// Validate Storage configurations
161+
if err := s.Storage.Validate(); err != nil {
162+
return err
163+
}
172164
return nil
173165
}
174166

@@ -790,6 +782,38 @@ func (n *StorageClassNames) GetSnapshots() *string {
790782
return n.Snapshots
791783
}
792784

785+
type Storage struct {
786+
// VolumeAttributesClassName specifies VolumeAttributeClass name to use for the storage PVCs
787+
// +optional
788+
VolumeAttributesClassName *string `json:"volumeAttributesClassName,omitempty"`
789+
// IOPS defines the IOPS number to configure for the storage PVCs
790+
// +optional
791+
IOPS *int `json:"iops,omitempty"`
792+
// Throughput defines the throughput number in MB/s for the storage PVCs
793+
// +optional
794+
Throughput *int `json:"throughput,omitempty"`
795+
}
796+
797+
// Validate storage configurations
798+
func (s *Storage) Validate() error {
799+
if s == nil {
800+
return nil
801+
}
802+
// User can specify either VolumeAttributesClassName or both IOPS and Throughput
803+
if s.VolumeAttributesClassName != nil {
804+
// Both IOPS and Throughput must be nil
805+
if s.Throughput != nil || s.IOPS != nil {
806+
return fmt.Errorf(".spec.storage: can not specify both VolumeAttributesClassName and IOPS/Throughput")
807+
}
808+
return nil
809+
}
810+
// Must specify either both IOPS and Throughput or none
811+
if (s.IOPS == nil && s.Throughput == nil) || (s.IOPS != nil && s.Throughput != nil) {
812+
return nil
813+
}
814+
return fmt.Errorf(".spec.storage: must specify both IOPS and Throughput")
815+
}
816+
793817
type ClusterPhase string
794818

795819
//goland:noinspection GoUnusedConst

api/v1/qdrantcluster_types_test.go

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"testing"
66

77
"github.com/stretchr/testify/assert"
8+
"k8s.io/utils/ptr"
89
)
910

1011
func TestValidate(t *testing.T) {
@@ -77,6 +78,103 @@ func TestValidate(t *testing.T) {
7778
},
7879
expectedError: fmt.Errorf("Spec.Resources.Memory error: quantities must match the regular expression '^([+-]?[0-9.]+)([eEinumkKMGTP]*[-+]?[0-9]*)$'"),
7980
},
81+
{
82+
name: "No storage configuration",
83+
spec: QdrantClusterSpec{
84+
Resources: Resources{
85+
CPU: "100m",
86+
Memory: "1Gi",
87+
Storage: "2Gi",
88+
},
89+
},
90+
expectedError: nil,
91+
},
92+
{
93+
name: "Empty storage configuration",
94+
spec: QdrantClusterSpec{
95+
Resources: Resources{
96+
CPU: "100m",
97+
Memory: "1Gi",
98+
Storage: "2Gi",
99+
},
100+
Storage: &Storage{},
101+
},
102+
expectedError: nil,
103+
},
104+
{
105+
name: "Only VolumeAttributeClassName specified",
106+
spec: QdrantClusterSpec{
107+
Resources: Resources{
108+
CPU: "100m",
109+
Memory: "1Gi",
110+
Storage: "2Gi",
111+
},
112+
Storage: &Storage{
113+
VolumeAttributesClassName: ptr.To("foo"),
114+
},
115+
},
116+
expectedError: nil,
117+
},
118+
119+
{
120+
name: "Both VolumeAttributeClassName and IOPS/Throughput specified",
121+
spec: QdrantClusterSpec{
122+
Resources: Resources{
123+
CPU: "100m",
124+
Memory: "1Gi",
125+
Storage: "2Gi",
126+
},
127+
Storage: &Storage{
128+
VolumeAttributesClassName: ptr.To("foo"),
129+
IOPS: ptr.To(10000),
130+
Throughput: ptr.To(500),
131+
},
132+
},
133+
expectedError: fmt.Errorf(".spec.storage: can not specify both VolumeAttributesClassName and IOPS/Throughput"),
134+
},
135+
{
136+
name: "Only IOPS specified",
137+
spec: QdrantClusterSpec{
138+
Resources: Resources{
139+
CPU: "100m",
140+
Memory: "1Gi",
141+
Storage: "2Gi",
142+
},
143+
Storage: &Storage{
144+
IOPS: ptr.To(10000),
145+
},
146+
},
147+
expectedError: fmt.Errorf(".spec.storage: must specify both IOPS and Throughput"),
148+
},
149+
{
150+
name: "Only Throughput specified",
151+
spec: QdrantClusterSpec{
152+
Resources: Resources{
153+
CPU: "100m",
154+
Memory: "1Gi",
155+
Storage: "2Gi",
156+
},
157+
Storage: &Storage{
158+
Throughput: ptr.To(500),
159+
},
160+
},
161+
expectedError: fmt.Errorf(".spec.storage: must specify both IOPS and Throughput"),
162+
},
163+
{
164+
name: "Both IOPS/Throughput specified",
165+
spec: QdrantClusterSpec{
166+
Resources: Resources{
167+
CPU: "100m",
168+
Memory: "1Gi",
169+
Storage: "2Gi",
170+
},
171+
Storage: &Storage{
172+
IOPS: ptr.To(10000),
173+
Throughput: ptr.To(500),
174+
},
175+
},
176+
expectedError: nil,
177+
},
80178
}
81179

82180
for _, tt := range testCases {

api/v1/zz_generated.deepcopy.go

Lines changed: 34 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

charts/qdrant-kubernetes-api/templates/region-crds/qdrant.io_qdrantclusters.yaml

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -858,6 +858,24 @@ spec:
858858
type: object
859859
type: object
860860
type: object
861+
storage:
862+
description: Storage specifies the storage specification for the PVCs
863+
of the cluster. If the field is not set, no configuration will be
864+
applied.
865+
properties:
866+
iops:
867+
description: IOPS defines the IOPS number to configure for the
868+
storage PVCs
869+
type: integer
870+
throughput:
871+
description: Throughput defines the throughput number in MB/s
872+
for the storage PVCs
873+
type: integer
874+
volumeAttributesClassName:
875+
description: VolumeAttributesClassName specifies VolumeAttributeClass
876+
name to use for the storage PVCs
877+
type: string
878+
type: object
861879
storageClassNames:
862880
description: StorageClassNames specifies the storage class names for
863881
db and snapshots.
@@ -870,19 +888,6 @@ spec:
870888
volume.
871889
type: string
872890
type: object
873-
storageTier:
874-
allOf:
875-
- enum:
876-
- budget
877-
- balanced
878-
- performance
879-
- enum:
880-
- budget
881-
- balanced
882-
- performance
883-
description: StorageTier specifies the performance tier to use for
884-
the disk
885-
type: string
886891
suspend:
887892
default: false
888893
description: |-

crds/qdrant.io_qdrantclusters.yaml

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -857,6 +857,24 @@ spec:
857857
type: object
858858
type: object
859859
type: object
860+
storage:
861+
description: Storage specifies the storage specification for the PVCs
862+
of the cluster. If the field is not set, no configuration will be
863+
applied.
864+
properties:
865+
iops:
866+
description: IOPS defines the IOPS number to configure for the
867+
storage PVCs
868+
type: integer
869+
throughput:
870+
description: Throughput defines the throughput number in MB/s
871+
for the storage PVCs
872+
type: integer
873+
volumeAttributesClassName:
874+
description: VolumeAttributesClassName specifies VolumeAttributeClass
875+
name to use for the storage PVCs
876+
type: string
877+
type: object
860878
storageClassNames:
861879
description: StorageClassNames specifies the storage class names for
862880
db and snapshots.
@@ -869,19 +887,6 @@ spec:
869887
volume.
870888
type: string
871889
type: object
872-
storageTier:
873-
allOf:
874-
- enum:
875-
- budget
876-
- balanced
877-
- performance
878-
- enum:
879-
- budget
880-
- balanced
881-
- performance
882-
description: StorageTier specifies the performance tier to use for
883-
the disk
884-
type: string
885890
suspend:
886891
default: false
887892
description: |-

docs/api.md

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -796,7 +796,7 @@ _Appears in:_
796796
| `gpu` _[GPU](#gpu)_ | GPU specifies GPU configuration for the cluster. If this field is not set, no GPU will be used. | | |
797797
| `statefulSet` _[KubernetesStatefulSet](#kubernetesstatefulset)_ | StatefulSet specifies the configuration of the Qdrant Kubernetes StatefulSet. | | |
798798
| `storageClassNames` _[StorageClassNames](#storageclassnames)_ | StorageClassNames specifies the storage class names for db and snapshots. | | |
799-
| `storageTier` _[StorageTier](#storagetier)_ | StorageTier specifies the performance tier to use for the disk | | Enum: [budget balanced performance] <br /> |
799+
| `storage` _[Storage](#storage)_ | Storage specifies the storage specification for the PVCs of the cluster. If the field is not set, no configuration will be applied. | | |
800800
| `topologySpreadConstraints` _[TopologySpreadConstraint](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/#topologyspreadconstraint-v1-core)_ | TopologySpreadConstraints specifies the topology spread constraints for the cluster. | | |
801801
| `podDisruptionBudget` _[PodDisruptionBudgetSpec](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/#poddisruptionbudgetspec-v1-policy)_ | PodDisruptionBudget specifies the pod disruption budget for the cluster. | | |
802802
| `restartAllPodsConcurrently` _boolean_ | RestartAllPodsConcurrently specifies whether to restart all pods concurrently (also called one-shot-restart).<br />If enabled, all the pods in the cluster will be restarted concurrently in situations where multiple pods<br />need to be restarted, like when RestartedAtAnnotationKey is added/updated or the Qdrant version needs to be upgraded.<br />This helps sharded but not replicated clusters to reduce downtime to a possible minimum during restart.<br />If unset, the operator is going to restart nodes concurrently if none of the collections if replicated. | | |
@@ -1290,6 +1290,24 @@ _Appears in:_
12901290
| `Disabled` | |
12911291

12921292

1293+
#### Storage
1294+
1295+
1296+
1297+
1298+
1299+
1300+
1301+
_Appears in:_
1302+
- [QdrantClusterSpec](#qdrantclusterspec)
1303+
1304+
| Field | Description | Default | Validation |
1305+
| --- | --- | --- | --- |
1306+
| `volumeAttributesClassName` _string_ | VolumeAttributesClassName specifies VolumeAttributeClass name to use for the storage PVCs | | |
1307+
| `iops` _integer_ | IOPS defines the IOPS number to configure for the storage PVCs | | |
1308+
| `throughput` _integer_ | Throughput defines the throughput number in MB/s for the storage PVCs | | |
1309+
1310+
12931311
#### StorageClass
12941312

12951313

@@ -1362,25 +1380,6 @@ _Appears in:_
13621380
| `async_scorer` _boolean_ | AsyncScorer enables io_uring when rescoring | | |
13631381

13641382

1365-
#### StorageTier
1366-
1367-
_Underlying type:_ _string_
1368-
1369-
StorageTier specifies the performance profile for the disk to use.
1370-
1371-
_Validation:_
1372-
- Enum: [budget balanced performance]
1373-
1374-
_Appears in:_
1375-
- [QdrantClusterSpec](#qdrantclusterspec)
1376-
1377-
| Field | Description |
1378-
| --- | --- |
1379-
| `budget` | |
1380-
| `balanced` | |
1381-
| `performance` | |
1382-
1383-
13841383
#### TraefikConfig
13851384

13861385

0 commit comments

Comments
 (0)