Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support strong-typing for --target values #16978

Merged
merged 1 commit into from
Jan 19, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions cmd/kops/create_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,11 @@ import (

type CreateClusterOptions struct {
cloudup.NewClusterOptions
Yes bool
Target string
Yes bool

// Target is the type of target we will operate against (direct, dry-run, terraform)
Target cloudup.Target

ControlPlaneVolumeSize int32
NodeVolumeSize int32
ContainerRuntime string
Expand Down Expand Up @@ -203,7 +206,7 @@ func NewCmdCreateCluster(f *util.Factory, out io.Writer) *cobra.Command {
}

cmd.Flags().BoolVarP(&options.Yes, "yes", "y", options.Yes, "Specify --yes to immediately create the cluster")
cmd.Flags().StringVar(&options.Target, "target", options.Target, fmt.Sprintf("Valid targets: %s, %s. Set this flag to %s if you want kOps to generate terraform", cloudup.TargetDirect, cloudup.TargetTerraform, cloudup.TargetTerraform))
cmd.Flags().Var(&options.Target, "target", fmt.Sprintf("Valid targets: %q, %q. Set this flag to %q if you want kOps to generate terraform", cloudup.TargetDirect, cloudup.TargetTerraform, cloudup.TargetTerraform))
cmd.RegisterFlagCompletionFunc("target", completeCreateClusterTarget(options))

// Configuration / state location
Expand Down Expand Up @@ -1010,7 +1013,7 @@ func completeNetworking(options *CreateClusterOptions) func(cmd *cobra.Command,

func completeCreateClusterTarget(options *CreateClusterOptions) func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
completions := []string{
completions := []cloudup.Target{
cloudup.TargetDirect,
cloudup.TargetDryRun,
}
Expand All @@ -1019,7 +1022,7 @@ func completeCreateClusterTarget(options *CreateClusterOptions) func(cmd *cobra.
completions = append(completions, cloudup.TargetTerraform)
}
}
return completions, cobra.ShellCompDirectiveNoFileComp
return toStringSlice(completions), cobra.ShellCompDirectiveNoFileComp
}
}

Expand Down
27 changes: 19 additions & 8 deletions cmd/kops/update_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,11 @@ type UpdateClusterOptions struct {
// which are shared with the reconcile cluster command.
// The fields _not_ shared with the reconcile cluster command are the ones in CreateKubecfgOptions.
type CoreUpdateClusterOptions struct {
Yes bool
Target string
Yes bool

// Target is the type of target we will operate against (direct, dry-run, terraform)
Target cloudup.Target

OutDir string
SSHPublicKey string
RunTasksOptions fi.RunTasksOptions
Expand Down Expand Up @@ -123,7 +126,7 @@ func (o *UpdateClusterOptions) InitDefaults() {

func (o *CoreUpdateClusterOptions) InitDefaults() {
o.Yes = false
o.Target = "direct"
o.Target = cloudup.TargetDirect
o.SSHPublicKey = ""
o.OutDir = ""
// By default we enforce the version skew between control plane and worker nodes
Expand Down Expand Up @@ -157,7 +160,7 @@ func NewCmdUpdateCluster(f *util.Factory, out io.Writer) *cobra.Command {
}

cmd.Flags().BoolVarP(&options.Yes, "yes", "y", options.Yes, "Create cloud resources, without --yes update is in dry run mode")
cmd.Flags().StringVar(&options.Target, "target", options.Target, "Target - direct, terraform")
cmd.Flags().Var(&options.Target, "target", fmt.Sprintf("Target - %q, %q", cloudup.TargetDirect, cloudup.TargetTerraform))
cmd.RegisterFlagCompletionFunc("target", completeUpdateClusterTarget(f, &options.CoreUpdateClusterOptions))
cmd.Flags().StringVar(&options.SSHPublicKey, "ssh-public-key", options.SSHPublicKey, "SSH public key to use (deprecated: use kops create secret instead)")
cmd.Flags().StringVar(&options.OutDir, "out", options.OutDir, "Path to write any local output")
Expand Down Expand Up @@ -552,14 +555,14 @@ func completeUpdateClusterTarget(f commandutils.Factory, options *CoreUpdateClus

cluster, _, _, directive := GetClusterForCompletion(ctx, f, nil)
if cluster == nil {
return []string{
return toStringSlice([]cloudup.Target{
cloudup.TargetDirect,
cloudup.TargetDryRun,
cloudup.TargetTerraform,
}, directive
}), directive
}

completions := []string{
completions := []cloudup.Target{
cloudup.TargetDirect,
cloudup.TargetDryRun,
}
Expand All @@ -568,8 +571,16 @@ func completeUpdateClusterTarget(f commandutils.Factory, options *CoreUpdateClus
completions = append(completions, cloudup.TargetTerraform)
}
}
return completions, cobra.ShellCompDirectiveNoFileComp
return toStringSlice(completions), cobra.ShellCompDirectiveNoFileComp
}
}

func toStringSlice[T ~string](targets []T) []string {
strings := make([]string, len(targets))
for i, target := range targets {
strings[i] = string(target)
}
return strings
}

func completeLifecycleOverrides(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
Expand Down
2 changes: 1 addition & 1 deletion docs/cli/kops_create_cluster.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion docs/cli/kops_update_cluster.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion upup/pkg/fi/cloudup/apply_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ type ApplyClusterCmd struct {
InstanceGroups []*kops.InstanceGroup

// TargetName specifies how we are operating e.g. direct to GCE, or AWS, or dry-run, or terraform
TargetName string
TargetName Target

// Target is the fi.Target we will operate against
Target fi.CloudupTarget
Expand Down
40 changes: 37 additions & 3 deletions upup/pkg/fi/cloudup/target.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,42 @@ limitations under the License.

package cloudup

import (
"fmt"
"strings"

"github.com/spf13/pflag"
)

// Target is the type of target we are operating against.
type Target string

const (
TargetDirect = "direct"
TargetDryRun = "dryrun"
TargetTerraform = "terraform"
// TargetDirect means we will apply the changes directly to the cloud.
TargetDirect Target = "direct"
// TargetDryRun means we will not apply the changes but will print what would have been done.
TargetDryRun Target = "dryrun"
// TargetTerraform means we will generate terraform code.
TargetTerraform Target = "terraform"
)

// Target can be used as a flag value.
var _ pflag.Value = (*Target)(nil)

func (t *Target) String() string {
return string(*t)
}

func (t *Target) Set(value string) error {
switch strings.ToLower(value) {
case string(TargetDirect), string(TargetDryRun), string(TargetTerraform):
*t = Target(value)
return nil
default:
return fmt.Errorf("invalid target: %q", value)
}
}

func (t *Target) Type() string {
return "target"
}
Loading