// MapEndpoint2IP maps endpoint nodes to their IP address, for joining // with container nodes. We drop endpoint nodes with pids, as they // will be joined to containers through the process topology, and we // don't want to double count edges. func MapEndpoint2IP(m RenderableNode, local report.Networks) RenderableNodes { // Don't include procspied connections, to prevent double counting _, ok := m.Latest.Lookup(endpoint.Procspied) if ok { return RenderableNodes{} } scope, addr, port, ok := report.ParseEndpointNodeID(m.ID) if !ok { return RenderableNodes{} } if ip := net.ParseIP(addr); ip != nil && !local.Contains(ip) { return RenderableNodes{TheInternetID: newDerivedPseudoNode(TheInternetID, TheInternetMajor, m)} } // We don't always know what port a container is listening on, and // container-to-container communications can be unambiguously identified // without ports. OTOH, connections to the host IPs which have been port // mapped to a container can only be unambiguously identified with the port. // So we need to emit two nodes, for two different cases. id := report.MakeScopedEndpointNodeID(scope, addr, "") idWithPort := report.MakeScopedEndpointNodeID(scope, addr, port) m = m.WithParents(report.EmptySets) return RenderableNodes{ id: NewRenderableNodeWith(id, "", "", "", m), idWithPort: NewRenderableNodeWith(idWithPort, "", "", "", m), } }
// MapAddressIdentity maps an address topology node to an address renderable // node. As it is only ever run on address topology nodes, we expect that // certain keys are present. func MapAddressIdentity(m RenderableNode, local report.Networks) RenderableNodes { addr, ok := m.Metadata[endpoint.Addr] if !ok { return RenderableNodes{} } // Nodes without a hostid are treated as psuedo nodes _, ok = m.Metadata[report.HostNodeID] if !ok { // If the addr is not in a network local to this report, we emit an // internet node if !local.Contains(net.ParseIP(addr)) { return RenderableNodes{TheInternetID: newDerivedPseudoNode(TheInternetID, TheInternetMajor, m)} } // Otherwise generate a pseudo node for every outputID := MakePseudoNodeID(addr, "") if len(m.Adjacency) > 0 { _, dstAddr, _ := report.ParseAddressNodeID(m.Adjacency[0]) outputID = MakePseudoNodeID(addr, dstAddr) } return RenderableNodes{outputID: newDerivedPseudoNode(outputID, addr, m)} } var ( id = MakeAddressID(report.ExtractHostID(m.Node), addr) major = addr minor = report.ExtractHostID(m.Node) rank = major ) return RenderableNodes{id: NewRenderableNodeWith(id, major, minor, rank, m)} }
// MapEndpointIdentity maps an endpoint topology node to a single endpoint // renderable node. As it is only ever run on endpoint topology nodes, we // expect that certain keys are present. func MapEndpointIdentity(m RenderableNode, local report.Networks) RenderableNodes { addr, ok := m.Metadata[endpoint.Addr] if !ok { return RenderableNodes{} } port, ok := m.Metadata[endpoint.Port] if !ok { return RenderableNodes{} } // We only show nodes found through procspy in this view. _, procspied := m.Metadata[endpoint.Procspied] if !procspied { return RenderableNodes{} } // Nodes without a hostid are treated as psuedo nodes if _, ok = m.Metadata[report.HostNodeID]; !ok { // If the dstNodeAddr is not in a network local to this report, we emit an // internet node if ip := net.ParseIP(addr); ip != nil && !local.Contains(ip) { return RenderableNodes{TheInternetID: newDerivedPseudoNode(TheInternetID, TheInternetMajor, m)} } // We are a 'client' pseudo node if the port is in the ephemeral port range. // Linux uses 32768 to 61000, IANA suggests 49152 to 65535. if p, err := strconv.Atoi(port); err == nil && len(m.Adjacency) > 0 && p >= 32768 && p < 65535 { // We only exist if there is something in our adjacency // Generate a single pseudo node for every (client ip, server ip, server port) dstNodeID := m.Adjacency[0] serverIP, serverPort := trySplitAddr(dstNodeID) outputID := MakePseudoNodeID(addr, serverIP, serverPort) return RenderableNodes{outputID: newDerivedPseudoNode(outputID, addr, m)} } // Otherwise (the server node is missing), generate a pseudo node for every (server ip, server port) outputID := MakePseudoNodeID(addr, port) if port != "" { return RenderableNodes{outputID: newDerivedPseudoNode(outputID, addr+":"+port, m)} } return RenderableNodes{outputID: newDerivedPseudoNode(outputID, addr, m)} } var ( id = MakeEndpointID(report.ExtractHostID(m.Node), addr, port) major = fmt.Sprintf("%s:%s", addr, port) minor = report.ExtractHostID(m.Node) rank = major ) pid, pidOK := m.Metadata[process.PID] if pidOK { minor = fmt.Sprintf("%s (%s)", minor, pid) } return RenderableNodes{id: NewRenderableNodeWith(id, major, minor, rank, m)} }
// MapEndpoint2IP maps endpoint nodes to their IP address, for joining // with container nodes. We drop endpoint nodes with pids, as they // will be joined to containers through the process topology, and we // don't want to double count edges. func MapEndpoint2IP(m RenderableNode, local report.Networks) RenderableNodes { _, ok := m.Metadata[process.PID] if ok { return RenderableNodes{} } addr, ok := m.Metadata[endpoint.Addr] if !ok { return RenderableNodes{} } if !local.Contains(net.ParseIP(addr)) { return RenderableNodes{TheInternetID: newDerivedPseudoNode(TheInternetID, TheInternetMajor, m)} } return RenderableNodes{addr: NewRenderableNodeWith(addr, "", "", "", m)} }
// MapEndpoint2Pseudo makes internet of host pesudo nodes from a endpoint node. func MapEndpoint2Pseudo(n report.Node, local report.Networks) report.Nodes { var node report.Node addr, ok := n.Latest.Lookup(endpoint.Addr) if !ok { return report.Nodes{} } if ip := net.ParseIP(addr); ip != nil && !local.Contains(ip) { // If the dstNodeAddr is not in a network local to this report, we emit an // internet node node = theInternetNode(n) } else { // due to https://github.com/weaveworks/scope/issues/1323 we are dropping // all non-internet pseudo nodes for now. // node = NewDerivedPseudoNode(MakePseudoNodeID(addr), n) return report.Nodes{} } return report.Nodes{node.ID: node} }
// MapAddressIdentity maps an address topology node to an address renderable // node. As it is only ever run on address topology nodes, we expect that // certain keys are present. func MapAddressIdentity(m RenderableNode, local report.Networks) RenderableNodes { addr, ok := m.Metadata[endpoint.Addr] if !ok { return RenderableNodes{} } // Conntracked connections don't have a host id unless // they were merged with a procspied connection. Filter // out those that weren't. _, hasHostID := m.Metadata[report.HostNodeID] _, conntracked := m.Metadata[endpoint.Conntracked] if !hasHostID && conntracked { return RenderableNodes{} } // Nodes without a hostid are treated as psuedo nodes if !hasHostID { // If the addr is not in a network local to this report, we emit an // internet node if !local.Contains(net.ParseIP(addr)) { return RenderableNodes{TheInternetID: newDerivedPseudoNode(TheInternetID, TheInternetMajor, m)} } // Otherwise generate a pseudo node for every outputID := MakePseudoNodeID(addr, "") if len(m.Adjacency) > 0 { _, dstAddr, _ := report.ParseAddressNodeID(m.Adjacency[0]) outputID = MakePseudoNodeID(addr, dstAddr) } return RenderableNodes{outputID: newDerivedPseudoNode(outputID, addr, m)} } var ( id = MakeAddressID(report.ExtractHostID(m.Node), addr) major = addr minor = report.ExtractHostID(m.Node) rank = major ) return RenderableNodes{id: NewRenderableNodeWith(id, major, minor, rank, m)} }