Merge pull request #10844 from afbjorklund/kubectl-ssh
Allow running kubectl over the ssh connectionpull/10832/head
commit
7a47f16eec
|
@ -27,7 +27,7 @@ import (
|
|||
"k8s.io/minikube/pkg/minikube/style"
|
||||
)
|
||||
|
||||
var path string
|
||||
var docsPath string
|
||||
|
||||
// generateDocs represents the generate-docs command
|
||||
var generateDocs = &cobra.Command{
|
||||
|
@ -38,20 +38,20 @@ var generateDocs = &cobra.Command{
|
|||
Hidden: true,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
// if directory does not exist
|
||||
docsPath, err := os.Stat(path)
|
||||
if err != nil || !docsPath.IsDir() {
|
||||
st, err := os.Stat(docsPath)
|
||||
if err != nil || !st.IsDir() {
|
||||
exit.Message(reason.Usage, "Unable to generate the documentation. Please ensure that the path specified is a directory, exists & you have permission to write to it.")
|
||||
}
|
||||
|
||||
// generate docs
|
||||
if err := generate.Docs(RootCmd, path); err != nil {
|
||||
if err := generate.Docs(RootCmd, docsPath); err != nil {
|
||||
exit.Error(reason.InternalGenerateDocs, "Unable to generate docs", err)
|
||||
}
|
||||
out.Step(style.Documentation, "Docs have been saved at - {{.path}}", out.V{"path": path})
|
||||
out.Step(style.Documentation, "Docs have been saved at - {{.path}}", out.V{"path": docsPath})
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
generateDocs.Flags().StringVar(&path, "path", "", "The path on the file system where the docs in markdown need to be saved")
|
||||
generateDocs.Flags().StringVar(&docsPath, "path", "", "The path on the file system where the docs in markdown need to be saved")
|
||||
RootCmd.AddCommand(generateDocs)
|
||||
}
|
||||
|
|
|
@ -20,14 +20,22 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"syscall"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"k8s.io/klog/v2"
|
||||
"k8s.io/minikube/pkg/minikube/config"
|
||||
"k8s.io/minikube/pkg/minikube/constants"
|
||||
"k8s.io/minikube/pkg/minikube/machine"
|
||||
"k8s.io/minikube/pkg/minikube/mustload"
|
||||
"k8s.io/minikube/pkg/minikube/node"
|
||||
"k8s.io/minikube/pkg/minikube/out"
|
||||
"k8s.io/minikube/pkg/minikube/vmpath"
|
||||
)
|
||||
|
||||
var (
|
||||
useSSH bool
|
||||
)
|
||||
|
||||
// kubectlCmd represents the kubectl command
|
||||
|
@ -36,9 +44,13 @@ var kubectlCmd = &cobra.Command{
|
|||
Short: "Run a kubectl binary matching the cluster version",
|
||||
Long: `Run the Kubernetes client, download it if necessary. Remember -- after kubectl!
|
||||
|
||||
Examples:
|
||||
minikube kubectl -- --help
|
||||
minikube kubectl -- get pods --namespace kube-system`,
|
||||
This will run the Kubernetes client (kubectl) with the same version as the cluster
|
||||
|
||||
Normally it will download a binary matching the host operating system and architecture,
|
||||
but optionally you can also run it directly on the control plane over the ssh connection.
|
||||
This can be useful if you cannot run kubectl locally for some reason, like unsupported
|
||||
host. Please be aware that when using --ssh all paths will apply to the remote machine.`,
|
||||
Example: "minikube kubectl -- --help\nminikube kubectl -- get pods --namespace kube-system",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cc, err := config.Load(ClusterFlagValue())
|
||||
|
||||
|
@ -47,8 +59,31 @@ minikube kubectl -- get pods --namespace kube-system`,
|
|||
version = cc.KubernetesConfig.KubernetesVersion
|
||||
}
|
||||
|
||||
cluster := []string{"--cluster", ClusterFlagValue()}
|
||||
args = append(cluster, args...)
|
||||
cname := ClusterFlagValue()
|
||||
|
||||
if useSSH {
|
||||
co := mustload.Running(cname)
|
||||
n := co.CP.Node
|
||||
|
||||
kc := []string{"sudo"}
|
||||
kc = append(kc, kubectlPath(*co.Config))
|
||||
kc = append(kc, "--kubeconfig")
|
||||
kc = append(kc, kubeconfigPath(*co.Config))
|
||||
args = append(kc, args...)
|
||||
|
||||
klog.Infof("Running SSH %v", args)
|
||||
err := machine.CreateSSHShell(co.API, *co.Config, *n, args, false)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error running kubectl: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if len(args) > 1 && args[0] != "--help" {
|
||||
cluster := []string{"--cluster", cname}
|
||||
args = append(cluster, args...)
|
||||
}
|
||||
|
||||
c, err := KubectlCommand(version, args...)
|
||||
if err != nil {
|
||||
|
@ -66,7 +101,7 @@ minikube kubectl -- get pods --namespace kube-system`,
|
|||
waitStatus := exitError.Sys().(syscall.WaitStatus)
|
||||
rc = waitStatus.ExitStatus()
|
||||
} else {
|
||||
fmt.Fprintf(os.Stderr, "Error running %s: %v\n", path, err)
|
||||
fmt.Fprintf(os.Stderr, "Error running %s: %v\n", c.Path, err)
|
||||
rc = 1
|
||||
}
|
||||
os.Exit(rc)
|
||||
|
@ -74,6 +109,16 @@ minikube kubectl -- get pods --namespace kube-system`,
|
|||
},
|
||||
}
|
||||
|
||||
// kubectlPath returns the path to kubectl
|
||||
func kubectlPath(cfg config.ClusterConfig) string {
|
||||
return path.Join(vmpath.GuestPersistentDir, "binaries", cfg.KubernetesConfig.KubernetesVersion, "kubectl")
|
||||
}
|
||||
|
||||
// kubeconfigPath returns the path to kubeconfig
|
||||
func kubeconfigPath(cfg config.ClusterConfig) string {
|
||||
return "/etc/kubernetes/admin.conf"
|
||||
}
|
||||
|
||||
// KubectlCommand will return kubectl command with a version matching the cluster
|
||||
func KubectlCommand(version string, args ...string) (*exec.Cmd, error) {
|
||||
if version == "" {
|
||||
|
@ -87,3 +132,7 @@ func KubectlCommand(version string, args ...string) (*exec.Cmd, error) {
|
|||
|
||||
return exec.Command(path, args...), nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
kubectlCmd.Flags().BoolVar(&useSSH, "ssh", false, "Use SSH for running kubernetes client on the node")
|
||||
}
|
||||
|
|
|
@ -61,7 +61,10 @@ func main() {
|
|||
bridgeLogMessages()
|
||||
defer klog.Flush()
|
||||
|
||||
setFlags()
|
||||
// Don't parse flags when running as kubectl
|
||||
_, callingCmd := filepath.Split(os.Args[0])
|
||||
parse := callingCmd != "kubectl"
|
||||
setFlags(parse)
|
||||
|
||||
s := stacklog.MustStartFromEnv("STACKLOG_PATH")
|
||||
defer s.Stop()
|
||||
|
@ -124,14 +127,16 @@ func (lb machineLogBridge) Write(b []byte) (n int, err error) {
|
|||
}
|
||||
|
||||
// setFlags sets the flags
|
||||
func setFlags() {
|
||||
func setFlags(parse bool) {
|
||||
// parse flags beyond subcommand - get aroung go flag 'limitations':
|
||||
// "Flag parsing stops just before the first non-flag argument" (ref: https://pkg.go.dev/flag#hdr-Command_line_flag_syntax)
|
||||
pflag.CommandLine.ParseErrorsWhitelist.UnknownFlags = true
|
||||
pflag.CommandLine.AddGoFlagSet(flag.CommandLine)
|
||||
// avoid 'pflag: help requested' error, as help will be defined later by cobra cmd.Execute()
|
||||
pflag.BoolP("help", "h", false, "")
|
||||
pflag.Parse()
|
||||
if parse {
|
||||
pflag.Parse()
|
||||
}
|
||||
|
||||
// set default flag value for logtostderr and alsologtostderr but don't override user's preferences
|
||||
if !pflag.CommandLine.Changed("logtostderr") {
|
||||
|
|
|
@ -13,14 +13,30 @@ Run a kubectl binary matching the cluster version
|
|||
|
||||
Run the Kubernetes client, download it if necessary. Remember -- after kubectl!
|
||||
|
||||
Examples:
|
||||
minikube kubectl -- --help
|
||||
minikube kubectl -- get pods --namespace kube-system
|
||||
This will run the Kubernetes client (kubectl) with the same version as the cluster
|
||||
|
||||
Normally it will download a binary matching the host operating system and architecture,
|
||||
but optionally you can also run it directly on the control plane over the ssh connection.
|
||||
This can be useful if you cannot run kubectl locally for some reason, like unsupported
|
||||
host. Please be aware that when using --ssh all paths will apply to the remote machine.
|
||||
|
||||
```shell
|
||||
minikube kubectl [flags]
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
```
|
||||
minikube kubectl -- --help
|
||||
minikube kubectl -- get pods --namespace kube-system
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
--ssh Use SSH for running kubernetes client on the node
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
|
|
Loading…
Reference in New Issue