Example #1
0
func cmdProxy(c *cli.Context) {
	if len(c.Args()) < 1 {
		Logger.Fatalf("assh: \"proxy\" requires 1 argument. See 'assh proxy --help'.")
	}

	conf, err := config.Open()
	if err != nil {
		Logger.Fatalf("Cannot open configuration file: %v", err)
	}

	// FIXME: handle complete host with json

	host, err := computeHost(c.Args()[0], c.Int("port"), conf)
	if err != nil {
		Logger.Fatalf("Cannot get host '%s': %v", c.Args()[0], err)
	}
	w := Logger.Writer()
	defer w.Close()
	host.WriteSshConfigTo(w)

	Logger.Debugf("Saving SSH config")
	err = conf.SaveSshConfig()
	if err != nil {
		Logger.Fatalf("Cannot save SSH config file: %v", err)
	}

	Logger.Debugf("Proxying")
	err = proxy(host, conf)
	if err != nil {
		Logger.Fatalf("Proxy error: %v", err)
	}
}
Example #2
0
func cmdInfo(c *cli.Context) error {
	conf, err := config.Open(c.GlobalString("config"))
	if err != nil {
		Logger.Fatalf("Cannot load configuration: %v", err)
		return nil
	}

	fmt.Printf("Debug mode (client): %v\n", os.Getenv("ASSH_DEBUG") == "1")
	cliPath, _ := osext.Executable()
	fmt.Printf("CLI Path: %s\n", cliPath)
	fmt.Printf("Go version: %s\n", runtime.Version())
	fmt.Printf("OS/Arch: %s/%s\n", runtime.GOOS, runtime.GOARCH)
	fmt.Println("")
	fmt.Printf("RC files:\n")
	homeDir := utils.GetHomeDir()
	for _, filename := range conf.IncludedFiles() {
		relativeFilename := strings.Replace(filename, homeDir, "~", -1)
		fmt.Printf("- %s\n", relativeFilename)
	}
	fmt.Println("")
	fmt.Println("Statistics:")
	fmt.Printf("- %d hosts\n", len(conf.Hosts))
	fmt.Printf("- %d templates\n", len(conf.Templates))
	fmt.Printf("- %d included files\n", len(conf.IncludedFiles()))
	// FIXME: print info about connections/running processes
	// FIXME: print info about current config file version

	return nil
}
Example #3
0
func cmdSearch(c *cli.Context) error {
	conf, err := config.Open(c.GlobalString("config"))
	if err != nil {
		Logger.Fatalf("Cannot load configuration: %v", err)
		return nil
	}

	needle := c.Args()[0]

	found := []*config.Host{}
	for _, host := range conf.Hosts.SortedList() {
		if host.Matches(needle) {
			found = append(found, host)
		}
	}

	if len(found) == 0 {
		fmt.Println("no results found.")
		return nil
	}

	fmt.Printf("Listing results for %s:\n", needle)
	for _, host := range found {
		fmt.Printf("    %s -> %s\n", host.Name(), host.Prototype())
	}

	return nil
}
Example #4
0
func cmdBuild(c *cli.Context) {
	conf, err := config.Open()
	if err != nil {
		Logger.Fatalf("Cannot open configuration file: %v", err)
	}

	conf.WriteSshConfigTo(os.Stdout)
}
Example #5
0
func cmdStats(c *cli.Context) {
	conf, err := config.Open()
	if err != nil {
		panic(err)
	}

	fmt.Printf("%d hosts\n", len(conf.Hosts))
}
Example #6
0
func cmdWrapper(c *cli.Context) error {
	if len(c.Args()) < 1 {
		Logger.Fatalf("Missing <target> argument. See usage with 'assh wrapper %s -h'.", c.Command.Name)
	}

	// prepare variables
	target := c.Args()[0]
	command := c.Args()[1:]
	options := []string{}
	for _, flag := range config.SSHBoolFlags {
		if c.Bool(flag) {
			options = append(options, fmt.Sprintf("-%s", flag))
		}
	}
	for _, flag := range config.SSHStringFlags {
		if val := c.String(flag); val != "" {
			options = append(options, fmt.Sprintf("-%s", flag))
			options = append(options, val)
		}
	}
	args := []string{c.Command.Name}
	args = append(args, options...)
	args = append(args, target)
	args = append(args, command...)
	bin, err := exec.LookPath(c.Command.Name)
	if err != nil {
		Logger.Fatalf("Cannot find %q in $PATH", c.Command.Name)
	}

	Logger.Debugf("Wrapper called with bin=%v target=%v command=%v options=%v, args=%v", bin, target, command, options, args)

	// check if config is up-to-date
	conf, err := config.Open(c.GlobalString("config"))
	if err != nil {
		Logger.Fatalf("Cannot open configuration file: %v", err)
	}

	if err = conf.LoadKnownHosts(); err != nil {
		Logger.Debugf("Failed to load assh known_hosts: %v", err)
	}

	// check if .ssh/config is outdated
	isOutdated, err := conf.IsConfigOutdated(target)
	if err != nil {
		Logger.Error(err)
	}
	if isOutdated {
		Logger.Debugf("The configuration file is outdated, rebuilding it before calling %s", c.Command.Name)
		if err = conf.SaveSSHConfig(); err != nil {
			Logger.Error(err)
		}
	}

	// Execute Binary
	syscall.Exec(bin, args, os.Environ())

	return nil
}
Example #7
0
func cmdBuild(c *cli.Context) error {
	conf, err := config.Open(c.GlobalString("config"))
	if err != nil {
		Logger.Fatalf("Cannot open configuration file: %v", err)
	}

	if c.Bool("expand") {
		for name := range conf.Hosts {
			conf.Hosts[name], err = conf.GetHost(name)
			if err != nil {
				Logger.Fatalf("Error while trying to expand hosts: %v", err)
			}
		}
	}

	conf.WriteSSHConfigTo(os.Stdout)

	return nil
}
Example #8
0
func cmdProxy(c *cli.Context) {
	Logger.Debugf("assh args: %s", c.Args())

	if len(c.Args()) < 1 {
		Logger.Fatalf("assh: \"proxy\" requires 1 argument. See 'assh proxy --help'.")
	}

	// dry-run option
	// Setting the 'ASSH_DRYRUN=1' environment variable,
	// so 'assh' can use gateways using sub-SSH commands.
	if c.Bool("dry-run") == true {
		os.Setenv("ASSH_DRYRUN", "1")
	}
	dryRun := os.Getenv("ASSH_DRYRUN") == "1"

	conf, err := config.Open()
	if err != nil {
		Logger.Fatalf("Cannot open configuration file: %v", err)
	}

	// FIXME: handle complete host with json

	host, err := computeHost(c.Args()[0], c.Int("port"), conf)
	if err != nil {
		Logger.Fatalf("Cannot get host '%s': %v", c.Args()[0], err)
	}
	w := Logger.Writer()
	defer w.Close()
	host.WriteSshConfigTo(w)

	Logger.Debugf("Saving SSH config")
	err = conf.SaveSshConfig()
	if err != nil {
		Logger.Fatalf("Cannot save SSH config file: %v", err)
	}

	Logger.Debugf("Proxying")
	err = proxy(host, conf, dryRun)
	if err != nil {
		Logger.Fatalf("Proxy error: %v", err)
	}
}
Example #9
0
func cmdList(c *cli.Context) error {
	conf, err := config.Open(c.GlobalString("config"))
	if err != nil {
		Logger.Fatalf("Cannot load configuration: %v", err)
		return nil
	}

	// ansi coloring
	greenColorize := func(input string) string { return input }
	redColorize := func(input string) string { return input }
	yellowColorize := func(input string) string { return input }
	if terminal.IsTerminal(int(os.Stdout.Fd())) {
		greenColorize = ansi.ColorFunc("green+b+h")
		redColorize = ansi.ColorFunc("red")
		yellowColorize = ansi.ColorFunc("yellow")
	}

	fmt.Printf("Listing entries\n\n")

	for _, host := range conf.Hosts.SortedList() {
		options := host.Options()
		options.Remove("User")
		options.Remove("Port")
		host.ApplyDefaults(&conf.Defaults)
		fmt.Printf("    %s -> %s\n", greenColorize(host.Name()), host.Prototype())
		if len(options) > 0 {
			fmt.Printf("        %s %s\n", yellowColorize("[custom options]"), strings.Join(options.ToStringList(), " "))
		}
		fmt.Println()
	}

	generalOptions := conf.Defaults.Options()
	if len(generalOptions) > 0 {
		fmt.Println(greenColorize("    (*) General options:"))
		for _, opt := range conf.Defaults.Options() {
			fmt.Printf("        %s: %s\n", redColorize(opt.Name), opt.Value)
		}
		fmt.Println()
	}

	return nil
}
Example #10
0
func cmdProxy(c *cli.Context) {
	if len(c.Args()) < 1 {
		logrus.Fatalf("assh: \"proxy\" requires 1 argument. See 'assh proxy --help'.")
	}

	conf, err := config.Open()
	if err != nil {
		logrus.Fatalf("Cannot open configuration file: %v", err)
	}

	// FIXME: handle complete host with json

	host, err := computeHost(c.Args()[0], c.Int("port"), conf)
	if err != nil {
		logrus.Fatalf("Cannot get host '%s': %v", c.Args()[0], err)
	}

	err = proxy(host, conf)
	if err != nil {
		logrus.Fatalf("Proxy error: %v", err)
	}
}
func cmdCsFlush(c *cli.Context) error {
	conf, err := config.Open(c.GlobalString("config"))
	if err != nil {
		Logger.Errorf("%v", err)
		os.Exit(-1)
	}

	controlPath := conf.Defaults.ControlPath
	if controlPath == "" {
		Logger.Errorf("Missing ControlPath in the configuration; Sockets features are disabled.")
		return nil
	}

	activeSockets, err := controlsockets.LookupControlPathDir(controlPath)
	if err != nil {
		Logger.Errorf("%v", err)
		os.Exit(-1)
	}

	if len(activeSockets) == 0 {
		fmt.Println("No active control sockets.")
	}

	success := 0
	for _, socket := range activeSockets {
		if err := os.Remove(socket.Path()); err != nil {
			Logger.Warnf("Failed to close control socket %q: %v", socket.Path(), err)
		} else {
			success++
		}
	}

	if success > 0 {
		fmt.Printf("Closed %d control sockets.\n", success)
	}

	return nil
}
Example #12
0
func cmdBuildJSON(c *cli.Context) error {
	conf, err := config.Open(c.GlobalString("config"))
	if err != nil {
		Logger.Fatalf("Cannot open configuration file: %v", err)
	}

	if c.Bool("expand") {
		for name := range conf.Hosts {
			conf.Hosts[name], err = conf.GetHost(name)
			if err != nil {
				Logger.Fatalf("Error while trying to expand hosts: %v", err)
			}
		}
	}

	s, err := json.MarshalIndent(conf, "", "  ")
	if err != nil {
		Logger.Fatalf("JSON encoding error: %v", err)
	}
	fmt.Println(string(s))

	return nil
}
func cmdCsList(c *cli.Context) error {
	conf, err := config.Open(c.GlobalString("config"))
	if err != nil {
		Logger.Errorf("%v", err)
		os.Exit(-1)
	}

	controlPath := conf.Defaults.ControlPath
	if controlPath == "" {
		Logger.Errorf("Missing ControlPath in the configuration; Sockets features are disabled.")
		return nil
	}

	activeSockets, err := controlsockets.LookupControlPathDir(controlPath)
	if err != nil {
		Logger.Errorf("%v", err)
		os.Exit(-1)
	}

	if len(activeSockets) == 0 {
		fmt.Println("No active control sockets.")
		return nil
	}

	fmt.Printf("%d active control sockets in %q:\n\n", len(activeSockets), controlPath)
	now := time.Now().UTC()
	for _, socket := range activeSockets {
		createdAt, err := socket.CreatedAt()
		if err != nil {
			Logger.Warnf("%v", err)
		}

		fmt.Printf("- %s (%v)\n", socket.RelativePath(), units.HumanDuration(now.Sub(createdAt)))
	}

	return nil
}
Example #14
0
func cmdInfo(c *cli.Context) {
	conf, err := config.Open()
	if err != nil {
		panic(err)
	}

	fmt.Printf("Debug mode (client): %v\n", os.Getenv("ASSH_DEBUG") == "1")
	cliPath, _ := osext.Executable()
	fmt.Printf("CLI Path: %s\n", cliPath)
	fmt.Printf("Go version: %s\n", runtime.Version())
	fmt.Printf("OS/Arch: %s/%s\n", runtime.GOOS, runtime.GOARCH)
	fmt.Println("")
	fmt.Printf("RC files:\n")
	for _, filename := range conf.IncludedFiles() {
		fmt.Printf("- %s\n", filename)
	}
	fmt.Println("")
	fmt.Println("Statistics:")
	fmt.Printf("- %d hosts\n", len(conf.Hosts))
	fmt.Printf("- %d templates\n", len(conf.Templates))
	fmt.Printf("- %d included files\n", len(conf.IncludedFiles()))
	// FIXME: print info about connections/running processes
	// FIXME: print info about current config file version
}
Example #15
0
func cmdProxy(c *cli.Context) error {
	Logger.Debugf("assh args: %s", c.Args())

	if len(c.Args()) < 1 {
		Logger.Fatalf("assh: \"connect\" requires 1 argument. See 'assh connect --help'.")
	}

	// dry-run option
	// Setting the 'ASSH_DRYRUN=1' environment variable,
	// so 'assh' can use gateways using sub-SSH commands.
	if c.Bool("dry-run") {
		os.Setenv("ASSH_DRYRUN", "1")
	}
	dryRun := os.Getenv("ASSH_DRYRUN") == "1"

	conf, err := config.Open(c.GlobalString("config"))
	if err != nil {
		Logger.Fatalf("Cannot open configuration file: %v", err)
	}

	if err = conf.LoadKnownHosts(); err != nil {
		Logger.Debugf("Failed to load assh known_hosts: %v", err)
	}

	target := c.Args()[0]

	isOutdated, err := conf.IsConfigOutdated(target)
	if err != nil {
		Logger.Warnf("Cannot check if ~/.ssh/config is outdated.")
	}
	if isOutdated {
		Logger.Debugf("The configuration file is outdated, rebuilding it before calling ssh")
		Logger.Warnf("'~/.ssh/config' has been rewritten.  SSH needs to be restarted.  See https://github.com/moul/advanced-ssh-config/issues/122 for more information.")
		Logger.Debugf("Saving SSH config")
		err = conf.SaveSSHConfig()
		if err != nil {
			Logger.Fatalf("Cannot save SSH config file: %v", err)
		}
	}

	// FIXME: handle complete host with json

	host, err := computeHost(target, c.Int("port"), conf)
	if err != nil {
		Logger.Fatalf("Cannot get host '%s': %v", target, err)
	}
	w := Logger.Writer()
	host.WriteSSHConfigTo(w)
	w.Close()

	hostJSON, err := json.Marshal(host)
	if err != nil {
		Logger.Warnf("Failed to marshal host: %v", err)
	}
	Logger.Debugf("Host: %s", hostJSON)

	Logger.Debugf("Proxying")
	err = proxy(host, conf, dryRun)
	if err != nil {
		Logger.Fatalf("Proxy error: %v", err)
	}

	return nil
}