Exemplo n.º 1
0
func removeHostEntry(hostEntries []*HostEntry, name string) []*HostEntry {
	for i, entry := range hostEntries {
		if entry.Name == name {
			if i < len(hostEntries)-1 {
				return append(hostEntries[:i], hostEntries[i+1:]...)
			}
			return hostEntries[:i]
		}
	}
	log.Warn("Did not find a host entry with name %s", name)
	return hostEntries
}
Exemplo n.º 2
0
// RemoteSSHCommand invokes the given command on a host and port
func RemoteSSHCommand(user string, privateKey string, host string, port string, cmd string, envVars map[string]string) error {
	if len(privateKey) == 0 {
		return fmt.Errorf("Could not find PrivateKey for entry %s", host)
	}
	log.Info("Connecting to host over SSH on host %s and port %s with user %s with command `%s`", host, port, user, cmd)

	hostPort := net.JoinHostPort(host, port)

	sshConfig := &ssh.ClientConfig{
		User: user,
		Auth: []ssh.AuthMethod{
			PublicKeyFile(privateKey),
		},
	}
	if sshConfig == nil {
		log.Warn("No sshConfig could be created!")
	}
	connection, err := ssh.Dial("tcp", hostPort, sshConfig)
	if err != nil {
		return fmt.Errorf("Failed to dial: %s", err)
	}
	session, err := connection.NewSession()
	if err != nil {
		return fmt.Errorf("Failed to create session: %s", err)
	}
	defer session.Close()

	modes := ssh.TerminalModes{
		// ssh.ECHO:          0,     // disable echoing
		ssh.TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud
		ssh.TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud
	}

	if err := session.RequestPty("xterm", 80, 40, modes); err != nil {
		return fmt.Errorf("Request for pseudo terminal failed: %s", err)
	}

	stdin, err := session.StdinPipe()
	if err != nil {
		return fmt.Errorf("Unable to setup stdin for session: %v", err)
	}
	go io.Copy(stdin, os.Stdin)

	stdout, err := session.StdoutPipe()
	if err != nil {
		return fmt.Errorf("Unable to setup stdout for session: %v", err)
	}
	go io.Copy(os.Stdout, stdout)

	stderr, err := session.StderrPipe()
	if err != nil {
		return fmt.Errorf("Unable to setup stderr for session: %v", err)
	}
	go io.Copy(os.Stderr, stderr)

	for envName, envValue := range envVars {
		log.Info("Setting environment value %s = %s", envName, envValue)
		if err := session.Setenv(envName, envValue); err != nil {
			return fmt.Errorf("Could not set environment variable %s = %s over SSH. This could be disabled by the sshd configuration. See the `AcceptEnv` setting in your /etc/ssh/sshd_config more info: http://linux.die.net/man/5/sshd_config . Error: %s", envName, envValue, err)
		}
	}

	signals := make(chan os.Signal, 1)
	signal.Notify(signals, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)
	signaled := false
	go func() {
		<-signals
		log.Info("Shutting down SSH session.")
		signaled = true
		session.Close()
	}()

	log.Info("Running command %s", cmd)
	err = session.Run(cmd)
	if !signaled && err != nil {
		return fmt.Errorf("Failed to run command: "+cmd+": %v", err)
	}
	return nil
}
Exemplo n.º 3
0
// RemoteWinRmCommand runs the remote command on a windows machine
func RemoteWinRmCommand(user string, password string, host string, port string, commandText string, c *client.Client, rc *api.ReplicationController, hostName string) error {
	portNumber, err := parsePortNumber(port)
	if err != nil {
		return err
	}
	log.Info("Connecting to windows host over WinRM on host %s and port %d with user %s with command `%s`", host, portNumber, user, commandText)
	client, err := winrm.NewClient(&winrm.Endpoint{Host: host, Port: portNumber, HTTPS: false, Insecure: false}, user, password)
	if err != nil {
		return fmt.Errorf("Could not create WinRM client: %s", err)
	}

	isBash := false
	isBashShellText := os.Getenv(ansible.EnvIsBashShell)
	if len(isBashShellText) > 0 && strings.ToLower(isBashShellText) == "true" {
		isBash = true
	}
	if rc.ObjectMeta.Annotations != nil && !isBash {
		oldShellID := rc.ObjectMeta.Annotations[ansible.WinRMShellAnnotationPrefix+hostName]
		if len(oldShellID) > 0 {
			// lets close the previously running shell on this machine
			log.Info("Closing the old WinRM Shell %s", oldShellID)
			shell := client.NewShell(oldShellID)
			err = shell.Close()
			if err != nil {
				log.Warn("Failed to close shell %s. Error: %s", oldShellID, err)
			}
		}
	}

	shell, err := client.CreateShell()
	if err != nil {
		return fmt.Errorf("Impossible to create WinRM shell: %s", err)
	}
	defer shell.Close()
	shellID := shell.ShellId
	log.Info("Created WinRM Shell %s", shellID)

	if rc != nil && c != nil && !isBash {
		rc.ObjectMeta.Annotations[ansible.WinRMShellAnnotationPrefix+hostName] = shellID
		_, err = c.ReplicationControllers(rc.ObjectMeta.Namespace).UpdateStatus(rc)
		if err != nil {
			return err
		}
	}

	var cmd *winrm.Command
	cmd, err = shell.Execute(commandText)
	if err != nil {
		return fmt.Errorf("Impossible to create Command %s\n", err)
	}

	go io.Copy(cmd.Stdin, os.Stdin)
	go io.Copy(os.Stdout, cmd.Stdout)
	go io.Copy(os.Stderr, cmd.Stderr)

	cmd.Wait()

	exitCode := cmd.ExitCode()
	if exitCode > 0 {
		return fmt.Errorf("Failed to run command '%s' got exit code %d", commandText, exitCode)
	}

	// TODO
	// return cmd.Error()
	return nil
}