diff --git a/internal/cmd/base/labels.go b/internal/cmd/base/labels.go index cee35c18..be4acc9a 100644 --- a/internal/cmd/base/labels.go +++ b/internal/cmd/base/labels.go @@ -4,8 +4,10 @@ import ( "errors" "fmt" "log" + "maps" "slices" "strings" + "sync" "github.com/spf13/cobra" @@ -15,6 +17,20 @@ import ( "github.com/hetznercloud/cli/internal/state" ) +// labelBatchSize is the batch size when processing multiple resources in parallel. +const labelBatchSize = 10 + +// BatchLabelResult represents the result of a batch label operation for a single resource. +type BatchLabelResult struct { + IDOrName string + Resource interface{} + Success bool + Error error + LabelsAdded []string + LabelsRemoved []string + AllLabelsRemoved bool +} + // LabelCmds allows defining commands for adding labels to resources. type LabelCmds[T any] struct { ResourceNameSingular string @@ -48,6 +64,10 @@ type LabelCmds[T any] struct { // Experimental is a function that will be used to mark the command as experimental. Experimental func(state.State, *cobra.Command) *cobra.Command + + // Batch operation support + FetchBatch func(s state.State, idOrNames []string) ([]T, []error) + SetLabelsBatch func(s state.State, resources []T, labels map[string]string) []error } // AddCobraCommand creates a command that can be registered with cobra. @@ -65,15 +85,15 @@ func (lc *LabelCmds[T]) AddCobraCommand(s state.State) *cobra.Command { } cmd := &cobra.Command{ - Use: fmt.Sprintf("add-label [--overwrite] %s