Home > Back-end >  cobra-cli pass all arguments and flags to an executable
cobra-cli pass all arguments and flags to an executable

Time:06-23

I have a cobra CLI for my own stuff. Now I want to add commonly used executables e.g. kubectl, calicoctl as subcommands which will consume all arguments and flags like

mywrapper kubectl get all --all-namespaces
mywrapper kubectl create deployment nginx --image=nginx --port=80

Reproduce cobra project

mkdir mywrapper; cd mywrapper; go mod init mywrapper; cobra-cli init .

And add a subcommand e.g. kubectl

cobra-cli add kubectl 

Then populate ./cmd/kubectl.go with

package cmd

import (
    "fmt"
    "os/exec"
    "strings"

    "github.com/spf13/cobra"
)

var kubectlCmd = &cobra.Command{
    Use:   "kubectl",
    Short: "run kubectl",
    Run: func(cmd *cobra.Command, args []string) {
        out, err := exec.Command("/bin/bash", "-c", fmt.Sprintf("kubectl %v", strings.Join(args, " "))).Output()
        if err != nil {
            fmt.Println(err)
        }
        fmt.Println(string(out))
    },
}

func init() {
    rootCmd.AddCommand(kubectlCmd)
}

I can now run kubectl command e.g. go run . kubectl get pods. But it fails when flags are added e.g. go run . kubectl get pods --selector app=nginx

CodePudding user response:

Pass your flags after the --. A double dash (--) is used to signify the end of command options. In our case it is required to distinguish between the flags passed to go and those that aren't. Everything after the double dash wont be considered to be go's flags.

I tried with gcloud:

package cmd

import (
    "fmt"
    "os/exec"

    "github.com/spf13/cobra"
)

var gcloudCmd = &cobra.Command{
    Use:   "gcloud",
    Short: "run gcloud",
    Run: func(cmd *cobra.Command, args []string) {
        out, err := exec.Command("gcloud", args...).Output()
        if err != nil {
            fmt.Println(err)
        }
        fmt.Println(string(out))
    },
}

func init() {
    rootCmd.AddCommand(gcloudCmd)
}

Then tried:

$ go run . gcloud compute regions list -- --filter="id<1250"

NAME          CPUS  DISKS_GB  ADDRESSES  RESERVED_ADDRESSES  STATUS  TURNDOWN_DATE
asia-east1    0/24  0/4096    0/8        0/8                 UP
europe-west1  0/24  0/4096    0/8        0/8                 UP
us-central1   0/24  0/4096    0/8        0/8                 UP
us-east1      0/24  0/4096    0/8        0/8                 UP
us-west1      0/24  0/4096    0/8        0/8                 UP

Adding more flags:

$ go run . gcloud compute regions list -- --filter="id<1250" --format="table(name,id)"

NAME          ID
asia-east1    1220
europe-west1  1100
us-central1   1000
us-east1      1230
us-west1      1210
  • Related