mirror of https://github.com/linkerd/linkerd2.git
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:
parent
cc44db054f
commit
77fb6d3709
|
@ -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)
|
|
@ -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"]
|
||||
|
||||
---
|
||||
|
|
|
@ -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"]
|
||||
|
||||
---
|
||||
|
|
|
@ -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"]
|
||||
|
||||
---
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue