// Run runs a remote command on a given host to test out SSH / WinRM func Run(c *cli.Context) { port, err := osExpandAndVerifyGlobal(c, "port") if err != nil { fail(err) } command, err := osExpandAndVerify(c, "command") if err != nil { fail(err) } host, err := osExpandAndVerify(c, "host") if err != nil { fail(err) } user, err := osExpandAndVerify(c, "user") if err != nil { fail(err) } connection := c.String("connection") if connection == ansible.ConnectionWinRM { password, err := osExpandAndVerify(c, "password") if err != nil { fail(err) } err = winrm.RemoteWinRmCommand(user, password, host, port, command) } else { privatekey, err := osExpandAndVerify(c, "privatekey") if err != nil { fail(err) } envVars := make(map[string]string) err = ssh.RemoteSSHCommand(user, privatekey, host, port, command, envVars) } if err != nil { log.Err("Failed: %v", err) } }
err = generateBashScript(bash, connection) if err != nil { log.Err("Failed to generate bash script at %s due to: %v", bash, err) return } } if connection == ansible.ConnectionWinRM { password := hostEntry.Password if len(password) == 0 { password = os.ExpandEnv(passwordFlag) if password == "" { log.Die("Cannot connect without a password") } } err = winrm.RemoteWinRmCommand(user, password, host, port, command, kubeclient, rc, hostEntry.Name) } else { privatekey := hostEntry.PrivateKey err = ssh.RemoteSSHCommand(user, privatekey, host, port, command, envVars) } if err != nil { log.Err("Failed: %v", err) } }, } func generateBashScript(file string, connection string) error { shellCommand := "bash" if connection == ansible.ConnectionWinRM { shellCommand = "cmd"
log.Die("Command is required") } host = os.ExpandEnv(host) if host == "" { log.Die("Host is required") } user = os.ExpandEnv(user) if user == "" { log.Die("User is required") } if connection == ansible.ConnectionWinRM { password = os.ExpandEnv(password) if password == "" { log.Die("Password is required") } err := winrm.RemoteWinRmCommand(user, password, host, strconv.Itoa(sshPort), command, nil, nil, "") if err != nil { log.Err("Failed: %v", err) } } else { privatekey = os.ExpandEnv(privatekey) if privatekey == "" { log.Die("Private key is required") } err := ssh.RemoteSSHCommand(user, privatekey, host, strconv.Itoa(sshPort), command, nil) if err != nil { log.Err("Failed: %v", err) } } }, }
// Pod runs the kansible pod for a given group of hosts in an Ansible playbook // this grabs a specific host (using annotations on the RC) then runs a remote command // on that host binding stdin, stdout, stderr to the remote process func Pod(c *cli.Context) { args := c.Args() if len(args) < 1 { log.Die("Expected arguments [hosts] [command]") } hosts := os.ExpandEnv(args[0]) command := "" if len(args) > 1 { command = os.ExpandEnv(strings.Join(args[1:], " ")) } f := cmdutil.NewFactory(nil) if f == nil { log.Die("Failed to create Kubernetes client factory!") } kubeclient, _ := f.Client() if kubeclient == nil { log.Die("Failed to create Kubernetes client!") } ns, _, _ := f.DefaultNamespace() if len(ns) == 0 { ns = "default" } inventory, err := osExpandAndVerify(c, "inventory") if err != nil { fail(err) } rcName, err := osExpandAndVerify(c, "rc") if err != nil { fail(err) } envVars := make(map[string]string) hostEntry, err := ansible.ChooseHostAndPrivateKey(inventory, hosts, kubeclient, ns, rcName, envVars) if err != nil { fail(err) } host := hostEntry.Host user := hostEntry.User port := hostEntry.Port if len(port) == 0 { port, err = osExpandAndVerifyGlobal(c, "port") } if err != nil { fail(err) } connection := hostEntry.Connection if len(connection) == 0 { connection = osExpand(c, "connection") } runCommand := hostEntry.RunCommand if len(runCommand) != 0 { command = runCommand } commandEnvVars := []string{} if len(command) == 0 { if len(connection) > 0 { envVarName := ansible.EnvCommand + "_" + strings.ToUpper(connection) commandEnvVars = append(commandEnvVars, envVarName) command = os.Getenv(envVarName) } } commandEnvVars = append(commandEnvVars, ansible.EnvCommand) if len(command) == 0 { command = os.Getenv(ansible.EnvCommand) } if len(command) == 0 { plural := "" if len(commandEnvVars) > 1 { plural = "s" } fail(fmt.Errorf("Could not find a command to execute from the environment variable%s: %s", plural, strings.Join(commandEnvVars, ", "))) } log.Info("running command on a host from %s and command `%s`", hosts, command) bash := osExpand(c, "bash") if len(bash) > 0 { err = generateBashScript(bash, connection) if err != nil { log.Err("Failed to generate bash script at %s due to: %v", bash, err) } } log.Info("using connection %s", connection) if connection == ansible.ConnectionWinRM { log.Info("Using WinRM to connect to the hosts %s", hosts) password := hostEntry.Password if len(password) == 0 { password, err = osExpandAndVerify(c, "password") if err != nil { fail(err) } } err = winrm.RemoteWinRmCommand(user, password, host, port, command) } else { privatekey := hostEntry.PrivateKey err = ssh.RemoteSSHCommand(user, privatekey, host, port, command, envVars) } if err != nil { log.Err("Failed: %v", err) } }