diff --git a/completers/k3d_completer/cmd/cluster.go b/completers/k3d_completer/cmd/cluster.go new file mode 100644 index 0000000000..db3e421cbe --- /dev/null +++ b/completers/k3d_completer/cmd/cluster.go @@ -0,0 +1,18 @@ +package cmd + +import ( + "github.com/rsteube/carapace" + "github.com/spf13/cobra" +) + +var clusterCmd = &cobra.Command{ + Use: "cluster", + Short: "Manage cluster(s)", + Run: func(cmd *cobra.Command, args []string) {}, +} + +func init() { + carapace.Gen(clusterCmd).Standalone() + + rootCmd.AddCommand(clusterCmd) +} diff --git a/completers/k3d_completer/cmd/cluster_create.go b/completers/k3d_completer/cmd/cluster_create.go new file mode 100644 index 0000000000..4f535177f2 --- /dev/null +++ b/completers/k3d_completer/cmd/cluster_create.go @@ -0,0 +1,101 @@ +package cmd + +import ( + "github.com/rsteube/carapace" + "github.com/rsteube/carapace-bin/pkg/actions/tools/k3d" + "github.com/spf13/cobra" +) + +var cluster_createCmd = &cobra.Command{ + Use: "create NAME", + Short: "Create a new cluster", + Run: func(cmd *cobra.Command, args []string) {}, +} + +func init() { + carapace.Gen(cluster_createCmd).Standalone() + + cluster_createCmd.Flags().StringP("agents", "a", "", "Specify how many agents you want to create") + cluster_createCmd.Flags().String("agents-memory", "", "Memory limit imposed on the agents nodes [From docker]") + cluster_createCmd.Flags().String("api-port", "", "Specify the Kubernetes API server port exposed on the LoadBalancer (Format: `[HOST:]HOSTPORT`)") + cluster_createCmd.Flags().StringP("config", "c", "", "Path of a config file to use") + cluster_createCmd.Flags().StringSliceP("env", "e", []string{}, "Add environment variables to nodes (Format: `KEY[=VALUE][@NODEFILTER[;NODEFILTER...]]`") + cluster_createCmd.Flags().String("gpus", "", "GPU devices to add to the cluster node containers ('all' to pass all GPUs) [From docker]") + cluster_createCmd.Flags().StringSlice("host-alias", []string{}, "Add `ip:host[,host,...]` mappings") + cluster_createCmd.Flags().Bool("host-pid-mode", false, "Enable host pid mode of server(s) and agent(s)") + cluster_createCmd.Flags().StringP("image", "i", "", "Specify k3s image that you want to use for the nodes") + cluster_createCmd.Flags().StringSlice("k3s-arg", []string{}, "Additional args passed to k3s command (Format: `ARG@NODEFILTER[;@NODEFILTER]`)") + cluster_createCmd.Flags().StringSlice("k3s-node-label", []string{}, "Add label to k3s node (Format: `KEY[=VALUE][@NODEFILTER[;NODEFILTER...]]`") + cluster_createCmd.Flags().Bool("kubeconfig-switch-context", false, "Directly switch the default kubeconfig's current-context to the new cluster's context (requires --kubeconfig-update-default)") + cluster_createCmd.Flags().Bool("kubeconfig-update-default", false, "Directly update the default kubeconfig with the new cluster's context") + cluster_createCmd.Flags().StringSlice("lb-config-override", []string{}, "Use dotted YAML path syntax to override nginx loadbalancer settings") + cluster_createCmd.Flags().String("network", "", "Join an existing network") + cluster_createCmd.Flags().Bool("no-image-volume", false, "Disable the creation of a volume for importing images") + cluster_createCmd.Flags().Bool("no-lb", false, "Disable the creation of a LoadBalancer in front of the server nodes") + cluster_createCmd.Flags().Bool("no-rollback", false, "Disable the automatic rollback actions, if anything goes wrong") + cluster_createCmd.Flags().StringSliceP("port", "p", []string{}, "Map ports from the node containers (via the serverlb) to the host (Format: `[HOST:][HOSTPORT:]CONTAINERPORT[/PROTOCOL][@NODEFILTER]`)") + cluster_createCmd.Flags().String("registry-config", "", "Specify path to an extra registries.yaml file") + cluster_createCmd.Flags().String("registry-create", "", "Create a k3d-managed registry and connect it to the cluster (Format: `NAME[:HOST][:HOSTPORT]`") + cluster_createCmd.Flags().StringSlice("registry-use", []string{}, "Connect to one or more k3d-managed registries running locally") + cluster_createCmd.Flags().StringSlice("runtime-label", []string{}, "Add label to container runtime (Format: `KEY[=VALUE][@NODEFILTER[;NODEFILTER...]]`") + cluster_createCmd.Flags().StringSlice("runtime-ulimit", []string{}, "Add ulimit to container runtime (Format: `NAME[=SOFT]:[HARD]`") + cluster_createCmd.Flags().StringP("servers", "s", "", "Specify how many servers you want to create") + cluster_createCmd.Flags().String("servers-memory", "", "Memory limit imposed on the server nodes [From docker]") + cluster_createCmd.Flags().String("subnet", "", "[Experimental: IPAM] Define a subnet for the newly created container network (Example: `172.28.0.0/16`)") + cluster_createCmd.Flags().String("timeout", "", "Rollback changes if cluster couldn't be created in specified duration.") + cluster_createCmd.Flags().String("token", "", "Specify a cluster token. By default, we generate one.") + cluster_createCmd.Flags().StringSliceP("volume", "v", []string{}, "Mount volumes into the nodes (Format: `[SOURCE:]DEST[@NODEFILTER[;NODEFILTER...]]`") + cluster_createCmd.Flags().Bool("wait", false, "Wait for the server(s) to be ready before returning. Use '--timeout DURATION' to not wait forever.") + clusterCmd.AddCommand(cluster_createCmd) + + carapace.Gen(cluster_createCmd).FlagCompletion(carapace.ActionMap{ + "api-port": carapace.ActionValues(), // TODO + "config": carapace.ActionFiles(), + "env": carapace.ActionMultiPartsN("@", 2, func(c carapace.Context) carapace.Action { + switch len(c.Parts) { + case 0: + return carapace.ActionValues() // KEY=VALUE + default: + return k3d.ActionNodeFilter().List(";") + } + }), + "gpus": carapace.ActionValues(), // TODO + "host-alias": carapace.ActionValues(), + "image": carapace.ActionValues(), + "k3s-arg": carapace.ActionValues(), + "k3s-node-label": carapace.ActionValues(), + "lb-config-override": carapace.ActionValues(), + "network": carapace.ActionValues(), + "port": carapace.ActionValues(), + "registry-config": carapace.ActionValues(), + "registry-create": carapace.ActionValues(), + "registry-use": carapace.ActionValues(), + "runtime-label": carapace.ActionValues(), + "runtime-ulimit": carapace.ActionValues(), + "servers": carapace.ActionValues(), + "servers-memory": carapace.ActionValues(), + "subnet": carapace.ActionValues(), + "timeout": carapace.ActionValues(), + "token": carapace.ActionValues(), + "volume": carapace.ActionValues(), + }) +} + +func x() { + // KEY[=VALUE][@NODEFILTER[;NODEFILTER...]] + carapace.ActionMultiPartsN("@", 2, func(c carapace.Context) carapace.Action { + switch len(c.Parts) { + case 0: + return carapace.ActionMultiPartsN("=", 2, func(c carapace.Context) carapace.Action { + switch len(c.Parts) { + case 0: + return carapace.ActionValues("TODO:key") + default: + return carapace.ActionValues("TODO:value") + } + }) + default: + return carapace.ActionValues("TODO:nodefilter").List(";") + } + }).List(",") +} diff --git a/completers/k3d_completer/cmd/cluster_delete.go b/completers/k3d_completer/cmd/cluster_delete.go new file mode 100644 index 0000000000..38aceedce2 --- /dev/null +++ b/completers/k3d_completer/cmd/cluster_delete.go @@ -0,0 +1,26 @@ +package cmd + +import ( + "github.com/rsteube/carapace" + "github.com/rsteube/carapace-bin/pkg/actions/tools/k3d" + "github.com/spf13/cobra" +) + +var cluster_deleteCmd = &cobra.Command{ + Use: "delete [NAME [NAME ...] | --all]", + Short: "Delete cluster(s).", + Aliases: []string{"del", "rm"}, + Run: func(cmd *cobra.Command, args []string) {}, +} + +func init() { + carapace.Gen(cluster_deleteCmd).Standalone() + + cluster_deleteCmd.Flags().BoolP("all", "a", false, "Delete all existing clusters") + cluster_deleteCmd.Flags().StringP("config", "c", "", "Path of a config file to use") + clusterCmd.AddCommand(cluster_deleteCmd) + + carapace.Gen(cluster_deleteCmd).PositionalAnyCompletion( + k3d.ActionClusters().FilterArgs(), + ) +} diff --git a/completers/k3d_completer/cmd/cluster_edit.go b/completers/k3d_completer/cmd/cluster_edit.go new file mode 100644 index 0000000000..cb1cac0f9d --- /dev/null +++ b/completers/k3d_completer/cmd/cluster_edit.go @@ -0,0 +1,41 @@ +package cmd + +import ( + "github.com/rsteube/carapace" + "github.com/rsteube/carapace-bin/pkg/actions/tools/k3d" + "github.com/spf13/cobra" +) + +var cluster_editCmd = &cobra.Command{ + Use: "edit CLUSTER", + Short: "[EXPERIMENTAL] Edit cluster(s).", + Aliases: []string{"update"}, + Run: func(cmd *cobra.Command, args []string) {}, +} + +func init() { + carapace.Gen(cluster_editCmd).Standalone() + + cluster_editCmd.Flags().StringSlice("port-add", []string{}, "[EXPERIMENTAL] Map ports from the node containers (via the serverlb) to the host (Format: `[HOST:][HOSTPORT:]CONTAINERPORT[/PROTOCOL][@NODEFILTER]`)") + clusterCmd.AddCommand(cluster_editCmd) + + carapace.Gen(cluster_editCmd).FlagCompletion(carapace.ActionMap{ + "port-add": carapace.ActionMultiPartsN("@", 2, func(c carapace.Context) carapace.Action { + cluster := "" + if len(c.Args) > 0 { + cluster = c.Args[0] + } + + switch len(c.Parts) { + case 0: + return carapace.ActionValues() + default: + return k3d.ActionNodes(k3d.NodeOpts{Cluster: cluster, Running: true, Stopped: true}).UniqueList(",") // TODO nodefilter? + } + }), + }) + + carapace.Gen(cluster_editCmd).PositionalCompletion( + k3d.ActionClusters(), + ) +} diff --git a/completers/k3d_completer/cmd/cluster_list.go b/completers/k3d_completer/cmd/cluster_list.go new file mode 100644 index 0000000000..db455758e2 --- /dev/null +++ b/completers/k3d_completer/cmd/cluster_list.go @@ -0,0 +1,22 @@ +package cmd + +import ( + "github.com/rsteube/carapace" + "github.com/spf13/cobra" +) + +var cluster_listCmd = &cobra.Command{ + Use: "list [NAME [NAME...]]", + Short: "List cluster(s)", + Aliases: []string{"ls", "get"}, + Run: func(cmd *cobra.Command, args []string) {}, +} + +func init() { + carapace.Gen(cluster_listCmd).Standalone() + + cluster_listCmd.Flags().Bool("no-headers", false, "Disable headers") + cluster_listCmd.Flags().StringP("output", "o", "", "Output format. One of: json|yaml") + cluster_listCmd.Flags().Bool("token", false, "Print k3s cluster token") + clusterCmd.AddCommand(cluster_listCmd) +} diff --git a/completers/k3d_completer/cmd/cluster_start.go b/completers/k3d_completer/cmd/cluster_start.go new file mode 100644 index 0000000000..45db524d5d --- /dev/null +++ b/completers/k3d_completer/cmd/cluster_start.go @@ -0,0 +1,21 @@ +package cmd + +import ( + "github.com/rsteube/carapace" + "github.com/spf13/cobra" +) + +var cluster_startCmd = &cobra.Command{ + Use: "start [NAME [NAME...] | --all]", + Short: "Start existing k3d cluster(s)", + Run: func(cmd *cobra.Command, args []string) {}, +} + +func init() { + carapace.Gen(cluster_startCmd).Standalone() + + cluster_startCmd.Flags().BoolP("all", "a", false, "Start all existing clusters") + cluster_startCmd.Flags().String("timeout", "", "Maximum waiting time for '--wait' before canceling/returning.") + cluster_startCmd.Flags().Bool("wait", false, "Wait for the server(s) (and loadbalancer) to be ready before returning.") + clusterCmd.AddCommand(cluster_startCmd) +} diff --git a/completers/k3d_completer/cmd/cluster_stop.go b/completers/k3d_completer/cmd/cluster_stop.go new file mode 100644 index 0000000000..2d39572768 --- /dev/null +++ b/completers/k3d_completer/cmd/cluster_stop.go @@ -0,0 +1,19 @@ +package cmd + +import ( + "github.com/rsteube/carapace" + "github.com/spf13/cobra" +) + +var cluster_stopCmd = &cobra.Command{ + Use: "stop [NAME [NAME...] | --all]", + Short: "Stop existing k3d cluster(s)", + Run: func(cmd *cobra.Command, args []string) {}, +} + +func init() { + carapace.Gen(cluster_stopCmd).Standalone() + + cluster_stopCmd.Flags().BoolP("all", "a", false, "Stop all existing clusters") + clusterCmd.AddCommand(cluster_stopCmd) +} diff --git a/completers/k3d_completer/cmd/completion.go b/completers/k3d_completer/cmd/completion.go new file mode 100644 index 0000000000..920bf33834 --- /dev/null +++ b/completers/k3d_completer/cmd/completion.go @@ -0,0 +1,18 @@ +package cmd + +import ( + "github.com/rsteube/carapace" + "github.com/spf13/cobra" +) + +var completionCmd = &cobra.Command{ + Use: "completion SHELL", + Short: "Generate completion scripts for [bash, zsh, fish, powershell | psh]", + Run: func(cmd *cobra.Command, args []string) {}, +} + +func init() { + carapace.Gen(completionCmd).Standalone() + + rootCmd.AddCommand(completionCmd) +} diff --git a/completers/k3d_completer/cmd/config.go b/completers/k3d_completer/cmd/config.go new file mode 100644 index 0000000000..6ff47e444f --- /dev/null +++ b/completers/k3d_completer/cmd/config.go @@ -0,0 +1,18 @@ +package cmd + +import ( + "github.com/rsteube/carapace" + "github.com/spf13/cobra" +) + +var configCmd = &cobra.Command{ + Use: "config", + Short: "Work with config file(s)", + Run: func(cmd *cobra.Command, args []string) {}, +} + +func init() { + carapace.Gen(configCmd).Standalone() + + rootCmd.AddCommand(configCmd) +} diff --git a/completers/k3d_completer/cmd/config_init.go b/completers/k3d_completer/cmd/config_init.go new file mode 100644 index 0000000000..d77893efce --- /dev/null +++ b/completers/k3d_completer/cmd/config_init.go @@ -0,0 +1,21 @@ +package cmd + +import ( + "github.com/rsteube/carapace" + "github.com/spf13/cobra" +) + +var config_initCmd = &cobra.Command{ + Use: "init", + Short: "", + Aliases: []string{"create"}, + Run: func(cmd *cobra.Command, args []string) {}, +} + +func init() { + carapace.Gen(config_initCmd).Standalone() + + config_initCmd.Flags().BoolP("force", "f", false, "Force overwrite of target file") + config_initCmd.Flags().StringP("output", "o", "", "Write a default k3d config") + configCmd.AddCommand(config_initCmd) +} diff --git a/completers/k3d_completer/cmd/config_migrate.go b/completers/k3d_completer/cmd/config_migrate.go new file mode 100644 index 0000000000..b17ebe6950 --- /dev/null +++ b/completers/k3d_completer/cmd/config_migrate.go @@ -0,0 +1,19 @@ +package cmd + +import ( + "github.com/rsteube/carapace" + "github.com/spf13/cobra" +) + +var config_migrateCmd = &cobra.Command{ + Use: "migrate INPUT [OUTPUT]", + Short: "", + Aliases: []string{"update"}, + Run: func(cmd *cobra.Command, args []string) {}, +} + +func init() { + carapace.Gen(config_migrateCmd).Standalone() + + configCmd.AddCommand(config_migrateCmd) +} diff --git a/completers/k3d_completer/cmd/debug.go b/completers/k3d_completer/cmd/debug.go new file mode 100644 index 0000000000..12d6d1c109 --- /dev/null +++ b/completers/k3d_completer/cmd/debug.go @@ -0,0 +1,19 @@ +package cmd + +import ( + "github.com/rsteube/carapace" + "github.com/spf13/cobra" +) + +var debugCmd = &cobra.Command{ + Use: "debug", + Short: "Debug k3d cluster(s)", + Hidden: true, + Run: func(cmd *cobra.Command, args []string) {}, +} + +func init() { + carapace.Gen(debugCmd).Standalone() + + rootCmd.AddCommand(debugCmd) +} diff --git a/completers/k3d_completer/cmd/debug_loadbalancer.go b/completers/k3d_completer/cmd/debug_loadbalancer.go new file mode 100644 index 0000000000..4e63ac5dfc --- /dev/null +++ b/completers/k3d_completer/cmd/debug_loadbalancer.go @@ -0,0 +1,19 @@ +package cmd + +import ( + "github.com/rsteube/carapace" + "github.com/spf13/cobra" +) + +var debug_loadbalancerCmd = &cobra.Command{ + Use: "loadbalancer", + Short: "Debug the loadbalancer", + Aliases: []string{"lb"}, + Run: func(cmd *cobra.Command, args []string) {}, +} + +func init() { + carapace.Gen(debug_loadbalancerCmd).Standalone() + + debugCmd.AddCommand(debug_loadbalancerCmd) +} diff --git a/completers/k3d_completer/cmd/debug_loadbalancer_getConfig.go b/completers/k3d_completer/cmd/debug_loadbalancer_getConfig.go new file mode 100644 index 0000000000..79e2302d65 --- /dev/null +++ b/completers/k3d_completer/cmd/debug_loadbalancer_getConfig.go @@ -0,0 +1,18 @@ +package cmd + +import ( + "github.com/rsteube/carapace" + "github.com/spf13/cobra" +) + +var debug_loadbalancer_getConfigCmd = &cobra.Command{ + Use: "get-config CLUSTERNAME", + Short: "", + Run: func(cmd *cobra.Command, args []string) {}, +} + +func init() { + carapace.Gen(debug_loadbalancer_getConfigCmd).Standalone() + + debug_loadbalancerCmd.AddCommand(debug_loadbalancer_getConfigCmd) +} diff --git a/completers/k3d_completer/cmd/help.go b/completers/k3d_completer/cmd/help.go new file mode 100644 index 0000000000..c742c862b0 --- /dev/null +++ b/completers/k3d_completer/cmd/help.go @@ -0,0 +1,18 @@ +package cmd + +import ( + "github.com/rsteube/carapace" + "github.com/spf13/cobra" +) + +var helpCmd = &cobra.Command{ + Use: "help [command]", + Short: "Help about any command", + Run: func(cmd *cobra.Command, args []string) {}, +} + +func init() { + carapace.Gen(helpCmd).Standalone() + + rootCmd.AddCommand(helpCmd) +} diff --git a/completers/k3d_completer/cmd/image.go b/completers/k3d_completer/cmd/image.go new file mode 100644 index 0000000000..7d51b63242 --- /dev/null +++ b/completers/k3d_completer/cmd/image.go @@ -0,0 +1,19 @@ +package cmd + +import ( + "github.com/rsteube/carapace" + "github.com/spf13/cobra" +) + +var imageCmd = &cobra.Command{ + Use: "image", + Short: "Handle container images.", + Aliases: []string{"images"}, + Run: func(cmd *cobra.Command, args []string) {}, +} + +func init() { + carapace.Gen(imageCmd).Standalone() + + rootCmd.AddCommand(imageCmd) +} diff --git a/completers/k3d_completer/cmd/image_import.go b/completers/k3d_completer/cmd/image_import.go new file mode 100644 index 0000000000..b2cfe2f376 --- /dev/null +++ b/completers/k3d_completer/cmd/image_import.go @@ -0,0 +1,23 @@ +package cmd + +import ( + "github.com/rsteube/carapace" + "github.com/spf13/cobra" +) + +var image_importCmd = &cobra.Command{ + Use: "import [IMAGE | ARCHIVE [IMAGE | ARCHIVE...]]", + Short: "Import image(s) from docker into k3d cluster(s).", + Aliases: []string{"load"}, + Run: func(cmd *cobra.Command, args []string) {}, +} + +func init() { + carapace.Gen(image_importCmd).Standalone() + + image_importCmd.Flags().StringSliceP("cluster", "c", []string{}, "Select clusters to load the image to.") + image_importCmd.Flags().BoolP("keep-tarball", "k", false, "Do not delete the tarball containing the saved images from the shared volume") + image_importCmd.Flags().BoolP("keep-tools", "t", false, "Do not delete the tools node after import") + image_importCmd.Flags().StringP("mode", "m", "", "Which method to use to import images into the cluster [auto, direct, tools]. See https://k3d.io/stable/usage/importing_images/") + imageCmd.AddCommand(image_importCmd) +} diff --git a/completers/k3d_completer/cmd/kubeconfig.go b/completers/k3d_completer/cmd/kubeconfig.go new file mode 100644 index 0000000000..0aee0fbcd2 --- /dev/null +++ b/completers/k3d_completer/cmd/kubeconfig.go @@ -0,0 +1,18 @@ +package cmd + +import ( + "github.com/rsteube/carapace" + "github.com/spf13/cobra" +) + +var kubeconfigCmd = &cobra.Command{ + Use: "kubeconfig", + Short: "Manage kubeconfig(s)", + Run: func(cmd *cobra.Command, args []string) {}, +} + +func init() { + carapace.Gen(kubeconfigCmd).Standalone() + + rootCmd.AddCommand(kubeconfigCmd) +} diff --git a/completers/k3d_completer/cmd/kubeconfig_get.go b/completers/k3d_completer/cmd/kubeconfig_get.go new file mode 100644 index 0000000000..61004d4a62 --- /dev/null +++ b/completers/k3d_completer/cmd/kubeconfig_get.go @@ -0,0 +1,20 @@ +package cmd + +import ( + "github.com/rsteube/carapace" + "github.com/spf13/cobra" +) + +var kubeconfig_getCmd = &cobra.Command{ + Use: "get [CLUSTER [CLUSTER [...]] | --all]", + Short: "Print kubeconfig(s) from cluster(s).", + Aliases: []string{"print", "show"}, + Run: func(cmd *cobra.Command, args []string) {}, +} + +func init() { + carapace.Gen(kubeconfig_getCmd).Standalone() + + kubeconfig_getCmd.Flags().BoolP("all", "a", false, "Output kubeconfigs from all existing clusters") + kubeconfigCmd.AddCommand(kubeconfig_getCmd) +} diff --git a/completers/k3d_completer/cmd/kubeconfig_merge.go b/completers/k3d_completer/cmd/kubeconfig_merge.go new file mode 100644 index 0000000000..df2c141cb8 --- /dev/null +++ b/completers/k3d_completer/cmd/kubeconfig_merge.go @@ -0,0 +1,25 @@ +package cmd + +import ( + "github.com/rsteube/carapace" + "github.com/spf13/cobra" +) + +var kubeconfig_mergeCmd = &cobra.Command{ + Use: "merge [CLUSTER [CLUSTER [...]] | --all]", + Short: "Write/Merge kubeconfig(s) from cluster(s) into new or existing kubeconfig/file.", + Aliases: []string{"write"}, + Run: func(cmd *cobra.Command, args []string) {}, +} + +func init() { + carapace.Gen(kubeconfig_mergeCmd).Standalone() + + kubeconfig_mergeCmd.Flags().BoolP("all", "a", false, "Get kubeconfigs from all existing clusters") + kubeconfig_mergeCmd.Flags().BoolP("kubeconfig-merge-default", "d", false, "Merge into the default kubeconfig ($KUBECONFIG or /home/rsteube/.kube/config)") + kubeconfig_mergeCmd.Flags().BoolP("kubeconfig-switch-context", "s", false, "Switch to new context") + kubeconfig_mergeCmd.Flags().StringP("output", "o", "", "Define output [ - | FILE ] (default from $KUBECONFIG or /home/rsteube/.kube/config") + kubeconfig_mergeCmd.Flags().Bool("overwrite", false, "[Careful!] Overwrite existing file, ignoring its contents") + kubeconfig_mergeCmd.Flags().BoolP("update", "u", false, "Update conflicting fields in existing kubeconfig") + kubeconfigCmd.AddCommand(kubeconfig_mergeCmd) +} diff --git a/completers/k3d_completer/cmd/node.go b/completers/k3d_completer/cmd/node.go new file mode 100644 index 0000000000..28832c75db --- /dev/null +++ b/completers/k3d_completer/cmd/node.go @@ -0,0 +1,18 @@ +package cmd + +import ( + "github.com/rsteube/carapace" + "github.com/spf13/cobra" +) + +var nodeCmd = &cobra.Command{ + Use: "node", + Short: "Manage node(s)", + Run: func(cmd *cobra.Command, args []string) {}, +} + +func init() { + carapace.Gen(nodeCmd).Standalone() + + rootCmd.AddCommand(nodeCmd) +} diff --git a/completers/k3d_completer/cmd/node_create.go b/completers/k3d_completer/cmd/node_create.go new file mode 100644 index 0000000000..8d82b7055b --- /dev/null +++ b/completers/k3d_completer/cmd/node_create.go @@ -0,0 +1,41 @@ +package cmd + +import ( + "github.com/rsteube/carapace" + "github.com/rsteube/carapace-bridge/pkg/actions/bridge" + "github.com/spf13/cobra" +) + +var node_createCmd = &cobra.Command{ + Use: "create NAME", + Short: "Create a new k3s node in docker", + Run: func(cmd *cobra.Command, args []string) {}, +} + +func init() { + carapace.Gen(node_createCmd).Standalone() + + node_createCmd.Flags().StringP("cluster", "c", "", "Cluster URL or k3d cluster name to connect to.") + node_createCmd.Flags().StringP("image", "i", "", "Specify k3s image used for the node(s) (default: copied from existing node)") + node_createCmd.Flags().StringSlice("k3s-arg", []string{}, "Additional args passed to k3d command") + node_createCmd.Flags().StringSlice("k3s-node-label", []string{}, "Specify k3s node labels in format \"foo=bar\"") + node_createCmd.Flags().String("memory", "", "Memory limit imposed on the node [From docker]") + node_createCmd.Flags().StringSliceP("network", "n", []string{}, "Add node to (another) runtime network") + node_createCmd.Flags().String("replicas", "", "Number of replicas of this node specification.") + node_createCmd.Flags().String("role", "", "Specify node role [server, agent]") + node_createCmd.Flags().StringSlice("runtime-label", []string{}, "Specify container runtime labels in format \"foo=bar\"") + node_createCmd.Flags().StringSlice("runtime-ulimit", []string{}, "Specify container runtime ulimit in format \"ulimit=soft:hard\"") + node_createCmd.Flags().String("timeout", "", "Maximum waiting time for '--wait' before canceling/returning.") + node_createCmd.Flags().StringP("token", "t", "", "Override cluster token (required when connecting to an external cluster)") + node_createCmd.Flags().Bool("wait", false, "Wait for the node(s) to be ready before returning.") + nodeCmd.AddCommand(node_createCmd) + + // TODO + carapace.Gen(node_createCmd).FlagCompletion(carapace.ActionMap{ + // "cluster": carapace.ActionValues(), + // "image": carapace.ActionValues(), + "k3s-arg": bridge.ActionCarapaceBin("k3s").Split(), // TODO verify + // "network": carapace.ActionValues(), + "role": carapace.ActionValues("server", "agent"), + }) +} diff --git a/completers/k3d_completer/cmd/node_delete.go b/completers/k3d_completer/cmd/node_delete.go new file mode 100644 index 0000000000..ba7739eebe --- /dev/null +++ b/completers/k3d_completer/cmd/node_delete.go @@ -0,0 +1,25 @@ +package cmd + +import ( + "github.com/rsteube/carapace" + "github.com/rsteube/carapace-bin/pkg/actions/tools/k3d" + "github.com/spf13/cobra" +) + +var node_deleteCmd = &cobra.Command{ + Use: "delete (NAME | --all)", + Short: "Delete node(s).", + Run: func(cmd *cobra.Command, args []string) {}, +} + +func init() { + carapace.Gen(node_deleteCmd).Standalone() + + node_deleteCmd.Flags().BoolP("all", "a", false, "Delete all existing nodes") + node_deleteCmd.Flags().BoolP("registries", "r", false, "Also delete registries") + nodeCmd.AddCommand(node_deleteCmd) + + carapace.Gen(node_deleteCmd).PositionalAnyCompletion( + k3d.ActionNodes(k3d.NodeOpts{}.Default()).FilterArgs(), + ) +} diff --git a/completers/k3d_completer/cmd/node_edit.go b/completers/k3d_completer/cmd/node_edit.go new file mode 100644 index 0000000000..1746a863ea --- /dev/null +++ b/completers/k3d_completer/cmd/node_edit.go @@ -0,0 +1,20 @@ +package cmd + +import ( + "github.com/rsteube/carapace" + "github.com/spf13/cobra" +) + +var node_editCmd = &cobra.Command{ + Use: "edit NODE", + Short: "[EXPERIMENTAL] Edit node(s).", + Aliases: []string{"update"}, + Run: func(cmd *cobra.Command, args []string) {}, +} + +func init() { + carapace.Gen(node_editCmd).Standalone() + + node_editCmd.Flags().StringSlice("port-add", []string{}, "[EXPERIMENTAL] (serverlb only!) Map ports from the node container to the host (Format: `[HOST:][HOSTPORT:]CONTAINERPORT[/PROTOCOL][@NODEFILTER]`)") + nodeCmd.AddCommand(node_editCmd) +} diff --git a/completers/k3d_completer/cmd/node_list.go b/completers/k3d_completer/cmd/node_list.go new file mode 100644 index 0000000000..ce6e43b599 --- /dev/null +++ b/completers/k3d_completer/cmd/node_list.go @@ -0,0 +1,27 @@ +package cmd + +import ( + "github.com/rsteube/carapace" + "github.com/spf13/cobra" +) + +var node_listCmd = &cobra.Command{ + Use: "list [NODE [NODE...]]", + Short: "List node(s)", + Aliases: []string{"ls", "get"}, + Run: func(cmd *cobra.Command, args []string) {}, +} + +func init() { + carapace.Gen(node_listCmd).Standalone() + + node_listCmd.Flags().Bool("no-headers", false, "Disable headers") + node_listCmd.Flags().StringP("output", "o", "", "Output format. One of: json|yaml") + nodeCmd.AddCommand(node_listCmd) + + carapace.Gen(node_listCmd).FlagCompletion(carapace.ActionMap{ + "output": carapace.ActionValues("json", "yaml"), + }) + + // TODO positional +} diff --git a/completers/k3d_completer/cmd/node_start.go b/completers/k3d_completer/cmd/node_start.go new file mode 100644 index 0000000000..73bb0128c9 --- /dev/null +++ b/completers/k3d_completer/cmd/node_start.go @@ -0,0 +1,18 @@ +package cmd + +import ( + "github.com/rsteube/carapace" + "github.com/spf13/cobra" +) + +var node_startCmd = &cobra.Command{ + Use: "start NODE", + Short: "Start an existing k3d node", + Run: func(cmd *cobra.Command, args []string) {}, +} + +func init() { + carapace.Gen(node_startCmd).Standalone() + + nodeCmd.AddCommand(node_startCmd) +} diff --git a/completers/k3d_completer/cmd/node_stop.go b/completers/k3d_completer/cmd/node_stop.go new file mode 100644 index 0000000000..5787b531d9 --- /dev/null +++ b/completers/k3d_completer/cmd/node_stop.go @@ -0,0 +1,18 @@ +package cmd + +import ( + "github.com/rsteube/carapace" + "github.com/spf13/cobra" +) + +var node_stopCmd = &cobra.Command{ + Use: "stop NAME", + Short: "Stop an existing k3d node", + Run: func(cmd *cobra.Command, args []string) {}, +} + +func init() { + carapace.Gen(node_stopCmd).Standalone() + + nodeCmd.AddCommand(node_stopCmd) +} diff --git a/completers/k3d_completer/cmd/registry.go b/completers/k3d_completer/cmd/registry.go new file mode 100644 index 0000000000..649d210302 --- /dev/null +++ b/completers/k3d_completer/cmd/registry.go @@ -0,0 +1,19 @@ +package cmd + +import ( + "github.com/rsteube/carapace" + "github.com/spf13/cobra" +) + +var registryCmd = &cobra.Command{ + Use: "registry", + Short: "Manage registry/registries", + Aliases: []string{"registries", "reg"}, + Run: func(cmd *cobra.Command, args []string) {}, +} + +func init() { + carapace.Gen(registryCmd).Standalone() + + rootCmd.AddCommand(registryCmd) +} diff --git a/completers/k3d_completer/cmd/registry_create.go b/completers/k3d_completer/cmd/registry_create.go new file mode 100644 index 0000000000..a48318a137 --- /dev/null +++ b/completers/k3d_completer/cmd/registry_create.go @@ -0,0 +1,28 @@ +package cmd + +import ( + "github.com/rsteube/carapace" + "github.com/spf13/cobra" +) + +var registry_createCmd = &cobra.Command{ + Use: "create NAME", + Short: "Create a new registry", + Run: func(cmd *cobra.Command, args []string) {}, +} + +func init() { + carapace.Gen(registry_createCmd).Standalone() + + registry_createCmd.Flags().StringSliceP("cluster", "c", []string{}, "[NotReady] Select the cluster(s) that the registry shall connect to.") + registry_createCmd.Flags().String("default-network", "", "Specify the network connected to the registry") + registry_createCmd.Flags().StringP("image", "i", "", "Specify image used for the registry") + registry_createCmd.Flags().Bool("no-help", false, "Disable the help text (How-To use the registry)") + registry_createCmd.Flags().StringP("port", "p", "", "Select which port the registry should be listening on on your machine (localhost) (Format: `[HOST:]HOSTPORT`)") + registry_createCmd.Flags().String("proxy-password", "", "Specify the password of the proxied remote registry") + registry_createCmd.Flags().String("proxy-remote-url", "", "Specify the url of the proxied remote registry") + registry_createCmd.Flags().String("proxy-username", "", "Specify the username of the proxied remote registry") + registry_createCmd.Flags().StringSliceP("volume", "v", []string{}, "Mount volumes into the registry node (Format: `[SOURCE:]DEST`") + registry_createCmd.Flag("cluster").Hidden = true + registryCmd.AddCommand(registry_createCmd) +} diff --git a/completers/k3d_completer/cmd/registry_delete.go b/completers/k3d_completer/cmd/registry_delete.go new file mode 100644 index 0000000000..ad7b9d33c5 --- /dev/null +++ b/completers/k3d_completer/cmd/registry_delete.go @@ -0,0 +1,20 @@ +package cmd + +import ( + "github.com/rsteube/carapace" + "github.com/spf13/cobra" +) + +var registry_deleteCmd = &cobra.Command{ + Use: "delete (NAME | --all)", + Short: "Delete registry/registries.", + Aliases: []string{"del", "rm"}, + Run: func(cmd *cobra.Command, args []string) {}, +} + +func init() { + carapace.Gen(registry_deleteCmd).Standalone() + + registry_deleteCmd.Flags().BoolP("all", "a", false, "Delete all existing registries") + registryCmd.AddCommand(registry_deleteCmd) +} diff --git a/completers/k3d_completer/cmd/registry_list.go b/completers/k3d_completer/cmd/registry_list.go new file mode 100644 index 0000000000..15d4e97367 --- /dev/null +++ b/completers/k3d_completer/cmd/registry_list.go @@ -0,0 +1,21 @@ +package cmd + +import ( + "github.com/rsteube/carapace" + "github.com/spf13/cobra" +) + +var registry_listCmd = &cobra.Command{ + Use: "list [NAME [NAME...]]", + Short: "List registries", + Aliases: []string{"ls", "get"}, + Run: func(cmd *cobra.Command, args []string) {}, +} + +func init() { + carapace.Gen(registry_listCmd).Standalone() + + registry_listCmd.Flags().Bool("no-headers", false, "Disable headers") + registry_listCmd.Flags().StringP("output", "o", "", "Output format. One of: json|yaml") + registryCmd.AddCommand(registry_listCmd) +} diff --git a/completers/k3d_completer/cmd/root.go b/completers/k3d_completer/cmd/root.go new file mode 100644 index 0000000000..51ecd15ae9 --- /dev/null +++ b/completers/k3d_completer/cmd/root.go @@ -0,0 +1,25 @@ +package cmd + +import ( + "github.com/rsteube/carapace" + "github.com/spf13/cobra" +) + +var rootCmd = &cobra.Command{ + Use: "k3d", + Short: "https://k3d.io/ -> Run k3s in Docker!", + Run: func(cmd *cobra.Command, args []string) {}, +} + +func Execute() error { + return rootCmd.Execute() +} + +func init() { + carapace.Gen(rootCmd).Standalone() + + rootCmd.PersistentFlags().Bool("timestamps", false, "Enable Log timestamps") + rootCmd.PersistentFlags().Bool("trace", false, "Enable super verbose output (trace logging)") + rootCmd.PersistentFlags().Bool("verbose", false, "Enable verbose output (debug logging)") + rootCmd.Flags().Bool("version", false, "Show k3d and default k3s version") +} diff --git a/completers/k3d_completer/cmd/runtimeInfo.go b/completers/k3d_completer/cmd/runtimeInfo.go new file mode 100644 index 0000000000..5b548a330d --- /dev/null +++ b/completers/k3d_completer/cmd/runtimeInfo.go @@ -0,0 +1,19 @@ +package cmd + +import ( + "github.com/rsteube/carapace" + "github.com/spf13/cobra" +) + +var runtimeInfoCmd = &cobra.Command{ + Use: "runtime-info", + Short: "Show runtime information", + Hidden: true, + Run: func(cmd *cobra.Command, args []string) {}, +} + +func init() { + carapace.Gen(runtimeInfoCmd).Standalone() + + rootCmd.AddCommand(runtimeInfoCmd) +} diff --git a/completers/k3d_completer/cmd/version.go b/completers/k3d_completer/cmd/version.go new file mode 100644 index 0000000000..5f1ce08279 --- /dev/null +++ b/completers/k3d_completer/cmd/version.go @@ -0,0 +1,19 @@ +package cmd + +import ( + "github.com/rsteube/carapace" + "github.com/spf13/cobra" +) + +var versionCmd = &cobra.Command{ + Use: "version", + Short: "Show k3d and default k3s version", + Run: func(cmd *cobra.Command, args []string) {}, +} + +func init() { + carapace.Gen(versionCmd).Standalone() + + versionCmd.Flags().StringP("output", "o", "", "This will return version information as a different format. Only json is supported") + rootCmd.AddCommand(versionCmd) +} diff --git a/completers/k3d_completer/cmd/version_list.go b/completers/k3d_completer/cmd/version_list.go new file mode 100644 index 0000000000..85bd952611 --- /dev/null +++ b/completers/k3d_completer/cmd/version_list.go @@ -0,0 +1,25 @@ +package cmd + +import ( + "github.com/rsteube/carapace" + "github.com/spf13/cobra" +) + +var version_listCmd = &cobra.Command{ + Use: "list COMPONENT", + Short: "List k3d/K3s versions. Component can be one of 'k3d', 'k3s', 'k3d-proxy', 'k3d-tools'.", + Aliases: []string{"ls"}, + Run: func(cmd *cobra.Command, args []string) {}, +} + +func init() { + carapace.Gen(version_listCmd).Standalone() + + version_listCmd.Flags().StringP("exclude", "e", "", "Exclude Regexp (default excludes pre-releases and arch-specific tags)") + version_listCmd.Flags().StringP("format", "f", "", "[DEPRECATED] Use --output instead") + version_listCmd.Flags().StringP("include", "i", "", "Include Regexp (default includes everything") + version_listCmd.Flags().StringP("limit", "l", "", "Limit number of tags in output (0 = unlimited)") + version_listCmd.Flags().StringP("output", "o", "", "Output Format [raw | repo]") + version_listCmd.Flags().StringP("sort", "s", "", "Sort Mode (asc | desc | off)") + versionCmd.AddCommand(version_listCmd) +} diff --git a/completers/k3d_completer/main.go b/completers/k3d_completer/main.go new file mode 100644 index 0000000000..b85d5d3478 --- /dev/null +++ b/completers/k3d_completer/main.go @@ -0,0 +1,7 @@ +package main + +import "github.com/rsteube/carapace-bin/completers/k3d_completer/cmd" + +func main() { + cmd.Execute() +} diff --git a/pkg/actions/tools/k3d/cluster.go b/pkg/actions/tools/k3d/cluster.go new file mode 100644 index 0000000000..6f3bc47854 --- /dev/null +++ b/pkg/actions/tools/k3d/cluster.go @@ -0,0 +1,41 @@ +package k3d + +import ( + "encoding/json" + + "github.com/rsteube/carapace" + "github.com/rsteube/carapace/pkg/style" +) + +type cluster struct { + Name string + ImageVolume string + ServersRunning int + ServersCount int +} + +func (c cluster) style() string { + switch { + case c.ServersRunning == 0: + return style.Carapace.KeywordNegative + case c.ServersRunning < c.ServersCount: + return style.Carapace.KeywordAmbiguous + default: + return style.Carapace.KeywordPositive + } +} + +func ActionClusters() carapace.Action { + return carapace.ActionExecCommand("k3d", "cluster", "list", "--output", "json")(func(output []byte) carapace.Action { + var clusters []cluster + if err := json.Unmarshal(output, &clusters); err != nil { + return carapace.ActionMessage(err.Error()) + } + + vals := make([]string, 0) + for _, c := range clusters { + vals = append(vals, c.Name, c.ImageVolume, c.style()) + } + return carapace.ActionStyledValuesDescribed(vals...) + }) +} diff --git a/pkg/actions/tools/k3d/node.go b/pkg/actions/tools/k3d/node.go new file mode 100644 index 0000000000..7da155a305 --- /dev/null +++ b/pkg/actions/tools/k3d/node.go @@ -0,0 +1,86 @@ +package k3d + +import ( + "encoding/json" + "fmt" + + "github.com/rsteube/carapace" + "github.com/rsteube/carapace/pkg/style" +) + +type NodeOpts struct { + Cluster string + Running bool + Stopped bool +} + +func (n NodeOpts) Default() NodeOpts { + n.Running = true + n.Stopped = true + return n +} + +type node struct { + Name string + Role string + RuntimeLabels struct { + K3dCluster string `json:"k3d.cluster"` + } + State struct { + Running bool + } +} + +func (n node) applies(opts NodeOpts) bool { + switch { + case opts.Cluster != "" && opts.Cluster != n.RuntimeLabels.K3dCluster: + return false + case opts.Running && n.State.Running: + return true + case opts.Stopped && !n.State.Running: + return true + default: + return false + } +} + +func (n node) style() string { + if n.State.Running { + return style.Carapace.KeywordPositive + } + return style.Carapace.KeywordNegative +} + +func ActionNodes(opts NodeOpts) carapace.Action { + return carapace.ActionExecCommand("k3d", "node", "list", "--output", "json")(func(output []byte) carapace.Action { + var nodes []node + if err := json.Unmarshal(output, &nodes); err != nil { + return carapace.ActionMessage(err.Error()) + } + + vals := make([]string, 0) + for _, n := range nodes { + if n.applies(opts) { + vals = append(vals, n.Name, fmt.Sprintf("%v.%v", n.RuntimeLabels.K3dCluster, n.Role), n.style()) + } + } + return carapace.ActionStyledValuesDescribed(vals...) + }) +} + +func ActionNodeGroups() carapace.Action { + return carapace.ActionValues("server", "servers", "agent", "agents", "loadbalancer", "all") +} + +func ActionNodeFilter() carapace.Action { // TODO limit to specific cluster + return carapace.ActionMultiPartsN(":", 3, func(c carapace.Context) carapace.Action { + switch len(c.Parts) { + case 0: + return ActionNodeGroups() + case 1: + return carapace.ActionValues() // TODO subset + default: + return carapace.ActionValues() // TODO suffix + } + }) +}