// MapContainer2Pod maps container Nodes to pod // Nodes. // // If this function is given a node without a kubernetes_pod_id // (including other pseudo nodes), it will produce an "Unmanaged" // pseudo node. // // Otherwise, this function will produce a node with the correct ID // format for a container, but without any Major or Minor labels. // It does not have enough info to do that, and the resulting graph // must be merged with a container graph to get that info. func MapContainer2Pod(n report.Node, _ report.Networks) report.Nodes { // Uncontained becomes unmanaged in the pods view if strings.HasPrefix(n.ID, MakePseudoNodeID(UncontainedID)) { id := MakePseudoNodeID(UnmanagedID, report.ExtractHostID(n)) node := NewDerivedPseudoNode(id, n) return report.Nodes{id: node} } // Propagate all pseudo nodes if n.Topology == Pseudo { return report.Nodes{n.ID: n} } // Ignore non-running containers if state, ok := n.Latest.Lookup(docker.ContainerState); ok && state != docker.StateRunning { return report.Nodes{} } // Otherwise, if some some reason the container doesn't have a pod uid (maybe // slightly out of sync reports, or its not in a pod), make it part of unmanaged. uid, ok := n.Latest.Lookup(docker.LabelPrefix + "io.kubernetes.pod.uid") if !ok { id := MakePseudoNodeID(UnmanagedID, report.ExtractHostID(n)) node := NewDerivedPseudoNode(id, n) return report.Nodes{id: node} } id := report.MakePodNodeID(uid) node := NewDerivedNode(id, n). WithTopology(report.Pod) node.Counters = node.Counters.Add(n.Topology, 1) return report.Nodes{id: node} }
// MapProcess2Container maps process Nodes to container // Nodes. // // If this function is given a node without a docker_container_id // (including other pseudo nodes), it will produce an "Uncontained" // pseudo node. // // Otherwise, this function will produce a node with the correct ID // format for a container, but without any Major or Minor labels. // It does not have enough info to do that, and the resulting graph // must be merged with a container graph to get that info. func MapProcess2Container(n report.Node, _ report.Networks) report.Nodes { // Propagate pseudo nodes if n.Topology == Pseudo { return report.Nodes{n.ID: n} } // Otherwise, if the process is not in a container, group it // into an per-host "Uncontained" node. If for whatever reason // this node doesn't have a host id in their nodemetadata, it'll // all get grouped into a single uncontained node. var ( id string node report.Node ) if containerID, ok := n.Latest.Lookup(docker.ContainerID); ok { id = report.MakeContainerNodeID(containerID) node = NewDerivedNode(id, n).WithTopology(report.Container) } else { id = MakePseudoNodeID(UncontainedID, report.ExtractHostID(n)) node = NewDerivedPseudoNode(id, n) node = propagateLatest(report.HostNodeID, n, node) node = propagateLatest(IsConnected, n, node) } return report.Nodes{id: node} }
func processNodeSummary(base NodeSummary, n report.Node) (NodeSummary, bool) { base.Label, _ = n.Latest.Lookup(process.Name) base.Rank, _ = n.Latest.Lookup(process.Name) pid, ok := n.Latest.Lookup(process.PID) if !ok { return NodeSummary{}, false } if containerName, ok := n.Latest.Lookup(docker.ContainerName); ok { base.LabelMinor = fmt.Sprintf("%s (%s:%s)", report.ExtractHostID(n), containerName, pid) } else { base.LabelMinor = fmt.Sprintf("%s (%s)", report.ExtractHostID(n), pid) } _, isConnected := n.Latest.Lookup(render.IsConnected) base.Linkable = isConnected return base, true }
func containerNodeSummary(base NodeSummary, n report.Node) (NodeSummary, bool) { base.Label = getRenderableContainerName(n) base.LabelMinor = report.ExtractHostID(n) if imageName, ok := n.Latest.Lookup(docker.ImageName); ok { base.Rank = docker.ImageNameWithoutVersion(imageName) } return base, true }
func pseudoNodeSummary(base NodeSummary, n report.Node) (NodeSummary, bool) { base.Pseudo = true base.Rank = n.ID if template, ok := map[string]struct{ Label, LabelMinor string }{ render.TheInternetID: {render.InboundMajor, ""}, render.IncomingInternetID: {render.InboundMajor, render.InboundMinor}, render.OutgoingInternetID: {render.OutboundMajor, render.OutboundMinor}, }[n.ID]; ok { base.Label = template.Label base.LabelMinor = template.LabelMinor base.Shape = report.Cloud return base, true } // try rendering it as an uncontained node if strings.HasPrefix(n.ID, render.MakePseudoNodeID(render.UncontainedID)) { base.Label = render.UncontainedMajor base.LabelMinor = report.ExtractHostID(n) base.Shape = report.Square base.Stack = true return base, true } // try rendering it as an unmanaged node if strings.HasPrefix(n.ID, render.MakePseudoNodeID(render.UnmanagedID)) { base.Label = render.UnmanagedMajor base.Shape = report.Square base.Stack = true base.LabelMinor = report.ExtractHostID(n) return base, true } // try rendering it as an endpoint if addr, ok := n.Latest.Lookup(endpoint.Addr); ok { base.Label = addr base.Shape = report.Circle return base, true } return NodeSummary{}, false }
// MapEndpoint2Host takes nodes from the endpoint topology and produces // host nodes or pseudo nodes. func MapEndpoint2Host(n report.Node, local report.Networks) report.Nodes { // Nodes without a hostid are treated as pseudo nodes hostNodeID, timestamp, ok := n.Latest.LookupEntry(report.HostNodeID) if !ok { return MapEndpoint2Pseudo(n, local) } id := report.MakeHostNodeID(report.ExtractHostID(n)) result := NewDerivedNode(id, n).WithTopology(report.Host) result.Latest = result.Latest.Set(report.HostNodeID, timestamp, hostNodeID) result.Counters = result.Counters.Add(n.Topology, 1) return report.Nodes{id: result} }
// MapX2Host maps any Nodes to host Nodes. // // If this function is given a node without a hostname // (including other pseudo nodes), it will drop the node. // // Otherwise, this function will produce a node with the correct ID // format for a container, but without any Major or Minor labels. // It does not have enough info to do that, and the resulting graph // must be merged with a container graph to get that info. func MapX2Host(n report.Node, _ report.Networks) report.Nodes { // Don't propagate all pseudo nodes - we do this in MapEndpoint2Host if n.Topology == Pseudo { return report.Nodes{} } hostNodeID, timestamp, ok := n.Latest.LookupEntry(report.HostNodeID) if !ok { return report.Nodes{} } id := report.MakeHostNodeID(report.ExtractHostID(n)) result := NewDerivedNode(id, n).WithTopology(report.Host) result.Latest = result.Latest.Set(report.HostNodeID, timestamp, hostNodeID) result.Counters = result.Counters.Add(n.Topology, 1) result.Children = report.MakeNodeSet(n) return report.Nodes{id: result} }
// MapEndpoint2Process maps endpoint Nodes to process // Nodes. // // If this function is given a pseudo node, then it will just return it; // Pseudo nodes will never have pids in them, and therefore will never // be able to be turned into a Process node. // // Otherwise, this function will produce a node with the correct ID // format for a process, but without any Major or Minor labels. // It does not have enough info to do that, and the resulting graph // must be merged with a process graph to get that info. func MapEndpoint2Process(n report.Node, local report.Networks) report.Nodes { // Nodes without a hostid are treated as pseudo nodes if _, ok := n.Latest.Lookup(report.HostNodeID); !ok { return MapEndpoint2Pseudo(n, local) } pid, timestamp, ok := n.Latest.LookupEntry(process.PID) if !ok { return report.Nodes{} } id := report.MakeProcessNodeID(report.ExtractHostID(n), pid) node := NewDerivedNode(id, n).WithTopology(report.Process) node.Latest = node.Latest.Set(process.PID, timestamp, pid) node.Counters = node.Counters.Add(n.Topology, 1) return report.Nodes{id: node} }