Beispiel #1
0
func applyAnsibleRC(c *cli.Context) {
	args := c.Args()
	if len(args) < 1 {
		log.Die("Expected an argument!")
	}
	hosts := args[0]

	f := cmdutil.NewFactory(nil)
	if f == nil {
		log.Die("Failed to create Kuberentes client factory!")
	}
	kubeclient, _ := f.Client()
	if kubeclient == nil {
		log.Die("Failed to create Kuberentes client!")
	}
	ns, _, _ := f.DefaultNamespace()
	if len(ns) == 0 {
		ns = "default"
	}

	rcName, err := osExpandAndVerify(c, "rc")
	if err != nil {
		fail(err)
	}

	inventory, err := osExpandAndVerify(c, "inventory")
	if err != nil {
		fail(err)
	}
	_, err = ansible.UpdateAnsibleRC(inventory, hosts, kubeclient, ns, rcName)
	if err != nil {
		fail(err)
	}
}
Beispiel #2
0
func main() {
	app := cli.NewApp()
	app.Name = "gosupervise"
	app.Usage = `Go Supervise

This command supervises a remote process inside a Pod inside Kubernetes to make
it look and feel like legacy processes running outside of Kubernetes are really
running inside Docker inside Kubernetes.

`
	app.Version = version
	app.EnableBashCompletion = true
	app.After = func(c *cli.Context) error {
		if log.ErrorState {
			return errors.New("Exiting with errors")
		}

		return nil
	}

	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:  "port",
			Value: "22",
			Usage: "The port for the remote SSH connection",
		},
		cli.BoolFlag{
			Name:  "debug",
			Usage: "Enable verbose debugging output",
		},
	}

	app.CommandNotFound = func(c *cli.Context, command string) {
		log.Err("No matching command '%s'", command)
		cli.ShowAppHelp(c)
		log.Die("")
	}

	app.Commands = []cli.Command{
		{
			Name:        "pod",
			Usage:       "Runs the supervisor pod for a single host in a set of hosts from an Ansible inventory.",
			Description: `This commmand will begin running the supervisor command on one host from the Ansible inventory.`,
			ArgsUsage:   "[hosts] [command]",
			Action:      runAnsiblePod,
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "inventory",
					Value: "inventory",
					Usage: "The location of your Ansible inventory file",
				},
				cli.StringFlag{
					Name:  "rc",
					Value: "rc.yml",
					Usage: "The YAML file of the ReplicationController for the supervisors",
				},
				cli.StringFlag{
					Name:  "password",
					Value: "$GOSUPERVISE_PASSWORD",
					Usage: "The password used for WinRM connections",
				},
				cli.BoolFlag{
					Name:   "winrm",
					EnvVar: "GOSUPERVISE_WINRM",
					Usage:  "Enables the use of WinRM instead of SSH",
				},
			},
		},
		{
			Name:        "rc",
			Usage:       "Applies ReplicationController for the supervisors for some hosts in an Ansible inventory.",
			Description: `This commmand will analyse the hosts in an Ansible inventory and creates or updates the ReplicationController for its supervisors.`,
			ArgsUsage:   "[hosts] [command]",
			Action:      applyAnsibleRC,
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "inventory",
					Value: "inventory",
					Usage: "The location of your Ansible inventory file",
				},
				cli.StringFlag{
					Name:  "rc",
					Value: "rc.yml",
					Usage: "The YAML file of the ReplicationController for the supervisors",
				},
			},
		},
		{
			Name:        "run",
			Usage:       "Runs a supervisor command on a given host as a user without using Ansible.",
			Description: `This commmand will begin running the supervisor on an avaiable host.`,
			ArgsUsage:   "[string]",
			Action:      run,
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "user",
					Value: "$GOSUPERVISE_USER",
					Usage: "The user to use on the remote connection",
				},
				cli.StringFlag{
					Name:  "privatekey",
					Value: "$GOSUPERVISE_PRIVATEKEY",
					Usage: "The private key used for SSH",
				},
				cli.StringFlag{
					Name:  "host",
					Value: "$GOSUPERVISE_HOST",
					Usage: "The host for the remote connection",
				},
				cli.StringFlag{
					Name:  "command",
					Value: "$GOSUPERVISE_COMMAND",
					Usage: "The remote command to invoke on the host",
				},
				cli.StringFlag{
					Name:  "password",
					Usage: "The password if using WinRM to execute the command",
				},
				cli.BoolFlag{
					Name:  "winrm",
					Usage: "Enables the use of WinRM instead of SSH",
				},
			},
		},
	}

	app.Before = func(c *cli.Context) error {
		log.IsDebugging = c.Bool("debug")
		return nil
	}

	app.RunAndExitOnError()
}
Beispiel #3
0
func runAnsiblePod(c *cli.Context) {
	args := c.Args()
	if len(args) < 2 {
		log.Die("Expected at least 2 arguments!")
	}
	hosts := args[0]
	command := strings.Join(args[1:], " ")

	log.Info("running command on a host from %s and command `%s`", hosts, command)

	f := cmdutil.NewFactory(nil)
	if f == nil {
		log.Die("Failed to create Kuberentes client factory!")
	}
	kubeclient, _ := f.Client()
	if kubeclient == nil {
		log.Die("Failed to create Kuberentes client!")
	}
	ns, _, _ := f.DefaultNamespace()
	if len(ns) == 0 {
		ns = "default"
	}

	rcFile, err := osExpandAndVerify(c, "rc")
	if err != nil {
		fail(err)
	}

	port, err := osExpandAndVerifyGlobal(c, "port")
	if err != nil {
		fail(err)
	}
	inventory, err := osExpandAndVerify(c, "inventory")
	if err != nil {
		fail(err)
	}
	rc, err := k8s.ReadReplicationControllerFromFile(rcFile)
	if err != nil {
		fail(err)
	}
	rcName := rc.ObjectMeta.Name
	if len(rcName) == 0 {
		log.Die("No ReplicationController name in the yaml file %s", rcFile)
	}
	hostEntry, err := ansible.ChooseHostAndPrivateKey(inventory, hosts, kubeclient, ns, rcName)
	if err != nil {
		fail(err)
	}
	host := hostEntry.Host
	user := hostEntry.User

	useWinRM := c.Bool("winrm") || hostEntry.UseWinRM
	if useWinRM {
		log.Info("Using WinRM to connect to the hosts %s", hosts)
		password, err := osExpandAndVerify(c, "password")
		if err != nil {
			fail(err)
		}
		err = winrm.RemoteWinRmCommand(user, password, host, port, command)
	} else {
		privatekey := hostEntry.PrivateKey
		hostPort := host + ":" + port
		err = ssh.RemoteSshCommand(user, privatekey, hostPort, command)
	}
	if err != nil {
		log.Err("Failed: %v", err)
	}
}
Beispiel #4
0
func fail(err error) {
	log.Die("Failed: %s", err)
}