Example #1
0
func getRegistryClient() (client.API, error) {
	var dial func(string, string) (net.Conn, error)
	tun := getTunnelFlag()
	if tun != "" {
		sshClient, err := ssh.NewSSHClient("core", tun, getChecker(), false)
		if err != nil {
			return nil, fmt.Errorf("failed initializing SSH client: %v", err)
		}

		dial = func(network, addr string) (net.Conn, error) {
			tcpaddr, err := net.ResolveTCPAddr(network, addr)
			if err != nil {
				return nil, err
			}
			return sshClient.DialTCP(network, nil, tcpaddr)
		}
	}

	trans := http.Transport{
		Dial: dial,
		TLSClientConfig: &tls.Config{
			InsecureSkipVerify: true,
		},
	}

	return client.NewRegistryClient(&trans, globalFlags.Endpoint, globalFlags.EtcdKeyPrefix)
}
Example #2
0
func getRegistry() *registry.Registry {
	tun := getTunnelFlag()
	endpoint := getEndpointFlag()

	machines := []string{endpoint}
	client := etcd.NewClient(machines)

	if tun != "" {
		sshClient, err := ssh.NewSSHClient("core", tun, getChecker(), false)
		if err != nil {
			log.Fatalf("Failed initializing SSH client: %v", err)
		}

		dial := func(network, addr string) (net.Conn, error) {
			tcpaddr, err := net.ResolveTCPAddr(network, addr)
			if err != nil {
				return nil, err
			}
			return sshClient.DialTCP(network, nil, tcpaddr)
		}

		tr := http.Transport{
			Dial: dial,
			TLSClientConfig: &tls.Config{
				InsecureSkipVerify: true,
			},
		}

		client.SetTransport(&tr)
	}

	return registry.New(client)
}
Example #3
0
func getRegistry(context *cli.Context) *registry.Registry {
	tun := getTunnelFlag(context)
	endpoint := context.GlobalString("endpoint")

	machines := []string{endpoint}
	client := etcd.NewClient(machines)

	if tun != "" {
		sshClient, err := ssh.NewSSHClient("core", tun)
		if err != nil {
			panic(err)
		}

		dial := func(network, addr string) (net.Conn, error) {
			tcpaddr, err := net.ResolveTCPAddr(network, addr)
			if err != nil {
				return nil, err
			}
			return sshClient.DialTCP(network, nil, tcpaddr)
		}

		tr := http.Transport{
			Dial: dial,
			TLSClientConfig: &tls.Config{
				InsecureSkipVerify: true,
			},
		}

		client.SetTransport(&tr)
	}

	return registry.New(client)
}
Example #4
0
// getRegistry initializes a connection to the Registry
func getRegistry() registry.Registry {
	tun := getTunnelFlag()

	machines := []string{globalFlags.Endpoint}
	client := etcd.NewClient(machines)

	if tun != "" {
		sshClient, err := ssh.NewSSHClient("core", tun, getChecker(), false)
		if err != nil {
			fmt.Fprintf(os.Stderr, "Failed initializing SSH client: %v\n", err)
			os.Exit(1)
		}

		dial := func(network, addr string) (net.Conn, error) {
			tcpaddr, err := net.ResolveTCPAddr(network, addr)
			if err != nil {
				return nil, err
			}
			return sshClient.DialTCP(network, nil, tcpaddr)
		}

		tr := http.Transport{
			Dial: dial,
			TLSClientConfig: &tls.Config{
				InsecureSkipVerify: true,
			},
		}

		client.SetTransport(&tr)
	}

	return registry.New(client, globalFlags.EtcdKeyPrefix)
}
Example #5
0
func runSSH(args []string) (exit int) {
	if flagUnit != "" && flagMachine != "" {
		fmt.Fprintln(os.Stderr, "Both machine and unit flags provided, please specify only one.")
		return 1
	}

	var err error
	var addr string

	switch {
	case flagMachine != "":
		addr, _ = findAddressInMachineList(flagMachine)
	case flagUnit != "":
		addr, _ = findAddressInRunningUnits(flagUnit)
	default:
		addr, err = globalMachineLookup(args)
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			return 1
		}
		// trim machine/unit name from args
		if len(args) > 0 {
			args = args[1:]
		}
	}

	if addr == "" {
		fmt.Fprintln(os.Stderr, "Requested machine could not be found.")
		return 1
	}

	args = pkg.TrimToDashes(args)

	var sshClient *ssh.SSHForwardingClient
	if tun := getTunnelFlag(); tun != "" {
		sshClient, err = ssh.NewTunnelledSSHClient("core", tun, addr, getChecker(), flagSSHAgentForwarding)
	} else {
		sshClient, err = ssh.NewSSHClient("core", addr, getChecker(), flagSSHAgentForwarding)
	}
	if err != nil {
		fmt.Fprintf(os.Stderr, "Failed building SSH client: %v\n", err)
		return 1
	}

	defer sshClient.Close()

	if len(args) > 0 {
		cmd := strings.Join(args, " ")
		err, exit = ssh.Execute(sshClient, cmd)
		if err != nil {
			fmt.Fprintf(os.Stderr, "Failed running command over SSH: %v\n", err)
		}
	} else {
		if err := ssh.Shell(sshClient); err != nil {
			fmt.Fprintf(os.Stderr, "Failed opening shell over SSH: %v\n", err)
			exit = 1
		}
	}
	return
}
Example #6
0
func printUnitStatus(c *cli.Context, jobName string) {
	js := registryCtl.GetJobState(jobName)

	if js == nil {
		fmt.Printf("%s does not appear to be running\n", jobName)
		syscall.Exit(1)
	}

	addr := fmt.Sprintf("%s:22", js.MachineState.PublicIP)

	var err error
	var sshClient *ssh.SSHForwardingClient

	if tun := getTunnelFlag(); tun != "" {
		sshClient, err = ssh.NewTunnelledSSHClient("core", tun, addr, getChecker(), false)
	} else {
		sshClient, err = ssh.NewSSHClient("core", addr, getChecker(), false)
	}
	if err != nil {
		log.Fatal(err.Error())
	}

	defer sshClient.Close()

	cmd := fmt.Sprintf("systemctl status -l %s", jobName)
	channel, err := ssh.Execute(sshClient, cmd)
	if err != nil {
		log.Fatalf("Unable to execute command over SSH: %s", err.Error())
	}

	readSSHChannel(channel)
}
Example #7
0
func getRegistryClient() (client.API, error) {
	var dial func(string, string) (net.Conn, error)
	tun := getTunnelFlag()
	if tun != "" {
		sshClient, err := ssh.NewSSHClient("core", tun, getChecker(), false)
		if err != nil {
			return nil, fmt.Errorf("failed initializing SSH client: %v", err)
		}

		dial = func(network, addr string) (net.Conn, error) {
			tcpaddr, err := net.ResolveTCPAddr(network, addr)
			if err != nil {
				return nil, err
			}
			return sshClient.DialTCP(network, nil, tcpaddr)
		}
	}

	tlsConfig, err := etcd.ReadTLSConfigFiles(globalFlags.EtcdCAFile, globalFlags.EtcdCertFile, globalFlags.EtcdKeyFile)
	if err != nil {
		return nil, err
	}

	trans := http.Transport{
		Dial:            dial,
		TLSClientConfig: tlsConfig,
	}

	timeout := time.Duration(globalFlags.RequestTimeout*1000) * time.Millisecond
	return client.NewRegistryClient(&trans, globalFlags.Endpoint, globalFlags.EtcdKeyPrefix, timeout)
}
Example #8
0
func sshAction(c *cli.Context) {
	unit := c.String("unit")
	machine := c.String("machine")

	if unit != "" && machine != "" {
		log.Fatal("Both flags, machine and unit provided, please specify only one")
	}

	args := c.Args()
	var err error
	var addr string

	switch {
	case machine != "":
		addr, _ = findAddressInMachineList(machine)
	case unit != "":
		addr, _ = findAddressInRunningUnits(unit)
	default:
		addr, err = globalMachineLookup(args)
		args = args[1:]
	}

	if err != nil {
		log.Fatal(err)
	}

	if addr == "" {
		log.Fatalf("Requested machine could not be found")
	}

	agentForwarding := c.Bool("agent")

	var sshClient *ssh.SSHForwardingClient
	if tun := getTunnelFlag(); tun != "" {
		sshClient, err = ssh.NewTunnelledSSHClient("core", tun, addr, getChecker(), agentForwarding)
	} else {
		sshClient, err = ssh.NewSSHClient("core", addr, getChecker(), agentForwarding)
	}
	if err != nil {
		log.Fatal(err.Error())
		return
	}

	defer sshClient.Close()

	if len(args) > 0 {
		cmd := strings.Join(args, " ")
		channel, err := ssh.Execute(sshClient, cmd)
		if err != nil {
			log.Fatalf("Unable to run command over SSH: %s", err.Error())
		}

		readSSHChannel(channel)
	} else {
		if err := ssh.Shell(sshClient); err != nil {
			log.Fatalf(err.Error())
		}
	}
}
Example #9
0
File: fleetctl.go Project: pulcy/j2
func getRegistryClient(cCmd *cobra.Command) (client.API, error) {
	var dial func(string, string) (net.Conn, error)
	SSHUserName, _ := cmdFleet.PersistentFlags().GetString("ssh-username")
	tun := getTunnelFlag(cCmd)
	if tun != "" {
		sshClient, err := ssh.NewSSHClient(SSHUserName, tun, getChecker(cCmd), false, getSSHTimeoutFlag(cCmd))
		if err != nil {
			return nil, fmt.Errorf("failed initializing SSH client: %v", err)
		}

		dial = func(network, addr string) (net.Conn, error) {
			tcpaddr, err := net.ResolveTCPAddr(network, addr)
			if err != nil {
				return nil, err
			}
			return sshClient.DialTCP(network, nil, tcpaddr)
		}
	}

	CAFile, _ := cmdFleet.PersistentFlags().GetString("ca-file")
	CertFile, _ := cmdFleet.PersistentFlags().GetString("cert-file")
	KeyFile, _ := cmdFleet.PersistentFlags().GetString("key-file")
	tlsConfig, err := pkg.ReadTLSConfigFiles(CAFile, CertFile, KeyFile)
	if err != nil {
		return nil, err
	}

	trans := &http.Transport{
		Dial:            dial,
		TLSClientConfig: tlsConfig,
	}

	endPoint, _ := cmdFleet.PersistentFlags().GetString("endpoint")
	eCfg := etcd.Config{
		Endpoints:               strings.Split(endPoint, ","),
		Transport:               trans,
		HeaderTimeoutPerRequest: getRequestTimeoutFlag(cCmd),
	}

	eClient, err := etcd.New(eCfg)
	if err != nil {
		return nil, err
	}

	etcdKeyPrefix, _ := cmdFleet.PersistentFlags().GetString("etcd-key-prefix")
	kAPI := etcd.NewKeysAPI(eClient)
	reg := registry.NewEtcdRegistry(kAPI, etcdKeyPrefix)

	if msg, ok := checkVersion(reg); !ok {
		stderr(msg)
	}

	return &client.RegistryClient{Registry: reg}, nil
}
Example #10
0
func journalAction(c *cli.Context) {
	if len(c.Args()) != 1 {
		fmt.Println("One unit file must be provided.")
		syscall.Exit(1)
	}
	jobName := c.Args()[0]

	js := registryCtl.GetJobState(jobName)

	if js == nil {
		fmt.Printf("%s does not appear to be running\n", jobName)
		syscall.Exit(1)
	}

	addr := fmt.Sprintf("%s:22", js.MachineState.PublicIP)

	var err error
	var sshClient *gossh.ClientConn
	if tun := getTunnelFlag(); tun != "" {
		sshClient, err = ssh.NewTunnelledSSHClient("core", tun, addr)
	} else {
		sshClient, err = ssh.NewSSHClient("core", addr)
	}
	if err != nil {
		log.Fatal(err.Error())
	}

	defer sshClient.Close()

	cmd := fmt.Sprintf("journalctl -u %s --no-pager -l -n %d", jobName, c.Int("lines"))
	if c.Bool("follow") {
		cmd += " -f"
	}
	stdout, err := ssh.Execute(sshClient, cmd)
	if err != nil {
		log.Fatalf("Unable to run command over SSH: %s", err.Error())
	}

	for true {
		bytes, prefix, err := stdout.ReadLine()
		if err != nil {
			break
		}

		fmt.Print(string(bytes))
		if !prefix {
			fmt.Print("\n")
		}
	}
}
Example #11
0
// runRemoteCommand runs the given command over SSH on the given IP, and returns
// any error encountered and the exit status of the command
func runRemoteCommand(cmd string, addr string) (err error, exit int) {
	var sshClient *ssh.SSHForwardingClient
	if tun := getTunnelFlag(); tun != "" {
		sshClient, err = ssh.NewTunnelledSSHClient("core", tun, addr, getChecker(), false)
	} else {
		sshClient, err = ssh.NewSSHClient("core", addr, getChecker(), false)
	}
	if err != nil {
		return err, -1
	}

	defer sshClient.Close()

	return ssh.Execute(sshClient, cmd)
}
Example #12
0
File: fleet.go Project: pulcy/j2
func getRegistryClient(config FleetConfig) (client.API, error) {
	var dial func(string, string) (net.Conn, error)
	tun := config.Tunnel
	if tun != "" {
		sshClient, err := ssh.NewSSHClient(config.SSHUserName, tun, getChecker(config), false, config.SSHTimeout)
		if err != nil {
			return nil, fmt.Errorf("failed initializing SSH client: %v", err)
		}

		dial = func(network, addr string) (net.Conn, error) {
			tcpaddr, err := net.ResolveTCPAddr(network, addr)
			if err != nil {
				return nil, err
			}
			return sshClient.DialTCP(network, nil, tcpaddr)
		}
	}

	tlsConfig, err := pkg.ReadTLSConfigFiles(config.CAFile, config.CertFile, config.KeyFile)
	if err != nil {
		return nil, err
	}

	trans := &http.Transport{
		Dial:            dial,
		TLSClientConfig: tlsConfig,
	}

	eCfg := etcd.Config{
		Endpoints:               strings.Split(config.EndPoint, ","),
		Transport:               trans,
		HeaderTimeoutPerRequest: config.RequestTimeout,
	}

	eClient, err := etcd.New(eCfg)
	if err != nil {
		return nil, err
	}

	kAPI := etcd.NewKeysAPI(eClient)
	reg := registry.NewEtcdRegistry(kAPI, config.EtcdKeyPrefix)

	/*if msg, ok := checkVersion(reg); !ok {
		stderr(msg)
	}*/

	return &client.RegistryClient{Registry: reg}, nil
}
Example #13
0
// runRemoteCommand runs the given command over SSH on the given IP, and returns
// any error encountered and the exit status of the command
func runRemoteCommand(cmd string, addr string, timeout time.Duration) (exit int, err error) {
	var sshClient *ssh.SSHForwardingClient
	if tun := getTunnelFlag(); tun != "" {
		sshClient, err = ssh.NewTunnelledSSHClient("core", tun, addr, getChecker(), false, timeout)
	} else {
		sshClient, err = ssh.NewSSHClient("core", addr, getChecker(), false, timeout)
	}
	if err != nil {
		return -1, err
	}

	defer sshClient.Close()

	err, exit = ssh.Execute(sshClient, cmd)
	return
}
Example #14
0
// runRemoteCommand runs the given command over SSH on the given IP, and returns
// any error encountered and the exit status of the command
func runRemoteCommand(cmd string, addr string) (err error, exit int) {
	var sshClient *ssh.SSHForwardingClient
	timeout := getSSHTimeoutFlag()
	if tun := getTunnelFlag(); tun != "" {
		sshClient, err = ssh.NewTunnelledSSHClient(globalFlags.SSHUserName, tun, addr, getChecker(), false, timeout)
	} else {
		sshClient, err = ssh.NewSSHClient(globalFlags.SSHUserName, addr, getChecker(), false, timeout)
	}
	if err != nil {
		return err, -1
	}

	defer sshClient.Close()

	return ssh.Execute(sshClient, cmd)
}
Example #15
0
File: ssh.go Project: gpxl/deis
// SSH opens an interactive shell to a machine in the cluster
func (c *FleetClient) SSH(name string) (err error) {
	var sshClient *ssh.SSHForwardingClient

	timeout := time.Duration(Flags.SSHTimeout*1000) * time.Millisecond

	ms, err := c.machineState(name)
	if err != nil {
		return err
	}

	// If name isn't a machine ID, try it as a unit instead
	if ms == nil {
		units, err := c.Units(name)

		if err != nil {
			return err
		}

		machID, err := c.findUnit(units[0])

		if err != nil {
			return err
		}

		ms, err = c.machineState(machID)

		if err != nil || ms == nil {
			return err
		}
	}

	addr := ms.PublicIP

	if tun := getTunnelFlag(); tun != "" {
		sshClient, err = ssh.NewTunnelledSSHClient("core", tun, addr, getChecker(), false, timeout)
	} else {
		sshClient, err = ssh.NewSSHClient("core", addr, getChecker(), false, timeout)
	}
	if err != nil {
		return err
	}

	defer sshClient.Close()
	err = ssh.Shell(sshClient)
	return err
}
Example #16
0
func getRegistryClient() (client.API, error) {
	var dial func(string, string) (net.Conn, error)
	sshTimeout := time.Duration(Flags.SSHTimeout*1000) * time.Millisecond
	tun := getTunnelFlag()
	if tun != "" {
		sshClient, err := ssh.NewSSHClient("core", tun, getChecker(), false, sshTimeout)
		if err != nil {
			return nil, fmt.Errorf("failed initializing SSH client: %v", err)
		}

		dial = func(network, addr string) (net.Conn, error) {
			tcpaddr, err := net.ResolveTCPAddr(network, addr)
			if err != nil {
				return nil, err
			}
			return sshClient.DialTCP(network, nil, tcpaddr)
		}
	}

	tlsConfig, err := pkg.ReadTLSConfigFiles(Flags.EtcdCAFile, Flags.EtcdCertFile, Flags.EtcdKeyFile)
	if err != nil {
		return nil, err
	}

	trans := &http.Transport{
		Dial:            dial,
		TLSClientConfig: tlsConfig,
	}

	timeout := time.Duration(Flags.RequestTimeout*1000) * time.Millisecond
	machines := []string{Flags.Endpoint}
	eClient, err := etcd.NewClient(machines, trans, timeout)
	if err != nil {
		return nil, err
	}

	reg := registry.NewEtcdRegistry(eClient, Flags.EtcdKeyPrefix)

	// if msg, ok := checkVersion(reg); !ok {
	// 	stderr(msg)
	// }

	return &client.RegistryClient{Registry: reg}, nil
}
Example #17
0
func getHTTPClient() (client.API, error) {
	dialDomainSocket := strings.HasPrefix(globalFlags.Endpoint, "/")

	tunnelFunc := net.Dial
	tun := getTunnelFlag()
	if tun != "" {
		sshClient, err := ssh.NewSSHClient(globalFlags.SSHUserName, tun, getChecker(), false)
		if err != nil {
			return nil, fmt.Errorf("failed initializing SSH client: %v", err)
		}

		tunnelFunc = func(net, addr string) (net.Conn, error) {
			return sshClient.Dial(net, addr)
		}
	}

	dialFunc := tunnelFunc
	if dialDomainSocket {
		dialFunc = func(net, addr string) (net.Conn, error) {
			return tunnelFunc("unix", globalFlags.Endpoint)
		}
	}

	trans := pkg.LoggingHTTPTransport{
		http.Transport{
			Dial: dialFunc,
		},
	}

	hc := http.Client{
		Transport: &trans,
	}

	endpoint := globalFlags.Endpoint
	if dialDomainSocket {
		endpoint = "http://domain-sock/"
	} else if !strings.HasPrefix(endpoint, "http") {
		endpoint = fmt.Sprintf("http://%s", endpoint)
	}

	return client.NewHTTPClient(&hc, endpoint)
}
Example #18
0
func printUnitStatus(c *cli.Context, r *registry.Registry, jobName string) {
	js := r.GetJobState(jobName)

	if js == nil {
		fmt.Printf("%s does not appear to be running\n", jobName)
		syscall.Exit(1)
	}

	addr := fmt.Sprintf("%s:22", js.MachineState.PublicIP)

	var err error
	var sshClient *gossh.ClientConn
	if tun := getTunnelFlag(c); tun != "" {
		sshClient, err = ssh.NewTunnelledSSHClient("core", tun, addr)
	} else {
		sshClient, err = ssh.NewSSHClient("core", addr)
	}
	if err != nil {
		log.Fatalf("Unable to establish SSH connection: %v", err)
	}

	defer sshClient.Close()

	cmd := fmt.Sprintf("systemctl status -l %s", jobName)
	stdout, err := ssh.Execute(sshClient, cmd)
	if err != nil {
		log.Fatalf("Unable to execute command over SSH: %s", err.Error())
	}

	for true {
		bytes, prefix, err := stdout.ReadLine()
		if err != nil {
			break
		}

		print(string(bytes))
		if !prefix {
			print("\n")
		}
	}
}
Example #19
0
File: etcd.go Project: gpxl/deis
func getEtcdClient() (*etcdClient, error) {
	var dial func(string, string) (net.Conn, error)
	sshTimeout := time.Duration(fleet.Flags.SSHTimeout*1000) * time.Millisecond
	tun := getTunnelFlag()
	if tun != "" {
		sshClient, err := ssh.NewSSHClient("core", tun, getChecker(), false, sshTimeout)
		if err != nil {
			return nil, fmt.Errorf("failed initializing SSH client: %v", err)
		}

		dial = func(network, addr string) (net.Conn, error) {
			tcpaddr, err := net.ResolveTCPAddr(network, addr)
			if err != nil {
				return nil, err
			}
			return sshClient.DialTCP(network, nil, tcpaddr)
		}
	}

	tlsConfig, err := pkg.ReadTLSConfigFiles(fleet.Flags.EtcdCAFile,
		fleet.Flags.EtcdCertFile, fleet.Flags.EtcdKeyFile)
	if err != nil {
		return nil, err
	}

	trans := http.Transport{
		Dial:            dial,
		TLSClientConfig: tlsConfig,
	}

	timeout := time.Duration(fleet.Flags.RequestTimeout*1000) * time.Millisecond
	machines := []string{fleet.Flags.Endpoint}

	c := etcd.NewClient(machines)
	c.SetDialTimeout(timeout)

	// use custom transport with SSH tunnel capability
	c.SetTransport(&trans)

	return &etcdClient{etcd: c}, nil
}
Example #20
0
File: ssh.go Project: pulcy/j2
// runRemoteCommand runs the given command over SSH on the given IP, and returns
// any error encountered and the exit status of the command
func runRemoteCommand(cCmd *cobra.Command, addr string, cmd string, args ...string) (err error, exit int) {
	var sshClient *ssh.SSHForwardingClient
	timeout := getSSHTimeoutFlag(cCmd)
	if tun := getTunnelFlag(cCmd); tun != "" {
		sshClient, err = ssh.NewTunnelledSSHClient(globalFlags.SSHUserName, tun, addr, getChecker(cCmd), false, timeout)
	} else {
		sshClient, err = ssh.NewSSHClient(globalFlags.SSHUserName, addr, getChecker(cCmd), false, timeout)
	}
	if err != nil {
		return err, -1
	}

	cmdargs := cmd
	for _, arg := range args {
		cmdargs += fmt.Sprintf(" %q", arg)
	}

	defer sshClient.Close()

	return ssh.Execute(sshClient, cmdargs)
}
Example #21
0
func runRemoteCommand(cmd string, ip string) (*ssh.Channel, error) {
	addr := fmt.Sprintf("%s:22", ip)

	var sshClient *ssh.SSHForwardingClient
	var err error
	if tun := getTunnelFlag(); tun != "" {
		sshClient, err = ssh.NewTunnelledSSHClient("core", tun, addr, getChecker(), false)
	} else {
		sshClient, err = ssh.NewSSHClient("core", addr, getChecker(), false)
	}
	if err != nil {
		return nil, err
	}

	defer sshClient.Close()

	channel, err := ssh.Execute(sshClient, cmd)
	if err != nil {
		return nil, err
	}
	return channel, nil
}
Example #22
0
File: ssh.go Project: CodeJuan/deis
func (c *FleetClient) sshConnect(name string) (*ssh.SSHForwardingClient, *machine.MachineState, error) {

	timeout := time.Duration(Flags.SSHTimeout*1000) * time.Millisecond

	ms, err := c.machineState(name)
	if err != nil {
		return nil, nil, err
	}

	// If name isn't a machine ID, try it as a unit instead
	if ms == nil {
		units, err := c.Units(name)

		if err != nil {
			return nil, nil, err
		}

		machID, err := c.findUnit(units[0])

		if err != nil {
			return nil, nil, err
		}

		ms, err = c.machineState(machID)

		if err != nil || ms == nil {
			return nil, nil, err
		}
	}

	addr := ms.PublicIP

	if tun := getTunnelFlag(); tun != "" {
		sshClient, err := ssh.NewTunnelledSSHClient("core", tun, addr, getChecker(), false, timeout)
		return sshClient, ms, err
	}
	sshClient, err := ssh.NewSSHClient("core", addr, getChecker(), false, timeout)
	return sshClient, ms, err
}
func getTunnelClient(driverEndpoint string, tunnelEndpoint string, maxRetries int) (client.API, error) {
	log.Printf("Using Fleet Tunnel connection for requests")

	getSSHClient := func() (interface{}, error) {
		return ssh.NewSSHClient("core", driverEndpoint, nil, false, defaultTimeout)
	}

	result, err := retry(getSSHClient, maxRetries)
	if err != nil {
		return nil, err
	}
	sshClient := result.(*ssh.SSHForwardingClient)

	dial := func(string, string) (net.Conn, error) {
		cmd := fmt.Sprintf("fleetctl fd-forward %s", tunnelEndpoint)
		return ssh.DialCommand(sshClient, cmd)
	}

	// This is needed to fake out the client - it isn't used
	// since we're overloading the dial method on the transport
	// but the client complains if it isn't set
	fakeHTTPEndpoint, err := url.Parse("http://domain-sock")

	if err != nil {
		return nil, err
	}

	trans := pkg.LoggingHTTPTransport{
		Transport: http.Transport{
			Dial: dial,
		},
	}

	httpClient := http.Client{
		Transport: &trans,
	}

	return client.NewHTTPClient(&httpClient, *fakeHTTPEndpoint)
}
// getAPI returns an API to Fleet.
func getAPI(hostAddr string, maxRetries int) (client.API, error) {
	if hostAddr == "" {
		return nullAPI{}, nil
	}

	getSSHClient := func() (interface{}, error) {
		return ssh.NewSSHClient("core", hostAddr, nil, false, time.Second*10)
	}

	result, err := retry(getSSHClient, maxRetries)
	if err != nil {
		return nil, err
	}
	sshClient := result.(*ssh.SSHForwardingClient)

	dial := func(string, string) (net.Conn, error) {
		cmd := "fleetctl fd-forward /var/run/fleet.sock"
		return ssh.DialCommand(sshClient, cmd)
	}

	trans := pkg.LoggingHTTPTransport{
		Transport: http.Transport{
			Dial: dial,
		},
	}

	httpClient := http.Client{
		Transport: &trans,
	}

	// since dial() ignores the endpoint, we just need something here that
	// won't make the HTTP client complain.
	endpoint, err := url.Parse("http://domain-sock")

	return client.NewHTTPClient(&httpClient, *endpoint)
}
Example #25
0
func getHTTPClient() (client.API, error) {
	ep, err := url.Parse(globalFlags.Endpoint)
	if err != nil {
		return nil, err
	}

	if len(ep.Scheme) == 0 {
		return nil, errors.New("URL scheme undefined")
	}

	tunnelFunc := net.Dial
	var tunneling bool
	tun := getTunnelFlag()
	if tun != "" {
		tunneling = true
		sshClient, err := ssh.NewSSHClient("core", tun, getChecker(), false, getSSHTimeoutFlag())
		if err != nil {
			return nil, fmt.Errorf("failed initializing SSH client: %v", err)
		}

		tunnelFunc = func(net, addr string) (net.Conn, error) {
			return sshClient.Dial(net, addr)
		}
	}

	dialFunc := tunnelFunc
	if ep.Scheme == "unix" || ep.Scheme == "file" {
		if tunneling {
			return nil, errors.New("unable to dial unix socket through SSH tunnel")
		}

		// This commonly happens if the user misses the leading slash after the scheme.
		// For example, "unix://var/run/fleet.sock" would be parsed as host "var".
		if len(ep.Host) > 0 {
			return nil, fmt.Errorf("unable to connect to host %q with scheme %q", ep.Host, ep.Scheme)
		}

		// The Path field is only used for dialing and should not be used when
		// building any further HTTP requests.
		sockPath := ep.Path
		ep.Path = ""

		// http.Client does not natively support dialing a unix domain socket, so the
		// dial function must be overridden.
		dialFunc = func(net, addr string) (net.Conn, error) {
			return tunnelFunc("unix", sockPath)
		}

		// http.Client doesn't support the schemes "unix" or "file", but it
		// is safe to use "http" as dialFunc ignores it anyway.
		ep.Scheme = "http"

		// The Host field is not used for dialing, but will be exposed in debug logs.
		ep.Host = "domain-sock"
	}

	tlsConfig, err := pkg.ReadTLSConfigFiles(globalFlags.CAFile, globalFlags.CertFile, globalFlags.KeyFile)
	if err != nil {
		return nil, err
	}

	trans := pkg.LoggingHTTPTransport{
		Transport: http.Transport{
			Dial:            dialFunc,
			TLSClientConfig: tlsConfig,
		},
	}

	hc := http.Client{
		Transport: &trans,
	}

	return client.NewHTTPClient(&hc, *ep)
}
Example #26
0
func getHTTPClient() (client.API, error) {
	endpoints := strings.Split(globalFlags.Endpoint, ",")
	if len(endpoints) > 1 {
		log.Warningf("multiple endpoints provided but only the first (%s) is used", endpoints[0])
	}

	ep, err := url.Parse(endpoints[0])
	if err != nil {
		return nil, err
	}

	if len(ep.Scheme) == 0 {
		return nil, errors.New("URL scheme undefined")
	}

	tun := getTunnelFlag()
	tunneling := tun != ""

	dialUnix := ep.Scheme == "unix" || ep.Scheme == "file"

	tunnelFunc := net.Dial
	if tunneling {
		sshClient, err := ssh.NewSSHClient(globalFlags.SSHUserName, tun, getChecker(), true, getSSHTimeoutFlag())
		if err != nil {
			return nil, fmt.Errorf("failed initializing SSH client: %v", err)
		}

		if dialUnix {
			tgt := ep.Path
			tunnelFunc = func(string, string) (net.Conn, error) {
				log.Debugf("Establishing remote fleetctl proxy to %s", tgt)
				cmd := fmt.Sprintf(`fleetctl fd-forward %s`, tgt)
				return ssh.DialCommand(sshClient, cmd)
			}
		} else {
			tunnelFunc = sshClient.Dial
		}
	}

	dialFunc := tunnelFunc
	if dialUnix {
		// This commonly happens if the user misses the leading slash after the scheme.
		// For example, "unix://var/run/fleet.sock" would be parsed as host "var".
		if len(ep.Host) > 0 {
			return nil, fmt.Errorf("unable to connect to host %q with scheme %q", ep.Host, ep.Scheme)
		}

		// The Path field is only used for dialing and should not be used when
		// building any further HTTP requests.
		sockPath := ep.Path
		ep.Path = ""

		// If not tunneling to the unix socket, http.Client will dial it directly.
		// http.Client does not natively support dialing a unix domain socket, so the
		// dial function must be overridden.
		if !tunneling {
			dialFunc = func(string, string) (net.Conn, error) {
				return net.Dial("unix", sockPath)
			}
		}

		// http.Client doesn't support the schemes "unix" or "file", but it
		// is safe to use "http" as dialFunc ignores it anyway.
		ep.Scheme = "http"

		// The Host field is not used for dialing, but will be exposed in debug logs.
		ep.Host = "domain-sock"
	}

	tlsConfig, err := pkg.ReadTLSConfigFiles(globalFlags.CAFile, globalFlags.CertFile, globalFlags.KeyFile)
	if err != nil {
		return nil, err
	}

	trans := pkg.LoggingHTTPTransport{
		Transport: http.Transport{
			Dial:            dialFunc,
			TLSClientConfig: tlsConfig,
		},
	}

	hc := http.Client{
		Transport: &trans,
	}

	return client.NewHTTPClient(&hc, *ep)
}
Example #27
0
func sshAction(c *cli.Context) {
	r := getRegistry(c)

	args := c.Args()
	unit := c.String("unit")
	if len(args) == 0 && unit == "" {
		log.Fatalf("Provide one machine or unit")
	}

	var addr string
	if unit == "" {
		lookup := args[0]
		args = args[1:]
		states := r.GetActiveMachines()
		var match *machine.MachineState
		for i, _ := range states {
			machState := states[i]
			if !strings.HasPrefix(machState.BootId, lookup) {
				continue
			} else if match != nil {
				log.Fatalf("Found more than one Machine, be more specfic")
			}
			match = &machState
		}

		if match == nil {
			log.Fatalf("Could not find provided Machine")
		}

		addr = fmt.Sprintf("%s:22", match.PublicIP)
	} else {
		js := r.GetJobState(unit)
		if js == nil {
			log.Fatalf("Requested unit %s does not appear to be running", unit)
		}
		addr = fmt.Sprintf("%s:22", js.MachineState.PublicIP)
	}

	var err error
	var sshClient *gossh.ClientConn
	if tun := getTunnelFlag(c); tun != "" {
		sshClient, err = ssh.NewTunnelledSSHClient("core", tun, addr)
	} else {
		sshClient, err = ssh.NewSSHClient("core", addr)
	}
	if err != nil {
		log.Fatalf("Unable to establish SSH connection: %v", err)
		return
	}

	defer sshClient.Close()

	if len(args) > 0 {
		cmd := strings.Join(args, " ")
		stdout, err := ssh.Execute(sshClient, cmd)
		if err != nil {
			log.Fatalf("Unable to run command over SSH: %s", err.Error())
		}

		for {
			bytes, prefix, err := stdout.ReadLine()
			if err != nil {
				break
			}

			print(string(bytes))
			if !prefix {
				print("\n")
			}
		}

	} else {
		if err := ssh.Shell(sshClient); err != nil {
			log.Fatalf(err.Error())
		}
	}
}
Example #28
0
func runSSH(args []string) (exit int) {
	if flagUnit != "" && flagMachine != "" {
		stderr("Both machine and unit flags provided, please specify only one.")
		return 1
	}

	var err error
	var addr string

	switch {
	case flagMachine != "":
		addr, _, err = findAddressInMachineList(flagMachine)
	case flagUnit != "":
		addr, _, err = findAddressInRunningUnits(flagUnit)
	default:
		addr, err = globalMachineLookup(args)
		// trim machine/unit name from args
		if len(args) > 0 {
			args = args[1:]
		}
	}

	if err != nil {
		stderr("Unable to proceed: %v", err)
		return 1
	}

	if addr == "" {
		stderr("Could not determine address of machine.")
		return 1
	}

	args = pkg.TrimToDashes(args)

	var sshClient *ssh.SSHForwardingClient
	timeout := getSSHTimeoutFlag()
	if tun := getTunnelFlag(); tun != "" {
		sshClient, err = ssh.NewTunnelledSSHClient(globalFlags.SSHUserName, tun, addr, getChecker(), flagSSHAgentForwarding, timeout)
	} else {
		sshClient, err = ssh.NewSSHClient(globalFlags.SSHUserName, addr, getChecker(), flagSSHAgentForwarding, timeout)
	}
	if err != nil {
		stderr("Failed building SSH client: %v", err)
		return 1
	}

	defer sshClient.Close()

	if len(args) > 0 {
		cmd := strings.Join(args, " ")
		err, exit = ssh.Execute(sshClient, cmd)
		if err != nil {
			stderr("Failed running command over SSH: %v", err)
		}
	} else {
		if err := ssh.Shell(sshClient); err != nil {
			stderr("Failed opening shell over SSH: %v", err)
			exit = 1
		}
	}
	return
}
Example #29
0
File: ssh.go Project: jsdir/fleet
func sshAction(c *cli.Context) {
	unit := c.String("unit")
	machine := c.String("machine")

	if unit != "" && machine != "" {
		log.Fatal("Both flags, machine and unit provided, please specify only one")
	}

	args := c.Args()
	var err error
	var addr string

	switch {
	case machine != "":
		addr, _ = findAddressInMachineList(machine)
	case unit != "":
		addr, _ = findAddressInRunningUnits(unit)
	default:
		addr, err = globalMachineLookup(args)
		args = args[1:]
	}

	if err != nil {
		log.Fatal(err)
	}

	if addr == "" {
		log.Fatalf("Requested machine could not be found")
	}

	var sshClient *gossh.ClientConn
	if tun := getTunnelFlag(); tun != "" {
		sshClient, err = ssh.NewTunnelledSSHClient("core", tun, addr)
	} else {
		sshClient, err = ssh.NewSSHClient("core", addr)
	}
	if err != nil {
		log.Fatal(err.Error())
		return
	}

	defer sshClient.Close()

	if len(args) > 0 {
		cmd := strings.Join(args, " ")
		stdout, err := ssh.Execute(sshClient, cmd)
		if err != nil {
			log.Fatalf("Unable to run command over SSH: %s", err.Error())
		}

		for {
			bytes, prefix, err := stdout.ReadLine()
			if err != nil {
				break
			}

			fmt.Print(string(bytes))
			if !prefix {
				fmt.Print("\n")
			}
		}

	} else {
		if err := ssh.Shell(sshClient); err != nil {
			log.Fatalf(err.Error())
		}
	}
}