Skip to content

Commit

Permalink
feat: allow adding/removing multiple labels at once (#665)
Browse files Browse the repository at this point in the history
Closes #662
  • Loading branch information
phm07 committed Jan 9, 2024
1 parent e1bd800 commit 919c446
Show file tree
Hide file tree
Showing 12 changed files with 106 additions and 42 deletions.
46 changes: 26 additions & 20 deletions internal/cmd/base/labels.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ type LabelCmds struct {
// AddCobraCommand creates a command that can be registered with cobra.
func (lc *LabelCmds) AddCobraCommand(s state.State) *cobra.Command {
cmd := &cobra.Command{
Use: fmt.Sprintf("add-label [FLAGS] %s LABEL", strings.ToUpper(lc.ResourceNameSingular)),
Use: fmt.Sprintf("add-label [FLAGS] %s LABEL...", strings.ToUpper(lc.ResourceNameSingular)),
Short: lc.ShortDescriptionAdd,
Args: cobra.ExactArgs(2),
Args: cobra.MinimumNArgs(2),
ValidArgsFunction: cmpl.SuggestArgs(cmpl.SuggestCandidatesF(lc.NameSuggestions(s.Client()))),
TraverseChildren: true,
DisableFlagsInUseLine: true,
Expand All @@ -56,26 +56,31 @@ func (lc *LabelCmds) RunAdd(s state.State, cmd *cobra.Command, args []string) er
labels = map[string]string{}
}

key, val := util.SplitLabelVars(args[1])
var keys []string
for _, label := range args[1:] {
key, val := util.SplitLabelVars(label)
keys = append(keys, key)

if _, ok := labels[key]; ok && !overwrite {
return fmt.Errorf("label %s on %s %d already exists", key, lc.ResourceNameSingular, id)
}
if _, ok := labels[key]; ok && !overwrite {
return fmt.Errorf("label %s on %s %d already exists", key, lc.ResourceNameSingular, id)
}

labels[key] = val
labels[key] = val
}

if err := lc.SetLabels(s, id, labels); err != nil {
return err
}

cmd.Printf("Label %s added to %s %d\n", key, lc.ResourceNameSingular, id)
cmd.Printf("Label(s) %s added to %s %d\n", strings.Join(keys, ", "), lc.ResourceNameSingular, id)
return nil
}

func validateAddLabel(_ *cobra.Command, args []string) error {
label := util.SplitLabel(args[1])
if len(label) != 2 {
return fmt.Errorf("invalid label: %s", args[1])
for _, label := range args[1:] {
if len(util.SplitLabel(label)) != 2 {
return fmt.Errorf("invalid label: %s", label)
}
}

return nil
Expand All @@ -84,9 +89,9 @@ func validateAddLabel(_ *cobra.Command, args []string) error {
// RemoveCobraCommand creates a command that can be registered with cobra.
func (lc *LabelCmds) RemoveCobraCommand(s state.State) *cobra.Command {
cmd := &cobra.Command{
Use: fmt.Sprintf("remove-label [FLAGS] %s LABEL", strings.ToUpper(lc.ResourceNameSingular)),
Use: fmt.Sprintf("remove-label [FLAGS] %s LABEL...", strings.ToUpper(lc.ResourceNameSingular)),
Short: lc.ShortDescriptionRemove,
Args: cobra.RangeArgs(1, 2),
Args: cobra.MinimumNArgs(1),
ValidArgsFunction: cmpl.SuggestArgs(
cmpl.SuggestCandidatesF(lc.NameSuggestions(s.Client())),
cmpl.SuggestCandidatesCtx(func(_ *cobra.Command, args []string) []string {
Expand Down Expand Up @@ -120,11 +125,12 @@ func (lc *LabelCmds) RunRemove(s state.State, cmd *cobra.Command, args []string)
if all {
labels = make(map[string]string)
} else {
key := args[1]
if _, ok := labels[key]; !ok {
return fmt.Errorf("label %s on %s %d does not exist", key, lc.ResourceNameSingular, id)
for _, key := range args[1:] {
if _, ok := labels[key]; !ok {
return fmt.Errorf("label %s on %s %d does not exist", key, lc.ResourceNameSingular, id)
}
delete(labels, key)
}
delete(labels, key)
}

if err := lc.SetLabels(s, id, labels); err != nil {
Expand All @@ -134,7 +140,7 @@ func (lc *LabelCmds) RunRemove(s state.State, cmd *cobra.Command, args []string)
if all {
cmd.Printf("All labels removed from %s %d\n", lc.ResourceNameSingular, id)
} else {
cmd.Printf("Label %s removed from %s %d\n", args[1], lc.ResourceNameSingular, id)
cmd.Printf("Label(s) %s removed from %s %d\n", strings.Join(args[1:], ", "), lc.ResourceNameSingular, id)
}

return nil
Expand All @@ -143,10 +149,10 @@ func (lc *LabelCmds) RunRemove(s state.State, cmd *cobra.Command, args []string)
func validateRemoveLabel(cmd *cobra.Command, args []string) error {
all, _ := cmd.Flags().GetBool("all")

if all && len(args) == 2 {
if all && len(args) > 1 {
return errors.New("must not specify a label key when using --all/-a")
}
if !all && len(args) != 2 {
if !all && len(args) <= 1 {
return errors.New("must specify a label key when not using --all/-a")
}

Expand Down
4 changes: 2 additions & 2 deletions internal/cmd/certificate/labels_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func TestLabelAdd(t *testing.T) {

out, _, err := fx.Run(cmd, []string{"123", "key=value"})

expOut := "Label key added to certificate 123\n"
expOut := "Label(s) key added to certificate 123\n"

assert.NoError(t, err)
assert.Equal(t, expOut, out)
Expand Down Expand Up @@ -57,7 +57,7 @@ func TestLabelRemove(t *testing.T) {

out, _, err := fx.Run(cmd, []string{"123", "key"})

expOut := "Label key removed from certificate 123\n"
expOut := "Label(s) key removed from certificate 123\n"

assert.NoError(t, err)
assert.Equal(t, expOut, out)
Expand Down
4 changes: 2 additions & 2 deletions internal/cmd/firewall/labels_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func TestLabelAdd(t *testing.T) {

out, _, err := fx.Run(cmd, []string{"123", "key=value"})

expOut := "Label key added to firewall 123\n"
expOut := "Label(s) key added to firewall 123\n"

assert.NoError(t, err)
assert.Equal(t, expOut, out)
Expand Down Expand Up @@ -57,7 +57,7 @@ func TestLabelRemove(t *testing.T) {

out, _, err := fx.Run(cmd, []string{"123", "key"})

expOut := "Label key removed from firewall 123\n"
expOut := "Label(s) key removed from firewall 123\n"

assert.NoError(t, err)
assert.Equal(t, expOut, out)
Expand Down
4 changes: 2 additions & 2 deletions internal/cmd/floatingip/labels_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func TestLabelAdd(t *testing.T) {

out, _, err := fx.Run(cmd, []string{"123", "key=value"})

expOut := "Label key added to Floating IP 123\n"
expOut := "Label(s) key added to Floating IP 123\n"

assert.NoError(t, err)
assert.Equal(t, expOut, out)
Expand Down Expand Up @@ -57,7 +57,7 @@ func TestLabelRemove(t *testing.T) {

out, _, err := fx.Run(cmd, []string{"123", "key"})

expOut := "Label key removed from Floating IP 123\n"
expOut := "Label(s) key removed from Floating IP 123\n"

assert.NoError(t, err)
assert.Equal(t, expOut, out)
Expand Down
4 changes: 2 additions & 2 deletions internal/cmd/image/labels_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func TestLabelAdd(t *testing.T) {

out, _, err := fx.Run(cmd, []string{"123", "key=value"})

expOut := "Label key added to image 123\n"
expOut := "Label(s) key added to image 123\n"

assert.NoError(t, err)
assert.Equal(t, expOut, out)
Expand Down Expand Up @@ -57,7 +57,7 @@ func TestLabelRemove(t *testing.T) {

out, _, err := fx.Run(cmd, []string{"123", "key"})

expOut := "Label key removed from image 123\n"
expOut := "Label(s) key removed from image 123\n"

assert.NoError(t, err)
assert.Equal(t, expOut, out)
Expand Down
4 changes: 2 additions & 2 deletions internal/cmd/loadbalancer/labels_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func TestLabelAdd(t *testing.T) {

out, _, err := fx.Run(cmd, []string{"123", "key=value"})

expOut := "Label key added to Load Balancer 123\n"
expOut := "Label(s) key added to Load Balancer 123\n"

assert.NoError(t, err)
assert.Equal(t, expOut, out)
Expand Down Expand Up @@ -57,7 +57,7 @@ func TestLabelRemove(t *testing.T) {

out, _, err := fx.Run(cmd, []string{"123", "key"})

expOut := "Label key removed from Load Balancer 123\n"
expOut := "Label(s) key removed from Load Balancer 123\n"

assert.NoError(t, err)
assert.Equal(t, expOut, out)
Expand Down
4 changes: 2 additions & 2 deletions internal/cmd/network/labels_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func TestLabelAdd(t *testing.T) {

out, _, err := fx.Run(cmd, []string{"123", "key=value"})

expOut := "Label key added to Network 123\n"
expOut := "Label(s) key added to Network 123\n"

assert.NoError(t, err)
assert.Equal(t, expOut, out)
Expand Down Expand Up @@ -57,7 +57,7 @@ func TestLabelRemove(t *testing.T) {

out, _, err := fx.Run(cmd, []string{"123", "key"})

expOut := "Label key removed from Network 123\n"
expOut := "Label(s) key removed from Network 123\n"

assert.NoError(t, err)
assert.Equal(t, expOut, out)
Expand Down
4 changes: 2 additions & 2 deletions internal/cmd/placementgroup/labels_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func TestLabelAdd(t *testing.T) {

out, _, err := fx.Run(cmd, []string{"123", "key=value"})

expOut := "Label key added to placement group 123\n"
expOut := "Label(s) key added to placement group 123\n"

assert.NoError(t, err)
assert.Equal(t, expOut, out)
Expand Down Expand Up @@ -57,7 +57,7 @@ func TestLabelRemove(t *testing.T) {

out, _, err := fx.Run(cmd, []string{"123", "key"})

expOut := "Label key removed from placement group 123\n"
expOut := "Label(s) key removed from placement group 123\n"

assert.NoError(t, err)
assert.Equal(t, expOut, out)
Expand Down
4 changes: 2 additions & 2 deletions internal/cmd/primaryip/labels_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func TestLabelAdd(t *testing.T) {

out, _, err := fx.Run(cmd, []string{"123", "key=value"})

expOut := "Label key added to primary-ip 123\n"
expOut := "Label(s) key added to primary-ip 123\n"

assert.NoError(t, err)
assert.Equal(t, expOut, out)
Expand Down Expand Up @@ -57,7 +57,7 @@ func TestLabelRemove(t *testing.T) {

out, _, err := fx.Run(cmd, []string{"123", "key"})

expOut := "Label key removed from primary-ip 123\n"
expOut := "Label(s) key removed from primary-ip 123\n"

assert.NoError(t, err)
assert.Equal(t, expOut, out)
Expand Down
62 changes: 60 additions & 2 deletions internal/cmd/server/labels_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,33 @@ func TestLabelAdd(t *testing.T) {

out, _, err := fx.Run(cmd, []string{"123", "key=value"})

expOut := "Label key added to server 123\n"
expOut := "Label(s) key added to server 123\n"

assert.NoError(t, err)
assert.Equal(t, expOut, out)
}

func TestMultiLabelAdd(t *testing.T) {
fx := testutil.NewFixture(t)
defer fx.Finish()

cmd := LabelCmds.AddCobraCommand(fx.State())
fx.ExpectEnsureToken()

fx.Client.ServerClient.EXPECT().
Get(gomock.Any(), "123").
Return(&hcloud.Server{ID: 123}, nil, nil)
fx.Client.ServerClient.EXPECT().
Update(gomock.Any(), &hcloud.Server{ID: 123}, hcloud.ServerUpdateOpts{
Labels: map[string]string{
"foo": "bar",
"baz": "qux",
},
})

out, _, err := fx.Run(cmd, []string{"123", "foo=bar", "baz=qux"})

expOut := "Label(s) foo, baz added to server 123\n"

assert.NoError(t, err)
assert.Equal(t, expOut, out)
Expand Down Expand Up @@ -57,7 +83,39 @@ func TestLabelRemove(t *testing.T) {

out, _, err := fx.Run(cmd, []string{"123", "key"})

expOut := "Label key removed from server 123\n"
expOut := "Label(s) key removed from server 123\n"

assert.NoError(t, err)
assert.Equal(t, expOut, out)
}

func TestMultiLabelRemove(t *testing.T) {
fx := testutil.NewFixture(t)
defer fx.Finish()

cmd := LabelCmds.RemoveCobraCommand(fx.State())
fx.ExpectEnsureToken()

fx.Client.ServerClient.EXPECT().
Get(gomock.Any(), "123").
Return(&hcloud.Server{
ID: 123,
Labels: map[string]string{
"key": "value",
"foo": "bar",
"baz": "qux",
},
}, nil, nil)
fx.Client.ServerClient.EXPECT().
Update(gomock.Any(), &hcloud.Server{ID: 123}, hcloud.ServerUpdateOpts{
Labels: map[string]string{
"key": "value",
},
})

out, _, err := fx.Run(cmd, []string{"123", "foo", "baz"})

expOut := "Label(s) foo, baz removed from server 123\n"

assert.NoError(t, err)
assert.Equal(t, expOut, out)
Expand Down
4 changes: 2 additions & 2 deletions internal/cmd/sshkey/labels_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func TestLabelAdd(t *testing.T) {

out, _, err := fx.Run(cmd, []string{"123", "key=value"})

expOut := "Label key added to SSH Key 123\n"
expOut := "Label(s) key added to SSH Key 123\n"

assert.NoError(t, err)
assert.Equal(t, expOut, out)
Expand Down Expand Up @@ -57,7 +57,7 @@ func TestLabelRemove(t *testing.T) {

out, _, err := fx.Run(cmd, []string{"123", "key"})

expOut := "Label key removed from SSH Key 123\n"
expOut := "Label(s) key removed from SSH Key 123\n"

assert.NoError(t, err)
assert.Equal(t, expOut, out)
Expand Down
4 changes: 2 additions & 2 deletions internal/cmd/volume/labels_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func TestLabelAdd(t *testing.T) {

out, _, err := fx.Run(cmd, []string{"123", "key=value"})

expOut := "Label key added to Volume 123\n"
expOut := "Label(s) key added to Volume 123\n"

assert.NoError(t, err)
assert.Equal(t, expOut, out)
Expand Down Expand Up @@ -57,7 +57,7 @@ func TestLabelRemove(t *testing.T) {

out, _, err := fx.Run(cmd, []string{"123", "key"})

expOut := "Label key removed from Volume 123\n"
expOut := "Label(s) key removed from Volume 123\n"

assert.NoError(t, err)
assert.Equal(t, expOut, out)
Expand Down

0 comments on commit 919c446

Please sign in to comment.