2015-02-23 19:00:33 +00:00
|
|
|
package control
|
2015-02-19 20:48:10 +00:00
|
|
|
|
|
|
|
import (
|
2015-04-29 11:38:43 +00:00
|
|
|
"fmt"
|
2015-03-16 20:50:30 +00:00
|
|
|
"io/ioutil"
|
2015-02-19 20:48:10 +00:00
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
|
2015-03-16 20:50:30 +00:00
|
|
|
log "github.com/Sirupsen/logrus"
|
|
|
|
|
2015-02-21 21:31:10 +00:00
|
|
|
"github.com/codegangsta/cli"
|
2015-02-19 20:48:10 +00:00
|
|
|
machineUtil "github.com/docker/machine/utils"
|
2015-03-16 20:50:30 +00:00
|
|
|
"github.com/rancherio/os/config"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
NAME string = "rancher"
|
|
|
|
BITS int = 2048
|
2015-02-19 20:48:10 +00:00
|
|
|
)
|
|
|
|
|
2015-02-21 21:31:10 +00:00
|
|
|
func tlsConfCommands() []cli.Command {
|
2015-02-23 19:00:33 +00:00
|
|
|
return []cli.Command{
|
2015-02-21 21:31:10 +00:00
|
|
|
{
|
2015-03-16 20:50:30 +00:00
|
|
|
Name: "generate",
|
|
|
|
Usage: "generates new set of TLS configuration certs",
|
2015-02-21 21:31:10 +00:00
|
|
|
Action: tlsConfCreate,
|
2015-02-23 19:00:33 +00:00
|
|
|
Flags: []cli.Flag{
|
2015-03-16 20:50:30 +00:00
|
|
|
cli.StringSliceFlag{
|
|
|
|
Name: "hostname",
|
|
|
|
Usage: "the hostname for which you want to generate the certificate",
|
|
|
|
Value: &cli.StringSlice{"localhost"},
|
2015-02-21 21:31:10 +00:00
|
|
|
},
|
2015-02-23 19:00:33 +00:00
|
|
|
cli.BoolFlag{
|
2015-03-16 20:50:30 +00:00
|
|
|
Name: "server, s",
|
|
|
|
Usage: "generate the server keys instead of client keys",
|
2015-02-21 21:31:10 +00:00
|
|
|
},
|
2015-02-23 19:00:33 +00:00
|
|
|
cli.StringFlag{
|
2015-03-16 20:50:30 +00:00
|
|
|
Name: "dir, d",
|
|
|
|
Usage: "the directory to save/read the certs to/from",
|
2015-04-29 11:38:43 +00:00
|
|
|
Value: "",
|
2015-02-21 21:31:10 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
2015-02-23 19:00:33 +00:00
|
|
|
}
|
2015-02-21 21:31:10 +00:00
|
|
|
|
2015-07-29 06:52:15 +00:00
|
|
|
func writeCerts(generateServer bool, hostname []string, cfg *config.CloudConfig, certPath, keyPath, caCertPath, caKeyPath string) error {
|
2015-03-16 20:50:30 +00:00
|
|
|
if !generateServer {
|
|
|
|
return machineUtil.GenerateCert([]string{""}, certPath, keyPath, caCertPath, caKeyPath, NAME, BITS)
|
|
|
|
}
|
2015-02-19 20:48:10 +00:00
|
|
|
|
2015-09-11 09:10:50 +00:00
|
|
|
if cfg.Rancher.Docker.ServerKey == "" || cfg.Rancher.Docker.ServerCert == "" {
|
2015-03-16 20:50:30 +00:00
|
|
|
err := machineUtil.GenerateCert(hostname, certPath, keyPath, caCertPath, caKeyPath, NAME, BITS)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2015-02-19 20:48:10 +00:00
|
|
|
|
2015-03-16 20:50:30 +00:00
|
|
|
cert, err := ioutil.ReadFile(certPath)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2015-02-23 19:00:33 +00:00
|
|
|
|
2015-03-16 20:50:30 +00:00
|
|
|
key, err := ioutil.ReadFile(keyPath)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2015-02-23 19:00:33 +00:00
|
|
|
|
2015-09-23 11:36:28 +00:00
|
|
|
cfg, err = cfg.Merge(map[interface{}]interface{}{
|
|
|
|
"rancher": map[interface{}]interface{}{
|
|
|
|
"docker": map[interface{}]interface{}{
|
|
|
|
"ca_key": cfg.Rancher.Docker.CAKey,
|
|
|
|
"ca_cert": cfg.Rancher.Docker.CACert,
|
|
|
|
"server_cert": string(cert),
|
|
|
|
"server_key": string(key),
|
2015-07-29 06:52:15 +00:00
|
|
|
},
|
2015-03-16 20:50:30 +00:00
|
|
|
},
|
|
|
|
})
|
2015-09-23 11:36:28 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return cfg.Save()
|
2015-02-21 21:31:10 +00:00
|
|
|
}
|
|
|
|
|
2015-09-11 09:10:50 +00:00
|
|
|
if err := ioutil.WriteFile(certPath, []byte(cfg.Rancher.Docker.ServerCert), 0400); err != nil {
|
2015-03-16 20:50:30 +00:00
|
|
|
return err
|
2015-02-23 19:00:33 +00:00
|
|
|
}
|
2015-02-19 20:48:10 +00:00
|
|
|
|
2015-09-11 09:10:50 +00:00
|
|
|
return ioutil.WriteFile(keyPath, []byte(cfg.Rancher.Docker.ServerKey), 0400)
|
2015-02-19 20:48:10 +00:00
|
|
|
|
2015-03-16 20:50:30 +00:00
|
|
|
}
|
2015-02-21 21:31:10 +00:00
|
|
|
|
2015-07-29 06:52:15 +00:00
|
|
|
func writeCaCerts(cfg *config.CloudConfig, caCertPath, caKeyPath string) error {
|
2015-09-11 09:10:50 +00:00
|
|
|
if cfg.Rancher.Docker.CACert == "" {
|
2015-03-16 20:50:30 +00:00
|
|
|
if err := machineUtil.GenerateCACertificate(caCertPath, caKeyPath, NAME, BITS); err != nil {
|
|
|
|
return err
|
2015-02-19 20:48:10 +00:00
|
|
|
}
|
|
|
|
|
2015-03-16 20:50:30 +00:00
|
|
|
caCert, err := ioutil.ReadFile(caCertPath)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2015-02-19 20:48:10 +00:00
|
|
|
|
2015-03-16 20:50:30 +00:00
|
|
|
caKey, err := ioutil.ReadFile(caKeyPath)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
2015-02-19 20:48:10 +00:00
|
|
|
}
|
|
|
|
|
2015-09-23 11:36:28 +00:00
|
|
|
cfg, err = cfg.Merge(map[interface{}]interface{}{
|
|
|
|
"rancher": map[interface{}]interface{}{
|
|
|
|
"docker": map[interface{}]interface{}{
|
|
|
|
"ca_key": string(caKey),
|
|
|
|
"ca_cert": string(caCert),
|
2015-07-29 06:52:15 +00:00
|
|
|
},
|
2015-03-16 20:50:30 +00:00
|
|
|
},
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return err
|
2015-02-19 20:48:10 +00:00
|
|
|
}
|
2015-03-16 20:50:30 +00:00
|
|
|
|
2015-09-23 11:36:28 +00:00
|
|
|
return cfg.Save()
|
2015-03-16 20:50:30 +00:00
|
|
|
}
|
|
|
|
|
2015-09-11 09:10:50 +00:00
|
|
|
if err := ioutil.WriteFile(caCertPath, []byte(cfg.Rancher.Docker.CACert), 0400); err != nil {
|
2015-03-16 20:50:30 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2015-09-11 09:10:50 +00:00
|
|
|
return ioutil.WriteFile(caKeyPath, []byte(cfg.Rancher.Docker.CAKey), 0400)
|
2015-03-16 20:50:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func tlsConfCreate(c *cli.Context) {
|
|
|
|
err := generate(c)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func generate(c *cli.Context) error {
|
2015-08-27 19:24:26 +00:00
|
|
|
generateServer := c.Bool("server")
|
|
|
|
outDir := c.String("dir")
|
|
|
|
hostnames := c.StringSlice("hostname")
|
|
|
|
|
|
|
|
return Generate(generateServer, outDir, hostnames)
|
|
|
|
}
|
|
|
|
|
|
|
|
func Generate(generateServer bool, outDir string, hostnames []string) error {
|
2015-03-16 20:50:30 +00:00
|
|
|
cfg, err := config.LoadConfig()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
2015-02-19 20:48:10 +00:00
|
|
|
}
|
|
|
|
|
2015-04-29 11:38:43 +00:00
|
|
|
if outDir == "" {
|
|
|
|
return fmt.Errorf("out directory (-d, --dir) not specified")
|
|
|
|
}
|
2015-03-16 20:50:30 +00:00
|
|
|
caCertPath := filepath.Join(outDir, "ca.pem")
|
|
|
|
caKeyPath := filepath.Join(outDir, "ca-key.pem")
|
|
|
|
certPath := filepath.Join(outDir, "cert.pem")
|
|
|
|
keyPath := filepath.Join(outDir, "key.pem")
|
2015-02-19 20:48:10 +00:00
|
|
|
|
2015-03-16 20:50:30 +00:00
|
|
|
if generateServer {
|
|
|
|
certPath = filepath.Join(outDir, "server-cert.pem")
|
|
|
|
keyPath = filepath.Join(outDir, "server-key.pem")
|
2015-02-19 20:48:10 +00:00
|
|
|
}
|
2015-03-16 20:50:30 +00:00
|
|
|
|
|
|
|
if _, err := os.Stat(outDir); os.IsNotExist(err) {
|
|
|
|
if err := os.MkdirAll(outDir, 0700); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := writeCaCerts(cfg, caCertPath, caKeyPath); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return writeCerts(generateServer, hostnames, cfg, certPath, keyPath, caCertPath, caKeyPath)
|
2015-02-19 20:48:10 +00:00
|
|
|
}
|