Files
weave/proxy/create_container_interceptor.go
T
Paul Bellamy 2c3baa9119 use weavedns search-domain by default
iff no hostname/dns-search specified
2015-06-16 15:13:19 +01:00

140 lines
3.5 KiB
Go

package proxy
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"strings"
"github.com/fsouza/go-dockerclient"
. "github.com/weaveworks/weave/common"
"github.com/weaveworks/weave/nameserver"
)
type createContainerInterceptor struct{ proxy *Proxy }
type createContainerRequestBody struct {
*docker.Config
HostConfig *docker.HostConfig `json:"HostConfig,omitempty" yaml:"HostConfig,omitempty"`
MacAddress string `json:"MacAddress,omitempty" yaml:"MacAddress,omitempty"`
}
func (i *createContainerInterceptor) InterceptRequest(r *http.Request) error {
body, err := ioutil.ReadAll(r.Body)
if err != nil {
return err
}
r.Body.Close()
container := createContainerRequestBody{}
if err := json.Unmarshal(body, &container); err != nil {
return err
}
if cidrs, ok := weaveCIDRsFromConfig(container.Config); ok || i.proxy.WithIPAM {
Info.Printf("Creating container with WEAVE_CIDR \"%s\"", strings.Join(cidrs, " "))
if container.HostConfig == nil {
container.HostConfig = &docker.HostConfig{}
}
container.HostConfig.VolumesFrom = append(container.HostConfig.VolumesFrom, "weaveproxy")
if container.Config == nil {
container.Config = &docker.Config{}
}
if err := i.setWeaveWaitEntrypoint(container.Config); err != nil {
return err
}
if err := i.setWeaveDNS(&container, r); err != nil {
return err
}
}
newBody, err := json.Marshal(container)
if err != nil {
return err
}
r.Body = ioutil.NopCloser(bytes.NewReader(newBody))
r.ContentLength = int64(len(newBody))
return nil
}
func (i *createContainerInterceptor) setWeaveWaitEntrypoint(container *docker.Config) error {
if len(container.Entrypoint) == 0 {
image, err := i.proxy.client.InspectImage(container.Image)
if err != nil {
return err
}
if len(container.Cmd) == 0 {
container.Cmd = image.Config.Cmd
}
if container.Entrypoint == nil {
container.Entrypoint = image.Config.Entrypoint
}
}
container.Entrypoint = append(weaveWaitEntrypoint, container.Entrypoint...)
return nil
}
func (i *createContainerInterceptor) setWeaveDNS(container *createContainerRequestBody, r *http.Request) error {
if i.proxy.WithoutDNS {
return nil
}
dnsDomain, dnsRunning := i.getDNSDomain()
if !(dnsRunning || i.proxy.WithDNS) {
return nil
}
container.HostConfig.DNS = append(container.HostConfig.DNS, i.proxy.dockerBridgeIP)
name := r.URL.Query().Get("name")
if container.Hostname == "" && name != "" {
container.Hostname = name
// Strip trailing period because it's unusual to see it used on the end of a host name
container.Domainname = strings.TrimSuffix(dnsDomain, ".")
}
if len(container.HostConfig.DNSSearch) == 0 {
if container.Hostname == "" {
container.HostConfig.DNSSearch = []string{dnsDomain}
} else {
container.HostConfig.DNSSearch = []string{"."}
}
}
return nil
}
func (i *createContainerInterceptor) getDNSDomain() (domain string, running bool) {
domain = nameserver.DefaultLocalDomain
dnsContainer, err := i.proxy.client.InspectContainer("weavedns")
if err != nil ||
dnsContainer.NetworkSettings == nil ||
dnsContainer.NetworkSettings.IPAddress == "" {
return
}
url := fmt.Sprintf("http://%s:%d/domain", dnsContainer.NetworkSettings.IPAddress, nameserver.DefaultHTTPPort)
resp, err := http.Get(url)
if err != nil || resp.StatusCode != http.StatusOK {
return
}
defer resp.Body.Close()
b, err := ioutil.ReadAll(resp.Body)
if err != nil {
return
}
return string(b), true
}
func (i *createContainerInterceptor) InterceptResponse(r *http.Response) error {
return nil
}