diff --git a/cmd/kube.go b/cmd/kube.go index d8a2c7ca..1f3646f8 100644 --- a/cmd/kube.go +++ b/cmd/kube.go @@ -15,6 +15,7 @@ import ( "github.com/outscale/octl/pkg/builder" "github.com/outscale/octl/pkg/config" "github.com/outscale/octl/pkg/debug" + "github.com/outscale/octl/pkg/flags" "github.com/outscale/octl/pkg/messages" "github.com/outscale/octl/pkg/preferences" "github.com/outscale/octl/pkg/runner" @@ -25,14 +26,15 @@ import ( // oksCmd represents the kubecommand var oksCmd = &cobra.Command{ - GroupID: "services", - Use: "kube", - Short: "OUTSCALE Kubernetes as a Service (OKS) management", - Aliases: []string{"oks"}, + GroupID: "services", + Use: "kube", + Short: "OUTSCALE Kubernetes as a Service (OKS) management", + Aliases: []string{"oks"}, + PersistentPreRunE: flagNamesToID, } var projectUseCmd = &cobra.Command{ - Use: "use [project_id_or_name]", + Use: "use [id_or_name]", Short: "Set a default project for cluster commands, reset it without args", Run: useProject, Args: cobra.MaximumNArgs(1), @@ -49,14 +51,20 @@ func init() { // Add --project flag to kube cluster commands clusterCmd, _ := lo.Find(oksCmd.Commands(), func(c *cobra.Command) bool { return c.Name() == "cluster" }) - clusterCmd.PersistentFlags().String("project", preferences.Preferences.Kube.DefaultProject, "project name") + clusterCmd.PersistentFlags().String("project", preferences.Preferences.Kube.DefaultProject, "Name or ID of project") + _ = flags.MarkAsNoForward(clusterCmd.PersistentFlags(), "project") + clusterCmd.PersistentPreRunE = clusterArgToID + clusterCreateCmd, _ := lo.Find(clusterCmd.Commands(), func(c *cobra.Command) bool { return c.Name() == "create" }) + _ = flags.SetDefault(clusterCreateCmd.Flags(), "project", preferences.Preferences.Kube.DefaultProject) // Remap to projectCmd, _ := lo.Find(oksCmd.Commands(), func(c *cobra.Command) bool { return c.Name() == "project" }) + projectCmd.PersistentPreRunE = projectArgToID projectClustersCmd, _ := lo.Find(projectCmd.Commands(), func(c *cobra.Command) bool { return c.Name() == "clusters" }) clusterListCmd, _ := lo.Find(clusterCmd.Commands(), func(c *cobra.Command) bool { return c.Name() == "list" }) runClusterListCmd := clusterListCmd.Run clusterListCmd.Run = func(cmd *cobra.Command, args []string) { + // remap flag to arg project, _ := cmd.Flags().GetString("project") if project != "" { cmd.Flag("project").Changed = false @@ -66,16 +74,8 @@ func init() { } } - // Project use + // cluster/project use projectCmd.AddCommand(projectUseCmd) - - // Add --project flag to kube api cluster commands - apiCmd, _ := lo.Find(oksCmd.Commands(), func(c *cobra.Command) bool { return c.Name() == "api" }) - lo.ForEach(apiCmd.Commands(), func(c *cobra.Command, _ int) { - if strings.HasSuffix(c.Name(), "Cluster") || c.Name() == "GetKubeconfig" { - c.Flags().String("project", preferences.Preferences.Kube.DefaultProject, "project name") - } - }) } func kube(cmd *cobra.Command, args []string) { @@ -83,8 +83,6 @@ func kube(cmd *cobra.Command, args []string) { p := loadProfile(cmd) cl, err := oks.NewClient(p, sdkOptions(cmd)...) if err == nil { - args = argNameToID(cmd, args, cl) - flagNameToID(cmd, cl) err = runner.Run[*oks.Client, *oks.ErrorResponse](cmd, args, cl, config.For("kube")) } if err != nil { @@ -92,43 +90,87 @@ func kube(cmd *cobra.Command, args []string) { } } -func argNameToID(cmd *cobra.Command, args []string, cl *oks.Client) []string { +func clusterArgToID(cmd *cobra.Command, args []string) error { + debug.Println("clusterArgToID") + p := loadProfile(cmd) + cl, err := oks.NewClient(p, sdkOptions(cmd)...) + if err != nil { + return err + } + if len(args) == 0 { debug.Println("no arg to replace") - return args + return nil } if _, err := uuid.Parse(args[0]); err == nil { debug.Println("arg is an uuid") - return args + return nil } - var err error - switch cmd.Name() { - case "GetProject", "DeleteProject", "GetProjectNets", "GetProjectQuotas", "GetProjectPublicIps", "GetProjectSnapshots": - args[0], err = projectNameToID(cmd.Context(), args[0], cl) - case "GetCluster", "UpdateCluster", "DeleteCluster", "GetKubeconfig": - project, _ := cmd.Flags().GetString("project") - args[0], err = clusterNameToID(cmd.Context(), args[0], project, cl) + project, _ := cmd.Flags().GetString("project") + args[0], err = clusterNameToID(cmd.Context(), args[0], project, cl) + return err +} + +func projectArgToID(cmd *cobra.Command, args []string) error { + // project use should store the name, not the ID + if cmd.Name() == "use" { + return nil } + debug.Println("projectArgToID") + p := loadProfile(cmd) + cl, err := oks.NewClient(p, sdkOptions(cmd)...) if err != nil { - messages.ExitErr(err) + return err + } + + if len(args) == 0 { + debug.Println("no arg to replace") + return nil + } + if _, err := uuid.Parse(args[0]); err == nil { + debug.Println("arg is an uuid") + return nil } - return args + args[0], err = projectNameToID(cmd.Context(), args[0], cl) + return err } -func flagNameToID(cmd *cobra.Command, cl *oks.Client) { - f := cmd.Flags().Lookup("ProjectId") - if f == nil { - debug.Println("no flag to replace") - return +func flagNamesToID(cmd *cobra.Command, args []string) error { + debug.Println("flagNamesToID") + p := loadProfile(cmd) + cl, err := oks.NewClient(p, sdkOptions(cmd)...) + if err != nil { + return err + } + + pf := cmd.Flags().Lookup("project") + if pf == nil { + debug.Println("no project flag to replace") + return nil } - id, err := projectNameToID(cmd.Context(), f.Value.String(), cl) + pid, err := projectNameToID(cmd.Context(), pf.Value.String(), cl) if err != nil { - messages.ExitErr(err) + return err + } + _ = pf.Value.Set(pid) + + cf := cmd.Flags().Lookup("cluster") + if cf == nil { + debug.Println("no cluster flag to replace") + return nil } - _ = f.Value.Set(id) + cid, err := clusterNameToID(cmd.Context(), cf.Value.String(), pid, cl) + if err != nil { + return err + } + _ = cf.Value.Set(cid) + return nil } func projectNameToID(ctx context.Context, name string, cl *oks.Client) (string, error) { + if name == "" { + return "", nil + } pjs, err := cl.ListProjects(ctx, &oks.ListProjectsParams{Name: &name}) if err != nil { return "", err @@ -137,12 +179,15 @@ func projectNameToID(ctx context.Context, name string, cl *oks.Client) (string, case 0: return "", fmt.Errorf("project %q not found", name) default: - debug.Println("replacing", name, "by", pjs.Projects[0].Id) + messages.Info("Resolving project name %q as ID %q", name, pjs.Projects[0].Id) return pjs.Projects[0].Id, nil } } func clusterNameToID(ctx context.Context, name, project string, cl *oks.Client) (string, error) { + if name == "" { + return "", nil + } var ( cs *oks.ClusterResponseList err error @@ -170,7 +215,7 @@ func clusterNameToID(ctx context.Context, name, project string, cl *oks.Client) case 0: return "", fmt.Errorf("cluster %q not found", name) case 1: - debug.Println("replacing", name, "by", clusters[0].Id) + messages.Info("Resolving cluster name %q as ID %q", name, clusters[0].Id) return clusters[0].Id, nil default: return "", fmt.Errorf("multiple clusters found with the name %q", name) diff --git a/cmd/kube_kubeapi.go b/cmd/kube_kubeapi.go index f7a4dad9..26f2a768 100644 --- a/cmd/kube_kubeapi.go +++ b/cmd/kube_kubeapi.go @@ -20,8 +20,7 @@ func kubeapi(provider string) func(cmd *cobra.Command, args []string) { messages.ExitErr(err) } cluster, _ := cmd.Flags().GetString("cluster") - project, _ := cmd.Flags().GetString("project") - kubeconfig, err := getKubeconfig(cmd.Context(), cluster, project, cl) + kubeconfig, err := getKubeconfig(cmd.Context(), cluster, cl) if err != nil { messages.ExitErr(err) } diff --git a/cmd/kube_kubectl.go b/cmd/kube_kubectl.go index de36b875..0365ed75 100644 --- a/cmd/kube_kubectl.go +++ b/cmd/kube_kubectl.go @@ -12,6 +12,7 @@ import ( "time" "github.com/outscale/octl/pkg/debug" + "github.com/outscale/octl/pkg/flags" "github.com/outscale/octl/pkg/messages" "github.com/outscale/octl/pkg/preferences" "github.com/outscale/osc-sdk-go/v3/pkg/oks" @@ -34,8 +35,7 @@ func kubectl(cmd *cobra.Command, args []string) { messages.ExitErr(err) } cluster, _ := cmd.Flags().GetString("cluster") - project, _ := cmd.Flags().GetString("project") - kubeconfig, err := getKubeconfig(cmd.Context(), cluster, project, cl) + kubeconfig, err := getKubeconfig(cmd.Context(), cluster, cl) if err != nil { messages.ExitErr(err) } @@ -52,19 +52,15 @@ func kubectl(cmd *cobra.Command, args []string) { } } -func getKubeconfig(ctx context.Context, cluster, project string, cl *oks.Client) (string, error) { - id, err := clusterNameToID(ctx, cluster, project, cl) - if err != nil { - return "", err - } - filename, err := kubeconfigPath(id) +func getKubeconfig(ctx context.Context, cluster string, cl *oks.Client) (string, error) { + filename, err := kubeconfigPath(cluster) if err != nil { return "", err } debug.Println("kubeconfig path", filename) if _, err := os.Stat(filename); errors.Is(err, fs.ErrNotExist) { debug.Println("no kubeconfig; refreshing") - err = refreshKubeconfig(ctx, id, filename, cl) + err = refreshKubeconfig(ctx, cluster, filename, cl) if err != nil { return "", err } @@ -86,7 +82,7 @@ func getKubeconfig(ctx context.Context, cluster, project string, cl *oks.Client) } if err == nil && time.Since(decoded.NotAfter) > 0 { debug.Println("expired kubeconfig certificate; refreshing") - err = refreshKubeconfig(ctx, id, filename, cl) + err = refreshKubeconfig(ctx, cluster, filename, cl) } if err != nil { return "", err @@ -125,4 +121,5 @@ func init() { kubectlCmd.Flags().String("cluster", "", "Name or ID of cluster") _ = kubectlCmd.MarkFlagRequired("cluster") kubectlCmd.Flags().String("project", preferences.Preferences.Kube.DefaultProject, "Name or ID of project") + _ = flags.MarkAsNoForward(kubectlCmd.Flags(), "project") } diff --git a/cmd/kube_nodepool.go b/cmd/kube_nodepool.go index ee2f8bea..343a76aa 100644 --- a/cmd/kube_nodepool.go +++ b/cmd/kube_nodepool.go @@ -6,6 +6,7 @@ import ( oksv1beta2 "github.com/outscale/goutils/oks/clientset/typed/oks.dev/v1beta2" "github.com/outscale/octl/pkg/builder" + "github.com/outscale/octl/pkg/flags" "github.com/outscale/octl/pkg/preferences" "github.com/samber/lo" "github.com/spf13/cobra" @@ -26,11 +27,16 @@ func init() { return slices.Contains([]string{"List", "Get", "Create", "Update", "Delete"}, m.Name) }, kubeapi("kubeclient_nodepool")) apiCmd, _ := lo.Find(nodepoolCmd.Commands(), func(c *cobra.Command) bool { return c.Name() == "api" }) - apiCmd.PersistentFlags().String("cluster", "", "[REQUIRED] Name or ID of cluster") - _ = apiCmd.MarkPersistentFlagRequired("cluster") - apiCmd.PersistentFlags().String("project", preferences.Preferences.Kube.DefaultProject, "Name or ID of project") - // nodepool commands need to be added to the upper level, otherwise we will get kube nodepool nodepool b.Build(oksCmd, apiCmd) - clusterCmd, _ := lo.Find(oksCmd.Commands(), func(c *cobra.Command) bool { return c.Name() == "nodepool" }) - clusterCmd.PersistentFlags().String("project", preferences.Preferences.Kube.DefaultProject, "project name") + for _, cmd := range nodepoolCmd.Commands() { + if cmd.Name() == "api" { + cmd.PersistentFlags().String("cluster", "", "[REQUIRED] ID of cluster") + _ = cmd.MarkPersistentFlagRequired("cluster") + } else { + cmd.Flags().String("cluster", "", "[REQUIRED] Name or ID of cluster") + cmd.Flags().String("project", preferences.Preferences.Kube.DefaultProject, "Name or ID of project") + _ = cmd.MarkFlagRequired("cluster") + _ = flags.MarkAsNoForward(cmd.Flags(), "project") + } + } } diff --git a/cmd/root.go b/cmd/root.go index 5ebad327..18916b19 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -60,6 +60,8 @@ func Root() *cobra.Command { } func init() { + cobra.EnableTraverseRunHooks = true + md := markdown.NewRenderer() if long, err := md.Render(rootCmd.Long); err == nil { rootCmd.Long = long diff --git a/docs/reference/octl_iaas_consumptionaccount_aggregate_all.md b/docs/reference/octl_iaas_consumptionaccount_aggregate_all.md index 7c6e5125..0d1b2a69 100644 --- a/docs/reference/octl_iaas_consumptionaccount_aggregate_all.md +++ b/docs/reference/octl_iaas_consumptionaccount_aggregate_all.md @@ -15,10 +15,10 @@ octl iaas consumptionaccount aggregate all [flags] ### Options ``` - --from-date osctime The beginning of the time period, in ISO 8601 date format (for example, 2020-06-14). + --from-date osctime The beginning of the time period, in ISO 8601 date format (for example, 2020-06-14). (default beginning-of-month) -h, --help help for all --overall If false, returns only the consumption of the specific account that sends this request. - --to-date osctime The end of the time period, in ISO 8601 date format (for example, 2020-06-30). + --to-date osctime The end of the time period, in ISO 8601 date format (for example, 2020-06-30). (default today) ``` ### Options inherited from parent commands diff --git a/docs/reference/octl_iaas_consumptionaccount_aggregate_compute.md b/docs/reference/octl_iaas_consumptionaccount_aggregate_compute.md index e72c9db2..0be9c367 100644 --- a/docs/reference/octl_iaas_consumptionaccount_aggregate_compute.md +++ b/docs/reference/octl_iaas_consumptionaccount_aggregate_compute.md @@ -15,10 +15,10 @@ octl iaas consumptionaccount aggregate compute [flags] ### Options ``` - --from-date osctime The beginning of the time period, in ISO 8601 date format (for example, 2020-06-14). + --from-date osctime The beginning of the time period, in ISO 8601 date format (for example, 2020-06-14). (default beginning-of-month) -h, --help help for compute --overall If false, returns only the consumption of the specific account that sends this request. - --to-date osctime The end of the time period, in ISO 8601 date format (for example, 2020-06-30). + --to-date osctime The end of the time period, in ISO 8601 date format (for example, 2020-06-30). (default today) ``` ### Options inherited from parent commands diff --git a/docs/reference/octl_iaas_consumptionaccount_aggregate_gpu.md b/docs/reference/octl_iaas_consumptionaccount_aggregate_gpu.md index 24f44f6a..df1be4ff 100644 --- a/docs/reference/octl_iaas_consumptionaccount_aggregate_gpu.md +++ b/docs/reference/octl_iaas_consumptionaccount_aggregate_gpu.md @@ -15,10 +15,10 @@ octl iaas consumptionaccount aggregate gpu [flags] ### Options ``` - --from-date osctime The beginning of the time period, in ISO 8601 date format (for example, 2020-06-14). + --from-date osctime The beginning of the time period, in ISO 8601 date format (for example, 2020-06-14). (default beginning-of-month) -h, --help help for gpu --overall If false, returns only the consumption of the specific account that sends this request. - --to-date osctime The end of the time period, in ISO 8601 date format (for example, 2020-06-30). + --to-date osctime The end of the time period, in ISO 8601 date format (for example, 2020-06-30). (default today) ``` ### Options inherited from parent commands diff --git a/docs/reference/octl_iaas_consumptionaccount_list.md b/docs/reference/octl_iaas_consumptionaccount_list.md index 54e7cbc8..522d5f36 100644 --- a/docs/reference/octl_iaas_consumptionaccount_list.md +++ b/docs/reference/octl_iaas_consumptionaccount_list.md @@ -15,12 +15,12 @@ octl iaas consumptionaccount list [flags] ### Options ``` - --from-date osctime The beginning of the time period, in ISO 8601 date format (for example, 2020-06-14). + --from-date osctime The beginning of the time period, in ISO 8601 date format (for example, 2020-06-14). (default beginning-of-month) -h, --help help for list --overall If false, returns only the consumption of the specific account that sends this request. --show-price If true, the response also includes the unit price of the consumed resource (UnitPrice) and the total price of the consumed resource during the specified time period (Price), in the currency of the Region's catalog. --show-resource-details By default or if false, returns the consumption aggregated by resource type. - --to-date osctime The end of the time period, in ISO 8601 date format (for example, 2020-06-30). + --to-date osctime The end of the time period, in ISO 8601 date format (for example, 2020-06-30). (default today) ``` ### Options inherited from parent commands diff --git a/docs/reference/octl_kube_api_CreateCluster.md b/docs/reference/octl_kube_api_CreateCluster.md index a890ff9f..daf52a11 100644 --- a/docs/reference/octl_kube_api_CreateCluster.md +++ b/docs/reference/octl_kube_api_CreateCluster.md @@ -52,7 +52,6 @@ octl kube api CreateCluster [flags] --Tags stringToString (default []) --Version string Version of Kubernetes to be deployed -h, --help help for CreateCluster - --project string project name ``` ### Options inherited from parent commands diff --git a/docs/reference/octl_kube_api_DeleteCluster.md b/docs/reference/octl_kube_api_DeleteCluster.md index 576cc9db..410c0bf1 100644 --- a/docs/reference/octl_kube_api_DeleteCluster.md +++ b/docs/reference/octl_kube_api_DeleteCluster.md @@ -13,8 +13,7 @@ octl kube api DeleteCluster id [flags] ### Options ``` - -h, --help help for DeleteCluster - --project string project name + -h, --help help for DeleteCluster ``` ### Options inherited from parent commands diff --git a/docs/reference/octl_kube_api_GetCluster.md b/docs/reference/octl_kube_api_GetCluster.md index e38f6c8a..ef62e58f 100644 --- a/docs/reference/octl_kube_api_GetCluster.md +++ b/docs/reference/octl_kube_api_GetCluster.md @@ -13,8 +13,7 @@ octl kube api GetCluster id [flags] ### Options ``` - -h, --help help for GetCluster - --project string project name + -h, --help help for GetCluster ``` ### Options inherited from parent commands diff --git a/docs/reference/octl_kube_api_GetKubeconfig.md b/docs/reference/octl_kube_api_GetKubeconfig.md index 52318c22..3981ee85 100644 --- a/docs/reference/octl_kube_api_GetKubeconfig.md +++ b/docs/reference/octl_kube_api_GetKubeconfig.md @@ -9,11 +9,10 @@ octl kube api GetKubeconfig id [flags] ### Options ``` - --Group string - --Ttl string - --User string - -h, --help help for GetKubeconfig - --project string project name + --Group string + --Ttl string + --User string + -h, --help help for GetKubeconfig ``` ### Options inherited from parent commands diff --git a/docs/reference/octl_kube_api_UpdateCluster.md b/docs/reference/octl_kube_api_UpdateCluster.md index f837721f..6f1a7ef9 100644 --- a/docs/reference/octl_kube_api_UpdateCluster.md +++ b/docs/reference/octl_kube_api_UpdateCluster.md @@ -44,7 +44,6 @@ octl kube api UpdateCluster id [flags] --Tags stringToString (default []) --Version string -h, --help help for UpdateCluster - --project string project name ``` ### Options inherited from parent commands diff --git a/docs/reference/octl_kube_api_UpgradeCluster.md b/docs/reference/octl_kube_api_UpgradeCluster.md index 2dbf5234..a46912df 100644 --- a/docs/reference/octl_kube_api_UpgradeCluster.md +++ b/docs/reference/octl_kube_api_UpgradeCluster.md @@ -13,8 +13,7 @@ octl kube api UpgradeCluster id [flags] ### Options ``` - -h, --help help for UpgradeCluster - --project string project name + -h, --help help for UpgradeCluster ``` ### Options inherited from parent commands diff --git a/docs/reference/octl_kube_cluster.md b/docs/reference/octl_kube_cluster.md index 2442af24..56c8f255 100644 --- a/docs/reference/octl_kube_cluster.md +++ b/docs/reference/octl_kube_cluster.md @@ -6,7 +6,7 @@ cluster commands ``` -h, --help help for cluster - --project string project name + --project string Name or ID of project ``` ### Options inherited from parent commands diff --git a/docs/reference/octl_kube_cluster_create.md b/docs/reference/octl_kube_cluster_create.md index b8c1ca32..dff8423f 100644 --- a/docs/reference/octl_kube_cluster_create.md +++ b/docs/reference/octl_kube_cluster_create.md @@ -36,7 +36,7 @@ octl kube cluster create [flags] --oidc-issuer-url string The URL of the provider that allows the API server to discover public signing keys. --oidc-username-claim string --oidc-username-prefix string - --project string [REQUIRED] Unique identifier of the project this cluster belongs to + --project string Unique identifier of the project this cluster belongs to --quirk strings --subregions strings List of subregions where control plane components are deployed --tags stringToString (default []) diff --git a/docs/reference/octl_kube_cluster_delete.md b/docs/reference/octl_kube_cluster_delete.md index 293a54f6..82f3a75a 100644 --- a/docs/reference/octl_kube_cluster_delete.md +++ b/docs/reference/octl_kube_cluster_delete.md @@ -34,7 +34,7 @@ octl kube cluster delete id_or_name [id_or_name]... [flags] -o, --output string output format (raw, json, yaml, table, csv, none, base64, text) --payload string JSON content for query body --profile string Profile to use in profile file (by default, "default") - --project string project name + --project string Name or ID of project --single convert single entry lists to a single object --template string JSON template file for query body -v, --verbose Verbose output diff --git a/docs/reference/octl_kube_cluster_describe.md b/docs/reference/octl_kube_cluster_describe.md index b2578533..ae66f8f9 100644 --- a/docs/reference/octl_kube_cluster_describe.md +++ b/docs/reference/octl_kube_cluster_describe.md @@ -34,7 +34,7 @@ octl kube cluster describe id_or_name [id_or_name]... [flags] -o, --output string output format (raw, json, yaml, table, csv, none, base64, text) --payload string JSON content for query body --profile string Profile to use in profile file (by default, "default") - --project string project name + --project string Name or ID of project --single convert single entry lists to a single object --template string JSON template file for query body -v, --verbose Verbose output diff --git a/docs/reference/octl_kube_cluster_kubeconfig.md b/docs/reference/octl_kube_cluster_kubeconfig.md index 3e83792e..0a566e4a 100644 --- a/docs/reference/octl_kube_cluster_kubeconfig.md +++ b/docs/reference/octl_kube_cluster_kubeconfig.md @@ -37,7 +37,7 @@ octl kube cluster kubeconfig id_or_name [flags] -o, --output string output format (raw, json, yaml, table, csv, none, base64, text) --payload string JSON content for query body --profile string Profile to use in profile file (by default, "default") - --project string project name + --project string Name or ID of project --single convert single entry lists to a single object --template string JSON template file for query body -v, --verbose Verbose output diff --git a/docs/reference/octl_kube_cluster_list.md b/docs/reference/octl_kube_cluster_list.md index 368ee857..9f28a2d9 100644 --- a/docs/reference/octl_kube_cluster_list.md +++ b/docs/reference/octl_kube_cluster_list.md @@ -41,7 +41,7 @@ octl kube cluster list [flags] -o, --output string output format (raw, json, yaml, table, csv, none, base64, text) --payload string JSON content for query body --profile string Profile to use in profile file (by default, "default") - --project string project name + --project string Name or ID of project --single convert single entry lists to a single object --template string JSON template file for query body -v, --verbose Verbose output diff --git a/docs/reference/octl_kube_cluster_update.md b/docs/reference/octl_kube_cluster_update.md index 70200b6a..8b89a49e 100644 --- a/docs/reference/octl_kube_cluster_update.md +++ b/docs/reference/octl_kube_cluster_update.md @@ -64,7 +64,7 @@ octl kube cluster update id_or_name [id_or_name]... [flags] -o, --output string output format (raw, json, yaml, table, csv, none, base64, text) --payload string JSON content for query body --profile string Profile to use in profile file (by default, "default") - --project string project name + --project string Name or ID of project --single convert single entry lists to a single object --template string JSON template file for query body -v, --verbose Verbose output diff --git a/docs/reference/octl_kube_nodepool.md b/docs/reference/octl_kube_nodepool.md index 5fee2448..4ada59d6 100644 --- a/docs/reference/octl_kube_nodepool.md +++ b/docs/reference/octl_kube_nodepool.md @@ -5,8 +5,7 @@ nodepool commands ### Options ``` - -h, --help help for nodepool - --project string project name + -h, --help help for nodepool ``` ### Options inherited from parent commands diff --git a/docs/reference/octl_kube_nodepool_api.md b/docs/reference/octl_kube_nodepool_api.md index db71062b..13fcddaa 100644 --- a/docs/reference/octl_kube_nodepool_api.md +++ b/docs/reference/octl_kube_nodepool_api.md @@ -5,9 +5,8 @@ nodepool api calls ### Options ``` - --cluster string [REQUIRED] Name or ID of cluster + --cluster string [REQUIRED] ID of cluster -h, --help help for api - --project string Name or ID of project ``` ### Options inherited from parent commands diff --git a/docs/reference/octl_kube_nodepool_api_Create.md b/docs/reference/octl_kube_nodepool_api_Create.md index a7826839..a703cc2e 100644 --- a/docs/reference/octl_kube_nodepool_api_Create.md +++ b/docs/reference/octl_kube_nodepool_api_Create.md @@ -87,7 +87,7 @@ octl kube nodepool api Create [flags] ### Options inherited from parent commands ``` - --cluster string [REQUIRED] Name or ID of cluster + --cluster string [REQUIRED] ID of cluster -c, --columns string columns to display - [+]:<jq query for content>||<title>:<jq query for content> --config string Path of profile file (by default, ~/.osc/config.json) --dry-run Display the request payload that would be sent to the API without sending it @@ -101,7 +101,6 @@ octl kube nodepool api Create [flags] -o, --output string output format (raw, json, yaml, table, csv, none, base64, text) --payload string JSON content for query body --profile string Profile to use in profile file (by default, "default") - --project string Name or ID of project --single convert single entry lists to a single object --template string JSON template file for query body -v, --verbose Verbose output diff --git a/docs/reference/octl_kube_nodepool_api_Delete.md b/docs/reference/octl_kube_nodepool_api_Delete.md index b4365f11..1c8d68af 100644 --- a/docs/reference/octl_kube_nodepool_api_Delete.md +++ b/docs/reference/octl_kube_nodepool_api_Delete.md @@ -15,7 +15,7 @@ octl kube nodepool api Delete id [flags] ### Options inherited from parent commands ``` - --cluster string [REQUIRED] Name or ID of cluster + --cluster string [REQUIRED] ID of cluster -c, --columns string columns to display - [+]<title>:<jq query for content>||<title>:<jq query for content> --config string Path of profile file (by default, ~/.osc/config.json) --dry-run Display the request payload that would be sent to the API without sending it @@ -29,7 +29,6 @@ octl kube nodepool api Delete id [flags] -o, --output string output format (raw, json, yaml, table, csv, none, base64, text) --payload string JSON content for query body --profile string Profile to use in profile file (by default, "default") - --project string Name or ID of project --single convert single entry lists to a single object --template string JSON template file for query body -v, --verbose Verbose output diff --git a/docs/reference/octl_kube_nodepool_api_Get.md b/docs/reference/octl_kube_nodepool_api_Get.md index c1fc3fb5..a465b9b5 100644 --- a/docs/reference/octl_kube_nodepool_api_Get.md +++ b/docs/reference/octl_kube_nodepool_api_Get.md @@ -15,7 +15,7 @@ octl kube nodepool api Get id [flags] ### Options inherited from parent commands ``` - --cluster string [REQUIRED] Name or ID of cluster + --cluster string [REQUIRED] ID of cluster -c, --columns string columns to display - [+]<title>:<jq query for content>||<title>:<jq query for content> --config string Path of profile file (by default, ~/.osc/config.json) --dry-run Display the request payload that would be sent to the API without sending it @@ -29,7 +29,6 @@ octl kube nodepool api Get id [flags] -o, --output string output format (raw, json, yaml, table, csv, none, base64, text) --payload string JSON content for query body --profile string Profile to use in profile file (by default, "default") - --project string Name or ID of project --single convert single entry lists to a single object --template string JSON template file for query body -v, --verbose Verbose output diff --git a/docs/reference/octl_kube_nodepool_api_List.md b/docs/reference/octl_kube_nodepool_api_List.md index 77440960..2ca6c986 100644 --- a/docs/reference/octl_kube_nodepool_api_List.md +++ b/docs/reference/octl_kube_nodepool_api_List.md @@ -15,7 +15,7 @@ octl kube nodepool api List [flags] ### Options inherited from parent commands ``` - --cluster string [REQUIRED] Name or ID of cluster + --cluster string [REQUIRED] ID of cluster -c, --columns string columns to display - [+]<title>:<jq query for content>||<title>:<jq query for content> --config string Path of profile file (by default, ~/.osc/config.json) --dry-run Display the request payload that would be sent to the API without sending it @@ -29,7 +29,6 @@ octl kube nodepool api List [flags] -o, --output string output format (raw, json, yaml, table, csv, none, base64, text) --payload string JSON content for query body --profile string Profile to use in profile file (by default, "default") - --project string Name or ID of project --single convert single entry lists to a single object --template string JSON template file for query body -v, --verbose Verbose output diff --git a/docs/reference/octl_kube_nodepool_api_Update.md b/docs/reference/octl_kube_nodepool_api_Update.md index 20b5a973..10f9dbc0 100644 --- a/docs/reference/octl_kube_nodepool_api_Update.md +++ b/docs/reference/octl_kube_nodepool_api_Update.md @@ -87,7 +87,7 @@ octl kube nodepool api Update [flags] ### Options inherited from parent commands ``` - --cluster string [REQUIRED] Name or ID of cluster + --cluster string [REQUIRED] ID of cluster -c, --columns string columns to display - [+]<title>:<jq query for content>||<title>:<jq query for content> --config string Path of profile file (by default, ~/.osc/config.json) --dry-run Display the request payload that would be sent to the API without sending it @@ -101,7 +101,6 @@ octl kube nodepool api Update [flags] -o, --output string output format (raw, json, yaml, table, csv, none, base64, text) --payload string JSON content for query body --profile string Profile to use in profile file (by default, "default") - --project string Name or ID of project --single convert single entry lists to a single object --template string JSON template file for query body -v, --verbose Verbose output diff --git a/docs/reference/octl_kube_nodepool_create.md b/docs/reference/octl_kube_nodepool_create.md index ac92f0e9..b6885738 100644 --- a/docs/reference/octl_kube_nodepool_create.md +++ b/docs/reference/octl_kube_nodepool_create.md @@ -36,6 +36,7 @@ octl kube nodepool create [flags] --placement-attract-server string --placement-repulse-cluster string --placement-repulse-server string + --project string Name or ID of project --taint --upgrade-duration-hour int --upgrade-max-surge int @@ -66,7 +67,6 @@ octl kube nodepool create [flags] -o, --output string output format (raw, json, yaml, table, csv, none, base64, text) --payload string JSON content for query body --profile string Profile to use in profile file (by default, "default") - --project string project name --single convert single entry lists to a single object --template string JSON template file for query body -v, --verbose Verbose output diff --git a/docs/reference/octl_kube_nodepool_delete.md b/docs/reference/octl_kube_nodepool_delete.md index c70c96ef..3fa7774d 100644 --- a/docs/reference/octl_kube_nodepool_delete.md +++ b/docs/reference/octl_kube_nodepool_delete.md @@ -17,6 +17,7 @@ octl kube nodepool delete name [name]... [flags] ``` --cluster string [REQUIRED] Name or ID of cluster -h, --help help for delete + --project string Name or ID of project ``` ### Options inherited from parent commands @@ -35,7 +36,6 @@ octl kube nodepool delete name [name]... [flags] -o, --output string output format (raw, json, yaml, table, csv, none, base64, text) --payload string JSON content for query body --profile string Profile to use in profile file (by default, "default") - --project string project name --single convert single entry lists to a single object --template string JSON template file for query body -v, --verbose Verbose output diff --git a/docs/reference/octl_kube_nodepool_describe.md b/docs/reference/octl_kube_nodepool_describe.md index 3fe1ea4e..5f7d6c7f 100644 --- a/docs/reference/octl_kube_nodepool_describe.md +++ b/docs/reference/octl_kube_nodepool_describe.md @@ -17,6 +17,7 @@ octl kube nodepool describe name [name]... [flags] ``` --cluster string [REQUIRED] Name or ID of cluster -h, --help help for describe + --project string Name or ID of project ``` ### Options inherited from parent commands @@ -35,7 +36,6 @@ octl kube nodepool describe name [name]... [flags] -o, --output string output format (raw, json, yaml, table, csv, none, base64, text) --payload string JSON content for query body --profile string Profile to use in profile file (by default, "default") - --project string project name --single convert single entry lists to a single object --template string JSON template file for query body -v, --verbose Verbose output diff --git a/docs/reference/octl_kube_nodepool_list.md b/docs/reference/octl_kube_nodepool_list.md index b909fdc3..949e2f3f 100644 --- a/docs/reference/octl_kube_nodepool_list.md +++ b/docs/reference/octl_kube_nodepool_list.md @@ -17,6 +17,7 @@ octl kube nodepool list [flags] ``` --cluster string [REQUIRED] Name or ID of cluster -h, --help help for list + --project string Name or ID of project ``` ### Options inherited from parent commands @@ -35,7 +36,6 @@ octl kube nodepool list [flags] -o, --output string output format (raw, json, yaml, table, csv, none, base64, text) --payload string JSON content for query body --profile string Profile to use in profile file (by default, "default") - --project string project name --single convert single entry lists to a single object --template string JSON template file for query body -v, --verbose Verbose output diff --git a/docs/reference/octl_kube_project_use.md b/docs/reference/octl_kube_project_use.md index 59861ef1..8481df69 100644 --- a/docs/reference/octl_kube_project_use.md +++ b/docs/reference/octl_kube_project_use.md @@ -3,7 +3,7 @@ Set a default project for cluster commands, reset it without args ``` -octl kube project use [project_id_or_name] [flags] +octl kube project use [id_or_name] [flags] ``` ### Options diff --git a/pkg/alias/run.go b/pkg/alias/run.go index 6c224057..ea62eb29 100644 --- a/pkg/alias/run.go +++ b/pkg/alias/run.go @@ -14,6 +14,7 @@ import ( "github.com/outscale/octl/pkg/config" "github.com/outscale/octl/pkg/debug" + "github.com/outscale/octl/pkg/flags" "github.com/outscale/octl/pkg/messages" "github.com/outscale/octl/pkg/output" "github.com/outscale/octl/pkg/runner" @@ -22,8 +23,6 @@ import ( "github.com/spf13/pflag" ) -const DefaultValue = "default.octl.outscale.com" - var prompts = map[config.Action]string{ config.ActionDelete: "Are you sure you want to delete these resource(s) ?", } @@ -135,27 +134,26 @@ func iterate(fn func(cmd *cobra.Command, args []string) int, cmd *cobra.Command, } // userArgs returns the list of args for the underlying command, including flags mapped from the alias flags. -func userArgs(cmd *cobra.Command, flags config.FlagSet, skipUserFlags bool) []string { +func userArgs(cmd *cobra.Command, fs config.FlagSet, skipUserFlags bool) []string { var userArgs []string cmd.Flags().VisitAll(func(f *pflag.Flag) { newFlag := f.Name - nf, found := flags.Get(newFlag) + nf, found := fs.Get(newFlag) switch { case newFlag == "verbose" || newFlag == "config" || newFlag == "profile": + case flags.IsNoForward(f): + return case !found && skipUserFlags: return case found: newFlag = nf.AliasTo } - switch { - case f.Changed: + if f.Changed || flags.HasDefault(f) { if svalue, ok := f.Value.(pflag.SliceValue); ok { userArgs = append(userArgs, "--"+newFlag+"="+strings.Join(svalue.GetSlice(), ",")) return } userArgs = append(userArgs, "--"+newFlag+"="+f.Value.String()) - case f.Annotations != nil && len(f.Annotations[DefaultValue]) > 0: - userArgs = append(userArgs, "--"+newFlag+"="+f.Annotations[DefaultValue][0]) } }) return userArgs diff --git a/pkg/builder/build.go b/pkg/builder/build.go index 6b290c8e..e27a29ef 100644 --- a/pkg/builder/build.go +++ b/pkg/builder/build.go @@ -99,7 +99,7 @@ func (b *Builder[T]) Build(rootCmd, apiCmd *cobra.Command) { nflag := *flag nflag.Name = f.Name if f.Default != "" { - nflag.Annotations = map[string][]string{alias.DefaultValue: {f.Default}} + flags.SetDefaultValue(&nflag, f.Default) } switch f.Type { case "base64File": diff --git a/pkg/config/defaults.zip b/pkg/config/defaults.zip index cb2bb6b5..4592572e 100644 Binary files a/pkg/config/defaults.zip and b/pkg/config/defaults.zip differ diff --git a/pkg/config/defaults_kube.yaml b/pkg/config/defaults_kube.yaml index 46467d11..97084236 100644 --- a/pkg/config/defaults_kube.yaml +++ b/pkg/config/defaults_kube.yaml @@ -354,7 +354,6 @@ aliases: required: true - name: project alias_to: ProjectId - required: true - name: quirk alias_to: Quirks - name: tags diff --git a/pkg/config/generate/kube/defaults.yaml b/pkg/config/generate/kube/defaults.yaml index a6921c73..c9110131 100644 --- a/pkg/config/generate/kube/defaults.yaml +++ b/pkg/config/generate/kube/defaults.yaml @@ -262,7 +262,6 @@ aliases: required: true - name: project alias_to: ProjectId - required: true - name: quirk alias_to: Quirks - name: tags diff --git a/pkg/flags/annotations.go b/pkg/flags/annotations.go new file mode 100644 index 00000000..bfbd0291 --- /dev/null +++ b/pkg/flags/annotations.go @@ -0,0 +1,43 @@ +package flags + +import ( + "fmt" + + "github.com/spf13/pflag" +) + +const aliasNoForward = "octl.outscale.com/no-forward" + +func MarkAsNoForward(fs *pflag.FlagSet, name string) error { + return fs.SetAnnotation(name, aliasNoForward, []string{""}) +} + +func IsNoForward(f *pflag.Flag) bool { + _, found := f.Annotations[aliasNoForward] + return found +} + +const defaultValue = "octl.outscale.com/default" + +func SetDefault(fs *pflag.FlagSet, name, value string) error { + f := fs.Lookup(name) + if f == nil { + return fmt.Errorf("flag %q not found", name) + } + SetDefaultValue(f, value) + return nil +} + +func SetDefaultValue(f *pflag.Flag, value string) { + f.DefValue = value + _ = f.Value.Set(value) + if f.Annotations == nil { + f.Annotations = map[string][]string{} + } + f.Annotations[defaultValue] = []string{value} +} + +func HasDefault(f *pflag.Flag) bool { + val, found := f.Annotations[defaultValue] + return found && len(val) > 0 +}