Add namespace as a resource type in public-api (#760)

* Add namespace as a resource type in public-api

The cli and public-api only supported deployments as a resource type.

This change adds support for namespace as a resource type in the cli and
public-api. This also change includes:
- cli statsummary now prints `-`'s when objects are not in the mesh
- cli statsummary prints `No resources found.` when applicable
- removed `out-` from cli statsummary flags, and analagous proto changes
- switched public-api to use native prometheus label types
- misc error handling and logging fixes

Part of #627

Signed-off-by: Andrew Seigner <siggy@buoyant.io>

* Refactor filter and groupby label formulation

Signed-off-by: Kevin Lingerfelt <kl@buoyant.io>

* Rename stat_summary.go to stat.go in cli

Signed-off-by: Kevin Lingerfelt <kl@buoyant.io>

* Update rbac privileges for namespace stats

Signed-off-by: Kevin Lingerfelt <kl@buoyant.io>
This commit is contained in:
Andrew Seigner 2018-04-13 16:53:01 -07:00 committed by GitHub
parent cc44db054f
commit 77fb6d3709
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 401 additions and 267 deletions

View File

@ -5,6 +5,7 @@ import (
"context"
"errors"
"fmt"
"os"
"sort"
"strings"
"text/tabwriter"
@ -13,13 +14,14 @@ import (
"github.com/prometheus/common/log"
"github.com/runconduit/conduit/controller/api/util"
pb "github.com/runconduit/conduit/controller/gen/public"
"github.com/runconduit/conduit/pkg/k8s"
"github.com/spf13/cobra"
"k8s.io/api/core/v1"
)
var timeWindow, namespace, resourceType, resourceName string
var outToNamespace, outToType, outToName string
var outFromNamespace, outFromType, outFromName string
var toNamespace, toType, toName string
var fromNamespace, fromType, fromName string
var allNamespaces bool
var statCmd = &cobra.Command{
@ -29,7 +31,8 @@ var statCmd = &cobra.Command{
Valid resource types include:
* deployment
* deployments
* namespaces
This command will hide resources that have completed, such as pods that are in the Succeeded or Failed phases.
If no resource name is specified, displays stats about all resources of the specified RESOURCETYPE`,
@ -37,9 +40,15 @@ If no resource name is specified, displays stats about all resources of the spec
conduit stat deployments -n test
# Get the hello1 deployment in the test namespace.
conduit stat deployments hello1 -n test`,
conduit stat deployments hello1 -n test
# Get the test namespace.
conduit stat namespaces test
# Get all namespaces.
conduit stat --all-namespaces=true namespaces`,
Args: cobra.RangeArgs(1, 2),
ValidArgs: []string{"deployment"},
ValidArgs: []string{k8s.KubernetesDeployments, k8s.KubernetesNamespaces},
RunE: func(cmd *cobra.Command, args []string) error {
switch len(args) {
case 1:
@ -71,12 +80,12 @@ func init() {
RootCmd.AddCommand(statCmd)
statCmd.PersistentFlags().StringVarP(&namespace, "namespace", "n", "default", "Namespace of the specified resource")
statCmd.PersistentFlags().StringVarP(&timeWindow, "time-window", "t", "1m", "Stat window (one of: \"10s\", \"1m\", \"10m\", \"1h\")")
statCmd.PersistentFlags().StringVar(&outToName, "out-to", "", "If present, restricts outbound stats to the specified resource name")
statCmd.PersistentFlags().StringVar(&outToNamespace, "out-to-namespace", "", "Sets the namespace used to lookup the \"--out-to\" resource; by default the current \"--namespace\" is used")
statCmd.PersistentFlags().StringVar(&outToType, "out-to-resource", "", "If present, restricts outbound stats to the specified resource type")
statCmd.PersistentFlags().StringVar(&outFromName, "out-from", "", "If present, restricts outbound stats to the specified resource name")
statCmd.PersistentFlags().StringVar(&outFromNamespace, "out-from-namespace", "", "Sets the namespace used to lookup the \"--out-from\" resource; by default the current \"--namespace\" is used")
statCmd.PersistentFlags().StringVar(&outFromType, "out-from-resource", "", "If present, restricts outbound stats to the specified resource type")
statCmd.PersistentFlags().StringVar(&toName, "to", "", "If present, restricts outbound stats to the specified resource name")
statCmd.PersistentFlags().StringVar(&toNamespace, "to-namespace", "", "Sets the namespace used to lookup the \"--to\" resource; by default the current \"--namespace\" is used")
statCmd.PersistentFlags().StringVar(&toType, "to-resource", "", "Sets the resource type used to lookup the \"--to\" resource; by default the RESOURCETYPE is used")
statCmd.PersistentFlags().StringVar(&fromName, "from", "", "If present, restricts outbound stats from the specified resource name")
statCmd.PersistentFlags().StringVar(&fromNamespace, "from-namespace", "", "Sets the namespace used from lookup the \"--from\" resource; by default the current \"--namespace\" is used")
statCmd.PersistentFlags().StringVar(&fromType, "from-resource", "", "Sets the resource type used to lookup the \"--from\" resource; by default the RESOURCETYPE is used")
statCmd.PersistentFlags().BoolVar(&allNamespaces, "all-namespaces", false, "If present, returns stats across all namespaces, ignoring the \"--namespace\" flag")
}
@ -110,8 +119,7 @@ func renderStats(resp *pb.StatSummaryResponse) string {
const padding = 3
type row struct {
meshed string
type rowStats struct {
requestRate float64
successRate float64
latencyP50 uint64
@ -119,6 +127,11 @@ type row struct {
latencyP99 uint64
}
type row struct {
meshed string
*rowStats
}
func writeStatsToBuffer(resp *pb.StatSummaryResponse, w *tabwriter.Writer) {
nameHeader := "NAME"
maxNameLength := len(nameHeader)
@ -147,14 +160,21 @@ func writeStatsToBuffer(resp *pb.StatSummaryResponse, w *tabwriter.Writer) {
}
if r.Stats != nil {
stats[key].requestRate = getRequestRate(*r)
stats[key].successRate = getSuccessRate(*r)
stats[key].latencyP50 = r.Stats.LatencyMsP50
stats[key].latencyP95 = r.Stats.LatencyMsP95
stats[key].latencyP99 = r.Stats.LatencyMsP99
stats[key].rowStats = &rowStats{
requestRate: getRequestRate(*r),
successRate: getSuccessRate(*r),
latencyP50: r.Stats.LatencyMsP50,
latencyP95: r.Stats.LatencyMsP95,
latencyP99: r.Stats.LatencyMsP99,
}
}
}
}
if len(stats) == 0 {
fmt.Fprintln(os.Stderr, "No traffic found.")
os.Exit(0)
}
headers := make([]string, 0)
if allNamespaces {
@ -170,6 +190,7 @@ func writeStatsToBuffer(resp *pb.StatSummaryResponse, w *tabwriter.Writer) {
"LATENCY_P95",
"LATENCY_P99\t", // trailing \t is required to format last column
}...)
fmt.Fprintln(w, strings.Join(headers, "\t"))
sortedKeys := sortStatsKeys(stats)
@ -179,15 +200,21 @@ func writeStatsToBuffer(resp *pb.StatSummaryResponse, w *tabwriter.Writer) {
name := parts[1]
values := make([]interface{}, 0)
templateString := "%s\t%s\t%.2f%%\t%.1frps\t%dms\t%dms\t%dms\t\n"
templateStringEmpty := "%s\t%s\t-\t-\t-\t-\t-\t\n"
if allNamespaces {
values = append(values,
namespace+strings.Repeat(" ", maxNamespaceLength-len(namespace)))
templateString = "%s\t" + templateString
templateStringEmpty = "%s\t" + templateStringEmpty
}
values = append(values, []interface{}{
name + strings.Repeat(" ", maxNameLength-len(name)),
stats[key].meshed,
}...)
if stats[key].rowStats != nil {
values = append(values, []interface{}{
stats[key].successRate * 100,
stats[key].requestRate,
stats[key].latencyP50,
@ -196,6 +223,9 @@ func writeStatsToBuffer(resp *pb.StatSummaryResponse, w *tabwriter.Writer) {
}...)
fmt.Fprintf(w, templateString, values...)
} else {
fmt.Fprintf(w, templateStringEmpty, values...)
}
}
}
@ -212,12 +242,12 @@ func buildStatSummaryRequest() (*pb.StatSummaryRequest, error) {
ResourceName: resourceName,
ResourceType: resourceType,
Namespace: targetNamespace,
OutToName: outToName,
OutToType: outToType,
OutToNamespace: outToNamespace,
OutFromName: outFromName,
OutFromType: outFromType,
OutFromNamespace: outFromNamespace,
ToName: toName,
ToType: toType,
ToNamespace: toNamespace,
FromName: fromName,
FromType: fromType,
FromNamespace: fromNamespace,
}
return util.BuildStatSummaryRequest(requestParams)

View File

@ -23,7 +23,7 @@ rules:
resources: ["deployments", "replicasets"]
verbs: ["list", "get", "watch"]
- apiGroups: [""]
resources: ["pods", "endpoints", "services"]
resources: ["pods", "endpoints", "services", "namespaces"]
verbs: ["list", "get", "watch"]
---

View File

@ -23,7 +23,7 @@ rules:
resources: ["deployments", "replicasets"]
verbs: ["list", "get", "watch"]
- apiGroups: [""]
resources: ["pods", "endpoints", "services"]
resources: ["pods", "endpoints", "services", "namespaces"]
verbs: ["list", "get", "watch"]
---

View File

@ -26,7 +26,7 @@ rules:
resources: ["deployments", "replicasets"]
verbs: ["list", "get", "watch"]
- apiGroups: [""]
resources: ["pods", "endpoints", "services"]
resources: ["pods", "endpoints", "services", "namespaces"]
verbs: ["list", "get", "watch"]
---

View File

@ -79,7 +79,7 @@ func (c *grpcOverHttpClient) Tap(ctx context.Context, req *pb.TapRequest, _ ...g
func (c *grpcOverHttpClient) apiRequest(ctx context.Context, endpoint string, req proto.Message, protoResponse proto.Message) error {
url := c.endpointNameToPublicApiUrl(endpoint)
log.Debugf("Making gRPC-over-HTTP call to [%s]", url.String())
log.Debugf("Making gRPC-over-HTTP call to [%s] [%+v]", url.String(), req)
httpRsp, err := c.post(ctx, url, req)
if err != nil {
return err

View File

@ -24,6 +24,7 @@ type (
grpcServer struct {
prometheusAPI promv1.API
tapClient tapPb.TapClient
namespaceLister corelisters.NamespaceLister
deployLister applisters.DeploymentLister
replicaSetLister applisters.ReplicaSetLister
podLister corelisters.PodLister
@ -43,6 +44,7 @@ const (
func newGrpcServer(
promAPI promv1.API,
tapClient tapPb.TapClient,
namespaceLister corelisters.NamespaceLister,
deployLister applisters.DeploymentLister,
replicaSetLister applisters.ReplicaSetLister,
podLister corelisters.PodLister,
@ -52,6 +54,7 @@ func newGrpcServer(
return &grpcServer{
prometheusAPI: promAPI,
tapClient: tapClient,
namespaceLister: namespaceLister,
deployLister: deployLister,
replicaSetLister: replicaSetLister,
podLister: podLister,

View File

@ -166,6 +166,7 @@ spec:
clientSet := fake.NewSimpleClientset(k8sObjs...)
sharedInformers := informers.NewSharedInformerFactory(clientSet, 10*time.Minute)
namespaceInformer := sharedInformers.Core().V1().Namespaces()
deployInformer := sharedInformers.Apps().V1beta2().Deployments()
replicaSetInformer := sharedInformers.Apps().V1beta2().ReplicaSets()
podInformer := sharedInformers.Core().V1().Pods()
@ -173,6 +174,7 @@ spec:
fakeGrpcServer := newGrpcServer(
&MockProm{Res: exp.promRes},
tap.NewTapClient(nil),
namespaceInformer.Lister(),
deployInformer.Lister(),
replicaSetInformer.Lister(),
podInformer.Lister(),
@ -183,6 +185,7 @@ spec:
sharedInformers.Start(stopCh)
if !cache.WaitForCacheSync(
stopCh,
namespaceInformer.Informer().HasSynced,
deployInformer.Informer().HasSynced,
replicaSetInformer.Informer().HasSynced,
podInformer.Informer().HasSynced,

View File

@ -199,6 +199,7 @@ func NewServer(
addr string,
prometheusClient promApi.Client,
tapClient tapPb.TapClient,
namespaceLister corelisters.NamespaceLister,
deployLister applisters.DeploymentLister,
replicaSetLister applisters.ReplicaSetLister,
podLister corelisters.PodLister,
@ -209,6 +210,7 @@ func NewServer(
grpcServer: newGrpcServer(
promv1.NewAPI(prometheusClient),
tapClient,
namespaceLister,
deployLister,
replicaSetLister,
podLister,

View File

@ -2,7 +2,6 @@ package public
import (
"context"
"errors"
"fmt"
"math"
"strings"
@ -15,6 +14,7 @@ import (
log "github.com/sirupsen/logrus"
appsv1beta2 "k8s.io/api/apps/v1beta2"
apiv1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/tools/cache"
@ -28,22 +28,24 @@ type promResult struct {
}
const (
reqQuery = "sum(increase(response_total{%s}[%s])) by (%s, namespace, classification)"
latencyQuantileQuery = "histogram_quantile(%s, sum(irate(response_latency_ms_bucket{%s}[%s])) by (le, namespace, %s))"
reqQuery = "sum(increase(response_total%s[%s])) by (%s, classification)"
latencyQuantileQuery = "histogram_quantile(%s, sum(irate(response_latency_ms_bucket%s[%s])) by (le, %s))"
promRequests = promType("QUERY_REQUESTS")
promLatencyP50 = promType("0.5")
promLatencyP95 = promType("0.95")
promLatencyP99 = promType("0.99")
namespaceLabel = "namespace"
namespaceLabel = model.LabelName("namespace")
dstNamespaceLabel = model.LabelName("dst_namespace")
)
var (
promTypes = []promType{promRequests, promLatencyP50, promLatencyP95, promLatencyP99}
k8sResourceTypesToPromLabels = map[string]string{
k8sResourceTypesToPromLabels = map[string]model.LabelName{
k8s.KubernetesDeployments: "deployment",
k8s.KubernetesNamespaces: namespaceLabel,
}
)
@ -53,15 +55,31 @@ type meshedCount struct {
}
func (s *grpcServer) StatSummary(ctx context.Context, req *pb.StatSummaryRequest) (*pb.StatSummaryResponse, error) {
var err error
var objectMap map[string]metav1.ObjectMeta
var meshCount map[string]*meshedCount
switch req.Selector.Resource.Type {
case k8s.KubernetesDeployments:
return s.deploymentQuery(ctx, req)
objectMap, meshCount, err = s.getDeployments(req.Selector.Resource)
case k8s.KubernetesNamespaces:
objectMap, meshCount, err = s.getNamespaces(req.Selector.Resource)
default:
return nil, errors.New("Unimplemented resource type: " + req.Selector.Resource.Type)
err = fmt.Errorf("Unimplemented resource type: %v", req.Selector.Resource.Type)
}
if err != nil {
return nil, err
}
return s.objectQuery(ctx, req, objectMap, meshCount)
}
func (s *grpcServer) deploymentQuery(ctx context.Context, req *pb.StatSummaryRequest) (*pb.StatSummaryResponse, error) {
func (s *grpcServer) objectQuery(
ctx context.Context,
req *pb.StatSummaryRequest,
objects map[string]metav1.ObjectMeta,
meshCount map[string]*meshedCount,
) (*pb.StatSummaryResponse, error) {
rows := make([]*pb.StatTable_PodGroup_Row, 0)
timeWindow, err := apiUtil.GetWindowString(req.TimeWindow)
@ -69,23 +87,29 @@ func (s *grpcServer) deploymentQuery(ctx context.Context, req *pb.StatSummaryReq
return nil, err
}
deployments, meshCount, err := s.getDeployments(req.Selector.Resource)
requestMetrics, err := s.getRequests(ctx, req, timeWindow)
if err != nil {
return nil, err
}
requestLabels := buildRequestLabels(req)
groupBy := promResourceType(req.Selector.Resource)
var keys []string
requestMetrics, err := s.getRequests(ctx, requestLabels, groupBy, timeWindow)
if err != nil {
return nil, err
if req.GetOutbound() == nil || req.GetNone() != nil {
// if this request doesn't have outbound filtering, return all rows
for key := range objects {
keys = append(keys, key)
}
} else {
// otherwise only return rows for which we have stats
for key := range requestMetrics {
keys = append(keys, key)
}
}
for _, resource := range deployments {
key, err := cache.MetaNamespaceKeyFunc(resource)
if err != nil {
return nil, err
for _, key := range keys {
resource, ok := objects[key]
if !ok {
continue
}
row := pb.StatTable_PodGroup_Row{
@ -125,74 +149,82 @@ func (s *grpcServer) deploymentQuery(ctx context.Context, req *pb.StatSummaryReq
return &rsp, nil
}
func promLabel(key, val string) string {
return fmt.Sprintf("%s=\"%s\"", key, val)
func promLabelNames(resource *pb.Resource) model.LabelNames {
names := model.LabelNames{namespaceLabel}
if resource.Type != k8s.KubernetesNamespaces {
names = append(names, promResourceType(resource))
}
return names
}
func promNameLabel(resource *pb.Resource) string {
return promLabel(promResourceType(resource), resource.Name)
func promDstLabelNames(resource *pb.Resource) model.LabelNames {
names := model.LabelNames{dstNamespaceLabel}
if resource.Type != k8s.KubernetesNamespaces {
names = append(names, "dst_"+promResourceType(resource))
}
return names
}
func promNamespaceLabel(resource *pb.Resource) string {
return promLabel(namespaceLabel, resource.Namespace)
func promLabels(resource *pb.Resource) model.LabelSet {
set := model.LabelSet{}
if resource.Name != "" {
set[promResourceType(resource)] = model.LabelValue(resource.Name)
}
if resource.Type != k8s.KubernetesNamespaces && resource.Namespace != "" {
set[namespaceLabel] = model.LabelValue(resource.Namespace)
}
return set
}
func promDstLabels(resource *pb.Resource) []string {
return []string{
promLabel("dst_"+namespaceLabel, resource.Namespace),
promLabel("dst_"+promResourceType(resource), resource.Name),
func promDstLabels(resource *pb.Resource) model.LabelSet {
set := model.LabelSet{}
if resource.Name != "" {
set["dst_"+promResourceType(resource)] = model.LabelValue(resource.Name)
}
if resource.Type != k8s.KubernetesNamespaces && resource.Namespace != "" {
set[dstNamespaceLabel] = model.LabelValue(resource.Namespace)
}
return set
}
func promDirectionLabels(direction string) model.LabelSet {
return model.LabelSet{
model.LabelName("direction"): model.LabelValue(direction),
}
}
func promResourceType(resource *pb.Resource) string {
func promResourceType(resource *pb.Resource) model.LabelName {
return k8sResourceTypesToPromLabels[resource.Type]
}
func buildRequestLabels(req *pb.StatSummaryRequest) string {
labels := []string{}
func buildRequestLabels(req *pb.StatSummaryRequest) (model.LabelSet, model.LabelNames) {
labels := model.LabelSet{}
aggregations := model.LabelNames{}
var direction string
switch req.Outbound.(type) {
case *pb.StatSummaryRequest_OutToResource:
direction = "outbound"
labels = append(labels, promDstLabels(req.GetOutToResource())...)
switch out := req.Outbound.(type) {
case *pb.StatSummaryRequest_ToResource:
aggregations = promLabelNames(req.Selector.Resource)
labels = labels.Merge(promDstLabels(out.ToResource))
labels = labels.Merge(promLabels(req.Selector.Resource))
labels = labels.Merge(promDirectionLabels("outbound"))
case *pb.StatSummaryRequest_OutFromResource:
direction = "outbound"
labels = append(labels, promDstLabels(req.Selector.Resource)...)
outFromNs := req.GetOutFromResource().Namespace
if outFromNs == "" {
outFromNs = req.Selector.Resource.Namespace
}
if outFromNs != "" {
labels = append(labels, promLabel(namespaceLabel, outFromNs))
}
if req.Selector.Resource.Name != "" {
labels = append(labels, promNameLabel(req.GetOutFromResource()))
}
case *pb.StatSummaryRequest_FromResource:
aggregations = promDstLabelNames(req.Selector.Resource)
labels = labels.Merge(promLabels(out.FromResource))
labels = labels.Merge(promDirectionLabels("outbound"))
default:
direction = "inbound"
aggregations = promLabelNames(req.Selector.Resource)
labels = labels.Merge(promLabels(req.Selector.Resource))
labels = labels.Merge(promDirectionLabels("inbound"))
}
// it's weird to check this again outside the switch, but including this code
// in the other three switch branches is very repetitive
if req.GetOutFromResource() == nil {
if req.Selector.Resource.Namespace != "" {
labels = append(labels, promNamespaceLabel(req.Selector.Resource))
}
if req.Selector.Resource.Name != "" {
labels = append(labels, promNameLabel(req.Selector.Resource))
}
}
labels = append(labels, promLabel("direction", direction))
return strings.Join(labels, ",")
return labels, aggregations
}
func (s *grpcServer) getRequests(ctx context.Context, reqLabels string, groupBy string, timeWindow string) (map[string]*pb.BasicStats, error) {
func (s *grpcServer) getRequests(ctx context.Context, req *pb.StatSummaryRequest, timeWindow string) (map[string]*pb.BasicStats, error) {
reqLabels, groupBy := buildRequestLabels(req)
resultChan := make(chan promResult)
// kick off 4 asynchronous queries: 1 request volume + 3 latency
@ -226,7 +258,7 @@ func (s *grpcServer) getRequests(ctx context.Context, reqLabels string, groupBy
for i := 0; i < len(promTypes); i++ {
result := <-resultChan
if result.err != nil {
log.Errorf("queryProm failed with: %s", err)
log.Errorf("queryProm failed with: %s", result.err)
err = result.err
} else {
results = append(results, result)
@ -239,12 +271,12 @@ func (s *grpcServer) getRequests(ctx context.Context, reqLabels string, groupBy
return processRequests(results, groupBy), nil
}
func processRequests(results []promResult, labelSelector string) map[string]*pb.BasicStats {
func processRequests(results []promResult, groupBy model.LabelNames) map[string]*pb.BasicStats {
basicStats := make(map[string]*pb.BasicStats)
for _, result := range results {
for _, sample := range result.vec {
label := metricToKey(sample.Metric, labelSelector)
label := metricToKey(sample.Metric, groupBy)
if basicStats[label] == nil {
basicStats[label] = &pb.BasicStats{}
}
@ -275,18 +307,15 @@ func processRequests(results []promResult, labelSelector string) map[string]*pb.
return basicStats
}
func metricToKey(metric model.Metric, labelSelector string) string {
if metric[model.LabelName(namespaceLabel)] == "" {
return string(metric[model.LabelName(labelSelector)])
func metricToKey(metric model.Metric, groupBy model.LabelNames) string {
values := []string{}
for _, k := range groupBy {
values = append(values, string(metric[k]))
}
return fmt.Sprintf("%s/%s",
metric[model.LabelName(namespaceLabel)],
metric[model.LabelName(labelSelector)],
)
return strings.Join(values, "/")
}
func (s *grpcServer) getDeployments(res *pb.Resource) ([]*appsv1beta2.Deployment, map[string]*meshedCount, error) {
func (s *grpcServer) getDeployments(res *pb.Resource) (map[string]metav1.ObjectMeta, map[string]*meshedCount, error) {
var err error
var deployments []*appsv1beta2.Deployment
@ -305,22 +334,59 @@ func (s *grpcServer) getDeployments(res *pb.Resource) ([]*appsv1beta2.Deployment
}
meshedPodCount := make(map[string]*meshedCount)
deploymentMap := make(map[string]metav1.ObjectMeta)
for _, deployment := range deployments {
meshCount, err := s.getMeshedPodCount(deployment.Namespace, deployment)
key, err := cache.MetaNamespaceKeyFunc(deployment)
if err != nil {
return nil, nil, err
}
key, err := cache.MetaNamespaceKeyFunc(deployment)
deploymentMap[key] = deployment.ObjectMeta
meshCount, err := s.getMeshedPodCount(deployment.Namespace, deployment)
if err != nil {
return nil, nil, err
}
meshedPodCount[key] = meshCount
}
return deployments, meshedPodCount, nil
return deploymentMap, meshedPodCount, nil
}
func (s *grpcServer) getNamespaces(res *pb.Resource) (map[string]metav1.ObjectMeta, map[string]*meshedCount, error) {
var err error
var namespaces []*apiv1.Namespace
if res.Name == "" {
namespaces, err = s.namespaceLister.List(labels.Everything())
} else {
var namespace *apiv1.Namespace
namespace, err = s.namespaceLister.Get(res.Name)
namespaces = []*apiv1.Namespace{namespace}
}
if err != nil {
return nil, nil, err
}
meshedPodCount := make(map[string]*meshedCount)
namespaceMap := make(map[string]metav1.ObjectMeta)
for _, namespace := range namespaces {
key, err := cache.MetaNamespaceKeyFunc(namespace)
if err != nil {
return nil, nil, err
}
namespaceMap[key] = namespace.ObjectMeta
meshCount, err := s.getMeshedPodCount(namespace.Name, namespace)
if err != nil {
return nil, nil, err
}
meshedPodCount[key] = meshCount
}
return namespaceMap, meshedPodCount, nil
}
// this takes a long time for namespaces with many pods
func (s *grpcServer) getMeshedPodCount(namespace string, obj runtime.Object) (*meshedCount, error) {
selector, err := getSelectorFromObject(obj)
if err != nil {
@ -350,6 +416,9 @@ func isInMesh(pod *apiv1.Pod) bool {
func getSelectorFromObject(obj runtime.Object) (labels.Selector, error) {
switch typed := obj.(type) {
case *apiv1.Namespace:
return labels.Everything(), nil
case *appsv1beta2.Deployment:
return labels.Set(typed.Spec.Selector.MatchLabels).AsSelector(), nil
@ -364,7 +433,7 @@ func (s *grpcServer) queryProm(ctx context.Context, query string) (model.Vector,
// single data point (aka summary) query
res, err := s.prometheusAPI.Query(ctx, query, time.Time{})
if err != nil {
log.Errorf("Query(%+v, %+v) failed with: %+v", query, err)
log.Errorf("Query(%+v) failed with: %+v", query, err)
return nil, err
}
log.Debugf("Query response: %+v", res)

View File

@ -136,6 +136,7 @@ metadata:
clientSet := fake.NewSimpleClientset(k8sObjs...)
sharedInformers := informers.NewSharedInformerFactory(clientSet, 10*time.Minute)
namespaceInformer := sharedInformers.Core().V1().Namespaces()
deployInformer := sharedInformers.Apps().V1beta2().Deployments()
replicaSetInformer := sharedInformers.Apps().V1beta2().ReplicaSets()
podInformer := sharedInformers.Core().V1().Pods()
@ -143,6 +144,7 @@ metadata:
fakeGrpcServer := newGrpcServer(
&MockProm{Res: exp.promRes},
tap.NewTapClient(nil),
namespaceInformer.Lister(),
deployInformer.Lister(),
replicaSetInformer.Lister(),
podInformer.Lister(),
@ -153,6 +155,7 @@ metadata:
sharedInformers.Start(stopCh)
if !cache.WaitForCacheSync(
stopCh,
namespaceInformer.Informer().HasSynced,
deployInformer.Informer().HasSynced,
replicaSetInformer.Informer().HasSynced,
podInformer.Informer().HasSynced,
@ -211,6 +214,7 @@ metadata:
fakeGrpcServer := newGrpcServer(
&MockProm{Res: exp.promRes},
tap.NewTapClient(nil),
sharedInformers.Core().V1().Namespaces().Lister(),
sharedInformers.Apps().V1beta2().Deployments().Lister(),
sharedInformers.Apps().V1beta2().ReplicaSets().Lister(),
sharedInformers.Core().V1().Pods().Lister(),

View File

@ -49,12 +49,12 @@ type StatSummaryRequestParams struct {
Namespace string
ResourceType string
ResourceName string
OutToNamespace string
OutToType string
OutToName string
OutFromNamespace string
OutFromType string
OutFromName string
ToNamespace string
ToType string
ToName string
FromNamespace string
FromType string
FromName string
}
func BuildStatSummaryRequest(p StatSummaryRequestParams) (*pb.StatSummaryRequest, error) {
@ -83,34 +83,50 @@ func BuildStatSummaryRequest(p StatSummaryRequestParams) (*pb.StatSummaryRequest
TimeWindow: window,
}
if p.OutToName != "" || p.OutToType != "" || p.OutToNamespace != "" {
if p.OutToNamespace == "" {
p.OutToNamespace = p.Namespace
if p.ToName != "" || p.ToType != "" || p.ToNamespace != "" {
if p.ToNamespace == "" {
p.ToNamespace = p.Namespace
}
if p.ToType == "" {
p.ToType = resourceType
}
outToResource := pb.StatSummaryRequest_OutToResource{
OutToResource: &pb.Resource{
Namespace: p.OutToNamespace,
Type: p.OutToType,
Name: p.OutToName,
toType, err := k8s.CanonicalKubernetesNameFromFriendlyName(p.ToType)
if err != nil {
return nil, err
}
toResource := pb.StatSummaryRequest_ToResource{
ToResource: &pb.Resource{
Namespace: p.ToNamespace,
Type: toType,
Name: p.ToName,
},
}
statRequest.Outbound = &outToResource
statRequest.Outbound = &toResource
}
if p.OutFromName != "" || p.OutFromType != "" || p.OutFromNamespace != "" {
if p.OutFromNamespace == "" {
p.OutFromNamespace = p.Namespace
if p.FromName != "" || p.FromType != "" || p.FromNamespace != "" {
if p.FromNamespace == "" {
p.FromNamespace = p.Namespace
}
if p.FromType == "" {
p.FromType = resourceType
}
outFromResource := pb.StatSummaryRequest_OutFromResource{
OutFromResource: &pb.Resource{
Namespace: p.OutFromNamespace,
Type: p.OutFromType,
Name: p.OutFromName,
fromType, err := k8s.CanonicalKubernetesNameFromFriendlyName(p.FromType)
if err != nil {
return nil, err
}
fromResource := pb.StatSummaryRequest_FromResource{
FromResource: &pb.Resource{
Namespace: p.FromNamespace,
Type: fromType,
Name: p.FromName,
},
}
statRequest.Outbound = &outFromResource
statRequest.Outbound = &fromResource
}
return statRequest, nil

View File

@ -57,6 +57,9 @@ func main() {
sharedInformers := informers.NewSharedInformerFactory(k8sClient, 10*time.Minute)
namespaceInformer := sharedInformers.Core().V1().Namespaces()
namespaceInformerSynced := namespaceInformer.Informer().HasSynced
deployInformer := sharedInformers.Apps().V1beta2().Deployments()
deployInformerSynced := deployInformer.Informer().HasSynced
@ -77,6 +80,7 @@ func main() {
*addr,
prometheusClient,
tapClient,
namespaceInformer.Lister(),
deployInformer.Lister(),
replicaSetInformer.Lister(),
podInformer.Lister(),
@ -91,6 +95,7 @@ func main() {
log.Infof("waiting for caches to sync")
if !cache.WaitForCacheSync(
ctx.Done(),
namespaceInformerSynced,
deployInformerSynced,
replicaSetInformerSynced,
podInformerSynced,

View File

@ -487,8 +487,8 @@ type StatSummaryRequest struct {
TimeWindow TimeWindow `protobuf:"varint,2,opt,name=time_window,json=timeWindow,enum=conduit.public.TimeWindow" json:"time_window,omitempty"`
// Types that are valid to be assigned to Outbound:
// *StatSummaryRequest_None
// *StatSummaryRequest_OutToResource
// *StatSummaryRequest_OutFromResource
// *StatSummaryRequest_ToResource
// *StatSummaryRequest_FromResource
Outbound isStatSummaryRequest_Outbound `protobuf_oneof:"outbound"`
}
@ -502,16 +502,16 @@ type isStatSummaryRequest_Outbound interface{ isStatSummaryRequest_Outbound() }
type StatSummaryRequest_None struct {
None *Empty `protobuf:"bytes,3,opt,name=none,oneof"`
}
type StatSummaryRequest_OutToResource struct {
OutToResource *Resource `protobuf:"bytes,4,opt,name=out_to_resource,json=outToResource,oneof"`
type StatSummaryRequest_ToResource struct {
ToResource *Resource `protobuf:"bytes,4,opt,name=to_resource,json=toResource,oneof"`
}
type StatSummaryRequest_OutFromResource struct {
OutFromResource *Resource `protobuf:"bytes,5,opt,name=out_from_resource,json=outFromResource,oneof"`
type StatSummaryRequest_FromResource struct {
FromResource *Resource `protobuf:"bytes,5,opt,name=from_resource,json=fromResource,oneof"`
}
func (*StatSummaryRequest_None) isStatSummaryRequest_Outbound() {}
func (*StatSummaryRequest_OutToResource) isStatSummaryRequest_Outbound() {}
func (*StatSummaryRequest_OutFromResource) isStatSummaryRequest_Outbound() {}
func (*StatSummaryRequest_ToResource) isStatSummaryRequest_Outbound() {}
func (*StatSummaryRequest_FromResource) isStatSummaryRequest_Outbound() {}
func (m *StatSummaryRequest) GetOutbound() isStatSummaryRequest_Outbound {
if m != nil {
@ -541,16 +541,16 @@ func (m *StatSummaryRequest) GetNone() *Empty {
return nil
}
func (m *StatSummaryRequest) GetOutToResource() *Resource {
if x, ok := m.GetOutbound().(*StatSummaryRequest_OutToResource); ok {
return x.OutToResource
func (m *StatSummaryRequest) GetToResource() *Resource {
if x, ok := m.GetOutbound().(*StatSummaryRequest_ToResource); ok {
return x.ToResource
}
return nil
}
func (m *StatSummaryRequest) GetOutFromResource() *Resource {
if x, ok := m.GetOutbound().(*StatSummaryRequest_OutFromResource); ok {
return x.OutFromResource
func (m *StatSummaryRequest) GetFromResource() *Resource {
if x, ok := m.GetOutbound().(*StatSummaryRequest_FromResource); ok {
return x.FromResource
}
return nil
}
@ -559,8 +559,8 @@ func (m *StatSummaryRequest) GetOutFromResource() *Resource {
func (*StatSummaryRequest) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) {
return _StatSummaryRequest_OneofMarshaler, _StatSummaryRequest_OneofUnmarshaler, _StatSummaryRequest_OneofSizer, []interface{}{
(*StatSummaryRequest_None)(nil),
(*StatSummaryRequest_OutToResource)(nil),
(*StatSummaryRequest_OutFromResource)(nil),
(*StatSummaryRequest_ToResource)(nil),
(*StatSummaryRequest_FromResource)(nil),
}
}
@ -573,14 +573,14 @@ func _StatSummaryRequest_OneofMarshaler(msg proto.Message, b *proto.Buffer) erro
if err := b.EncodeMessage(x.None); err != nil {
return err
}
case *StatSummaryRequest_OutToResource:
case *StatSummaryRequest_ToResource:
b.EncodeVarint(4<<3 | proto.WireBytes)
if err := b.EncodeMessage(x.OutToResource); err != nil {
if err := b.EncodeMessage(x.ToResource); err != nil {
return err
}
case *StatSummaryRequest_OutFromResource:
case *StatSummaryRequest_FromResource:
b.EncodeVarint(5<<3 | proto.WireBytes)
if err := b.EncodeMessage(x.OutFromResource); err != nil {
if err := b.EncodeMessage(x.FromResource); err != nil {
return err
}
case nil:
@ -601,21 +601,21 @@ func _StatSummaryRequest_OneofUnmarshaler(msg proto.Message, tag, wire int, b *p
err := b.DecodeMessage(msg)
m.Outbound = &StatSummaryRequest_None{msg}
return true, err
case 4: // outbound.out_to_resource
case 4: // outbound.to_resource
if wire != proto.WireBytes {
return true, proto.ErrInternalBadWireType
}
msg := new(Resource)
err := b.DecodeMessage(msg)
m.Outbound = &StatSummaryRequest_OutToResource{msg}
m.Outbound = &StatSummaryRequest_ToResource{msg}
return true, err
case 5: // outbound.out_from_resource
case 5: // outbound.from_resource
if wire != proto.WireBytes {
return true, proto.ErrInternalBadWireType
}
msg := new(Resource)
err := b.DecodeMessage(msg)
m.Outbound = &StatSummaryRequest_OutFromResource{msg}
m.Outbound = &StatSummaryRequest_FromResource{msg}
return true, err
default:
return false, nil
@ -631,13 +631,13 @@ func _StatSummaryRequest_OneofSizer(msg proto.Message) (n int) {
n += proto.SizeVarint(3<<3 | proto.WireBytes)
n += proto.SizeVarint(uint64(s))
n += s
case *StatSummaryRequest_OutToResource:
s := proto.Size(x.OutToResource)
case *StatSummaryRequest_ToResource:
s := proto.Size(x.ToResource)
n += proto.SizeVarint(4<<3 | proto.WireBytes)
n += proto.SizeVarint(uint64(s))
n += s
case *StatSummaryRequest_OutFromResource:
s := proto.Size(x.OutFromResource)
case *StatSummaryRequest_FromResource:
s := proto.Size(x.FromResource)
n += proto.SizeVarint(5<<3 | proto.WireBytes)
n += proto.SizeVarint(uint64(s))
n += s
@ -1238,81 +1238,80 @@ var _Api_serviceDesc = grpc.ServiceDesc{
func init() { proto.RegisterFile("public/api.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 1204 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0x5d, 0x6f, 0x1b, 0x45,
0x17, 0xb6, 0xd7, 0x4e, 0xb2, 0x3e, 0x8e, 0xd3, 0x74, 0xf2, 0xbe, 0x68, 0x6b, 0xa0, 0x32, 0xdb,
0x12, 0x22, 0x3e, 0x9c, 0xc8, 0x10, 0x89, 0xb4, 0x42, 0x90, 0xa4, 0x2e, 0x8e, 0xd4, 0x26, 0xd6,
0xc4, 0x7c, 0x48, 0x5c, 0x58, 0xe3, 0xdd, 0x49, 0xbc, 0x64, 0x77, 0x67, 0xba, 0x33, 0x4b, 0xc8,
0xff, 0xe0, 0x82, 0x3b, 0xee, 0xf8, 0x27, 0x48, 0xfc, 0x00, 0xf8, 0x37, 0x5c, 0xa0, 0xf9, 0xd8,
0x8d, 0xe3, 0x24, 0x6d, 0x55, 0xae, 0x3c, 0xe7, 0x39, 0xcf, 0x9c, 0x39, 0xe7, 0x39, 0x67, 0xd6,
0x03, 0xab, 0x3c, 0x9f, 0xc4, 0x51, 0xb0, 0x49, 0x78, 0xd4, 0xe5, 0x19, 0x93, 0x0c, 0xad, 0x04,
0x2c, 0x0d, 0xf3, 0x48, 0x76, 0x8d, 0xa7, 0x7d, 0xff, 0x94, 0xb1, 0xd3, 0x98, 0x6e, 0x6a, 0xef,
0x24, 0x3f, 0xd9, 0x0c, 0xf3, 0x8c, 0xc8, 0x88, 0xa5, 0x86, 0xdf, 0x5e, 0x0b, 0x58, 0x92, 0xb0,
0x74, 0xd3, 0xfc, 0x58, 0xf0, 0xa1, 0x05, 0xa7, 0x94, 0xc4, 0x72, 0x1a, 0x4c, 0x69, 0x70, 0x36,
0xbb, 0x36, 0x2c, 0x7f, 0x09, 0x16, 0xfa, 0x09, 0x97, 0x17, 0xfe, 0x0b, 0x68, 0x7e, 0x4b, 0x33,
0x11, 0xb1, 0xf4, 0x20, 0x3d, 0x61, 0xe8, 0x1d, 0x68, 0x9c, 0x32, 0x0b, 0x78, 0xd5, 0x4e, 0x75,
0xa3, 0x81, 0x2f, 0x01, 0xe5, 0x9d, 0xe4, 0x51, 0x1c, 0x3e, 0x21, 0x92, 0x7a, 0x8e, 0xf1, 0x96,
0x00, 0x5a, 0x87, 0x95, 0x8c, 0xc6, 0x94, 0x08, 0x5a, 0x04, 0xa8, 0x69, 0xca, 0x1c, 0xea, 0x3f,
0x86, 0xd5, 0x67, 0x91, 0x90, 0x43, 0x16, 0x0a, 0x4c, 0x05, 0x67, 0xa9, 0xa0, 0xe8, 0x03, 0xa8,
0x73, 0x16, 0x0a, 0xaf, 0xda, 0xa9, 0x6d, 0x34, 0x7b, 0x6b, 0xdd, 0xab, 0x4a, 0x74, 0x87, 0x2c,
0xc4, 0x9a, 0xe0, 0xff, 0xea, 0x40, 0x6d, 0xc8, 0x42, 0x84, 0xa0, 0x9e, 0x92, 0x84, 0xda, 0x1c,
0xf5, 0x1a, 0xfd, 0x0f, 0x16, 0x38, 0x0b, 0x0f, 0x86, 0x36, 0x35, 0x63, 0xa0, 0xfb, 0x00, 0x21,
0xe5, 0x31, 0xbb, 0x48, 0x68, 0x2a, 0x6d, 0x4a, 0x33, 0x08, 0x7a, 0x0b, 0x16, 0x85, 0x24, 0x32,
0x17, 0x5e, 0x5d, 0xfb, 0xac, 0xa5, 0xa2, 0x91, 0x30, 0xa4, 0xa1, 0xb7, 0xd0, 0xa9, 0x6e, 0xb8,
0xd8, 0x18, 0x68, 0x1f, 0xee, 0x88, 0x28, 0x0d, 0xe8, 0x33, 0x22, 0x24, 0xa6, 0x9c, 0x65, 0xd2,
0x5b, 0xec, 0x54, 0x37, 0x9a, 0xbd, 0x7b, 0x5d, 0xd3, 0xad, 0x6e, 0xd1, 0xad, 0xee, 0x13, 0xdb,
0x2d, 0x3c, 0xbf, 0x03, 0x6d, 0xc1, 0x5a, 0xc0, 0x52, 0x99, 0xb1, 0x38, 0xa6, 0xd9, 0x21, 0x49,
0xa8, 0xe0, 0x24, 0xa0, 0xde, 0x92, 0x3e, 0xff, 0x26, 0x17, 0xf2, 0x61, 0xd9, 0xc2, 0xc3, 0x98,
0xa4, 0xd4, 0x73, 0x75, 0x4e, 0x57, 0x30, 0xff, 0x77, 0x07, 0x60, 0x44, 0x38, 0xa6, 0x2f, 0x72,
0x2a, 0x24, 0x42, 0x50, 0xe3, 0x2c, 0x34, 0x02, 0x0d, 0x2a, 0x58, 0x19, 0xa8, 0x73, 0x45, 0x0b,
0xc7, 0xba, 0xe6, 0xd4, 0x48, 0xc8, 0xcf, 0x98, 0x0b, 0xad, 0x94, 0x83, 0xad, 0xa5, 0x70, 0xc9,
0x86, 0xaa, 0x5c, 0xa5, 0x52, 0x0b, 0x5b, 0x4b, 0xf5, 0x41, 0xb2, 0x83, 0xa1, 0x16, 0xa9, 0x81,
0xf5, 0x1a, 0xb5, 0xc1, 0x3d, 0xc9, 0x58, 0x32, 0x2c, 0xc4, 0x69, 0xe1, 0xd2, 0x56, 0x71, 0xd4,
0xfa, 0x60, 0x68, 0xab, 0xb5, 0x96, 0xee, 0x42, 0x30, 0xa5, 0x89, 0x29, 0x4d, 0x75, 0x41, 0x5b,
0x3a, 0x1f, 0x2a, 0xa7, 0x2c, 0xf4, 0x1a, 0x06, 0x37, 0x96, 0x1a, 0x45, 0x92, 0xcb, 0x29, 0xcb,
0x22, 0x79, 0xe1, 0x81, 0x19, 0xc5, 0x12, 0x50, 0x59, 0x71, 0x22, 0xa7, 0x5e, 0xd3, 0x64, 0xa5,
0xd6, 0x7b, 0x2e, 0x2c, 0x4a, 0x92, 0x9d, 0x52, 0xe9, 0x77, 0xc0, 0xdd, 0xe5, 0x51, 0x3f, 0xcb,
0x58, 0xa6, 0xba, 0x4c, 0xd5, 0xc2, 0x0e, 0x92, 0x31, 0xfc, 0x21, 0xb8, 0x98, 0x0a, 0x96, 0x67,
0x01, 0x55, 0x27, 0xa5, 0x65, 0x8b, 0xec, 0x95, 0x28, 0x01, 0x5d, 0xff, 0x05, 0x2f, 0x6e, 0x83,
0x5e, 0x97, 0xb3, 0x59, 0xbb, 0x9c, 0x4d, 0x9f, 0xc3, 0xdd, 0x22, 0xe2, 0x31, 0x8d, 0x69, 0xa0,
0x06, 0x03, 0x7d, 0x06, 0x6e, 0x66, 0x41, 0x1d, 0xb9, 0xd9, 0xf3, 0xe6, 0x27, 0xbf, 0xd8, 0x84,
0x4b, 0x26, 0x7a, 0x1f, 0x56, 0x62, 0x32, 0xa1, 0xf1, 0x58, 0xe8, 0x40, 0x2c, 0xb3, 0x87, 0xb7,
0x34, 0x7a, 0x6c, 0x41, 0xff, 0x07, 0x68, 0x15, 0x9b, 0x4d, 0xa9, 0x6f, 0x76, 0x5a, 0x29, 0x90,
0x33, 0x2b, 0xd0, 0xdf, 0x0e, 0xa0, 0x63, 0x49, 0xe4, 0x71, 0x9e, 0x24, 0x24, 0xbb, 0x28, 0x66,
0xee, 0x0b, 0x70, 0xcb, 0xa4, 0xcc, 0x11, 0xef, 0xdd, 0x76, 0x44, 0xa9, 0x02, 0x2e, 0xb7, 0xa0,
0xc7, 0xd0, 0x94, 0x51, 0x42, 0xc7, 0xe7, 0x51, 0x1a, 0xb2, 0x73, 0x7d, 0xe2, 0x4a, 0xaf, 0x3d,
0x1f, 0x61, 0x14, 0x25, 0xf4, 0x3b, 0xcd, 0xc0, 0x20, 0xcb, 0x35, 0xfa, 0x08, 0xea, 0x29, 0x4b,
0x8d, 0xea, 0xcd, 0xde, 0xff, 0xe7, 0x77, 0xe9, 0xcf, 0xdd, 0xa0, 0x82, 0x35, 0x09, 0xed, 0xc1,
0x1d, 0x96, 0xcb, 0xb1, 0x64, 0xe3, 0x52, 0x92, 0xfa, 0xcb, 0x25, 0x19, 0x54, 0x70, 0x8b, 0xe5,
0x72, 0xc4, 0xca, 0xc1, 0x78, 0x0a, 0x77, 0x55, 0x0c, 0x35, 0xc0, 0x97, 0x51, 0x16, 0x5e, 0x19,
0x45, 0x1d, 0xfc, 0x34, 0x63, 0x49, 0x01, 0xed, 0x01, 0xb8, 0x2c, 0x97, 0x13, 0x96, 0xa7, 0xa1,
0xff, 0x57, 0x15, 0xd6, 0xae, 0xe8, 0x6a, 0xbf, 0x8f, 0x9f, 0x83, 0xc3, 0xce, 0xac, 0xa4, 0xeb,
0xf3, 0xc1, 0x6f, 0xd8, 0xd0, 0x3d, 0x3a, 0x1b, 0x54, 0xb0, 0xc3, 0xce, 0xd0, 0xf6, 0x6c, 0xff,
0x9a, 0xbd, 0x77, 0x6f, 0xcb, 0x4c, 0xcf, 0xc8, 0xa0, 0x62, 0x1b, 0xdc, 0xfe, 0x0a, 0x9c, 0xa3,
0x33, 0xf4, 0x08, 0x9a, 0xea, 0x6b, 0x38, 0x96, 0x64, 0x12, 0xd3, 0xe2, 0xeb, 0x7c, 0xef, 0xa6,
0xf3, 0x47, 0x8a, 0x81, 0x41, 0x14, 0x4b, 0xa1, 0xca, 0xca, 0x6c, 0x36, 0xfe, 0x9f, 0x55, 0x80,
0x3d, 0x22, 0xa2, 0x40, 0x51, 0x05, 0x7a, 0x00, 0x2d, 0x91, 0x07, 0x01, 0x15, 0x62, 0x1c, 0xb0,
0x3c, 0x95, 0xba, 0xb0, 0x3a, 0x5e, 0xb6, 0xe0, 0xbe, 0xc2, 0x14, 0xe9, 0x84, 0x44, 0x71, 0x9e,
0x51, 0x4b, 0x72, 0x0c, 0xc9, 0x82, 0x86, 0xf4, 0x50, 0xdd, 0x05, 0x49, 0xd3, 0xe0, 0x62, 0x9c,
0x88, 0x31, 0xdf, 0xde, 0xd2, 0xed, 0xaf, 0xe3, 0x65, 0x8b, 0x3e, 0x17, 0xc3, 0xed, 0xad, 0x79,
0xd6, 0xce, 0xb6, 0x6e, 0xf6, 0x15, 0xd6, 0xce, 0xf6, 0x35, 0xd6, 0x8e, 0x6e, 0xe6, 0x55, 0xd6,
0x8e, 0xff, 0x5b, 0x0d, 0x1a, 0x65, 0xc1, 0x68, 0x17, 0x1a, 0x9c, 0x85, 0xe3, 0xd3, 0x8c, 0xe5,
0xdc, 0xb6, 0xc7, 0xbf, 0x55, 0x1e, 0xf5, 0x37, 0xf6, 0xb5, 0x62, 0x0e, 0x2a, 0xd8, 0xe5, 0x76,
0xdd, 0xfe, 0xc3, 0x01, 0xb7, 0x70, 0xa0, 0x47, 0x50, 0xcf, 0xd8, 0x79, 0xa1, 0xf4, 0xfa, 0xab,
0x43, 0x75, 0x31, 0x3b, 0xc7, 0x7a, 0x4f, 0xfb, 0x9f, 0x2a, 0xd4, 0x30, 0x3b, 0x7f, 0xc3, 0x7b,
0xfe, 0x9f, 0xee, 0xde, 0x06, 0xac, 0x26, 0x54, 0x4c, 0x69, 0x38, 0x56, 0x6a, 0x98, 0x76, 0x99,
0x46, 0xac, 0x18, 0x7c, 0xc8, 0x42, 0xd3, 0xb0, 0x75, 0xb8, 0x23, 0x99, 0x24, 0xf1, 0x0c, 0xd1,
0xf4, 0xa2, 0xa5, 0xe1, 0x92, 0xb7, 0x05, 0x0b, 0x6a, 0x96, 0x84, 0xbd, 0x50, 0xd7, 0x12, 0xb9,
0x9c, 0x26, 0x6c, 0x88, 0x7b, 0x4b, 0xb0, 0xa0, 0xc7, 0xf4, 0xc3, 0x5d, 0x80, 0xcb, 0x34, 0x51,
0x13, 0x96, 0x46, 0xfd, 0xc3, 0xf1, 0x71, 0x7f, 0x7f, 0xb5, 0xa2, 0x8c, 0xa3, 0xc3, 0xfe, 0xf8,
0xf9, 0xc1, 0xe1, 0x6a, 0xb5, 0xf0, 0x28, 0xc3, 0x41, 0xcb, 0xe0, 0x2a, 0xcf, 0xe0, 0xe8, 0x1b,
0xbc, 0x5a, 0xeb, 0xfd, 0x52, 0x83, 0xda, 0x2e, 0x8f, 0xd0, 0xf7, 0xd0, 0x9c, 0xb9, 0x5c, 0xc8,
0x7f, 0xe9, 0xcd, 0xd3, 0x9f, 0xc0, 0xf6, 0x83, 0xd7, 0xb8, 0x9d, 0x7e, 0x05, 0x7d, 0x09, 0x4b,
0xc5, 0xab, 0xea, 0xe6, 0x4f, 0x55, 0xfb, 0xed, 0x79, 0x78, 0xe6, 0x9d, 0xe6, 0x57, 0x50, 0x1f,
0xdc, 0xe2, 0x15, 0x75, 0x5b, 0x84, 0xce, 0x3c, 0x3c, 0xff, 0xec, 0xf2, 0x2b, 0xe8, 0x47, 0x68,
0x1c, 0xd3, 0xf8, 0x64, 0x5f, 0xbd, 0x0d, 0xd1, 0xc7, 0xe5, 0x06, 0xfb, 0xa4, 0x9c, 0x7d, 0x38,
0x96, 0xb4, 0xa2, 0xd2, 0x4f, 0x5e, 0x93, 0x3d, 0x53, 0x73, 0x6d, 0x44, 0x38, 0xba, 0x3e, 0x54,
0xe5, 0xa3, 0xa5, 0xed, 0xcd, 0xc7, 0x1c, 0x11, 0xde, 0xff, 0x89, 0xa6, 0xd2, 0xaf, 0x6c, 0x55,
0x27, 0x8b, 0xfa, 0x6d, 0xf5, 0xe9, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x43, 0x1e, 0x96, 0xb2,
0x3b, 0x0b, 0x00, 0x00,
// 1189 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0xdd, 0x6e, 0x1b, 0xc5,
0x17, 0xb7, 0xd7, 0x4e, 0xb2, 0x3e, 0x8e, 0xd3, 0xfc, 0x27, 0x7f, 0xd0, 0xd6, 0x40, 0x65, 0xb6,
0x25, 0x44, 0x7c, 0x38, 0x91, 0x21, 0x12, 0x69, 0x85, 0x4a, 0x92, 0x5a, 0x24, 0x52, 0x9b, 0x58,
0x93, 0xf0, 0x21, 0x71, 0x61, 0x8d, 0x77, 0x27, 0xf1, 0x92, 0xdd, 0x9d, 0xe9, 0xce, 0x2c, 0x21,
0xef, 0xc1, 0x05, 0x77, 0xdc, 0xf1, 0x26, 0x08, 0x1e, 0x80, 0xc7, 0xe1, 0x02, 0xcd, 0xc7, 0x6e,
0xec, 0x6d, 0xd2, 0x56, 0xe5, 0xca, 0xe7, 0xfc, 0xce, 0xef, 0x9c, 0x39, 0x5f, 0xb3, 0x1e, 0x58,
0xe5, 0xf9, 0x24, 0x8e, 0x82, 0x4d, 0xc2, 0xa3, 0x3e, 0xcf, 0x98, 0x64, 0x68, 0x25, 0x60, 0x69,
0x98, 0x47, 0xb2, 0x6f, 0x2c, 0xdd, 0x7b, 0xe7, 0x8c, 0x9d, 0xc7, 0x74, 0x53, 0x5b, 0x27, 0xf9,
0xd9, 0x66, 0x98, 0x67, 0x44, 0x46, 0x2c, 0x35, 0xfc, 0xee, 0x5a, 0xc0, 0x92, 0x84, 0xa5, 0x9b,
0xe6, 0xc7, 0x82, 0x0f, 0x2c, 0x38, 0xa5, 0x24, 0x96, 0xd3, 0x60, 0x4a, 0x83, 0x8b, 0x59, 0xd9,
0xb0, 0xfc, 0x25, 0x58, 0x18, 0x26, 0x5c, 0x5e, 0xf9, 0xcf, 0xa1, 0xfd, 0x2d, 0xcd, 0x44, 0xc4,
0xd2, 0xc3, 0xf4, 0x8c, 0xa1, 0x77, 0xa1, 0x75, 0xce, 0x2c, 0xe0, 0xd5, 0x7b, 0xf5, 0x8d, 0x16,
0xbe, 0x06, 0x94, 0x75, 0x92, 0x47, 0x71, 0xf8, 0x84, 0x48, 0xea, 0x39, 0xc6, 0x5a, 0x02, 0x68,
0x1d, 0x56, 0x32, 0x1a, 0x53, 0x22, 0x68, 0x11, 0xa0, 0xa1, 0x29, 0x15, 0xd4, 0x7f, 0x04, 0xab,
0x4f, 0x23, 0x21, 0x47, 0x2c, 0x14, 0x98, 0x0a, 0xce, 0x52, 0x41, 0xd1, 0x87, 0xd0, 0xe4, 0x2c,
0x14, 0x5e, 0xbd, 0xd7, 0xd8, 0x68, 0x0f, 0xd6, 0xfa, 0xf3, 0x9d, 0xe8, 0x8f, 0x58, 0x88, 0x35,
0xc1, 0xff, 0xd5, 0x81, 0xc6, 0x88, 0x85, 0x08, 0x41, 0x33, 0x25, 0x09, 0xb5, 0x39, 0x6a, 0x19,
0xfd, 0x1f, 0x16, 0x38, 0x0b, 0x0f, 0x47, 0x36, 0x35, 0xa3, 0xa0, 0x7b, 0x00, 0x21, 0xe5, 0x31,
0xbb, 0x4a, 0x68, 0x2a, 0x6d, 0x4a, 0x33, 0x08, 0x7a, 0x1b, 0x16, 0x85, 0x24, 0x32, 0x17, 0x5e,
0x53, 0xdb, 0xac, 0xa6, 0xa2, 0x91, 0x30, 0xa4, 0xa1, 0xb7, 0xd0, 0xab, 0x6f, 0xb8, 0xd8, 0x28,
0x68, 0x1f, 0xee, 0x88, 0x28, 0x0d, 0xe8, 0x53, 0x22, 0x24, 0xa6, 0x9c, 0x65, 0xd2, 0x5b, 0xec,
0xd5, 0x37, 0xda, 0x83, 0xbb, 0x7d, 0x33, 0xad, 0x7e, 0x31, 0xad, 0xfe, 0x13, 0x3b, 0x2d, 0x5c,
0xf5, 0x40, 0x5b, 0xb0, 0x16, 0xb0, 0x54, 0x66, 0x2c, 0x8e, 0x69, 0x76, 0x44, 0x12, 0x2a, 0x38,
0x09, 0xa8, 0xb7, 0xa4, 0xcf, 0xbf, 0xc9, 0x84, 0x7c, 0x58, 0xb6, 0xf0, 0x28, 0x26, 0x29, 0xf5,
0x5c, 0x9d, 0xd3, 0x1c, 0xe6, 0xff, 0xee, 0x00, 0x9c, 0x12, 0x8e, 0xe9, 0xf3, 0x9c, 0x0a, 0x89,
0x10, 0x34, 0x38, 0x0b, 0x4d, 0x83, 0x0e, 0x6a, 0x58, 0x29, 0xa8, 0x37, 0xd7, 0x0b, 0xc7, 0x9a,
0x2a, 0xdd, 0x48, 0xc8, 0xcf, 0x98, 0x0b, 0xdd, 0x29, 0x07, 0x5b, 0x4d, 0xe1, 0x92, 0x8d, 0x54,
0xb9, 0xaa, 0x4b, 0x1d, 0x6c, 0x35, 0x35, 0x07, 0xc9, 0x0e, 0x47, 0xba, 0x49, 0x2d, 0xac, 0x65,
0xd4, 0x05, 0xf7, 0x2c, 0x63, 0xc9, 0xa8, 0x68, 0x4e, 0x07, 0x97, 0xba, 0x8a, 0xa3, 0xe4, 0xc3,
0x91, 0xad, 0xd6, 0x6a, 0x7a, 0x0a, 0xc1, 0x94, 0x26, 0xa6, 0x34, 0x35, 0x05, 0xad, 0xe9, 0x7c,
0xa8, 0x9c, 0xb2, 0xd0, 0x6b, 0x19, 0xdc, 0x68, 0x6a, 0x15, 0x49, 0x2e, 0xa7, 0x2c, 0x8b, 0xe4,
0x95, 0x07, 0x66, 0x15, 0x4b, 0x40, 0x65, 0xc5, 0x89, 0x9c, 0x7a, 0x6d, 0x93, 0x95, 0x92, 0xf7,
0x5c, 0x58, 0x94, 0x24, 0x3b, 0xa7, 0xd2, 0xef, 0x81, 0xbb, 0xcb, 0xa3, 0x61, 0x96, 0xb1, 0x4c,
0x4d, 0x99, 0x2a, 0xc1, 0x2e, 0x92, 0x51, 0xfc, 0x11, 0xb8, 0x98, 0x0a, 0x96, 0x67, 0x01, 0x55,
0x27, 0xa5, 0xe5, 0x88, 0xec, 0x95, 0x28, 0x01, 0x5d, 0xff, 0x15, 0x2f, 0x6e, 0x83, 0x96, 0xcb,
0xdd, 0x6c, 0x5c, 0xef, 0xa6, 0xcf, 0xe1, 0x7f, 0x45, 0xc4, 0x13, 0x1a, 0xd3, 0x40, 0x2d, 0x06,
0xfa, 0x1c, 0xdc, 0xcc, 0x82, 0x3a, 0x72, 0x7b, 0xe0, 0x55, 0x37, 0xbf, 0x70, 0xc2, 0x25, 0x13,
0x7d, 0x00, 0x2b, 0x31, 0x99, 0xd0, 0x78, 0x2c, 0x74, 0x20, 0x96, 0xd9, 0xc3, 0x3b, 0x1a, 0x3d,
0xb1, 0xa0, 0xff, 0x03, 0x74, 0x0a, 0x67, 0x53, 0xea, 0x9b, 0x9d, 0x56, 0x36, 0xc8, 0x99, 0x6d,
0xd0, 0x9f, 0x0e, 0xa0, 0x13, 0x49, 0xe4, 0x49, 0x9e, 0x24, 0x24, 0xbb, 0x2a, 0x76, 0xee, 0x4b,
0x70, 0xcb, 0xa4, 0xcc, 0x11, 0xef, 0xdf, 0x76, 0x44, 0xd9, 0x05, 0x5c, 0xba, 0xa0, 0x47, 0xd0,
0x96, 0x51, 0x42, 0xc7, 0x97, 0x51, 0x1a, 0xb2, 0x4b, 0x7d, 0xe2, 0xca, 0xa0, 0x5b, 0x8d, 0x70,
0x1a, 0x25, 0xf4, 0x3b, 0xcd, 0xc0, 0x20, 0x4b, 0x19, 0x7d, 0x0c, 0xcd, 0x94, 0xa5, 0xa6, 0xeb,
0xed, 0xc1, 0x5b, 0x55, 0x2f, 0xfd, 0xb9, 0x3b, 0xa8, 0x61, 0x4d, 0xd2, 0x27, 0xb1, 0x71, 0xd9,
0x8e, 0xe6, 0xcb, 0xdb, 0xa1, 0xee, 0x88, 0x64, 0xe5, 0x46, 0x3c, 0x86, 0x8e, 0xda, 0xda, 0x6b,
0xf7, 0x85, 0x57, 0xba, 0x2f, 0x2b, 0x87, 0x42, 0xdf, 0x03, 0x70, 0x59, 0x2e, 0x27, 0x2c, 0x4f,
0x43, 0xff, 0xef, 0x3a, 0xac, 0xcd, 0x75, 0xd2, 0x7e, 0x11, 0xbf, 0x00, 0x87, 0x5d, 0xd8, 0x26,
0xae, 0x57, 0x23, 0xdf, 0xe0, 0xd0, 0x3f, 0xbe, 0x38, 0xa8, 0x61, 0x87, 0x5d, 0xa0, 0xed, 0xd9,
0x89, 0xb5, 0x07, 0xef, 0xdd, 0x96, 0x96, 0xde, 0x8a, 0x83, 0x9a, 0x1d, 0x69, 0xf7, 0x2b, 0x70,
0x8e, 0x2f, 0xd0, 0x43, 0x68, 0xab, 0xef, 0xdf, 0x58, 0x92, 0x49, 0x4c, 0x8b, 0xef, 0xf1, 0xdd,
0x9b, 0xce, 0x3f, 0x55, 0x0c, 0x0c, 0xa2, 0x10, 0x85, 0x2a, 0x2b, 0xb3, 0xd9, 0xf8, 0x7f, 0xd5,
0x01, 0xf6, 0x88, 0x88, 0x02, 0x45, 0x15, 0xe8, 0x3e, 0x74, 0x44, 0x1e, 0x04, 0x54, 0x88, 0x71,
0xc0, 0xf2, 0x54, 0xea, 0xc2, 0x9a, 0x78, 0xd9, 0x82, 0xfb, 0x0a, 0x53, 0xa4, 0x33, 0x12, 0xc5,
0x79, 0x46, 0x2d, 0xc9, 0x31, 0x24, 0x0b, 0x1a, 0xd2, 0x03, 0xb5, 0xfd, 0x92, 0xa6, 0xc1, 0xd5,
0x38, 0x11, 0x63, 0xbe, 0xbd, 0xa5, 0x07, 0xde, 0xc4, 0xcb, 0x16, 0x7d, 0x26, 0x46, 0xdb, 0x5b,
0x55, 0xd6, 0xce, 0xb6, 0x1e, 0xf1, 0x1c, 0x6b, 0x67, 0xfb, 0x05, 0xd6, 0x8e, 0x9e, 0xe4, 0x3c,
0x6b, 0xc7, 0xff, 0xad, 0x01, 0xad, 0xb2, 0x60, 0xb4, 0x0b, 0x2d, 0xce, 0xc2, 0xf1, 0x79, 0xc6,
0x72, 0x6e, 0xc7, 0xe3, 0xdf, 0xda, 0x1e, 0xf5, 0xc7, 0xf5, 0xb5, 0x62, 0x1e, 0xd4, 0xb0, 0xcb,
0xad, 0xdc, 0xfd, 0xc3, 0x01, 0xb7, 0x30, 0xa0, 0x87, 0xd0, 0xcc, 0xd8, 0x65, 0xd1, 0xe9, 0xf5,
0x57, 0x87, 0xea, 0x63, 0x76, 0x89, 0xb5, 0x4f, 0xf7, 0x9f, 0x3a, 0x34, 0x30, 0xbb, 0x7c, 0xc3,
0x9b, 0xfd, 0x9f, 0x6e, 0xdb, 0x06, 0xac, 0x26, 0x54, 0x4c, 0x69, 0x38, 0x56, 0xdd, 0x30, 0xe3,
0x32, 0x83, 0x58, 0x31, 0xf8, 0x88, 0x85, 0x66, 0x60, 0xeb, 0x70, 0x47, 0x32, 0x49, 0xe2, 0x19,
0xa2, 0x99, 0x45, 0x47, 0xc3, 0x25, 0x6f, 0x0b, 0x16, 0xd4, 0x2e, 0x09, 0x7b, 0x9b, 0x5e, 0x48,
0xe4, 0x7a, 0x9b, 0xb0, 0x21, 0xee, 0x2d, 0xc1, 0x82, 0x5e, 0xd3, 0x8f, 0x76, 0x01, 0xae, 0xd3,
0x44, 0x6d, 0x58, 0x3a, 0x1d, 0x1e, 0x8d, 0x4f, 0x86, 0xfb, 0xab, 0x35, 0xa5, 0x1c, 0x1f, 0x0d,
0xc7, 0xcf, 0x0e, 0x8f, 0x56, 0xeb, 0x85, 0x45, 0x29, 0x0e, 0x5a, 0x06, 0x57, 0x59, 0x0e, 0x8e,
0xbf, 0xc1, 0xab, 0x8d, 0xc1, 0x2f, 0x0d, 0x68, 0xec, 0xf2, 0x08, 0x7d, 0x0f, 0xed, 0x99, 0xcb,
0x85, 0xfc, 0x97, 0xde, 0x3c, 0xfd, 0xd1, 0xeb, 0xde, 0x7f, 0x8d, 0xdb, 0xe9, 0xd7, 0xd0, 0x63,
0x58, 0x2a, 0xde, 0x51, 0x37, 0x7f, 0x9c, 0xba, 0xef, 0x54, 0xe1, 0x99, 0x97, 0x99, 0x5f, 0x43,
0x43, 0x70, 0x8b, 0x77, 0xd3, 0x6d, 0x11, 0x7a, 0x55, 0xb8, 0xfa, 0xd0, 0xf2, 0x6b, 0xe8, 0x47,
0x68, 0x9d, 0xd0, 0xf8, 0x6c, 0x5f, 0xbd, 0x06, 0xd1, 0x27, 0xa5, 0x83, 0x7d, 0x44, 0xce, 0x3e,
0x15, 0x4b, 0x5a, 0x51, 0xe9, 0xa7, 0xaf, 0xc9, 0x9e, 0xa9, 0xb9, 0x71, 0x4a, 0x38, 0x7a, 0x71,
0xa9, 0xca, 0x67, 0x4a, 0xd7, 0xab, 0xc6, 0x3c, 0x25, 0x7c, 0xf8, 0x13, 0x4d, 0xa5, 0x5f, 0xdb,
0xaa, 0x4f, 0x16, 0xf5, 0x6b, 0xea, 0xb3, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0xa1, 0x9d, 0x3d,
0xa9, 0x2d, 0x0b, 0x00, 0x00,
}

View File

@ -10,6 +10,7 @@ import (
const (
KubernetesDeployments = "deployments"
KubernetesNamespaces = "namespaces"
KubernetesPods = "pods"
)
@ -58,6 +59,8 @@ func CanonicalKubernetesNameFromFriendlyName(friendlyName string) (string, error
switch friendlyName {
case "deploy", "deployment", "deployments":
return KubernetesDeployments, nil
case "ns", "namespace", "namespaces":
return KubernetesNamespaces, nil
case "po", "pod", "pods":
return KubernetesPods, nil
}

View File

@ -80,8 +80,8 @@ message StatSummaryRequest {
oneof outbound {
Empty none = 3;
Resource out_to_resource = 4;
Resource out_from_resource = 5;
Resource to_resource = 4;
Resource from_resource = 5;
}
}

View File

@ -75,12 +75,12 @@ func (h *handler) handleApiStat(w http.ResponseWriter, req *http.Request, p http
ResourceName: req.FormValue("resource_name"),
ResourceType: req.FormValue("resource_type"),
Namespace: req.FormValue("namespace"),
OutToName: req.FormValue("out_to_name"),
OutToType: req.FormValue("out_to_type"),
OutToNamespace: req.FormValue("out_to_namespace"),
OutFromName: req.FormValue("out_from_name"),
OutFromType: req.FormValue("out_from_type"),
OutFromNamespace: req.FormValue("out_from_namespace"),
ToName: req.FormValue("to_name"),
ToType: req.FormValue("to_type"),
ToNamespace: req.FormValue("to_namespace"),
FromName: req.FormValue("from_name"),
FromType: req.FormValue("from_type"),
FromNamespace: req.FormValue("from_namespace"),
}
// default to returning deployment stats