diff --git a/cmd/vclusterctl/cmd/connect.go b/cmd/vclusterctl/cmd/connect.go index f894121368..2a36f496f2 100644 --- a/cmd/vclusterctl/cmd/connect.go +++ b/cmd/vclusterctl/cmd/connect.go @@ -6,6 +6,7 @@ import ( "fmt" "io" "os" + "strings" "github.com/sirupsen/logrus" @@ -25,15 +26,11 @@ type ConnectCmd struct { Log log.Logger *flags.GlobalFlags cli.ConnectOptions + CobraCmd *cobra.Command } // NewConnectCmd creates a new command func NewConnectCmd(globalFlags *flags.GlobalFlags) *cobra.Command { - cmd := &ConnectCmd{ - GlobalFlags: globalFlags, - Log: log.GetInstance(), - } - useLine, nameValidator := util.NamedPositionalArgsValidator(true, false, "VCLUSTER_NAME") cobraCmd := &cobra.Command{ @@ -53,12 +50,19 @@ vcluster connect test -n test -- kubectl get ns `, Args: nameValidator, ValidArgsFunction: completion.NewValidVClusterNameFunc(globalFlags), - RunE: func(cobraCmd *cobra.Command, args []string) error { - // Check for newer version - upgrade.PrintNewerVersionWarning() + } + + cmd := &ConnectCmd{ + GlobalFlags: globalFlags, + Log: log.GetInstance(), + CobraCmd: cobraCmd, + } + + cobraCmd.RunE = func(_ *cobra.Command, args []string) error { + // Check for newer version + upgrade.PrintNewerVersionWarning() - return cmd.Run(cobraCmd.Context(), args) - }, + return cmd.Run(cobraCmd.Context(), args) } cobraCmd.Flags().StringVar(&cmd.Driver, "driver", "", "The driver to use for managing the virtual cluster, can be either helm or platform.") @@ -95,6 +99,19 @@ func (cmd *ConnectCmd) Run(ctx context.Context, args []string) error { return cli.ConnectPlatform(ctx, &cmd.ConnectOptions, cmd.GlobalFlags, vClusterName, args[1:], cmd.Log) } + // warn if platform flags have been set when using driver helm + var fs []string + pfs := connect.ChangedPlatformFlags(cmd.CobraCmd) + for pf, changed := range pfs { + if changed { + fs = append(fs, pf) + } + } + + if len(fs) > 0 { + cmd.Log.Warnf("Following platform flags have been set, which won't have any effect when using driver type %s: %s", config.HelmDriver, strings.Join(fs, ", ")) + } + return cli.ConnectHelm(ctx, &cmd.ConnectOptions, cmd.GlobalFlags, vClusterName, args[1:], cmd.Log) } diff --git a/cmd/vclusterctl/cmd/create.go b/cmd/vclusterctl/cmd/create.go index bd9f2b90e2..eba95b5e01 100644 --- a/cmd/vclusterctl/cmd/create.go +++ b/cmd/vclusterctl/cmd/create.go @@ -2,9 +2,9 @@ package cmd import ( "cmp" - "context" "errors" "fmt" + "strings" "github.com/loft-sh/log" "github.com/loft-sh/vcluster/pkg/cli" @@ -60,7 +60,7 @@ vcluster create test --namespace test // Check for newer version upgrade.PrintNewerVersionWarning() - return cmd.Run(cobraCmd.Context(), newArgs) + return cmd.Run(cobraCmd, newArgs) }, } @@ -74,7 +74,7 @@ vcluster create test --namespace test } // Run executes the functionality -func (cmd *CreateCmd) Run(ctx context.Context, args []string) error { +func (cmd *CreateCmd) Run(cobraCmd *cobra.Command, args []string) error { if !cmd.UpdateCurrent { cmd.log.Warnf("%q has no effect anymore. Please consider using %q", "--update-current=false", "--connect=false") } @@ -87,6 +87,8 @@ func (cmd *CreateCmd) Run(ctx context.Context, args []string) error { return fmt.Errorf("parse driver type: %w", err) } + ctx := cobraCmd.Context() + // check if there is a platform client or we skip the info message _, err = platform.InitClientFromConfig(ctx, cfg) if err == nil { @@ -97,5 +99,19 @@ func (cmd *CreateCmd) Run(ctx context.Context, args []string) error { if driver == config.PlatformDriver { return cli.CreatePlatform(ctx, &cmd.CreateOptions, cmd.GlobalFlags, args[0], cmd.log) } + + // warn if platform flags have been set when using driver helm + var fs []string + pfs := create.ChangedPlatformFlags(cobraCmd) + for pf, changed := range pfs { + if changed { + fs = append(fs, pf) + } + } + + if len(fs) > 0 { + cmd.log.Warnf("Following platform flags have been set, which won't have any effect when using driver type %s: %s", config.HelmDriver, strings.Join(fs, ", ")) + } + return cli.CreateHelm(ctx, &cmd.CreateOptions, cmd.GlobalFlags, args[0], cmd.log) } diff --git a/cmd/vclusterctl/cmd/delete.go b/cmd/vclusterctl/cmd/delete.go index 5faf7f5357..7903e8bc50 100644 --- a/cmd/vclusterctl/cmd/delete.go +++ b/cmd/vclusterctl/cmd/delete.go @@ -2,8 +2,8 @@ package cmd import ( "cmp" - "context" "fmt" + "strings" "github.com/loft-sh/log" "github.com/loft-sh/vcluster/pkg/cli" @@ -47,7 +47,7 @@ vcluster delete test --namespace test Aliases: []string{"rm"}, ValidArgsFunction: completion.NewValidVClusterNameFunc(globalFlags), RunE: func(cobraCmd *cobra.Command, args []string) error { - return cmd.Run(cobraCmd.Context(), args) + return cmd.Run(cobraCmd, args) }, } @@ -61,7 +61,7 @@ vcluster delete test --namespace test } // Run executes the functionality -func (cmd *DeleteCmd) Run(ctx context.Context, args []string) error { +func (cmd *DeleteCmd) Run(cobraCmd *cobra.Command, args []string) error { cfg := cmd.LoadedConfig(cmd.log) // If driver has been passed as flag use it, otherwise read it from the config file @@ -70,6 +70,8 @@ func (cmd *DeleteCmd) Run(ctx context.Context, args []string) error { return fmt.Errorf("parse driver type: %w", err) } + ctx := cobraCmd.Context() + // check if there is a platform client or we skip the info message platformClient, err := platform.InitClientFromConfig(ctx, cfg) if err == nil { @@ -80,5 +82,18 @@ func (cmd *DeleteCmd) Run(ctx context.Context, args []string) error { return cli.DeletePlatform(ctx, platformClient, &cmd.DeleteOptions, args[0], cmd.log) } + // warn if platform flags have been set when using driver helm + var fs []string + pfs := flagsdelete.ChangedPlatformFlags(cobraCmd) + for pf, changed := range pfs { + if changed { + fs = append(fs, pf) + } + } + + if len(fs) > 0 { + cmd.log.Warnf("Following platform flags have been set, which won't have any effect when using driver type %s: %s", config.HelmDriver, strings.Join(fs, ", ")) + } + return cli.DeleteHelm(ctx, platformClient, &cmd.DeleteOptions, cmd.GlobalFlags, args[0], cmd.log) } diff --git a/pkg/cli/flags/connect/connect.go b/pkg/cli/flags/connect/connect.go index 2a1aed0e29..3ddc7c5323 100644 --- a/pkg/cli/flags/connect/connect.go +++ b/pkg/cli/flags/connect/connect.go @@ -5,9 +5,14 @@ import ( "strings" "github.com/loft-sh/vcluster/pkg/cli" + "github.com/loft-sh/vcluster/pkg/cli/flags" "github.com/spf13/cobra" ) +const FlagNameProject = "project" + +var platformFlags = []string{FlagNameProject} + func AddCommonFlags(cmd *cobra.Command, options *cli.ConnectOptions) { cmd.Flags().StringVar(&options.KubeConfigContextName, "kube-config-context-name", "", "If set, will override the context name of the generated virtual cluster kube config with this name") cmd.Flags().StringVar(&options.KubeConfig, "kube-config", "./kubeconfig.yaml", "Writes the created kube config to this file") @@ -32,5 +37,9 @@ func AddCommonFlags(cmd *cobra.Command, options *cli.ConnectOptions) { func AddPlatformFlags(cmd *cobra.Command, options *cli.ConnectOptions, prefixes ...string) { prefix := strings.Join(prefixes, "") - cmd.Flags().StringVar(&options.Project, "project", "", fmt.Sprintf("%sThe platform project the vCluster is in", prefix)) + cmd.Flags().StringVar(&options.Project, FlagNameProject, "", fmt.Sprintf("%sThe platform project the vCluster is in", prefix)) +} + +func ChangedPlatformFlags(cmd *cobra.Command) map[string]bool { + return flags.ChangedFlags(cmd, platformFlags) } diff --git a/pkg/cli/flags/create/create.go b/pkg/cli/flags/create/create.go index 90b3ed8ad2..d9758979a6 100644 --- a/pkg/cli/flags/create/create.go +++ b/pkg/cli/flags/create/create.go @@ -5,11 +5,37 @@ import ( "strings" "github.com/loft-sh/vcluster/pkg/cli" + "github.com/loft-sh/vcluster/pkg/cli/flags" "github.com/loft-sh/vcluster/pkg/constants" "github.com/loft-sh/vcluster/pkg/upgrade" "github.com/spf13/cobra" ) +const ( + FlagNameProject = "project" + FlagNameLabels = "labels" + FlagNameAnnotation = "annotations" + FlagNameCluster = "cluster" + FlagNameTemplate = "template" + FlagNameTemplateVersion = "template-version" + FlagNameLinks = "link" + FlagNameParams = "params" + FlagNameParameters = "parameters" + FlagNameSetParams = "set-params" + FlagNameSetParameters = "set-parameters" + FlagNameDescription = "description" + FlagNameDisplayName = "display-name" + FlagNameTeam = "team" + FlagNameUser = "user" + FlagNameUseExisting = "use" + FlagNameRecreate = "recreate" + FlagNameSkipWait = "skip-wait" +) + +var platformFlags = []string{FlagNameProject, FlagNameLabels, FlagNameAnnotation, FlagNameCluster, FlagNameTemplate, FlagNameTemplateVersion, FlagNameLinks, FlagNameParams, + FlagNameParameters, FlagNameSetParams, FlagNameSetParameters, FlagNameDescription, FlagNameDisplayName, FlagNameTeam, FlagNameUser, FlagNameUseExisting, FlagNameRecreate, FlagNameSkipWait, +} + func AddCommonFlags(cmd *cobra.Command, options *cli.CreateOptions) { cmd.Flags().StringVar(&options.KubeConfigContextName, "kube-config-context-name", "", "If set, will override the context name of the generated virtual cluster kube config with this name") cmd.Flags().StringVar(&options.ChartVersion, "chart-version", upgrade.GetVersion(), "The virtual cluster chart version to use (e.g. v0.9.1)") @@ -45,22 +71,26 @@ func AddHelmFlags(cmd *cobra.Command, options *cli.CreateOptions) { func AddPlatformFlags(cmd *cobra.Command, options *cli.CreateOptions, prefixes ...string) { prefix := strings.Join(prefixes, "") - cmd.Flags().StringVar(&options.Project, "project", "", fmt.Sprintf("%sThe vCluster platform project to use", prefix)) - cmd.Flags().StringSliceVarP(&options.Labels, "labels", "l", []string{}, fmt.Sprintf("%sComma separated labels to apply to the virtualclusterinstance", prefix)) - cmd.Flags().StringSliceVar(&options.Annotations, "annotations", []string{}, fmt.Sprintf("%sComma separated annotations to apply to the virtualclusterinstance", prefix)) - cmd.Flags().StringVar(&options.Cluster, "cluster", "", fmt.Sprintf("%sThe vCluster platform connected cluster to use", prefix)) - cmd.Flags().StringVar(&options.Template, "template", "", fmt.Sprintf("%sThe vCluster platform template to use", prefix)) - cmd.Flags().StringVar(&options.TemplateVersion, "template-version", "", fmt.Sprintf("%sThe vCluster platform template version to use", prefix)) - cmd.Flags().StringArrayVar(&options.Links, "link", []string{}, fmt.Sprintf("%sA link to add to the vCluster. E.g. --link 'prod=http://exampleprod.com'", prefix)) - cmd.Flags().StringVar(&options.Params, "params", "", fmt.Sprintf("%sIf a template is used, this can be used to use a file for the parameters. E.g. --params path/to/my/file.yaml", prefix)) - cmd.Flags().StringVar(&options.Params, "parameters", "", fmt.Sprintf("%sIf a template is used, this can be used to use a file for the parameters. E.g. --parameters path/to/my/file.yaml", prefix)) - cmd.Flags().StringArrayVar(&options.SetParams, "set-param", []string{}, fmt.Sprintf("%sIf a template is used, this can be used to set a specific parameter. E.g. --set-param 'my-param=my-value'", prefix)) - cmd.Flags().StringArrayVar(&options.SetParams, "set-parameter", []string{}, fmt.Sprintf("%sIf a template is used, this can be used to set a specific parameter. E.g. --set-parameter 'my-param=my-value'", prefix)) - cmd.Flags().StringVar(&options.Description, "description", "", fmt.Sprintf("%sThe description to show in the platform UI for this virtual cluster", prefix)) - cmd.Flags().StringVar(&options.DisplayName, "display-name", "", fmt.Sprintf("%sThe display name to show in the platform UI for this virtual cluster", prefix)) - cmd.Flags().StringVar(&options.Team, "team", "", fmt.Sprintf("%sThe team to create the space for", prefix)) - cmd.Flags().StringVar(&options.User, "user", "", fmt.Sprintf("%sThe user to create the space for", prefix)) - cmd.Flags().BoolVar(&options.UseExisting, "use", false, fmt.Sprintf("%sIf the platform should use the virtual cluster if its already there", prefix)) - cmd.Flags().BoolVar(&options.Recreate, "recreate", false, fmt.Sprintf("%sIf enabled and there already exists a virtual cluster with this name, it will be deleted first", prefix)) - cmd.Flags().BoolVar(&options.SkipWait, "skip-wait", false, fmt.Sprintf("%sIf true, will not wait until the virtual cluster is running", prefix)) + cmd.Flags().StringVar(&options.Project, FlagNameProject, "", fmt.Sprintf("%sThe vCluster platform project to use", prefix)) + cmd.Flags().StringSliceVarP(&options.Labels, FlagNameLabels, "l", []string{}, fmt.Sprintf("%sComma separated labels to apply to the virtualclusterinstance", prefix)) + cmd.Flags().StringSliceVar(&options.Annotations, FlagNameAnnotation, []string{}, fmt.Sprintf("%sComma separated annotations to apply to the virtualclusterinstance", prefix)) + cmd.Flags().StringVar(&options.Cluster, FlagNameCluster, "", fmt.Sprintf("%sThe vCluster platform connected cluster to use", prefix)) + cmd.Flags().StringVar(&options.Template, FlagNameTemplate, "", fmt.Sprintf("%sThe vCluster platform template to use", prefix)) + cmd.Flags().StringVar(&options.TemplateVersion, FlagNameTemplateVersion, "", fmt.Sprintf("%sThe vCluster platform template version to use", prefix)) + cmd.Flags().StringArrayVar(&options.Links, FlagNameLinks, []string{}, fmt.Sprintf("%sA link to add to the vCluster. E.g. --link 'prod=http://exampleprod.com'", prefix)) + cmd.Flags().StringVar(&options.Params, FlagNameParams, "", fmt.Sprintf("%sIf a template is used, this can be used to use a file for the parameters. E.g. --params path/to/my/file.yaml", prefix)) + cmd.Flags().StringVar(&options.Params, FlagNameParameters, "", fmt.Sprintf("%sIf a template is used, this can be used to use a file for the parameters. E.g. --parameters path/to/my/file.yaml", prefix)) + cmd.Flags().StringArrayVar(&options.SetParams, FlagNameSetParams, []string{}, fmt.Sprintf("%sIf a template is used, this can be used to set a specific parameter. E.g. --set-param 'my-param=my-value'", prefix)) + cmd.Flags().StringArrayVar(&options.SetParams, FlagNameSetParameters, []string{}, fmt.Sprintf("%sIf a template is used, this can be used to set a specific parameter. E.g. --set-parameter 'my-param=my-value'", prefix)) + cmd.Flags().StringVar(&options.Description, FlagNameDescription, "", fmt.Sprintf("%sThe description to show in the platform UI for this virtual cluster", prefix)) + cmd.Flags().StringVar(&options.DisplayName, FlagNameDisplayName, "", fmt.Sprintf("%sThe display name to show in the platform UI for this virtual cluster", prefix)) + cmd.Flags().StringVar(&options.Team, FlagNameTeam, "", fmt.Sprintf("%sThe team to create the space for", prefix)) + cmd.Flags().StringVar(&options.User, FlagNameUser, "", fmt.Sprintf("%sThe user to create the space for", prefix)) + cmd.Flags().BoolVar(&options.UseExisting, FlagNameUseExisting, false, fmt.Sprintf("%sIf the platform should use the virtual cluster if its already there", prefix)) + cmd.Flags().BoolVar(&options.Recreate, FlagNameRecreate, false, fmt.Sprintf("%sIf enabled and there already exists a virtual cluster with this name, it will be deleted first", prefix)) + cmd.Flags().BoolVar(&options.SkipWait, FlagNameSkipWait, false, fmt.Sprintf("%sIf true, will not wait until the virtual cluster is running", prefix)) +} + +func ChangedPlatformFlags(cmd *cobra.Command) map[string]bool { + return flags.ChangedFlags(cmd, platformFlags) } diff --git a/pkg/cli/flags/delete/delete.go b/pkg/cli/flags/delete/delete.go index 5846798740..7bf9f6efe4 100644 --- a/pkg/cli/flags/delete/delete.go +++ b/pkg/cli/flags/delete/delete.go @@ -5,9 +5,14 @@ import ( "strings" "github.com/loft-sh/vcluster/pkg/cli" + "github.com/loft-sh/vcluster/pkg/cli/flags" "github.com/spf13/cobra" ) +const FlagNameProject = "project" + +var platformFlags = []string{FlagNameProject} + func AddCommonFlags(cmd *cobra.Command, options *cli.DeleteOptions) { cmd.Flags().BoolVar(&options.Wait, "wait", true, "If enabled, vcluster will wait until the vcluster is deleted") cmd.Flags().BoolVar(&options.DeleteContext, "delete-context", true, "If the corresponding kube context should be deleted if there is any") @@ -24,5 +29,9 @@ func AddHelmFlags(cmd *cobra.Command, options *cli.DeleteOptions) { func AddPlatformFlags(cmd *cobra.Command, options *cli.DeleteOptions, prefixes ...string) { prefix := strings.Join(prefixes, "") - cmd.Flags().StringVar(&options.Project, "project", "", fmt.Sprintf("%sThe vCluster platform project to use", prefix)) + cmd.Flags().StringVar(&options.Project, FlagNameProject, "", fmt.Sprintf("%sThe vCluster platform project to use", prefix)) +} + +func ChangedPlatformFlags(cmd *cobra.Command) map[string]bool { + return flags.ChangedFlags(cmd, platformFlags) } diff --git a/pkg/cli/flags/flags.go b/pkg/cli/flags/flags.go index 5c4c50b4c3..c279afde0c 100644 --- a/pkg/cli/flags/flags.go +++ b/pkg/cli/flags/flags.go @@ -1,9 +1,11 @@ package flags import ( + "fmt" + "github.com/loft-sh/log" "github.com/loft-sh/vcluster/pkg/cli/config" - + "github.com/spf13/cobra" flag "github.com/spf13/pflag" ) @@ -39,3 +41,20 @@ func SetGlobalFlags(flags *flag.FlagSet, log log.Logger) *GlobalFlags { return globalFlags } + +// ChangedFlags checks if the given flags have been changed and returns a map indicating the change. +func ChangedFlags(cmd *cobra.Command, flagNames []string) map[string]bool { + if cmd == nil { + return nil + } + + flags := make(map[string]bool) + + for _, f := range flagNames { + if cmd.Flags().Changed(f) { + flags[fmt.Sprintf("--%s", f)] = true + } + } + + return flags +} diff --git a/test/framework/framework.go b/test/framework/framework.go index 235206dae1..a789ca2663 100644 --- a/test/framework/framework.go +++ b/test/framework/framework.go @@ -14,6 +14,7 @@ import ( "github.com/loft-sh/vcluster/pkg/scheme" logutil "github.com/loft-sh/vcluster/pkg/util/log" "github.com/loft-sh/vcluster/pkg/util/translate" + "github.com/spf13/cobra" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/kubernetes" @@ -200,7 +201,8 @@ func (f *Framework) RefreshVirtualClient() error { // vKubeConfigFile removal is done in the Framework.Cleanup() which gets called in ginkgo's AfterSuite() connectCmd := cmd.ConnectCmd{ - Log: f.Log, + CobraCmd: &cobra.Command{}, + Log: f.Log, GlobalFlags: &flags.GlobalFlags{ Namespace: f.VClusterNamespace, Debug: true,