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) } }
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 }
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 }
func cmdBuild(c *cli.Context) { conf, err := config.Open() if err != nil { Logger.Fatalf("Cannot open configuration file: %v", err) } conf.WriteSshConfigTo(os.Stdout) }
func cmdStats(c *cli.Context) { conf, err := config.Open() if err != nil { panic(err) } fmt.Printf("%d hosts\n", len(conf.Hosts)) }
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 }
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 }
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) } }
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 }
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 }
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 }
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 }
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 }