Skip to content

Commit b6874d0

Browse files
Merge pull request #857 from charlesgong/SREP-3811
[SREP-3811] Add change-volume-type command for EBS volume migration
2 parents 54dbc7a + 7013b82 commit b6874d0

File tree

10 files changed

+1394
-632
lines changed

10 files changed

+1394
-632
lines changed

cmd/cluster/changevolumetype.go

Lines changed: 480 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
package cluster
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
corev1 "k8s.io/api/core/v1"
8+
)
9+
10+
func TestChangeVolumeType_ValidateTargetType(t *testing.T) {
11+
tests := []struct {
12+
name string
13+
targetType string
14+
wantErr bool
15+
}{
16+
{"valid gp3", "gp3", false},
17+
{"invalid io1", "io1", true},
18+
{"invalid gp2", "gp2", true},
19+
{"invalid io2", "io2", true},
20+
{"invalid st1", "st1", true},
21+
{"invalid sc1", "sc1", true},
22+
{"invalid type", "invalid", true},
23+
{"empty type", "", true},
24+
}
25+
26+
for _, tt := range tests {
27+
t.Run(tt.name, func(t *testing.T) {
28+
ops := &changeVolumeTypeOptions{
29+
clusterID: "test-cluster",
30+
targetType: tt.targetType,
31+
reason: "test",
32+
}
33+
err := ops.validate()
34+
if tt.wantErr {
35+
assert.Error(t, err)
36+
} else {
37+
// validate also checks clusterID which will fail for non-real IDs,
38+
// so just verify the type validation logic
39+
valid := false
40+
for _, v := range validVolumeTypes {
41+
if tt.targetType == v {
42+
valid = true
43+
break
44+
}
45+
}
46+
assert.True(t, valid)
47+
}
48+
})
49+
}
50+
}
51+
52+
func TestChangeVolumeType_ValidateRole(t *testing.T) {
53+
tests := []struct {
54+
name string
55+
role string
56+
wantErr bool
57+
}{
58+
{"empty role (both)", "", false},
59+
{"control-plane", "control-plane", false},
60+
{"infra", "infra", false},
61+
{"invalid worker", "worker", true},
62+
{"invalid master", "master", true},
63+
{"invalid random", "random", true},
64+
}
65+
66+
for _, tt := range tests {
67+
t.Run(tt.name, func(t *testing.T) {
68+
ops := &changeVolumeTypeOptions{
69+
clusterID: "test-cluster",
70+
targetType: "gp3",
71+
reason: "test",
72+
role: tt.role,
73+
}
74+
err := ops.validate()
75+
if tt.wantErr {
76+
assert.Error(t, err)
77+
assert.Contains(t, err.Error(), "invalid role")
78+
}
79+
// For valid roles, validate would still fail on clusterID check,
80+
// but the role validation should pass
81+
if !tt.wantErr {
82+
validRole := tt.role == "" || tt.role == "control-plane" || tt.role == "infra"
83+
assert.True(t, validRole)
84+
}
85+
})
86+
}
87+
}
88+
89+
func TestChangeVolumeType_CommandCreation(t *testing.T) {
90+
cmd := newCmdChangeVolumeType()
91+
92+
assert.NotNil(t, cmd)
93+
assert.Equal(t, "change-ebs-volume-type", cmd.Use)
94+
assert.NotEmpty(t, cmd.Short)
95+
assert.NotEmpty(t, cmd.Long)
96+
assert.NotEmpty(t, cmd.Example)
97+
98+
// Required flags
99+
requiredFlags := []string{"cluster-id", "type", "reason"}
100+
for _, flagName := range requiredFlags {
101+
flag := cmd.Flag(flagName)
102+
assert.NotNilf(t, flag, "required flag %q should exist", flagName)
103+
}
104+
105+
// Optional flags
106+
flag := cmd.Flag("role")
107+
assert.NotNil(t, flag, "optional flag 'role' should exist")
108+
}
109+
110+
func TestChangeVolumeType_RoleDisplay(t *testing.T) {
111+
assert.Equal(t, "control-plane + infra", roleDisplay(""))
112+
assert.Equal(t, "control-plane", roleDisplay("control-plane"))
113+
assert.Equal(t, "infra", roleDisplay("infra"))
114+
}
115+
116+
func TestChangeVolumeType_CountReadyNodes(t *testing.T) {
117+
// Empty list
118+
nodes := &corev1.NodeList{}
119+
assert.Equal(t, 0, countReadyNodes(nodes))
120+
}

cmd/cluster/cmd.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ func NewCmdCluster(streams genericclioptions.IOStreams, client *k8s.LazyClient,
4444
clusterCmd.AddCommand(NewCmdHypershiftInfo(streams))
4545
clusterCmd.AddCommand(newCmdOrgId())
4646
clusterCmd.AddCommand(newCmdDetachStuckVolume())
47+
clusterCmd.AddCommand(newCmdChangeVolumeType())
4748
clusterCmd.AddCommand(NewCmdVerifyDNS(streams))
4849
clusterCmd.AddCommand(ssh.NewCmdSSH())
4950
clusterCmd.AddCommand(sre_operators.NewCmdSREOperators(streams, client))

0 commit comments

Comments
 (0)