Example #1
0
File: rc.go Project: rhuss/kansible
// RC creates or updates the kansible ReplicationController for some hosts in an Ansible inventory
func RC(c *cli.Context) {
	args := c.Args()
	if len(args) < 1 {
		log.Die("Expected argument [hosts] for the name of the hosts in the ansible inventory file")
	}
	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"
	}

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

	hostEntries, err := ansible.LoadHostEntries(inventory, hosts)
	if err != nil {
		fail(err)
	}
	log.Info("Found %d host entries in the Ansible inventory for %s", len(hostEntries), hosts)

	rcFile := "kubernetes/" + hosts + "/rc.yml"

	_, err = ansible.UpdateKansibleRC(hostEntries, hosts, kubeclient, ns, rcFile)
	if err != nil {
		fail(err)
	}
}
Example #2
0
func init() {
	killCmd.Flags().StringVar(&rcName, "rc", "$KANSIBLE_RC", "the name of the ReplicationController for the supervisors")

	RootCmd.AddCommand(killCmd)
}

// killCmd kills the pending windows shell of the current pod if its still running
var killCmd = &cobra.Command{
	Use:   "kill <hosts> [command]",
	Short: "Kills any pending shells for this pod.",
	Long:  `This commmand will find the shell thats associated with a pod and kill it.`,
	Run: func(cmd *cobra.Command, args []string) {
		f := cmdutil.NewFactory(clientConfig)
		if f == nil {
			log.Die("Failed to create Kubernetes client factory!")
		}
		kubeclient, err := f.Client()
		if err != nil || kubeclient == nil {
			log.Die(MessageFailedToCreateKubernetesClient, err)
		}
		ns, _, _ := f.DefaultNamespace()
		if len(ns) == 0 {
			ns = "default"
		}
		thisPodName, err := k8s.GetThisPodName()
		if err != nil {
			log.Die("Failed to get this pod name: %s", err)
		}

		pod, err := kubeclient.Pods(ns).Get(thisPodName)
Example #3
0
	runCmd.Flags().StringVar(&command, "command", "${KANSIBLE_COMMAND}", "the remote command to invoke on the host")
	runCmd.Flags().StringVar(&password, "password", "", "the password if using WinRM to execute the command")
	runCmd.Flags().StringVar(&connection, "connection", "", "the Ansible connection type to use. Defaults to SSH unless 'winrm' is defined to use WinRM on Windows")

	RootCmd.AddCommand(runCmd)
}

// runCmd runs a remote command on a given host to test out SSH / WinRM
var runCmd = &cobra.Command{
	Use:   "run [command]",
	Short: "Runs a remote command on a given host to test out SSH / WinRM",
	Long:  `This commmand will begin running the supervisor on an avaiable host.`,
	Run: func(cmd *cobra.Command, args []string) {
		command = os.ExpandEnv(command)
		if command == "" {
			log.Die("Command is required")
		}
		host = os.ExpandEnv(host)
		if host == "" {
			log.Die("Host is required")
		}
		user = os.ExpandEnv(user)
		if user == "" {
			log.Die("User is required")
		}
		if connection == ansible.ConnectionWinRM {
			password = os.ExpandEnv(password)
			if password == "" {
				log.Die("Password is required")
			}
			err := winrm.RemoteWinRmCommand(user, password, host, strconv.Itoa(sshPort), command, nil, nil, "")
Example #4
0
	podCmd.Flags().StringVar(&bash, "bash", "$KANSIBLE_BASH", "if specified a script is generated for running a bash like shell on the remote machine")

	RootCmd.AddCommand(podCmd)
}

// podCmd is the root command for the whole program.
var podCmd = &cobra.Command{
	Use:   "pod <hosts> [command]",
	Short: "Runs the kansible pod which owns a host from the Ansible inventory then runs a remote command on the host",
	Long:  `This commmand will pick an available host from the Ansible inventory, then run a remote command on that host.`,
	Run: func(cmd *cobra.Command, args []string) {
		// Pod runs the kansible pod for a given group of hosts in an Ansible playbook
		// this grabs a specific host (using annotations on the RC) then runs a remote command
		// on that host binding stdin, stdout, stderr to the remote process
		if len(args) < 1 {
			log.Die("Expected arguments <hosts> [command]")
		}
		hosts := os.ExpandEnv(args[0])
		command := ""
		if len(args) > 1 {
			command = os.ExpandEnv(strings.Join(args[1:], " "))
		}

		f := cmdutil.NewFactory(clientConfig)
		if f == nil {
			log.Die("Failed to create Kubernetes client factory!")
		}
		kubeclient, err := f.Client()
		if err != nil || kubeclient == nil {
			log.Die(MessageFailedToCreateKubernetesClient, err)
		}
Example #5
0
func main() {
	app := cli.NewApp()
	app.Name = "kansible"
	app.Usage = `Kansible

Kansible orchestrates processes in the same way as you orchestrate Docker containers with Kubernetes.

Once you have created an Ansible playbook to install and configure your software you can use Kansible to create
a Kubernetes Replication Controller to run, scale and manage the processes providing a universal view in Kubernetes
of all your containers and processes along with common scaling, high availability, service discovery and load balancing.

More help is here: https://github.com/fabric8io/kansible/blob/master/README.md`
	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:        "rc",
			Usage:       "Creates or updates the kansible ReplicationController 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 the kansible pods.`,
			ArgsUsage:   "[hosts] [command]",
			Action:      cmds.RC,
			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:        "pod",
			Usage:       "Runs the kansible pod which owns a host from the Ansible inventory then runs a remote command on the host.",
			Description: `This commmand will pick an available host from the Ansible inventory, then run a remote command on that host.`,
			ArgsUsage:   "[hosts] [command]",
			Action:      cmds.Pod,
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "inventory",
					Value: "inventory",
					Usage: "The location of your Ansible inventory file",
				},
				cli.StringFlag{
					Name:  "rc",
					Value: "$KANSIBLE_RC",
					Usage: "The name of the ReplicationController for the supervisors",
				},
				cli.StringFlag{
					Name:  "password",
					Value: "$KANSIBLE_PASSWORD",
					Usage: "The password used for WinRM connections",
				},
				cli.StringFlag{
					Name:  "connection",
					Usage: "The Ansible connection type to use. Defaults to SSH unless 'winrm' is defined to use WinRM on Windows",
				},
				cli.StringFlag{
					Name:  "bash",
					Value: "$KANSIBLE_BASH",
					Usage: "If specified a script is generated for running a bash like shell on the remote machine",
				},
			},
		},
		{
			Name:        "run",
			Usage:       "Runs a remote command on a given host to test out SSH / WinRM",
			Description: `This commmand will begin running the supervisor on an avaiable host.`,
			ArgsUsage:   "[string]",
			Action:      cmds.Run,
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "user",
					Value: "$KANSIBLE_USER",
					Usage: "The user to use on the remote connection",
				},
				cli.StringFlag{
					Name:  "privatekey",
					Value: "$KANSIBLE_PRIVATEKEY",
					Usage: "The private key used for SSH",
				},
				cli.StringFlag{
					Name:  "host",
					Value: "$KANSIBLE_HOST",
					Usage: "The host for the remote connection",
				},
				cli.StringFlag{
					Name:  "command",
					Value: "$KANSIBLE_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.StringFlag{
					Name:  "connection",
					Usage: "The Ansible connection type to use. Defaults to SSH unless 'winrm' is defined to use WinRM on Windows",
				},
			},
		},
	}

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

	app.RunAndExitOnError()
}
Example #6
0
// Pod runs the kansible pod for a given group of hosts in an Ansible playbook
// this grabs a specific host (using annotations on the RC) then runs a remote command
// on that host binding stdin, stdout, stderr to the remote process
func Pod(c *cli.Context) {
	args := c.Args()
	if len(args) < 1 {
		log.Die("Expected arguments [hosts] [command]")
	}
	hosts := os.ExpandEnv(args[0])
	command := ""
	if len(args) > 1 {
		command = os.ExpandEnv(strings.Join(args[1:], " "))
	}

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

	inventory, err := osExpandAndVerify(c, "inventory")
	if err != nil {
		fail(err)
	}
	rcName, err := osExpandAndVerify(c, "rc")
	if err != nil {
		fail(err)
	}
	envVars := make(map[string]string)
	hostEntry, err := ansible.ChooseHostAndPrivateKey(inventory, hosts, kubeclient, ns, rcName, envVars)
	if err != nil {
		fail(err)
	}
	host := hostEntry.Host
	user := hostEntry.User
	port := hostEntry.Port
	if len(port) == 0 {
		port, err = osExpandAndVerifyGlobal(c, "port")
	}
	if err != nil {
		fail(err)
	}

	connection := hostEntry.Connection
	if len(connection) == 0 {
		connection = osExpand(c, "connection")
	}

	runCommand := hostEntry.RunCommand
	if len(runCommand) != 0 {
		command = runCommand
	}

	commandEnvVars := []string{}
	if len(command) == 0 {
		if len(connection) > 0 {
			envVarName := ansible.EnvCommand + "_" + strings.ToUpper(connection)
			commandEnvVars = append(commandEnvVars, envVarName)
			command = os.Getenv(envVarName)
		}
	}
	commandEnvVars = append(commandEnvVars, ansible.EnvCommand)
	if len(command) == 0 {
		command = os.Getenv(ansible.EnvCommand)
	}
	if len(command) == 0 {
		plural := ""
		if len(commandEnvVars) > 1 {
			plural = "s"
		}
		fail(fmt.Errorf("Could not find a command to execute from the environment variable%s: %s", plural, strings.Join(commandEnvVars, ", ")))
	}

	log.Info("running command on a host from %s and command `%s`", hosts, command)
	bash := osExpand(c, "bash")
	if len(bash) > 0 {
		err = generateBashScript(bash, connection)
		if err != nil {
			log.Err("Failed to generate bash script at %s due to: %v", bash, err)
		}
	}

	log.Info("using connection %s", connection)
	if connection == ansible.ConnectionWinRM {
		log.Info("Using WinRM to connect to the hosts %s", hosts)
		password := hostEntry.Password
		if len(password) == 0 {
			password, err = osExpandAndVerify(c, "password")
			if err != nil {
				fail(err)
			}
		}
		err = winrm.RemoteWinRmCommand(user, password, host, port, command)
	} else {
		privatekey := hostEntry.PrivateKey

		err = ssh.RemoteSSHCommand(user, privatekey, host, port, command, envVars)
	}
	if err != nil {
		log.Err("Failed: %v", err)
	}
}
Example #7
0
func init() {
	rcCmd.Flags().StringVar(&inventory, "inventory", "inventory", "the location of your Ansible inventory file")
	rcCmd.Flags().IntVar(&replicas, "replicas", -1, "specifies the number of replicas to create for the RC")

	RootCmd.AddCommand(rcCmd)
}

// RCCmd is the root command for the whole program.
var rcCmd = &cobra.Command{
	Use:   "rc <hosts>",
	Short: "Creates or updates the kansible ReplicationController for some hosts in an Ansible inventory",
	Long:  `This commmand will analyse the hosts in an Ansible inventory and creates or updates the ReplicationController for the kansible pods.`,
	Run: func(cmd *cobra.Command, args []string) {
		if len(args) != 1 {
			log.Die("Expected argument <hosts> for the name of the hosts in the ansible inventory file")
		}
		hosts := args[0]

		f := cmdutil.NewFactory(clientConfig)
		if f == nil {
			log.Die("Failed to create Kubernetes client factory!")
		}
		kubeclient, err := f.Client()
		if err != nil || kubeclient == nil {
			log.Die(MessageFailedToCreateKubernetesClient, err)
		}
		ns, _, _ := f.DefaultNamespace()
		if len(ns) == 0 {
			ns = "default"
		}
Example #8
0
func fail(err error) {
	log.Die("Failed: %s", err)
}