Beispiel #1
0
func main() {
	cmd := cli.NewApp()
	cmd.Version = "0.0.10"
	cmd.Name = "gotty"
	cmd.Usage = "Share your terminal as a web application"
	cmd.HideHelp = true

	flags := []flag{
		flag{"address", "a", "IP address to listen"},
		flag{"port", "p", "Port number to listen"},
		flag{"permit-write", "w", "Permit clients to write to the TTY (BE CAREFUL)"},
		flag{"credential", "c", "Credential for Basic Authentication (ex: user:pass, default disabled)"},
		flag{"random-url", "r", "Add a random string to the URL"},
		flag{"random-url-length", "", "Random URL length"},
		flag{"tls", "t", "Enable TLS/SSL"},
		flag{"tls-crt", "", "TLS/SSL crt file path"},
		flag{"tls-key", "", "TLS/SSL key file path"},
		flag{"index", "", "Custom index.html file"},
		flag{"title-format", "", "Title format of browser window"},
		flag{"reconnect", "", "Enable reconnection"},
		flag{"reconnect-time", "", "Time to reconnect"},
		flag{"once", "", "Accept only one client and exit on disconnection"},
		flag{"permit-arguments", "", "Allow to send arguments"},
	}

	mappingHint := map[string]string{
		"index":      "IndexFile",
		"tls":        "EnableTLS",
		"tls-crt":    "TLSCrtFile",
		"tls-key":    "TLSKeyFile",
		"random-url": "EnableRandomUrl",
		"reconnect":  "EnableReconnect",
	}

	cliFlags, err := generateFlags(flags, mappingHint)
	if err != nil {
		exit(err, 3)
	}

	cmd.Flags = append(
		cliFlags,
		cli.StringFlag{
			Name:   "config",
			Value:  "~/.gotty",
			Usage:  "Config file path",
			EnvVar: "GOTTY_CONFIG",
		},
	)

	cmd.Action = func(c *cli.Context) {
		if len(c.Args()) == 0 {
			fmt.Println("Error: No command given.\n")
			cli.ShowAppHelp(c)
			exit(err, 1)
		}

		options := app.DefaultOptions

		configFile := c.String("config")
		_, err := os.Stat(app.ExpandHomeDir(configFile))
		if configFile != "~/.gotty" || !os.IsNotExist(err) {
			if err := app.ApplyConfigFile(&options, configFile); err != nil {
				exit(err, 2)
			}
		}

		applyFlags(&options, flags, mappingHint, c)

		if c.IsSet("credential") {
			options.EnableBasicAuth = true
		}

		app, err := app.New(c.Args(), &options)
		if err != nil {
			exit(err, 3)
		}

		registerSignals(app)

		err = app.Run()
		if err != nil {
			exit(err, 4)
		}
	}

	cli.AppHelpTemplate = helpTemplate

	cmd.Run(os.Args)
}
Beispiel #2
0
func GoTTY() {

	flags := []struct {
		name        string
		shortName   string
		description string
	}{
		{"address", "a", "IP address to listen"},
		{"port", "p", "Port number to listen"},
		{"permit-write", "w", "Permit clients to write to the TTY (BE CAREFUL)"},
		{"credential", "c", "Credential for Basic Authentication (ex: user:pass, default disabled)"},
		{"random-url", "r", "Add a random string to the URL"},
		{"random-url-length", "", "Random URL length"},
		{"tls", "t", "Enable TLS/SSL"},
		{"tls-crt", "", "TLS/SSL certificate file path"},
		{"tls-key", "", "TLS/SSL key file path"},
		{"tls-ca-crt", "", "TLS/SSL CA certificate file for client certifications"},
		{"index", "", "Custom index.html file"},
		{"title-format", "", "Title format of browser window"},
		{"reconnect", "", "Enable reconnection"},
		{"reconnect-time", "", "Time to reconnect"},
		{"once", "", "Accept only one client and exit on disconnection"},
		{"permit-arguments", "", "Permit clients to send command line arguments in URL (e.g. http://example.com:8080/?arg=AAA&arg=BBB)"},
		{"close-signal", "", "Signal sent to the command process when gotty close it (default: SIGHUP)"},
	}

	mappingHint := map[string]string{
		"index":      "IndexFile",
		"tls":        "EnableTLS",
		"tls-crt":    "TLSCrtFile",
		"tls-key":    "TLSKeyFile",
		"tls-ca-crt": "TLSCACrtFile",
		"random-url": "EnableRandomUrl",
		"reconnect":  "EnableReconnect",
	}

	options := gotty.DefaultOptions

	var configFile string = "~/.gotty"
	if v, ok := os.LookupEnv("GOTTY_CONFIG"); ok {
		configFile = v
	}
	args := os.Args[1:]
	//si := SliceIndex(len(args), func(i int) bool { return strings.Contains(args[i], "-config") })

	flag.StringVar(&configFile, "config", configFile, "Config file path")

	//cliFlags, err := generateFlags(flags, mappingHint)
	//applyFlags(&options, flags, mappingHint, c)
	o := structs.New(&options)
	for _, f := range flags {
		fieldname := fieldName(f.name, mappingHint)

		field, ok := o.FieldOk(fieldname)
		if !ok {
			glog.Warningf("No such field: %s", fieldname)
			continue
		}

		//flagname := f.name
		//if f.shortName != "" {
		//	flagname += ", " + f.shortName
		//}
		envName := "GOTTY_" + strings.ToUpper(strings.Join(strings.Split(f.name, "-"), "_"))

		//field := o.Field(fieldname)
		field.Set(os.Getenv(envName))
		var val interface{}
		switch field.Kind() {
		case reflect.String:
			val = flag.String(f.name, field.Value().(string), f.description)
		case reflect.Bool:
			val = flag.Bool(f.name, false, f.description)
		case reflect.Int:
			val = flag.Int(f.name, field.Value().(int), f.description)
		}
		field.Set(val)
	}

	flag.Parse()

	_, err := os.Stat(gotty.ExpandHomeDir(configFile))
	if configFile != "~/.gotty" || !os.IsNotExist(err) {
		if err := gotty.ApplyConfigFile(&options, configFile); err != nil {
			exit(err, 2)
		}
	}

	if options.Credential != "" {
		options.EnableBasicAuth = true
	}
	if options.TLSCACrtFile != "" {
		options.EnableTLSClientAuth = true
	}

	if err := gotty.CheckConfig(&options); err != nil {
		exit(err, 6)
	}

	var app *App

	if len(args) == 0 {
		app, err = NewApp([]string{"kubectl", "exec", "-ti", "netcat-simple", "ash"}, &options)
	} else {
		clientConfig := directKClientConfig(_kubeconfig, _context, _apiserver)
		if clientConfig == nil {
			exit(fmt.Errorf("kubeclient required"), 1)
		}
		pty, tty, err := openPTYTTY()
		if err != nil {
			exit(err, 1)
		}
		app, err = NewCmdExec(clientConfig, _ns, _pod, _container, _stdin, _tty, pty, tty, tty, tty, _command, &options)
	}
	if err != nil {
		exit(err, 3)
	}

	registerSignals(app)

	err = app.Run()
	if err != nil {
		exit(err, 4)
	}
}