Files
weave/proxy/proxy.go
T
Matthias Radestock fee2898c05 remove detailed proxy status
There are two problems with obtaining the proxy status via the normal
proxy endpoint...

1. when TLS is enabled, this requires using TLS at the client end

2. the status URL is mixed in with the docker remote API, which is
rather unclean

There is limited value to having some status output from the proxy,
since all the output is constant.

So instead we log the version and command line args, and in `weave
status` only report whether the proxy is running.

We still want a way to wait for the proxy to start up, and log a nice
error if it dies. We do this by polling the docker logs for a startup
message.

Fixes #877. Fixes #876.

Undoes most of #756, #800, #854.
2015-06-09 14:03:52 +01:00

117 lines
2.6 KiB
Go

package proxy
import (
"crypto/tls"
"net"
"net/http"
"net/url"
"regexp"
"github.com/fsouza/go-dockerclient"
. "github.com/weaveworks/weave/common"
)
const (
defaultCaFile = "ca.pem"
defaultKeyFile = "key.pem"
defaultCertFile = "cert.pem"
)
var (
containerCreateRegexp = regexp.MustCompile("^(/v[0-9\\.]*)?/containers/create$")
containerStartRegexp = regexp.MustCompile("^(/v[0-9\\.]*)?/containers/[^/]*/(re)?start$")
execCreateRegexp = regexp.MustCompile("^(/v[0-9\\.]*)?/containers/[^/]*/exec$")
)
type Proxy struct {
Config
dial func() (net.Conn, error)
client *docker.Client
dockerBridgeIP string
}
type Config struct {
DockerAddr string
ListenAddr string
TLSConfig TLSConfig
Version string
WithDNS bool
WithIPAM bool
}
func NewProxy(c Config) (*Proxy, error) {
u, err := url.Parse(c.DockerAddr)
if err != nil {
return nil, err
}
targetAddr := ""
switch u.Scheme {
case "tcp":
targetAddr = u.Host
case "unix":
targetAddr = u.Path
}
p := &Proxy{
Config: c,
dial: func() (net.Conn, error) {
return net.Dial(u.Scheme, targetAddr)
},
}
if p.WithDNS {
dockerBridgeIP, err := callWeave("docker-bridge-ip")
if err != nil {
return nil, err
}
p.dockerBridgeIP = string(dockerBridgeIP)
}
if err := p.TLSConfig.loadCerts(); err != nil {
Error.Fatalf("Could not configure tls for proxy: %s", err)
}
p.client, err = docker.NewClient(p.DockerAddr)
if err != nil {
return nil, err
}
return p, nil
}
func (proxy *Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
Info.Printf("%s %s", r.Method, r.URL)
path := r.URL.Path
switch {
case containerCreateRegexp.MatchString(path):
proxy.serveWithInterceptor(&createContainerInterceptor{proxy.client, proxy.dockerBridgeIP, proxy.WithDNS, proxy.WithIPAM}, w, r)
case containerStartRegexp.MatchString(path):
proxy.serveWithInterceptor(&startContainerInterceptor{proxy.client, proxy.WithDNS, proxy.WithIPAM}, w, r)
case execCreateRegexp.MatchString(path):
proxy.serveWithInterceptor(&createExecInterceptor{proxy.client, proxy.WithIPAM}, w, r)
default:
proxy.serveWithInterceptor(&nullInterceptor{}, w, r)
}
}
func (proxy *Proxy) serveWithInterceptor(i interceptor, w http.ResponseWriter, r *http.Request) {
newClient(proxy.dial, i).ServeHTTP(w, r)
}
func (proxy *Proxy) ListenAndServe() error {
listener, err := net.Listen("tcp", proxy.ListenAddr)
if err != nil {
return err
}
if proxy.TLSConfig.enabled() {
listener = tls.NewListener(listener, proxy.TLSConfig.Config)
}
Info.Println("proxy listening")
return (&http.Server{Handler: proxy}).Serve(listener)
}