syntax = "proto3"; package linkerd2.public; import "google/protobuf/duration.proto"; import "common/healthcheck.proto"; option go_package = "github.com/linkerd/linkerd2/controller/gen/public"; message Empty {} message VersionInfo { string goVersion = 1; string buildDate = 2; string releaseVersion = 3; } message ListServicesRequest { string namespace = 1; } message ListServicesResponse { repeated Service services = 1; } message Service { string name = 1; string namespace = 2; } message ListPodsRequest { string namespace = 1; } message ListPodsResponse { repeated Pod pods = 1; } message Pod { string name = 1; string podIP = 2; oneof owner { string deployment = 3; string replica_set = 10; string replication_controller = 11; string stateful_set = 12; string daemon_set = 13; string job = 14; } string status = 4; bool added = 5; // true if this pod has a proxy sidecar (data plane) google.protobuf.Duration sinceLastReport = 6; string controllerNamespace = 7; // namespace of controller this pod reports to bool controlPlane = 8; // true if this pod is part of the control plane google.protobuf.Duration uptime = 9; // uptime of this pod bool proxyReady = 15; // true if this pod has proxy container and that one is in ready state string proxyVersion = 16; // version of the proxy if present } message TapRequest { option deprecated = true; oneof target { string pod = 1; string deployment = 2; } // validation of these fields happens on the server float maxRps = 3; uint32 toPort = 4; string toIP = 5; uint32 fromPort = 6; string fromIP = 7; string scheme = 8; string method = 9; string authority = 10; string path = 11; } // A tap request over kubernetes resources. message TapByResourceRequest { // Describes the kubernetes pods that should be tapped. ResourceSelection target = 1; // Selects over events to be reported. Match match = 2; // Limits the number of events to be inspected. float maxRps = 3; message Match { oneof match { // If empty, matches all messages. Seq all = 1; // If empty, matches no messages. Seq any = 2; // Inverts the inner match. Match not = 3; // Matches events being sent to any of the selected destinations. ResourceSelection destinations = 4; // Matches HTTP requests by their metadata. Http http = 5; } message Seq { repeated Match matches = 1; } message Http { oneof match { string scheme = 1; string method = 2; string authority = 3; string path = 4; } } } } message HttpMethod { enum Registered { GET = 0; POST = 1; PUT = 2; DELETE = 3; PATCH = 4; OPTIONS = 5; CONNECT = 6; HEAD = 7; TRACE = 8; } oneof type { Registered registered = 1; string unregistered = 2; } } message Scheme { enum Registered { HTTP = 0; HTTPS = 1; } oneof type { Registered registered = 1; string unregistered = 2; } } message IPAddress { oneof ip { fixed32 ipv4 = 1; IPv6 ipv6 = 2; } } message IPv6 { fixed64 first = 1; // hextets 1-4 fixed64 last = 2; // hextets 5-8 } message TcpAddress { IPAddress ip = 1; uint32 port = 2; } message Eos { oneof end { uint32 grpc_status_code = 1; uint32 reset_error_code = 2; } } message TapEvent { TcpAddress source = 1; EndpointMeta source_meta = 5; TcpAddress destination = 2; EndpointMeta destination_meta = 4; RouteMeta route_meta = 7; ProxyDirection proxy_direction = 6; enum ProxyDirection { UNKNOWN = 0; INBOUND = 1; OUTBOUND = 2; } oneof event { Http http = 3; } message EndpointMeta { map labels = 1; } message RouteMeta { map labels = 1; } message Http { oneof event { RequestInit request_init = 1; ResponseInit response_init = 2; ResponseEnd response_end = 3; } message StreamId { // A randomized base (stable across a process's runtime) uint32 base = 1; // A stream id unique within the lifetime of `base`. uint64 stream = 2; } message RequestInit { StreamId id = 1; HttpMethod method = 2; Scheme scheme = 3; string authority = 4; string path = 5; // TODO headers } message ResponseInit { StreamId id = 1; google.protobuf.Duration since_request_init = 2; uint32 http_status = 3; } message ResponseEnd { StreamId id = 1; google.protobuf.Duration since_request_init = 2; google.protobuf.Duration since_response_init = 3; uint64 response_bytes = 4; Eos eos = 5; } } } message ApiError { string error = 1; } message PodErrors { repeated PodError errors = 1; message PodError { oneof error { ContainerError container = 1; } // To report init-container and container failures message ContainerError { string message = 1; string container = 2; string image = 3; string reason = 4; } } } message Resource { // The namespace the resource is in. // // If empty, indicates all namespaces should be considered. string namespace = 1; // The type of resource. // // This can be: // - "all" -- includes all Kubernetes resource types only // - "authority" -- a special resource type derived from request `:authority` values // - Otherwise, the resource type may be any Kubernetes resource (e.g. "namespace", "deployment"). string type = 2; // An optional resource name. string name = 3; } message ResourceSelection { // Identifies a Kubernetes resource. Resource resource = 1; // A string-formatted Kubernetes label selector as passed to `kubectl get // --selector`. // // XXX in the future this may be superceded by a data structure that more // richly describes a parsed label selector. string label_selector = 2; } message ResourceError { Resource resource = 1; string error = 2; } message StatSummaryRequest { ResourceSelection selector = 1; string time_window = 2; oneof outbound { Empty none = 3; Resource to_resource = 4; Resource from_resource = 5; } } message StatSummaryResponse { oneof response { Ok ok = 1; ResourceError error = 2; } message Ok { repeated StatTable stat_tables = 1; } } message BasicStats { uint64 success_count = 1; uint64 failure_count = 2; uint64 latency_ms_p50 = 3; uint64 latency_ms_p95 = 4; uint64 latency_ms_p99 = 5; uint64 tls_request_count = 6; } message StatTable { oneof table { PodGroup pod_group = 1; } message PodGroup { repeated Row rows = 1; message Row { Resource resource = 1; string time_window = 2; // number of pending or running pods in this resource that have linkerd injected uint64 meshed_pod_count = 3; // number of pending or running pods in this resource uint64 running_pod_count = 4; // number of pods in this resource that have Phase PodFailed uint64 failed_pod_count = 6; BasicStats stats = 5; // Stores a set of errors for each pod name. If a pod has no errors, it may be omitted. map errors_by_pod = 7; } } } message TopRoutesRequest { ResourceSelection selector = 1; string time_window = 2; oneof outbound { Empty none = 3; string to_authority = 5; Empty to_all = 6; } } message TopRoutesResponse { oneof response { RouteTable routes = 1; ResourceError error = 2; } } message RouteTable { repeated Row rows = 1; message Row { string route = 1; string time_window = 2; string authority = 6; BasicStats stats = 5; } } service Api { rpc StatSummary(StatSummaryRequest) returns (StatSummaryResponse) {} rpc TopRoutes(TopRoutesRequest) returns (TopRoutesResponse) {} rpc ListPods(ListPodsRequest) returns (ListPodsResponse) {} rpc ListServices(ListServicesRequest) returns (ListServicesResponse) {} // Superceded by `TapByResource`. rpc Tap(TapRequest) returns (stream TapEvent) { option deprecated = true; } // Executes tapping over Kubernetes resources. rpc TapByResource(TapByResourceRequest) returns (stream TapEvent) {} rpc Version(Empty) returns (VersionInfo) {} rpc SelfCheck(common.healthcheck.SelfCheckRequest) returns (common.healthcheck.SelfCheckResponse) {} }