diff --git a/api/v1/qdrantcluster_types.go b/api/v1/qdrantcluster_types.go index e5301dc..0c7ab3a 100644 --- a/api/v1/qdrantcluster_types.go +++ b/api/v1/qdrantcluster_types.go @@ -59,7 +59,7 @@ func GetQdrantClusterCrdForHash(qc QdrantCluster) QdrantCluster { cloned.Resources.Storage = "" cloned.RestartAllPodsConcurrently = false cloned.Service = nil - cloned.ServicePerNode = false + cloned.ServicePerNode = nil cloned.Size = 1 if v := cloned.StatefulSet; v != nil { v.Annotations = nil @@ -86,7 +86,7 @@ type QdrantClusterSpec struct { // ServicePerNode specifies whether the cluster should start a dedicated service for each node. // +kubebuilder:default=true // +optional - ServicePerNode bool `json:"servicePerNode"` + ServicePerNode *bool `json:"servicePerNode,omitempty"` // ClusterManager specifies whether to use the cluster manager for this cluster. // The Python-operator will deploy a dedicated cluster manager instance. // The Go-operator will use a shared instance. diff --git a/api/v1/qdrantcluster_types_test.go b/api/v1/qdrantcluster_types_test.go index 8abe5ba..f50b932 100644 --- a/api/v1/qdrantcluster_types_test.go +++ b/api/v1/qdrantcluster_types_test.go @@ -1,8 +1,12 @@ package v1 import ( + "crypto/sha256" + "encoding/json" + "fmt" "testing" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -17,3 +21,51 @@ func TestValidate(t *testing.T) { require.Error(t, err) require.ErrorContains(t, err, "Spec.Resources.CPU error: quantities must match the regular expression '^([+-]?[0-9.]+)([eEinumkKMGTP]*[-+]?[0-9]*)$'") } + +func TestGetQdrantClusterCrdForHash(t *testing.T) { + qc := QdrantCluster{} + hash, err := getQdrantClusterCrdHash(qc) + require.NoError(t, err) + assert.Equal(t, "523a8cb", hash) + + falseVal := false + qc.Spec.ServicePerNode = &falseVal + hash, err = getQdrantClusterCrdHash(qc) + require.NoError(t, err) + assert.Equal(t, "523a8cb", hash) + + trueVal := true + qc.Spec.ServicePerNode = &trueVal + hash, err = getQdrantClusterCrdHash(qc) + require.NoError(t, err) + assert.Equal(t, "523a8cb", hash) +} + +// getQdrantClusterCrdHash created a hash for the provided QdrantCluster, +// however a subset only, see GetQdrantClusterCrdForHash for details. +func getQdrantClusterCrdHash(qc QdrantCluster) (string, error) { + inspect := GetQdrantClusterCrdForHash(qc) + // Get the hash, so we can diff later + hash, err := getHash(inspect) + if err != nil { + return "", fmt.Errorf("failed to get hash for QdrantCluster: %w", err) + } + return hash, err +} + +// Get hash of provided value. +// Returns the first 7 characters of the hash (like GitHub). +func getHash(v any) (string, error) { + json, err := json.Marshal(v) + if err != nil { + return "", fmt.Errorf("marshal failed: %w", err) + } + // Initialize hash + hash := sha256.New() + // add the serialized content + hash.Write(json) + // close hash + sum := hash.Sum(nil) + // Return first 7 characters + return fmt.Sprintf("%x", sum)[:7], nil +} diff --git a/api/v1/zz_generated.deepcopy.go b/api/v1/zz_generated.deepcopy.go index b6795bd..0bb6817 100644 --- a/api/v1/zz_generated.deepcopy.go +++ b/api/v1/zz_generated.deepcopy.go @@ -807,6 +807,11 @@ func (in *QdrantClusterSnapshotStatus) DeepCopy() *QdrantClusterSnapshotStatus { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *QdrantClusterSpec) DeepCopyInto(out *QdrantClusterSpec) { *out = *in + if in.ServicePerNode != nil { + in, out := &in.ServicePerNode, &out.ServicePerNode + *out = new(bool) + **out = **in + } if in.ClusterManager != nil { in, out := &in.ClusterManager, &out.ClusterManager *out = new(bool)