Rework TLS support, remove unsupported options

This commit is contained in:
Ross Cadogan 2016-10-14 11:10:48 +01:00
parent 69db640b98
commit 42fea79860
3 changed files with 43 additions and 148 deletions

147
main.go
View file

@ -1,13 +1,9 @@
package main // import "github.com/CenturyLinkLabs/watchtower"
import (
"crypto/tls"
"crypto/x509"
"fmt"
"io/ioutil"
"os"
"os/signal"
"strings"
"sync"
"syscall"
"time"
@ -16,15 +12,11 @@ import (
"github.com/CenturyLinkLabs/watchtower/container"
log "github.com/Sirupsen/logrus"
"github.com/urfave/cli"
"github.com/docker/docker/api/types"
dockerclient "github.com/docker/docker/client"
"golang.org/x/net/context"
)
var (
wg sync.WaitGroup
client container.Client
registryClient container.Client
pollInterval time.Duration
cleanup bool
)
@ -34,12 +26,6 @@ func init() {
}
func main() {
rootCertPath := "/etc/ssl/docker"
if os.Getenv("DOCKER_CERT_PATH") != "" {
rootCertPath = os.Getenv("DOCKER_CERT_PATH")
}
app := cli.NewApp()
app.Name = "watchtower"
app.Usage = "Automatically update running Docker containers"
@ -52,12 +38,6 @@ func main() {
Value: "unix:///var/run/docker.sock",
EnvVar: "DOCKER_HOST",
},
cli.StringFlag{
Name: "registry",
Usage: "docker registry from which to pull images",
Value: "unix:///var/run/docker.sock",
EnvVar: "DOCKER_REGISTRY",
},
cli.IntFlag{
Name: "interval, i",
Usage: "poll interval (in seconds)",
@ -71,34 +51,20 @@ func main() {
Name: "cleanup",
Usage: "remove old images after updating",
},
cli.BoolFlag{
Name: "tls",
Usage: "use TLS; implied by --tlsverify",
},
cli.BoolFlag{
Name: "tlsverify",
Usage: "use TLS and verify the remote",
EnvVar: "DOCKER_TLS_VERIFY",
},
cli.StringFlag{
Name: "tlscacert",
Usage: "trust certs signed only by this CA",
Value: fmt.Sprintf("%s/ca.pem", rootCertPath),
},
cli.StringFlag{
Name: "tlscert",
Usage: "client certificate for TLS authentication",
Value: fmt.Sprintf("%s/cert.pem", rootCertPath),
},
cli.StringFlag{
Name: "tlskey",
Usage: "client key for TLS authentication",
Value: fmt.Sprintf("%s/key.pem", rootCertPath),
},
cli.BoolFlag{
Name: "debug",
Usage: "enable debug mode with verbose logging",
},
cli.StringFlag{
Name: "apiversion",
Usage: "the version of the docker api",
EnvVar: "DOCKER_API_VERSION",
},
}
if err := app.Run(os.Args); err != nil {
@ -114,40 +80,18 @@ func before(c *cli.Context) error {
pollInterval = time.Duration(c.Int("interval")) * time.Second
cleanup = c.GlobalBool("cleanup")
// Set-up container client
_, err := tlsConfig(c)
// configure environment vars for client
err := envConfig(c)
if err != nil {
return err
}
client = container.NewClient(c.GlobalString("host"), !c.GlobalBool("no-pull"))
//login(c)
client = container.NewClient(!c.GlobalBool("no-pull"))
handleSignals()
return nil
}
func login(c *cli.Context) {
registry := c.GlobalString("registry")
if registry != "" && registry != c.GlobalString("host") {
log.Debug("Logging into registry")
clint, err := dockerclient.NewEnvClient()
if err != nil {
panic(err)
}
regAuth := types.AuthConfig{
Username: "testuser",
Password: "testpassword",
ServerAddress: registry,
}
resp, err := clint.RegistryLogin(context.Background(), regAuth)
if err != nil {
panic(err)
}
log.Debugf("Authenticated client with registry %s, %s", registry, resp)
}
}
func start(c *cli.Context) {
names := c.Args()
@ -179,56 +123,31 @@ func handleSignals() {
}()
}
// tlsConfig translates the command-line options into a tls.Config struct
func tlsConfig(c *cli.Context) (*tls.Config, error) {
var tlsConfig *tls.Config
var err error
caCertFlag := c.GlobalString("tlscacert")
certFlag := c.GlobalString("tlscert")
keyFlag := c.GlobalString("tlskey")
if c.GlobalBool("tls") || c.GlobalBool("tlsverify") {
tlsConfig = &tls.Config{
InsecureSkipVerify: !c.GlobalBool("tlsverify"),
}
// Load CA cert
if caCertFlag != "" {
var caCert []byte
if strings.HasPrefix(caCertFlag, "/") {
caCert, err = ioutil.ReadFile(caCertFlag)
if err != nil {
return nil, err
}
} else {
caCert = []byte(caCertFlag)
}
caCertPool := x509.NewCertPool()
caCertPool.AppendCertsFromPEM(caCert)
tlsConfig.RootCAs = caCertPool
}
// Load client certificate
if certFlag != "" && keyFlag != "" {
var cert tls.Certificate
if strings.HasPrefix(certFlag, "/") && strings.HasPrefix(keyFlag, "/") {
cert, err = tls.LoadX509KeyPair(certFlag, keyFlag)
if err != nil {
return nil, err
}
} else {
cert, err = tls.X509KeyPair([]byte(certFlag), []byte(keyFlag))
if err != nil {
return nil, err
}
}
tlsConfig.Certificates = []tls.Certificate{cert}
func setEnvOptStr(env string, opt string) error {
if (opt != "" && opt != os.Getenv(env)) {
err := os.Setenv(env, opt)
if (err != nil) {
return err
}
}
return tlsConfig, nil
return nil
}
func setEnvOptBool(env string, opt bool) error {
if (opt == true) {
return setEnvOptStr(env, "1")
}
return nil
}
// envConfig translates the command-line options into environment variables
// that will initialize the api client
func envConfig(c *cli.Context) error {
var err error
err = setEnvOptStr("DOCKER_HOST", c.GlobalString("host"))
err = setEnvOptBool("DOCKER_TLS_VERIFY", c.GlobalBool("tlsverify"))
err = setEnvOptStr("DOCKER_API_VERSION", c.GlobalString("apiversion"))
return err
}