Skip to content

Commit f925e9e

Browse files
authored
Merge pull request #16978 from justinsb/strong_type_target
Support strong-typing for --target values
2 parents bd2a42c + 284b15b commit f925e9e

File tree

6 files changed

+67
-19
lines changed

6 files changed

+67
-19
lines changed

cmd/kops/create_cluster.go

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,11 @@ import (
6161

6262
type CreateClusterOptions struct {
6363
cloudup.NewClusterOptions
64-
Yes bool
65-
Target string
64+
Yes bool
65+
66+
// Target is the type of target we will operate against (direct, dry-run, terraform)
67+
Target cloudup.Target
68+
6669
ControlPlaneVolumeSize int32
6770
NodeVolumeSize int32
6871
ContainerRuntime string
@@ -203,7 +206,7 @@ func NewCmdCreateCluster(f *util.Factory, out io.Writer) *cobra.Command {
203206
}
204207

205208
cmd.Flags().BoolVarP(&options.Yes, "yes", "y", options.Yes, "Specify --yes to immediately create the cluster")
206-
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))
209+
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))
207210
cmd.RegisterFlagCompletionFunc("target", completeCreateClusterTarget(options))
208211

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

10111014
func completeCreateClusterTarget(options *CreateClusterOptions) func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
10121015
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
1013-
completions := []string{
1016+
completions := []cloudup.Target{
10141017
cloudup.TargetDirect,
10151018
cloudup.TargetDryRun,
10161019
}
@@ -1019,7 +1022,7 @@ func completeCreateClusterTarget(options *CreateClusterOptions) func(cmd *cobra.
10191022
completions = append(completions, cloudup.TargetTerraform)
10201023
}
10211024
}
1022-
return completions, cobra.ShellCompDirectiveNoFileComp
1025+
return toStringSlice(completions), cobra.ShellCompDirectiveNoFileComp
10231026
}
10241027
}
10251028

cmd/kops/update_cluster.go

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,11 @@ type UpdateClusterOptions struct {
7676
// which are shared with the reconcile cluster command.
7777
// The fields _not_ shared with the reconcile cluster command are the ones in CreateKubecfgOptions.
7878
type CoreUpdateClusterOptions struct {
79-
Yes bool
80-
Target string
79+
Yes bool
80+
81+
// Target is the type of target we will operate against (direct, dry-run, terraform)
82+
Target cloudup.Target
83+
8184
OutDir string
8285
SSHPublicKey string
8386
RunTasksOptions fi.RunTasksOptions
@@ -123,7 +126,7 @@ func (o *UpdateClusterOptions) InitDefaults() {
123126

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

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

553556
cluster, _, _, directive := GetClusterForCompletion(ctx, f, nil)
554557
if cluster == nil {
555-
return []string{
558+
return toStringSlice([]cloudup.Target{
556559
cloudup.TargetDirect,
557560
cloudup.TargetDryRun,
558561
cloudup.TargetTerraform,
559-
}, directive
562+
}), directive
560563
}
561564

562-
completions := []string{
565+
completions := []cloudup.Target{
563566
cloudup.TargetDirect,
564567
cloudup.TargetDryRun,
565568
}
@@ -568,8 +571,16 @@ func completeUpdateClusterTarget(f commandutils.Factory, options *CoreUpdateClus
568571
completions = append(completions, cloudup.TargetTerraform)
569572
}
570573
}
571-
return completions, cobra.ShellCompDirectiveNoFileComp
574+
return toStringSlice(completions), cobra.ShellCompDirectiveNoFileComp
575+
}
576+
}
577+
578+
func toStringSlice[T ~string](targets []T) []string {
579+
strings := make([]string, len(targets))
580+
for i, target := range targets {
581+
strings[i] = string(target)
572582
}
583+
return strings
573584
}
574585

575586
func completeLifecycleOverrides(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {

docs/cli/kops_create_cluster.md

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/cli/kops_update_cluster.md

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

upup/pkg/fi/cloudup/apply_cluster.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ type ApplyClusterCmd struct {
9393
InstanceGroups []*kops.InstanceGroup
9494

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

9898
// Target is the fi.Target we will operate against
9999
Target fi.CloudupTarget

upup/pkg/fi/cloudup/target.go

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,42 @@ limitations under the License.
1616

1717
package cloudup
1818

19+
import (
20+
"fmt"
21+
"strings"
22+
23+
"github.com/spf13/pflag"
24+
)
25+
26+
// Target is the type of target we are operating against.
27+
type Target string
28+
1929
const (
20-
TargetDirect = "direct"
21-
TargetDryRun = "dryrun"
22-
TargetTerraform = "terraform"
30+
// TargetDirect means we will apply the changes directly to the cloud.
31+
TargetDirect Target = "direct"
32+
// TargetDryRun means we will not apply the changes but will print what would have been done.
33+
TargetDryRun Target = "dryrun"
34+
// TargetTerraform means we will generate terraform code.
35+
TargetTerraform Target = "terraform"
2336
)
37+
38+
// Target can be used as a flag value.
39+
var _ pflag.Value = (*Target)(nil)
40+
41+
func (t *Target) String() string {
42+
return string(*t)
43+
}
44+
45+
func (t *Target) Set(value string) error {
46+
switch strings.ToLower(value) {
47+
case string(TargetDirect), string(TargetDryRun), string(TargetTerraform):
48+
*t = Target(value)
49+
return nil
50+
default:
51+
return fmt.Errorf("invalid target: %q", value)
52+
}
53+
}
54+
55+
func (t *Target) Type() string {
56+
return "target"
57+
}

0 commit comments

Comments
 (0)