mirror of
https://github.com/weaveworks/scope.git
synced 2026-03-06 11:41:28 +00:00
The probe reports namespaces
This commit is contained in:
@@ -36,6 +36,7 @@ type Client interface {
|
||||
WalkCronJobs(f func(CronJob) error) error
|
||||
WalkReplicationControllers(f func(ReplicationController) error) error
|
||||
WalkNodes(f func(*apiv1.Node) error) error
|
||||
WalkNamespaces(f func(NamespaceResource) error) error
|
||||
|
||||
WatchPods(f func(Event, Pod))
|
||||
|
||||
@@ -59,6 +60,7 @@ type client struct {
|
||||
cronJobStore cache.Store
|
||||
replicationControllerStore cache.Store
|
||||
nodeStore cache.Store
|
||||
namespaceStore cache.Store
|
||||
|
||||
podWatchesMutex sync.Mutex
|
||||
podWatches []func(Event, Pod)
|
||||
@@ -158,6 +160,7 @@ func NewClient(config ClientConfig) (Client, error) {
|
||||
result.serviceStore = result.setupStore(c.CoreV1Client.RESTClient(), "services", &apiv1.Service{}, nil)
|
||||
result.replicationControllerStore = result.setupStore(c.CoreV1Client.RESTClient(), "replicationcontrollers", &apiv1.ReplicationController{}, nil)
|
||||
result.nodeStore = result.setupStore(c.CoreV1Client.RESTClient(), "nodes", &apiv1.Node{}, nil)
|
||||
result.namespaceStore = result.setupStore(c.CoreV1Client.RESTClient(), "namespaces", &apiv1.Namespace{}, nil)
|
||||
|
||||
// We list deployments here to check if this version of kubernetes is >= 1.2.
|
||||
// We would use NegotiateVersion, but Kubernetes 1.1 "supports"
|
||||
@@ -326,6 +329,16 @@ func (c *client) WalkNodes(f func(*apiv1.Node) error) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *client) WalkNamespaces(f func(NamespaceResource) error) error {
|
||||
for _, m := range c.namespaceStore.List() {
|
||||
namespace := m.(*apiv1.Namespace)
|
||||
if err := f(NewNamespace(namespace)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *client) GetLogs(namespaceID, podID string) (io.ReadCloser, error) {
|
||||
req := c.client.CoreV1().Pods(namespaceID).GetLogs(
|
||||
podID,
|
||||
|
||||
@@ -58,3 +58,36 @@ func (m meta) MetaNode(id string) report.Node {
|
||||
Created: m.Created(),
|
||||
}).AddPrefixPropertyList(LabelPrefix, m.Labels())
|
||||
}
|
||||
|
||||
type namespaceMeta struct {
|
||||
ObjectMeta metav1.ObjectMeta
|
||||
}
|
||||
|
||||
func (m namespaceMeta) UID() string {
|
||||
return string(m.ObjectMeta.UID)
|
||||
}
|
||||
|
||||
func (m namespaceMeta) Name() string {
|
||||
return m.ObjectMeta.Name
|
||||
}
|
||||
|
||||
func (m namespaceMeta) Namespace() string {
|
||||
return m.ObjectMeta.Namespace
|
||||
}
|
||||
|
||||
func (m namespaceMeta) Created() string {
|
||||
return m.ObjectMeta.CreationTimestamp.Format(time.RFC3339Nano)
|
||||
}
|
||||
|
||||
func (m namespaceMeta) Labels() map[string]string {
|
||||
return m.ObjectMeta.Labels
|
||||
}
|
||||
|
||||
// MetaNode gets the node metadata
|
||||
// For namespaces, ObjectMeta.Namespace is not set
|
||||
func (m namespaceMeta) MetaNode(id string) report.Node {
|
||||
return report.MakeNodeWith(id, map[string]string{
|
||||
Name: m.Name(),
|
||||
Created: m.Created(),
|
||||
}).AddPrefixPropertyList(LabelPrefix, m.Labels())
|
||||
}
|
||||
|
||||
28
probe/kubernetes/namespace.go
Normal file
28
probe/kubernetes/namespace.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package kubernetes
|
||||
|
||||
import (
|
||||
"github.com/weaveworks/scope/report"
|
||||
|
||||
apiv1 "k8s.io/client-go/pkg/api/v1"
|
||||
)
|
||||
|
||||
// NamespaceResource represents a Kubernetes namespace
|
||||
// `Namespace` is already taken in meta.go
|
||||
type NamespaceResource interface {
|
||||
Meta
|
||||
GetNode() report.Node
|
||||
}
|
||||
|
||||
type namespace struct {
|
||||
ns *apiv1.Namespace
|
||||
Meta
|
||||
}
|
||||
|
||||
// NewNamespace creates a new Namespace
|
||||
func NewNamespace(ns *apiv1.Namespace) NamespaceResource {
|
||||
return &namespace{ns: ns, Meta: namespaceMeta{ns.ObjectMeta}}
|
||||
}
|
||||
|
||||
func (ns *namespace) GetNode() report.Node {
|
||||
return ns.MetaNode(report.MakeNamespaceNodeID(ns.UID()))
|
||||
}
|
||||
@@ -264,6 +264,10 @@ func (r *Reporter) Report() (report.Report, error) {
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
namespaceTopology, err := r.namespaceTopology()
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
result.Pod = result.Pod.Merge(podTopology)
|
||||
result.Service = result.Service.Merge(serviceTopology)
|
||||
result.Host = result.Host.Merge(hostTopology)
|
||||
@@ -271,6 +275,7 @@ func (r *Reporter) Report() (report.Report, error) {
|
||||
result.StatefulSet = result.StatefulSet.Merge(statefulSetTopology)
|
||||
result.CronJob = result.CronJob.Merge(cronJobTopology)
|
||||
result.Deployment = result.Deployment.Merge(deploymentTopology)
|
||||
result.Namespace = result.Namespace.Merge(namespaceTopology)
|
||||
return result, nil
|
||||
}
|
||||
|
||||
@@ -500,3 +505,12 @@ func (r *Reporter) podTopology(services []Service, deployments []Deployment, dae
|
||||
})
|
||||
return pods, err
|
||||
}
|
||||
|
||||
func (r *Reporter) namespaceTopology() (report.Topology, error) {
|
||||
result := report.MakeTopology()
|
||||
err := r.client.WalkNamespaces(func(ns NamespaceResource) error {
|
||||
result = result.AddNode(ns.GetNode())
|
||||
return nil
|
||||
})
|
||||
return result, err
|
||||
}
|
||||
|
||||
@@ -154,6 +154,9 @@ func (c *mockClient) WalkReplicationControllers(f func(kubernetes.ReplicationCon
|
||||
func (*mockClient) WalkNodes(f func(*apiv1.Node) error) error {
|
||||
return nil
|
||||
}
|
||||
func (c *mockClient) WalkNamespaces(f func(kubernetes.NamespaceResource) error) error {
|
||||
return nil
|
||||
}
|
||||
func (*mockClient) WatchPods(func(kubernetes.Event, kubernetes.Pod)) {}
|
||||
func (c *mockClient) GetLogs(namespaceID, podName string) (io.ReadCloser, error) {
|
||||
r, ok := c.logs[namespaceID+";"+podName]
|
||||
|
||||
@@ -140,6 +140,12 @@ var (
|
||||
// ParseCronJobNodeID parses a cronjob node ID
|
||||
ParseCronJobNodeID = parseSingleComponentID("cronjob")
|
||||
|
||||
// MakeNamespaceNodeID produces a namespace node ID from its composite parts.
|
||||
MakeNamespaceNodeID = makeSingleComponentID("namespace")
|
||||
|
||||
// ParseNamespaceNodeID parses a namespace set node ID
|
||||
ParseNamespaceNodeID = parseSingleComponentID("namespace")
|
||||
|
||||
// MakeECSTaskNodeID produces a ECSTask node ID from its composite parts.
|
||||
MakeECSTaskNodeID = makeSingleComponentID("ecs_task")
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ const (
|
||||
DaemonSet = "daemon_set"
|
||||
StatefulSet = "stateful_set"
|
||||
CronJob = "cron_job"
|
||||
Namespace = "namespace"
|
||||
ContainerImage = "container_image"
|
||||
Host = "host"
|
||||
Overlay = "overlay"
|
||||
@@ -56,6 +57,7 @@ var topologyNames = []string{
|
||||
DaemonSet,
|
||||
StatefulSet,
|
||||
CronJob,
|
||||
Namespace,
|
||||
Host,
|
||||
Overlay,
|
||||
ECSTask,
|
||||
@@ -115,6 +117,11 @@ type Report struct {
|
||||
// present.
|
||||
CronJob Topology
|
||||
|
||||
// Namespace nodes represent all Kubernetes Namespaces running on hosts running probes.
|
||||
// Metadata includes things like Namespace id, name, etc. Edges are not
|
||||
// present.
|
||||
Namespace Topology
|
||||
|
||||
// ContainerImages nodes represent all Docker containers images on
|
||||
// hosts running probes. Metadata includes things like image id, name etc.
|
||||
// Edges are not present.
|
||||
@@ -217,6 +224,8 @@ func MakeReport() Report {
|
||||
WithShape(Triangle).
|
||||
WithLabel("cron job", "cron jobs"),
|
||||
|
||||
Namespace: MakeTopology(),
|
||||
|
||||
Overlay: MakeTopology().
|
||||
WithShape(Circle).
|
||||
WithLabel("peer", "peers"),
|
||||
@@ -317,6 +326,8 @@ func (r *Report) topology(name string) *Topology {
|
||||
return &r.StatefulSet
|
||||
case CronJob:
|
||||
return &r.CronJob
|
||||
case Namespace:
|
||||
return &r.Namespace
|
||||
case Host:
|
||||
return &r.Host
|
||||
case Overlay:
|
||||
|
||||
Reference in New Issue
Block a user