Merge pull request #394 from weaveworks/weave-dns-hostnames

Tag containers with WeaveDNS hostnames.
This commit is contained in:
Tom Wilkie
2015-08-25 17:49:33 +01:00
4 changed files with 101 additions and 30 deletions

View File

@@ -127,7 +127,7 @@ func main() {
}
if *weaveRouterAddr != "" {
weave, err := overlay.NewWeave(*weaveRouterAddr)
weave, err := overlay.NewWeave(hostID, *weaveRouterAddr)
if err != nil {
log.Fatalf("failed to start Weave tagger: %v", err)
}

View File

@@ -18,6 +18,9 @@ const (
// WeavePeerNickName is the key for the peer nickname, typically a
// hostname.
WeavePeerNickName = "weave_peer_nick_name"
// WeaveDNSHostname is the ket for the WeaveDNS hostname
WeaveDNSHostname = "weave_dns_hostname"
)
// Weave represents a single Weave router, presumably on the same host
@@ -26,27 +29,37 @@ const (
// overlay -- though I'm not sure what that would look like in practice right
// now.
type Weave struct {
url string
url string
hostID string
}
type weaveStatus struct {
Router struct {
Peers []struct {
Name string `json:"name"`
NickName string `json:"nickname"`
} `json:"peers"`
} `json:"router"`
Name string
NickName string
}
}
DNS struct {
Entries []struct {
Hostname string
ContainerID string
Tombstone int64
}
}
}
// NewWeave returns a new Weave tagger based on the Weave router at
// address. The address should be an IP or FQDN, no port.
func NewWeave(weaveRouterAddress string) (*Weave, error) {
func NewWeave(hostID, weaveRouterAddress string) (*Weave, error) {
s, err := sanitize("http://", 6784, "/report")(weaveRouterAddress)
if err != nil {
return nil, err
}
return &Weave{
url: s,
url: s,
hostID: hostID,
}, nil
}
@@ -72,8 +85,26 @@ func (w Weave) update() (weaveStatus, error) {
// Tag implements Tagger.
func (w Weave) Tag(r report.Report) (report.Report, error) {
// The status-json endpoint doesn't return any link information, so
// there's nothing to tag, yet.
status, err := w.update()
if err != nil {
return r, nil
}
for _, entry := range status.DNS.Entries {
if entry.Tombstone > 0 {
continue
}
nodeID := report.MakeContainerNodeID(w.hostID, entry.ContainerID)
node, ok := r.Container.NodeMetadatas[nodeID]
if !ok {
continue
}
hostnames := report.IDList(strings.Fields(node.Metadata[WeaveDNSHostname]))
hostnames = hostnames.Add(strings.TrimSuffix(entry.Hostname, "."))
node.Metadata[WeaveDNSHostname] = strings.Join(hostnames, " ")
r.Container.NodeMetadatas[nodeID] = node
}
return r, nil
}

View File

@@ -16,43 +16,81 @@ func TestWeaveTaggerOverlayTopology(t *testing.T) {
s := httptest.NewServer(http.HandlerFunc(mockWeaveRouter))
defer s.Close()
w, err := overlay.NewWeave(s.URL)
w, err := overlay.NewWeave(mockHostID, s.URL)
if err != nil {
t.Fatal(err)
}
have, err := w.Report()
if err != nil {
t.Fatal(err)
{
have, err := w.Report()
if err != nil {
t.Fatal(err)
}
if want, have := (report.Topology{
Adjacency: report.Adjacency{},
EdgeMetadatas: report.EdgeMetadatas{},
NodeMetadatas: report.NodeMetadatas{
report.MakeOverlayNodeID(mockWeavePeerName): report.MakeNodeMetadataWith(map[string]string{
overlay.WeavePeerName: mockWeavePeerName,
overlay.WeavePeerNickName: mockWeavePeerNickName,
}),
},
}), have.Overlay; !reflect.DeepEqual(want, have) {
t.Error(test.Diff(want, have))
}
}
if want, have := (report.Topology{
Adjacency: report.Adjacency{},
EdgeMetadatas: report.EdgeMetadatas{},
NodeMetadatas: report.NodeMetadatas{
report.MakeOverlayNodeID(mockWeavePeerName): report.MakeNodeMetadataWith(map[string]string{
overlay.WeavePeerName: mockWeavePeerName,
overlay.WeavePeerNickName: mockWeavePeerNickName,
}),
},
}), have.Overlay; !reflect.DeepEqual(want, have) {
t.Error(test.Diff(want, have))
{
nodeID := report.MakeContainerNodeID(mockHostID, mockContainerID)
want := report.Report{
Container: report.Topology{
NodeMetadatas: report.NodeMetadatas{
nodeID: report.MakeNodeMetadataWith(map[string]string{
overlay.WeaveDNSHostname: mockHostname,
}),
},
},
}
have, err := w.Tag(report.Report{
Container: report.Topology{
NodeMetadatas: report.NodeMetadatas{
nodeID: report.MakeNodeMetadata(),
},
},
})
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(want, have) {
t.Error(test.Diff(want, have))
}
}
}
const (
mockHostID = "host1"
mockWeavePeerName = "winnebago"
mockWeavePeerNickName = "winny"
mockContainerID = "a1b2c3d4e5"
mockHostname = "hostname.weave.local"
)
var (
mockResponse = fmt.Sprintf(`{
"router": {
"peers": [{
"name": "%s",
"nickname": "%s"
"Router": {
"Peers": [{
"Name": "%s",
"Nickname": "%s"
}]
},
"DNS": {
"Entries": [{
"ContainerID": "%s",
"Hostname": "%s.",
"Tombstone": 0
}]
}
}`, mockWeavePeerName, mockWeavePeerNickName)
}`, mockWeavePeerName, mockWeavePeerNickName, mockContainerID, mockHostname)
)
func mockWeaveRouter(w http.ResponseWriter, r *http.Request) {

View File

@@ -7,6 +7,7 @@ import (
"github.com/weaveworks/scope/probe/docker"
"github.com/weaveworks/scope/probe/host"
"github.com/weaveworks/scope/probe/overlay"
"github.com/weaveworks/scope/probe/process"
"github.com/weaveworks/scope/report"
)
@@ -296,6 +297,7 @@ func containerOriginTable(nmd report.NodeMetadata, addHostTag bool) (Table, bool
rows := []Row{}
for _, tuple := range []struct{ key, human string }{
{docker.ContainerID, "ID"},
{overlay.WeaveDNSHostname, "Weave DNS Hostname"},
{docker.ImageID, "Image ID"},
{docker.ContainerPorts, "Ports"},
{docker.ContainerCreated, "Created"},