Repository: scylladb/scylla-operator
Pull request #465 (2021-03-05 08:46:31)

cluster: fix source of rack version in cluster status
    
Take version from the first pod in a rack, which is upgraded as a last
one.



Patch:
diff --git a/pkg/controllers/cluster/status.go b/pkg/controllers/cluster/status.go
index f44477c0c..384f6ef38 100644
--- a/pkg/controllers/cluster/status.go
+++ b/pkg/controllers/cluster/status.go
@@ -82,7 +82,7 @@ func (cc *ClusterReconciler) updateStatus(ctx context.Context, cluster *scyllav1
 			if err != nil {
 				return errors.WithStack(err)
 			}
-			rackStatus.Version, err = naming.ScyllaVersion(sts.Spec.Template.Spec.Containers)
+			rackStatus.Version, err = naming.ScyllaVersion(firstRackMember.Spec.Containers)
 			if err != nil {
 				return errors.WithStack(err)
 			}


Test patch:
diff --git a/pkg/controllers/cluster/status_test.go b/pkg/controllers/cluster/status_test.go
index 713ed17b7..63a0164ca 100644
--- a/pkg/controllers/cluster/status_test.go
+++ b/pkg/controllers/cluster/status_test.go
@@ -4,11 +4,18 @@ package cluster
 
 import (
 	"context"
+	"fmt"
 	"testing"
 
+	"github.com/scylladb/scylla-operator/pkg/controllers/cluster/resource"
+	"github.com/scylladb/scylla-operator/pkg/naming"
 	"github.com/scylladb/scylla-operator/pkg/test/unit"
+	appsv1 "k8s.io/api/apps/v1"
+	corev1 "k8s.io/api/core/v1"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
 	clientgoscheme "k8s.io/client-go/kubernetes/scheme"
+	"k8s.io/utils/pointer"
 	"sigs.k8s.io/controller-runtime/pkg/client/fake"
 )
 
@@ -32,3 +39,57 @@ func TestClusterStatus_RackStatusIsRemovedWhenStatefulSetNoLongerExists(t *testi
 		t.Errorf("expected rack status to be cleared, got %v", v)
 	}
 }
+
+func TestClusterStatus_SourceOfRackStatus(t *testing.T) {
+	const (
+		scyllaVersion = "1.2.3"
+	)
+	cluster := unit.NewSingleRackCluster(1)
+	rack := cluster.Spec.Datacenter.Racks[0]
+
+	scheme := runtime.NewScheme()
+	if err := clientgoscheme.AddToScheme(scheme); err != nil {
+		t.Fatal(err)
+	}
+
+	rackFirstPodName := fmt.Sprintf("%s-0", naming.StatefulSetNameForRack(rack, cluster))
+	rackFirstPod := &corev1.Pod{
+		ObjectMeta: metav1.ObjectMeta{
+			Name:      rackFirstPodName,
+			Namespace: cluster.Namespace,
+		},
+		Spec: corev1.PodSpec{
+			Containers: []corev1.Container{
+				{
+					Name:  naming.ScyllaContainerName,
+					Image: fmt.Sprintf("scylladb/scylla:%s", scyllaVersion),
+				},
+			},
+		},
+	}
+
+	rackSts := resource.StatefulSetForRack(rack, cluster, "image")
+	rackSts.Spec.Replicas = pointer.Int32Ptr(123)
+	rackSts.Status = appsv1.StatefulSetStatus{
+		Replicas:      2,
+		ReadyReplicas: 1,
+	}
+	cc := &ClusterReconciler{
+		Client: fake.NewFakeClientWithScheme(scheme, []runtime.Object{rackSts, rackFirstPod}...),
+	}
+
+	if err := cc.updateStatus(context.Background(), cluster); err != nil {
+		t.Errorf("expected nil, got %s", err)
+	}
+
+	rackStatus := cluster.Status.Racks[rack.Name]
+	if rackStatus.Version != scyllaVersion {
+		t.Errorf("expected rack version to be taken from container spec from first pod, got %s", rackStatus.Version)
+	}
+	if rackStatus.ReadyMembers != rackSts.Status.ReadyReplicas {
+		t.Errorf("expected ready replicas to be taken from rack stateful status, got %d", rackStatus.ReadyMembers)
+	}
+	if rackStatus.Members != *rackSts.Spec.Replicas {
+		t.Errorf("expected replicas to be taken from rack stateful spec, got %d", rackStatus.Members)
+	}
+}