Skip to content

Commit

Permalink
Verify the ReplaceNode pod name exists in the Datacenter before repla…
Browse files Browse the repository at this point in the history
…cing it, fixes k8ssandra#315
  • Loading branch information
burmanm committed Apr 26, 2022
1 parent 973cea8 commit 64cef53
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 10 deletions.
30 changes: 20 additions & 10 deletions pkg/reconciliation/reconcile_racks.go
Original file line number Diff line number Diff line change
Expand Up @@ -1070,19 +1070,29 @@ func (rc *ReconciliationContext) startReplacePodsIfReplacePodsSpecified() error
dc := rc.Datacenter

if len(dc.Spec.ReplaceNodes) > 0 {
rc.ReqLogger.Info("Replacing pods", "pods", dc.Spec.ReplaceNodes)

podNamesString := strings.Join(dc.Spec.ReplaceNodes, ", ")
rc.ReqLogger.Info("Requested replacing pods", "pods", dc.Spec.ReplaceNodes)

for _, podName := range dc.Spec.ReplaceNodes {
// Each podName has to be in the dcPods
for _, dcPod := range rc.dcPods {
if podName == dcPod.Name {
dc.Status.NodeReplacements = utils.AppendValuesToStringArrayIfNotPresent(
dc.Status.NodeReplacements, podName)
break
}
}
rc.ReqLogger.Error(fmt.Errorf("invalid pod name in ReplaceNodes"), "Rejected ReplaceNode entry, pod does not exist in the Datacenter", "PodName", podName)
}

_ = rc.setCondition(
api.NewDatacenterCondition(api.DatacenterReplacingNodes, corev1.ConditionTrue))
if len(dc.Status.NodeReplacements) > 0 {
podNamesString := strings.Join(dc.Spec.ReplaceNodes, ", ")

rc.Recorder.Eventf(rc.Datacenter, corev1.EventTypeNormal, events.ReplacingNode,
"Replacing Cassandra nodes for pods %s", podNamesString)
_ = rc.setCondition(
api.NewDatacenterCondition(api.DatacenterReplacingNodes, corev1.ConditionTrue))

dc.Status.NodeReplacements = utils.AppendValuesToStringArrayIfNotPresent(
dc.Status.NodeReplacements,
dc.Spec.ReplaceNodes...)
rc.Recorder.Eventf(rc.Datacenter, corev1.EventTypeNormal, events.ReplacingNode,
"Replacing Cassandra nodes for pods %s", podNamesString)
}

// Now that we've recorded these nodes in the status, we can blank
// out this field on the spec
Expand Down
52 changes: 52 additions & 0 deletions pkg/reconciliation/reconcile_racks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1549,3 +1549,55 @@ func TestStripPassword(t *testing.T) {

assert.False(t, strings.Contains(err.Error(), password))
}

func TestNodereplacements(t *testing.T) {
assert := assert.New(t)
rc, _, cleanupMockScr := setupTest()
defer cleanupMockScr()

pod := &corev1.Pod{
TypeMeta: metav1.TypeMeta{
Kind: "Pod",
APIVersion: "v1",
},
ObjectMeta: metav1.ObjectMeta{
Name: "dc1-default-sts-0",
},
}

pod2 := &corev1.Pod{
TypeMeta: metav1.TypeMeta{
Kind: "Pod",
APIVersion: "v1",
},
ObjectMeta: metav1.ObjectMeta{
Name: "dc1-default-sts-1",
},
}

rc.dcPods = []*corev1.Pod{
pod, pod2,
}

err := rc.startReplacePodsIfReplacePodsSpecified()
assert.NoError(err)
assert.Equal(0, len(rc.Datacenter.Status.NodeReplacements))

rc.Datacenter.Spec.ReplaceNodes = []string{""}
err = rc.startReplacePodsIfReplacePodsSpecified()
assert.NoError(err)
assert.Equal(0, len(rc.Datacenter.Status.NodeReplacements))
assert.Equal(0, len(rc.Datacenter.Spec.ReplaceNodes))

rc.Datacenter.Spec.ReplaceNodes = []string{"dc1-default-sts-3"} // Does not exists
err = rc.startReplacePodsIfReplacePodsSpecified()
assert.NoError(err)
assert.Equal(0, len(rc.Datacenter.Status.NodeReplacements))
assert.Equal(0, len(rc.Datacenter.Spec.ReplaceNodes))

rc.Datacenter.Spec.ReplaceNodes = []string{"dc1-default-sts-0"}
err = rc.startReplacePodsIfReplacePodsSpecified()
assert.NoError(err)
assert.Equal(1, len(rc.Datacenter.Status.NodeReplacements))
assert.Equal(0, len(rc.Datacenter.Spec.ReplaceNodes))
}

0 comments on commit 64cef53

Please sign in to comment.