diff --git a/internal/cmd/base/labels.go b/internal/cmd/base/labels.go index 5feadeff..cd1f1c5e 100644 --- a/internal/cmd/base/labels.go +++ b/internal/cmd/base/labels.go @@ -18,9 +18,10 @@ type LabelCmds struct { ResourceNameSingular string ShortDescriptionAdd string ShortDescriptionRemove string + AdditionalFlags func(cmd *cobra.Command) NameSuggestions func(client hcapi2.Client) func() []string LabelKeySuggestions func(client hcapi2.Client) func(idOrName string) []string - FetchLabels func(s state.State, idOrName string) (map[string]string, int64, error) + FetchLabels func(s state.State, cmd *cobra.Command, idOrName string) (map[string]string, int64, error) SetLabels func(s state.State, id int64, labels map[string]string) error } @@ -39,6 +40,10 @@ func (lc *LabelCmds) AddCobraCommand(s state.State) *cobra.Command { }, } cmd.Flags().BoolP("overwrite", "o", false, "Overwrite label if it exists already") + + if lc.AdditionalFlags != nil { + lc.AdditionalFlags(cmd) + } return cmd } @@ -47,7 +52,7 @@ func (lc *LabelCmds) RunAdd(s state.State, cmd *cobra.Command, args []string) er overwrite, _ := cmd.Flags().GetBool("overwrite") idOrName := args[0] - labels, id, err := lc.FetchLabels(s, idOrName) + labels, id, err := lc.FetchLabels(s, cmd, idOrName) if err != nil { return err } @@ -109,6 +114,10 @@ func (lc *LabelCmds) RemoveCobraCommand(s state.State) *cobra.Command { }, } cmd.Flags().BoolP("all", "a", false, "Remove all labels") + + if lc.AdditionalFlags != nil { + lc.AdditionalFlags(cmd) + } return cmd } @@ -117,7 +126,7 @@ func (lc *LabelCmds) RunRemove(s state.State, cmd *cobra.Command, args []string) all, _ := cmd.Flags().GetBool("all") idOrName := args[0] - labels, id, err := lc.FetchLabels(s, idOrName) + labels, id, err := lc.FetchLabels(s, cmd, idOrName) if err != nil { return err } diff --git a/internal/cmd/certificate/labels.go b/internal/cmd/certificate/labels.go index 60d1305d..11ea1dd0 100644 --- a/internal/cmd/certificate/labels.go +++ b/internal/cmd/certificate/labels.go @@ -3,6 +3,8 @@ package certificate import ( "fmt" + "github.com/spf13/cobra" + "github.com/hetznercloud/cli/internal/cmd/base" "github.com/hetznercloud/cli/internal/hcapi2" "github.com/hetznercloud/cli/internal/state" @@ -15,7 +17,7 @@ var LabelCmds = base.LabelCmds{ ShortDescriptionRemove: "Remove a label from an certificate", NameSuggestions: func(c hcapi2.Client) func() []string { return c.Certificate().Names }, LabelKeySuggestions: func(c hcapi2.Client) func(idOrName string) []string { return c.Certificate().LabelKeys }, - FetchLabels: func(s state.State, idOrName string) (map[string]string, int64, error) { + FetchLabels: func(s state.State, _ *cobra.Command, idOrName string) (map[string]string, int64, error) { certificate, _, err := s.Client().Certificate().Get(s, idOrName) if err != nil { return nil, 0, err diff --git a/internal/cmd/firewall/labels.go b/internal/cmd/firewall/labels.go index 4c1f9883..c97d0f6c 100644 --- a/internal/cmd/firewall/labels.go +++ b/internal/cmd/firewall/labels.go @@ -3,6 +3,8 @@ package firewall import ( "fmt" + "github.com/spf13/cobra" + "github.com/hetznercloud/cli/internal/cmd/base" "github.com/hetznercloud/cli/internal/hcapi2" "github.com/hetznercloud/cli/internal/state" @@ -15,7 +17,7 @@ var LabelCmds = base.LabelCmds{ ShortDescriptionRemove: "Remove a label from an firewall", NameSuggestions: func(c hcapi2.Client) func() []string { return c.Firewall().Names }, LabelKeySuggestions: func(c hcapi2.Client) func(idOrName string) []string { return c.Firewall().LabelKeys }, - FetchLabels: func(s state.State, idOrName string) (map[string]string, int64, error) { + FetchLabels: func(s state.State, _ *cobra.Command, idOrName string) (map[string]string, int64, error) { firewall, _, err := s.Client().Firewall().Get(s, idOrName) if err != nil { return nil, 0, err diff --git a/internal/cmd/floatingip/labels.go b/internal/cmd/floatingip/labels.go index a63a7598..a894a3eb 100644 --- a/internal/cmd/floatingip/labels.go +++ b/internal/cmd/floatingip/labels.go @@ -3,6 +3,8 @@ package floatingip import ( "fmt" + "github.com/spf13/cobra" + "github.com/hetznercloud/cli/internal/cmd/base" "github.com/hetznercloud/cli/internal/hcapi2" "github.com/hetznercloud/cli/internal/state" @@ -15,7 +17,7 @@ var LabelCmds = base.LabelCmds{ ShortDescriptionRemove: "Remove a label from an Floating IP", NameSuggestions: func(c hcapi2.Client) func() []string { return c.FloatingIP().Names }, LabelKeySuggestions: func(c hcapi2.Client) func(idOrName string) []string { return c.FloatingIP().LabelKeys }, - FetchLabels: func(s state.State, idOrName string) (map[string]string, int64, error) { + FetchLabels: func(s state.State, _ *cobra.Command, idOrName string) (map[string]string, int64, error) { floatingIP, _, err := s.Client().FloatingIP().Get(s, idOrName) if err != nil { return nil, 0, err diff --git a/internal/cmd/image/delete.go b/internal/cmd/image/delete.go index 77066e76..cf999926 100644 --- a/internal/cmd/image/delete.go +++ b/internal/cmd/image/delete.go @@ -1,9 +1,13 @@ package image import ( + "fmt" + "os" + "github.com/spf13/cobra" "github.com/hetznercloud/cli/internal/cmd/base" + "github.com/hetznercloud/cli/internal/cmd/cmpl" "github.com/hetznercloud/cli/internal/hcapi2" "github.com/hetznercloud/cli/internal/state" "github.com/hetznercloud/hcloud-go/v2/hcloud" @@ -14,8 +18,19 @@ var DeleteCmd = base.DeleteCmd{ ResourceNamePlural: "images", ShortDescription: "Delete an image", NameSuggestions: func(c hcapi2.Client) func() []string { return c.Image().Names }, + AdditionalFlags: func(cmd *cobra.Command) { + cmd.Flags().StringP("architecture", "a", string(hcloud.ArchitectureX86), "architecture of the image, default is x86") + _ = cmd.RegisterFlagCompletionFunc("architecture", cmpl.SuggestCandidates(string(hcloud.ArchitectureX86), string(hcloud.ArchitectureARM))) + }, Fetch: func(s state.State, cmd *cobra.Command, idOrName string) (interface{}, *hcloud.Response, error) { - return s.Client().Image().Get(s, idOrName) + arch, err := cmd.Flags().GetString("architecture") + if err != nil { + return nil, nil, err + } + if !cmd.Flags().Changed("architecture") { + _, _ = fmt.Fprintln(os.Stderr, "INFO: This command only returns x86 images by default. Explicitly set the --architecture=x86|arm flag to hide this message.") + } + return s.Client().Image().GetForArchitecture(s, idOrName, hcloud.Architecture(arch)) }, Delete: func(s state.State, cmd *cobra.Command, resource interface{}) (*hcloud.Action, error) { image := resource.(*hcloud.Image) diff --git a/internal/cmd/image/labels.go b/internal/cmd/image/labels.go index e1ae3849..e80a6b3c 100644 --- a/internal/cmd/image/labels.go +++ b/internal/cmd/image/labels.go @@ -2,8 +2,12 @@ package image import ( "fmt" + "os" + + "github.com/spf13/cobra" "github.com/hetznercloud/cli/internal/cmd/base" + "github.com/hetznercloud/cli/internal/cmd/cmpl" "github.com/hetznercloud/cli/internal/hcapi2" "github.com/hetznercloud/cli/internal/state" "github.com/hetznercloud/hcloud-go/v2/hcloud" @@ -15,8 +19,20 @@ var LabelCmds = base.LabelCmds{ ShortDescriptionRemove: "Remove a label from an image", NameSuggestions: func(c hcapi2.Client) func() []string { return c.Image().Names }, LabelKeySuggestions: func(c hcapi2.Client) func(idOrName string) []string { return c.Image().LabelKeys }, - FetchLabels: func(s state.State, idOrName string) (map[string]string, int64, error) { - image, _, err := s.Client().Image().Get(s, idOrName) + AdditionalFlags: func(cmd *cobra.Command) { + // We can't use the -a shortcut here, because it is already used for --all + cmd.Flags().String("architecture", string(hcloud.ArchitectureX86), "architecture of the image, default is x86") + _ = cmd.RegisterFlagCompletionFunc("architecture", cmpl.SuggestCandidates(string(hcloud.ArchitectureX86), string(hcloud.ArchitectureARM))) + }, + FetchLabels: func(s state.State, cmd *cobra.Command, idOrName string) (map[string]string, int64, error) { + arch, err := cmd.Flags().GetString("architecture") + if err != nil { + return nil, 0, err + } + if !cmd.Flags().Changed("architecture") { + _, _ = fmt.Fprintln(os.Stderr, "INFO: This command only returns x86 images by default. Explicitly set the --architecture=x86|arm flag to hide this message.") + } + image, _, err := s.Client().Image().GetForArchitecture(s, idOrName, hcloud.Architecture(arch)) if err != nil { return nil, 0, err } diff --git a/internal/cmd/image/update.go b/internal/cmd/image/update.go index 75e2562f..ea5facde 100644 --- a/internal/cmd/image/update.go +++ b/internal/cmd/image/update.go @@ -1,6 +1,9 @@ package image import ( + "fmt" + "os" + "github.com/spf13/cobra" "github.com/spf13/pflag" @@ -15,13 +18,23 @@ var UpdateCmd = base.UpdateCmd{ ResourceNameSingular: "Image", ShortDescription: "Update an image", NameSuggestions: func(c hcapi2.Client) func() []string { return c.Image().Names }, - Fetch: func(s state.State, cmd *cobra.Command, idOrName string) (interface{}, *hcloud.Response, error) { - return s.Client().Image().Get(s, idOrName) - }, DefineFlags: func(cmd *cobra.Command) { cmd.Flags().String("description", "", "Image description") cmd.Flags().String("type", "", "Image type") cmd.RegisterFlagCompletionFunc("type", cmpl.SuggestCandidates("snapshot")) + + cmd.Flags().StringP("architecture", "a", string(hcloud.ArchitectureX86), "architecture of the image, default is x86") + _ = cmd.RegisterFlagCompletionFunc("architecture", cmpl.SuggestCandidates(string(hcloud.ArchitectureX86), string(hcloud.ArchitectureARM))) + }, + Fetch: func(s state.State, cmd *cobra.Command, idOrName string) (interface{}, *hcloud.Response, error) { + arch, err := cmd.Flags().GetString("architecture") + if err != nil { + return nil, nil, err + } + if !cmd.Flags().Changed("architecture") { + _, _ = fmt.Fprintln(os.Stderr, "INFO: This command only returns x86 images by default. Explicitly set the --architecture=x86|arm flag to hide this message.") + } + return s.Client().Image().GetForArchitecture(s, idOrName, hcloud.Architecture(arch)) }, Update: func(s state.State, cmd *cobra.Command, resource interface{}, flags map[string]pflag.Value) error { image := resource.(*hcloud.Image) diff --git a/internal/cmd/loadbalancer/labels.go b/internal/cmd/loadbalancer/labels.go index c7c19d74..e21b19b0 100644 --- a/internal/cmd/loadbalancer/labels.go +++ b/internal/cmd/loadbalancer/labels.go @@ -3,6 +3,8 @@ package loadbalancer import ( "fmt" + "github.com/spf13/cobra" + "github.com/hetznercloud/cli/internal/cmd/base" "github.com/hetznercloud/cli/internal/hcapi2" "github.com/hetznercloud/cli/internal/state" @@ -15,7 +17,7 @@ var LabelCmds = base.LabelCmds{ ShortDescriptionRemove: "Remove a label from a Load Balancer", NameSuggestions: func(c hcapi2.Client) func() []string { return c.LoadBalancer().Names }, LabelKeySuggestions: func(c hcapi2.Client) func(idOrName string) []string { return c.LoadBalancer().LabelKeys }, - FetchLabels: func(s state.State, idOrName string) (map[string]string, int64, error) { + FetchLabels: func(s state.State, _ *cobra.Command, idOrName string) (map[string]string, int64, error) { loadBalancer, _, err := s.Client().LoadBalancer().Get(s, idOrName) if err != nil { return nil, 0, err diff --git a/internal/cmd/network/labels.go b/internal/cmd/network/labels.go index 415d70ae..51e043b9 100644 --- a/internal/cmd/network/labels.go +++ b/internal/cmd/network/labels.go @@ -3,6 +3,8 @@ package network import ( "fmt" + "github.com/spf13/cobra" + "github.com/hetznercloud/cli/internal/cmd/base" "github.com/hetznercloud/cli/internal/hcapi2" "github.com/hetznercloud/cli/internal/state" @@ -15,7 +17,7 @@ var LabelCmds = base.LabelCmds{ ShortDescriptionRemove: "Remove a label from a Network", NameSuggestions: func(c hcapi2.Client) func() []string { return c.Network().Names }, LabelKeySuggestions: func(c hcapi2.Client) func(idOrName string) []string { return c.Network().LabelKeys }, - FetchLabels: func(s state.State, idOrName string) (map[string]string, int64, error) { + FetchLabels: func(s state.State, _ *cobra.Command, idOrName string) (map[string]string, int64, error) { network, _, err := s.Client().Network().Get(s, idOrName) if err != nil { return nil, 0, err diff --git a/internal/cmd/placementgroup/labels.go b/internal/cmd/placementgroup/labels.go index fc6dfe2a..63bc2daf 100644 --- a/internal/cmd/placementgroup/labels.go +++ b/internal/cmd/placementgroup/labels.go @@ -3,6 +3,8 @@ package placementgroup import ( "fmt" + "github.com/spf13/cobra" + "github.com/hetznercloud/cli/internal/cmd/base" "github.com/hetznercloud/cli/internal/hcapi2" "github.com/hetznercloud/cli/internal/state" @@ -15,7 +17,7 @@ var LabelCmds = base.LabelCmds{ ShortDescriptionRemove: "Remove a label from a placement group", NameSuggestions: func(c hcapi2.Client) func() []string { return c.PlacementGroup().Names }, LabelKeySuggestions: func(c hcapi2.Client) func(idOrName string) []string { return c.PlacementGroup().LabelKeys }, - FetchLabels: func(s state.State, idOrName string) (map[string]string, int64, error) { + FetchLabels: func(s state.State, _ *cobra.Command, idOrName string) (map[string]string, int64, error) { placementGroup, _, err := s.Client().PlacementGroup().Get(s, idOrName) if err != nil { return nil, 0, err diff --git a/internal/cmd/primaryip/labels.go b/internal/cmd/primaryip/labels.go index 5a84f92d..44cf582a 100644 --- a/internal/cmd/primaryip/labels.go +++ b/internal/cmd/primaryip/labels.go @@ -3,6 +3,8 @@ package primaryip import ( "fmt" + "github.com/spf13/cobra" + "github.com/hetznercloud/cli/internal/cmd/base" "github.com/hetznercloud/cli/internal/hcapi2" "github.com/hetznercloud/cli/internal/state" @@ -15,7 +17,7 @@ var LabelCmds = base.LabelCmds{ ShortDescriptionRemove: "Remove a label from a Primary IP", NameSuggestions: func(c hcapi2.Client) func() []string { return c.PrimaryIP().Names }, LabelKeySuggestions: func(c hcapi2.Client) func(idOrName string) []string { return c.PrimaryIP().LabelKeys }, - FetchLabels: func(s state.State, idOrName string) (map[string]string, int64, error) { + FetchLabels: func(s state.State, _ *cobra.Command, idOrName string) (map[string]string, int64, error) { primaryIP, _, err := s.Client().PrimaryIP().Get(s, idOrName) if err != nil { return nil, 0, err diff --git a/internal/cmd/server/labels.go b/internal/cmd/server/labels.go index ecb5ede0..16b71e83 100644 --- a/internal/cmd/server/labels.go +++ b/internal/cmd/server/labels.go @@ -3,6 +3,8 @@ package server import ( "fmt" + "github.com/spf13/cobra" + "github.com/hetznercloud/cli/internal/cmd/base" "github.com/hetznercloud/cli/internal/hcapi2" state "github.com/hetznercloud/cli/internal/state" @@ -15,7 +17,7 @@ var LabelCmds = base.LabelCmds{ ShortDescriptionRemove: "Remove a label from a server", NameSuggestions: func(c hcapi2.Client) func() []string { return c.Server().Names }, LabelKeySuggestions: func(c hcapi2.Client) func(idOrName string) []string { return c.Server().LabelKeys }, - FetchLabels: func(s state.State, idOrName string) (map[string]string, int64, error) { + FetchLabels: func(s state.State, _ *cobra.Command, idOrName string) (map[string]string, int64, error) { server, _, err := s.Client().Server().Get(s, idOrName) if err != nil { return nil, 0, err diff --git a/internal/cmd/sshkey/labels.go b/internal/cmd/sshkey/labels.go index 3bfaf396..9b1f917a 100644 --- a/internal/cmd/sshkey/labels.go +++ b/internal/cmd/sshkey/labels.go @@ -3,6 +3,8 @@ package sshkey import ( "fmt" + "github.com/spf13/cobra" + "github.com/hetznercloud/cli/internal/cmd/base" "github.com/hetznercloud/cli/internal/hcapi2" "github.com/hetznercloud/cli/internal/state" @@ -15,7 +17,7 @@ var LabelCmds = base.LabelCmds{ ShortDescriptionRemove: "Remove a label from a SSH Key", NameSuggestions: func(c hcapi2.Client) func() []string { return c.SSHKey().Names }, LabelKeySuggestions: func(c hcapi2.Client) func(idOrName string) []string { return c.SSHKey().LabelKeys }, - FetchLabels: func(s state.State, idOrName string) (map[string]string, int64, error) { + FetchLabels: func(s state.State, _ *cobra.Command, idOrName string) (map[string]string, int64, error) { sshKey, _, err := s.Client().SSHKey().Get(s, idOrName) if err != nil { return nil, 0, err diff --git a/internal/cmd/volume/labels.go b/internal/cmd/volume/labels.go index 57a8d972..aa5e6eff 100644 --- a/internal/cmd/volume/labels.go +++ b/internal/cmd/volume/labels.go @@ -3,6 +3,8 @@ package volume import ( "fmt" + "github.com/spf13/cobra" + "github.com/hetznercloud/cli/internal/cmd/base" "github.com/hetznercloud/cli/internal/hcapi2" "github.com/hetznercloud/cli/internal/state" @@ -15,7 +17,7 @@ var LabelCmds = base.LabelCmds{ ShortDescriptionRemove: "Remove a label from a Volume", NameSuggestions: func(c hcapi2.Client) func() []string { return c.Volume().Names }, LabelKeySuggestions: func(c hcapi2.Client) func(idOrName string) []string { return c.Volume().LabelKeys }, - FetchLabels: func(s state.State, idOrName string) (map[string]string, int64, error) { + FetchLabels: func(s state.State, _ *cobra.Command, idOrName string) (map[string]string, int64, error) { volume, _, err := s.Client().Volume().Get(s, idOrName) if err != nil { return nil, 0, err