Skip to content
Merged
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
52 changes: 38 additions & 14 deletions api/v1/qdrantcluster_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,17 +55,6 @@ const (
ByCountAndSize RebalanceStrategy = "by_count_and_size"
)

// StorageTier specifies the performance profile for the disk to use.
// +kubebuilder:validation:Enum=budget;balanced;performance
type StorageTier string

//goland:noinspection GoUnusedConst
const (
StorageTierBudget StorageTier = "budget"
StorageTierBalanced StorageTier = "balanced"
StorageTierPerformance StorageTier = "performance"
)

// QdrantClusterSpec defines the desired state of QdrantCluster
// +kubebuilder:pruning:PreserveUnknownFields
type QdrantClusterSpec struct {
Expand Down Expand Up @@ -128,10 +117,9 @@ type QdrantClusterSpec struct {
// StorageClassNames specifies the storage class names for db and snapshots.
// +optional
StorageClassNames *StorageClassNames `json:"storageClassNames,omitempty"`
// StorageTier specifies the performance tier to use for the disk
// +kubebuilder:validation:Enum=budget;balanced;performance
// Storage specifies the storage specification for the PVCs of the cluster. If the field is not set, no configuration will be applied.
// +optional
StorageTier *StorageTier `json:"storageTier,omitempty"`
Storage *Storage `json:"storage,omitempty"`
// TopologySpreadConstraints specifies the topology spread constraints for the cluster.
// +optional
TopologySpreadConstraints *[]corev1.TopologySpreadConstraint `json:"topologySpreadConstraints,omitempty"`
Expand Down Expand Up @@ -169,6 +157,10 @@ func (s QdrantClusterSpec) Validate() error {
if err := s.Resources.Validate("Spec.Resources"); err != nil {
return err
}
// Validate Storage configurations
if err := s.Storage.Validate(); err != nil {
return err
}
return nil
}

Expand Down Expand Up @@ -790,6 +782,38 @@ func (n *StorageClassNames) GetSnapshots() *string {
return n.Snapshots
}

type Storage struct {
// VolumeAttributesClassName specifies VolumeAttributeClass name to use for the storage PVCs
// +optional
VolumeAttributesClassName *string `json:"volumeAttributesClassName,omitempty"`
// IOPS defines the IOPS number to configure for the storage PVCs
// +optional
IOPS *int `json:"iops,omitempty"`
// Throughput defines the throughput number in MB/s for the storage PVCs
// +optional
Throughput *int `json:"throughput,omitempty"`
}

// Validate storage configurations
func (s *Storage) Validate() error {
if s == nil {
return nil
}
// User can specify either VolumeAttributesClassName or both IOPS and Throughput
if s.VolumeAttributesClassName != nil {
// Both IOPS and Throughput must be nil
if s.Throughput != nil || s.IOPS != nil {
return fmt.Errorf(".spec.storage: can not specify both VolumeAttributesClassName and IOPS/Throughput")
}
return nil
}
// Must specify either both IOPS and Throughput or none
if (s.IOPS == nil && s.Throughput == nil) || (s.IOPS != nil && s.Throughput != nil) {
return nil
}
return fmt.Errorf(".spec.storage: must specify both IOPS and Throughput")
}

type ClusterPhase string

//goland:noinspection GoUnusedConst
Expand Down
98 changes: 98 additions & 0 deletions api/v1/qdrantcluster_types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"testing"

"github.com/stretchr/testify/assert"
"k8s.io/utils/ptr"
)

func TestValidate(t *testing.T) {
Expand Down Expand Up @@ -77,6 +78,103 @@ func TestValidate(t *testing.T) {
},
expectedError: fmt.Errorf("Spec.Resources.Memory error: quantities must match the regular expression '^([+-]?[0-9.]+)([eEinumkKMGTP]*[-+]?[0-9]*)$'"),
},
{
name: "No storage configuration",
spec: QdrantClusterSpec{
Resources: Resources{
CPU: "100m",
Memory: "1Gi",
Storage: "2Gi",
},
},
expectedError: nil,
},
{
name: "Empty storage configuration",
spec: QdrantClusterSpec{
Resources: Resources{
CPU: "100m",
Memory: "1Gi",
Storage: "2Gi",
},
Storage: &Storage{},
},
expectedError: nil,
},
{
name: "Only VolumeAttributeClassName specified",
spec: QdrantClusterSpec{
Resources: Resources{
CPU: "100m",
Memory: "1Gi",
Storage: "2Gi",
},
Storage: &Storage{
VolumeAttributesClassName: ptr.To("foo"),
},
},
expectedError: nil,
},

{
name: "Both VolumeAttributeClassName and IOPS/Throughput specified",
spec: QdrantClusterSpec{
Resources: Resources{
CPU: "100m",
Memory: "1Gi",
Storage: "2Gi",
},
Storage: &Storage{
VolumeAttributesClassName: ptr.To("foo"),
IOPS: ptr.To(10000),
Throughput: ptr.To(500),
},
},
expectedError: fmt.Errorf(".spec.storage: can not specify both VolumeAttributesClassName and IOPS/Throughput"),
},
{
name: "Only IOPS specified",
spec: QdrantClusterSpec{
Resources: Resources{
CPU: "100m",
Memory: "1Gi",
Storage: "2Gi",
},
Storage: &Storage{
IOPS: ptr.To(10000),
},
},
expectedError: fmt.Errorf(".spec.storage: must specify both IOPS and Throughput"),
},
{
name: "Only Throughput specified",
spec: QdrantClusterSpec{
Resources: Resources{
CPU: "100m",
Memory: "1Gi",
Storage: "2Gi",
},
Storage: &Storage{
Throughput: ptr.To(500),
},
},
expectedError: fmt.Errorf(".spec.storage: must specify both IOPS and Throughput"),
},
{
name: "Both IOPS/Throughput specified",
spec: QdrantClusterSpec{
Resources: Resources{
CPU: "100m",
Memory: "1Gi",
Storage: "2Gi",
},
Storage: &Storage{
IOPS: ptr.To(10000),
Throughput: ptr.To(500),
},
},
expectedError: nil,
},
}

for _, tt := range testCases {
Expand Down
38 changes: 34 additions & 4 deletions api/v1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -858,6 +858,24 @@ spec:
type: object
type: object
type: object
storage:
description: Storage specifies the storage specification for the PVCs
of the cluster. If the field is not set, no configuration will be
applied.
properties:
iops:
description: IOPS defines the IOPS number to configure for the
storage PVCs
type: integer
throughput:
description: Throughput defines the throughput number in MB/s
for the storage PVCs
type: integer
volumeAttributesClassName:
description: VolumeAttributesClassName specifies VolumeAttributeClass
name to use for the storage PVCs
type: string
type: object
storageClassNames:
description: StorageClassNames specifies the storage class names for
db and snapshots.
Expand All @@ -870,19 +888,6 @@ spec:
volume.
type: string
type: object
storageTier:
allOf:
- enum:
- budget
- balanced
- performance
- enum:
- budget
- balanced
- performance
description: StorageTier specifies the performance tier to use for
the disk
type: string
suspend:
default: false
description: |-
Expand Down
31 changes: 18 additions & 13 deletions crds/qdrant.io_qdrantclusters.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -857,6 +857,24 @@ spec:
type: object
type: object
type: object
storage:
description: Storage specifies the storage specification for the PVCs
of the cluster. If the field is not set, no configuration will be
applied.
properties:
iops:
description: IOPS defines the IOPS number to configure for the
storage PVCs
type: integer
throughput:
description: Throughput defines the throughput number in MB/s
for the storage PVCs
type: integer
volumeAttributesClassName:
description: VolumeAttributesClassName specifies VolumeAttributeClass
name to use for the storage PVCs
type: string
type: object
storageClassNames:
description: StorageClassNames specifies the storage class names for
db and snapshots.
Expand All @@ -869,19 +887,6 @@ spec:
volume.
type: string
type: object
storageTier:
allOf:
- enum:
- budget
- balanced
- performance
- enum:
- budget
- balanced
- performance
description: StorageTier specifies the performance tier to use for
the disk
type: string
suspend:
default: false
description: |-
Expand Down
39 changes: 19 additions & 20 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -796,7 +796,7 @@ _Appears in:_
| `gpu` _[GPU](#gpu)_ | GPU specifies GPU configuration for the cluster. If this field is not set, no GPU will be used. | | |
| `statefulSet` _[KubernetesStatefulSet](#kubernetesstatefulset)_ | StatefulSet specifies the configuration of the Qdrant Kubernetes StatefulSet. | | |
| `storageClassNames` _[StorageClassNames](#storageclassnames)_ | StorageClassNames specifies the storage class names for db and snapshots. | | |
| `storageTier` _[StorageTier](#storagetier)_ | StorageTier specifies the performance tier to use for the disk | | Enum: [budget balanced performance] <br /> |
| `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. | | |
| `topologySpreadConstraints` _[TopologySpreadConstraint](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/#topologyspreadconstraint-v1-core)_ | TopologySpreadConstraints specifies the topology spread constraints for the cluster. | | |
| `podDisruptionBudget` _[PodDisruptionBudgetSpec](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/#poddisruptionbudgetspec-v1-policy)_ | PodDisruptionBudget specifies the pod disruption budget for the cluster. | | |
| `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. | | |
Expand Down Expand Up @@ -1290,6 +1290,24 @@ _Appears in:_
| `Disabled` | |


#### Storage







_Appears in:_
- [QdrantClusterSpec](#qdrantclusterspec)

| Field | Description | Default | Validation |
| --- | --- | --- | --- |
| `volumeAttributesClassName` _string_ | VolumeAttributesClassName specifies VolumeAttributeClass name to use for the storage PVCs | | |
| `iops` _integer_ | IOPS defines the IOPS number to configure for the storage PVCs | | |
| `throughput` _integer_ | Throughput defines the throughput number in MB/s for the storage PVCs | | |


#### StorageClass


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


#### StorageTier

_Underlying type:_ _string_

StorageTier specifies the performance profile for the disk to use.

_Validation:_
- Enum: [budget balanced performance]

_Appears in:_
- [QdrantClusterSpec](#qdrantclusterspec)

| Field | Description |
| --- | --- |
| `budget` | |
| `balanced` | |
| `performance` | |


#### TraefikConfig


Expand Down
Loading
Loading