mirror of https://github.com/linkerd/linkerd2.git
Adds conduit-api check for status command (#140)
* Abstract Conduit API client from protobuf interface to add new features Signed-off-by: Phil Calcado <phil@buoyant.io> * Consolidate mock api clients Signed-off-by: Phil Calcado <phil@buoyant.io> * Add simple implementation of healthcheck for conduit api Signed-off-by: Phil Calcado <phil@buoyant.io> * Change NextSteps to FriendlyMessageToUser Signed-off-by: Phil Calcado <phil@buoyant.io> * Add grpc check for status on the client Signed-off-by: Phil Calcado <phil@buoyant.io> * Add simple server-side check for Conduit API Signed-off-by: Phil Calcado <phil@buoyant.io> * Fix feedback from PR Signed-off-by: Phil Calcado <phil@buoyant.io>
This commit is contained in:
parent
de4ab1d807
commit
e328db7e87
|
|
@ -4,12 +4,13 @@ import (
|
|||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/runconduit/conduit/controller/api/public"
|
||||
pb "github.com/runconduit/conduit/controller/gen/public"
|
||||
)
|
||||
|
||||
func TestGetPods(t *testing.T) {
|
||||
t.Run("Returns names of existing pods if everything went ok", func(t *testing.T) {
|
||||
mockClient := &mockApiClient{}
|
||||
mockClient := &public.MockConduitApiClient{}
|
||||
|
||||
pods := []*pb.Pod{
|
||||
{Name: "pod-a"},
|
||||
|
|
@ -26,7 +27,7 @@ func TestGetPods(t *testing.T) {
|
|||
Pods: pods,
|
||||
}
|
||||
|
||||
mockClient.listPodsResponseToReturn = response
|
||||
mockClient.ListPodsResponseToReturn = response
|
||||
actualPodNames, err := getPods(mockClient)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
|
|
@ -41,9 +42,9 @@ func TestGetPods(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("Returns empty list if no [ods found", func(t *testing.T) {
|
||||
mockClient := &mockApiClient{}
|
||||
mockClient := &public.MockConduitApiClient{}
|
||||
|
||||
mockClient.listPodsResponseToReturn = &pb.ListPodsResponse{
|
||||
mockClient.ListPodsResponseToReturn = &pb.ListPodsResponse{
|
||||
Pods: []*pb.Pod{},
|
||||
}
|
||||
|
||||
|
|
@ -58,8 +59,8 @@ func TestGetPods(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("Returns error if cant find pods in API", func(t *testing.T) {
|
||||
mockClient := &mockApiClient{}
|
||||
mockClient.errorToReturn = errors.New("expected")
|
||||
mockClient := &public.MockConduitApiClient{}
|
||||
mockClient.ErrorToReturn = errors.New("expected")
|
||||
|
||||
_, err := getPods(mockClient)
|
||||
if err == nil {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/runconduit/conduit/controller/api/public"
|
||||
pb "github.com/runconduit/conduit/controller/gen/public"
|
||||
"github.com/runconduit/conduit/pkg/k8s"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
|
@ -15,7 +16,7 @@ import (
|
|||
|
||||
func TestRequestStatsFromApi(t *testing.T) {
|
||||
t.Run("Returns string output containing the data returned by the API", func(t *testing.T) {
|
||||
mockClient := &mockApiClient{}
|
||||
mockClient := &public.MockConduitApiClient{}
|
||||
|
||||
podName := "pod-1"
|
||||
metricDatapoints := []*pb.MetricDatapoint{
|
||||
|
|
@ -36,7 +37,7 @@ func TestRequestStatsFromApi(t *testing.T) {
|
|||
Datapoints: metricDatapoints,
|
||||
},
|
||||
}
|
||||
mockClient.metricResponseToReturn = &pb.MetricResponse{
|
||||
mockClient.MetricResponseToReturn = &pb.MetricResponse{
|
||||
Metrics: series,
|
||||
}
|
||||
|
||||
|
|
@ -51,8 +52,8 @@ func TestRequestStatsFromApi(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("Returns error if API call failed", func(t *testing.T) {
|
||||
mockClient := &mockApiClient{}
|
||||
mockClient.errorToReturn = errors.New("Expected")
|
||||
mockClient := &public.MockConduitApiClient{}
|
||||
mockClient.ErrorToReturn = errors.New("Expected")
|
||||
output, err := requestStatsFromApi(mockClient, k8s.KubernetesPods)
|
||||
|
||||
if err == nil {
|
||||
|
|
|
|||
|
|
@ -6,13 +6,14 @@ import (
|
|||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/runconduit/conduit/controller/api/public"
|
||||
"github.com/runconduit/conduit/pkg/healthcheck"
|
||||
"github.com/runconduit/conduit/pkg/k8s"
|
||||
"github.com/runconduit/conduit/pkg/shell"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
const lineWidth = 52
|
||||
const lineWidth = 80
|
||||
|
||||
var statusCmd = &cobra.Command{
|
||||
Use: "status",
|
||||
|
|
@ -35,11 +36,17 @@ problems were found.`,
|
|||
return statusCheckResultWasError(os.Stdout)
|
||||
}
|
||||
|
||||
return checkStatus(os.Stdout, kubectl, kubeApi)
|
||||
conduitApi, err := newApiClient(kubeApi)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error with Conduit API: %s\n", err.Error())
|
||||
return statusCheckResultWasError(os.Stdout)
|
||||
}
|
||||
|
||||
return checkStatus(os.Stdout, kubectl, kubeApi, healthcheck.NewGrpcStatusChecker(public.ConduitApiSubsystemName, conduitApi))
|
||||
}),
|
||||
}
|
||||
|
||||
func checkStatus(w io.Writer, kubectl k8s.Kubectl, kubeApi k8s.KubernetesApi) error {
|
||||
func checkStatus(w io.Writer, checkers ...healthcheck.StatusChecker) error {
|
||||
prettyPrintResults := func(result healthcheck.CheckResult) {
|
||||
checkLabel := fmt.Sprintf("%s: %s", result.SubsystemName, result.CheckDescription)
|
||||
|
||||
|
|
@ -52,15 +59,17 @@ func checkStatus(w io.Writer, kubectl k8s.Kubectl, kubeApi k8s.KubernetesApi) er
|
|||
case healthcheck.CheckOk:
|
||||
fmt.Fprintf(w, "%s%s[ok]\n", checkLabel, filler)
|
||||
case healthcheck.CheckFailed:
|
||||
fmt.Fprintf(w, "%s%s[FAIL] -- %s\n", checkLabel, filler, result.NextSteps)
|
||||
fmt.Fprintf(w, "%s%s[FAIL] -- %s\n", checkLabel, filler, result.FriendlyMessageToUser)
|
||||
case healthcheck.CheckError:
|
||||
fmt.Fprintf(w, "%s%s[ERROR] -- %s\n", checkLabel, filler, result.NextSteps)
|
||||
fmt.Fprintf(w, "%s%s[ERROR] -- %s\n", checkLabel, filler, result.FriendlyMessageToUser)
|
||||
}
|
||||
}
|
||||
|
||||
checker := healthcheck.MakeHealthChecker()
|
||||
checker.Add(kubectl)
|
||||
checker.Add(kubeApi)
|
||||
for _, c := range checkers {
|
||||
checker.Add(c)
|
||||
}
|
||||
|
||||
check := checker.PerformCheck(prettyPrintResults)
|
||||
|
||||
fmt.Fprintln(w, "")
|
||||
|
|
|
|||
|
|
@ -14,38 +14,38 @@ func TestCheckStatus(t *testing.T) {
|
|||
kubectl := &k8s.MockKubectl{}
|
||||
kubectl.SelfCheckResultsToReturn = []healthcheck.CheckResult{
|
||||
{
|
||||
SubsystemName: k8s.KubectlSubsystemName,
|
||||
CheckDescription: k8s.KubectlConnectivityCheckDescription,
|
||||
Status: healthcheck.CheckOk,
|
||||
NextSteps: "This shouldnt be printed",
|
||||
SubsystemName: k8s.KubectlSubsystemName,
|
||||
CheckDescription: k8s.KubectlConnectivityCheckDescription,
|
||||
Status: healthcheck.CheckOk,
|
||||
FriendlyMessageToUser: "This shouldnt be printed",
|
||||
},
|
||||
{
|
||||
SubsystemName: k8s.KubectlSubsystemName,
|
||||
CheckDescription: k8s.KubectlIsInstalledCheckDescription,
|
||||
Status: healthcheck.CheckFailed,
|
||||
NextSteps: "This should contain instructions for fail",
|
||||
SubsystemName: k8s.KubectlSubsystemName,
|
||||
CheckDescription: k8s.KubectlIsInstalledCheckDescription,
|
||||
Status: healthcheck.CheckFailed,
|
||||
FriendlyMessageToUser: "This should contain instructions for fail",
|
||||
},
|
||||
{
|
||||
SubsystemName: k8s.KubectlSubsystemName,
|
||||
CheckDescription: k8s.KubectlVersionCheckDescription,
|
||||
Status: healthcheck.CheckError,
|
||||
NextSteps: "This should contain instructions for err",
|
||||
SubsystemName: k8s.KubectlSubsystemName,
|
||||
CheckDescription: k8s.KubectlVersionCheckDescription,
|
||||
Status: healthcheck.CheckError,
|
||||
FriendlyMessageToUser: "This should contain instructions for err",
|
||||
},
|
||||
}
|
||||
|
||||
kubeApi := &k8s.MockKubeApi{}
|
||||
kubeApi.SelfCheckResultsToReturn = []healthcheck.CheckResult{
|
||||
{
|
||||
SubsystemName: k8s.KubeapiSubsystemName,
|
||||
CheckDescription: k8s.KubeapiClientCheckDescription,
|
||||
Status: healthcheck.CheckFailed,
|
||||
NextSteps: "This should contain instructions for fail",
|
||||
SubsystemName: k8s.KubeapiSubsystemName,
|
||||
CheckDescription: k8s.KubeapiClientCheckDescription,
|
||||
Status: healthcheck.CheckFailed,
|
||||
FriendlyMessageToUser: "This should contain instructions for fail",
|
||||
},
|
||||
{
|
||||
SubsystemName: k8s.KubeapiSubsystemName,
|
||||
CheckDescription: k8s.KubeapiAccessCheckDescription,
|
||||
Status: healthcheck.CheckOk,
|
||||
NextSteps: "This shouldnt be printed",
|
||||
SubsystemName: k8s.KubeapiSubsystemName,
|
||||
CheckDescription: k8s.KubeapiAccessCheckDescription,
|
||||
Status: healthcheck.CheckOk,
|
||||
FriendlyMessageToUser: "This shouldnt be printed",
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import (
|
|||
|
||||
"github.com/golang/protobuf/ptypes/duration"
|
||||
google_protobuf "github.com/golang/protobuf/ptypes/duration"
|
||||
"github.com/runconduit/conduit/controller/api/public"
|
||||
common "github.com/runconduit/conduit/controller/gen/common"
|
||||
pb "github.com/runconduit/conduit/controller/gen/public"
|
||||
"github.com/runconduit/conduit/controller/util"
|
||||
|
|
@ -25,7 +26,7 @@ func TestRequestTapFromApi(t *testing.T) {
|
|||
path := "/some/path"
|
||||
sourceIp := "234.234.234.234"
|
||||
targetIp := "123.123.123.123"
|
||||
mockApiClient := &mockApiClient{}
|
||||
mockApiClient := &public.MockConduitApiClient{}
|
||||
|
||||
event1 := createEvent(&common.TapEvent_Http{
|
||||
Event: &common.TapEvent_Http_RequestInit_{
|
||||
|
|
@ -55,8 +56,8 @@ func TestRequestTapFromApi(t *testing.T) {
|
|||
},
|
||||
},
|
||||
})
|
||||
mockApiClient.api_TapClientToReturn = &mockApi_TapClient{
|
||||
tapEventsToReturn: []common.TapEvent{event1, event2},
|
||||
mockApiClient.Api_TapClientToReturn = &public.MockApi_TapClient{
|
||||
TapEventsToReturn: []common.TapEvent{event1, event2},
|
||||
}
|
||||
|
||||
partialReq := &pb.TapRequest{
|
||||
|
|
@ -96,10 +97,10 @@ func TestRequestTapFromApi(t *testing.T) {
|
|||
path := "/some/path"
|
||||
sourceIp := "234.234.234.234"
|
||||
targetIp := "123.123.123.123"
|
||||
mockApiClient := &mockApiClient{}
|
||||
mockApiClient := &public.MockConduitApiClient{}
|
||||
|
||||
mockApiClient.api_TapClientToReturn = &mockApi_TapClient{
|
||||
tapEventsToReturn: []common.TapEvent{},
|
||||
mockApiClient.Api_TapClientToReturn = &public.MockApi_TapClient{
|
||||
TapEventsToReturn: []common.TapEvent{},
|
||||
}
|
||||
|
||||
partialReq := &pb.TapRequest{
|
||||
|
|
@ -140,9 +141,9 @@ func TestRequestTapFromApi(t *testing.T) {
|
|||
path := "/some/path"
|
||||
sourceIp := "234.234.234.234"
|
||||
targetIp := "123.123.123.123"
|
||||
mockApiClient := &mockApiClient{}
|
||||
mockApiClient.api_TapClientToReturn = &mockApi_TapClient{
|
||||
errorsToReturn: []error{errors.New("expected")},
|
||||
mockApiClient := &public.MockConduitApiClient{}
|
||||
mockApiClient.Api_TapClientToReturn = &public.MockApi_TapClient{
|
||||
ErrorsToReturn: []error{errors.New("expected")},
|
||||
}
|
||||
|
||||
partialReq := &pb.TapRequest{
|
||||
|
|
|
|||
|
|
@ -1,56 +0,0 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
|
||||
common "github.com/runconduit/conduit/controller/gen/common"
|
||||
pb "github.com/runconduit/conduit/controller/gen/public"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
type mockApiClient struct {
|
||||
errorToReturn error
|
||||
versionInfoToReturn *pb.VersionInfo
|
||||
listPodsResponseToReturn *pb.ListPodsResponse
|
||||
metricResponseToReturn *pb.MetricResponse
|
||||
api_TapClientToReturn pb.Api_TapClient
|
||||
}
|
||||
|
||||
func (c *mockApiClient) Stat(ctx context.Context, in *pb.MetricRequest, opts ...grpc.CallOption) (*pb.MetricResponse, error) {
|
||||
return c.metricResponseToReturn, c.errorToReturn
|
||||
}
|
||||
|
||||
func (c *mockApiClient) Version(ctx context.Context, in *pb.Empty, opts ...grpc.CallOption) (*pb.VersionInfo, error) {
|
||||
return c.versionInfoToReturn, c.errorToReturn
|
||||
}
|
||||
|
||||
func (c *mockApiClient) ListPods(ctx context.Context, in *pb.Empty, opts ...grpc.CallOption) (*pb.ListPodsResponse, error) {
|
||||
return c.listPodsResponseToReturn, c.errorToReturn
|
||||
}
|
||||
|
||||
func (c *mockApiClient) Tap(ctx context.Context, in *pb.TapRequest, opts ...grpc.CallOption) (pb.Api_TapClient, error) {
|
||||
return c.api_TapClientToReturn, c.errorToReturn
|
||||
}
|
||||
|
||||
type mockApi_TapClient struct {
|
||||
tapEventsToReturn []common.TapEvent
|
||||
errorsToReturn []error
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
func (a *mockApi_TapClient) Recv() (*common.TapEvent, error) {
|
||||
var eventPopped common.TapEvent
|
||||
var errorPopped error
|
||||
if len(a.tapEventsToReturn) == 0 && len(a.errorsToReturn) == 0 {
|
||||
return nil, io.EOF
|
||||
}
|
||||
if len(a.tapEventsToReturn) != 0 {
|
||||
eventPopped, a.tapEventsToReturn = a.tapEventsToReturn[0], a.tapEventsToReturn[1:]
|
||||
}
|
||||
if len(a.errorsToReturn) != 0 {
|
||||
errorPopped, a.errorsToReturn = a.errorsToReturn[0], a.errorsToReturn[1:]
|
||||
}
|
||||
|
||||
return &eventPopped, errorPopped
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
kubectl: can talk to Kubernetes cluster.............[ok]
|
||||
kubectl: is in $PATH................................[FAIL] -- This should contain instructions for fail
|
||||
kubectl: has compatible version.....................[ERROR] -- This should contain instructions for err
|
||||
kubernetes-api: can initialize the client...........[FAIL] -- This should contain instructions for fail
|
||||
kubernetes-api: can query the Kubernetes API........[ok]
|
||||
kubectl: can talk to Kubernetes cluster.........................................[ok]
|
||||
kubectl: is in $PATH............................................................[FAIL] -- This should contain instructions for fail
|
||||
kubectl: has compatible version.................................................[ERROR] -- This should contain instructions for err
|
||||
kubernetes-api: can initialize the client.......................................[FAIL] -- This should contain instructions for fail
|
||||
kubernetes-api: can query the Kubernetes API....................................[ok]
|
||||
|
||||
Status check results are [ERROR]
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/runconduit/conduit/controller"
|
||||
"github.com/runconduit/conduit/controller/api/public"
|
||||
pb "github.com/runconduit/conduit/controller/gen/public"
|
||||
)
|
||||
|
||||
|
|
@ -12,8 +13,8 @@ func TestGetVersion(t *testing.T) {
|
|||
t.Run("Returns existing versions from server and client", func(t *testing.T) {
|
||||
expectedServerVersion := "1.2.3"
|
||||
expectedClientVersion := controller.Version
|
||||
mockClient := &mockApiClient{}
|
||||
mockClient.versionInfoToReturn = &pb.VersionInfo{
|
||||
mockClient := &public.MockConduitApiClient{}
|
||||
mockClient.VersionInfoToReturn = &pb.VersionInfo{
|
||||
ReleaseVersion: expectedServerVersion,
|
||||
}
|
||||
|
||||
|
|
@ -25,11 +26,11 @@ func TestGetVersion(t *testing.T) {
|
|||
}
|
||||
})
|
||||
|
||||
t.Run("Returns undfined when cannot gt server version", func(t *testing.T) {
|
||||
t.Run("Returns undefined when cannot get server version", func(t *testing.T) {
|
||||
expectedServerVersion := "unavailable"
|
||||
expectedClientVersion := controller.Version
|
||||
mockClient := &mockApiClient{}
|
||||
mockClient.errorToReturn = errors.New("expected")
|
||||
mockClient := &public.MockConduitApiClient{}
|
||||
mockClient.ErrorToReturn = errors.New("expected")
|
||||
|
||||
versions := getVersions(mockClient)
|
||||
|
||||
|
|
|
|||
|
|
@ -19,17 +19,18 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
ApiRoot = "/" // Must be absolute (with a leading slash).
|
||||
ApiVersion = "v1"
|
||||
JsonContentType = "application/json"
|
||||
ApiPrefix = "api/" + ApiVersion + "/" // Must be relative (without a leading slash).
|
||||
ProtobufContentType = "application/octet-stream"
|
||||
ErrorHeader = "conduit-error"
|
||||
ApiRoot = "/" // Must be absolute (with a leading slash).
|
||||
ApiVersion = "v1"
|
||||
JsonContentType = "application/json"
|
||||
ApiPrefix = "api/" + ApiVersion + "/" // Must be relative (without a leading slash).
|
||||
ProtobufContentType = "application/octet-stream"
|
||||
ErrorHeader = "conduit-error"
|
||||
ConduitApiSubsystemName = "conduit-api"
|
||||
)
|
||||
|
||||
type client struct {
|
||||
serverURL *url.URL
|
||||
client *http.Client
|
||||
type grpcOverHttpClient struct {
|
||||
serverURL *url.URL
|
||||
httpClient *http.Client
|
||||
}
|
||||
|
||||
type tapClient struct {
|
||||
|
|
@ -37,26 +38,33 @@ type tapClient struct {
|
|||
reader *bufio.Reader
|
||||
}
|
||||
|
||||
func (c *client) Stat(ctx context.Context, req *pb.MetricRequest, _ ...grpc.CallOption) (*pb.MetricResponse, error) {
|
||||
func (c *grpcOverHttpClient) Stat(ctx context.Context, req *pb.MetricRequest, _ ...grpc.CallOption) (*pb.MetricResponse, error) {
|
||||
var msg pb.MetricResponse
|
||||
err := c.apiRequest(ctx, "Stat", req, &msg)
|
||||
return &msg, err
|
||||
}
|
||||
|
||||
func (c *client) Version(ctx context.Context, req *pb.Empty, _ ...grpc.CallOption) (*pb.VersionInfo, error) {
|
||||
func (c *grpcOverHttpClient) Version(ctx context.Context, req *pb.Empty, _ ...grpc.CallOption) (*pb.VersionInfo, error) {
|
||||
var msg pb.VersionInfo
|
||||
err := c.apiRequest(ctx, "Version", req, &msg)
|
||||
return &msg, err
|
||||
}
|
||||
|
||||
func (c *client) ListPods(ctx context.Context, req *pb.Empty, _ ...grpc.CallOption) (*pb.ListPodsResponse, error) {
|
||||
func (c *grpcOverHttpClient) SelfCheck(ctx context.Context, req *common.SelfCheckRequest, _ ...grpc.CallOption) (*common.SelfCheckResponse, error) {
|
||||
var msg common.SelfCheckResponse
|
||||
err := c.apiRequest(ctx, "SelfCheck", req, &msg)
|
||||
return &msg, err
|
||||
}
|
||||
|
||||
func (c *grpcOverHttpClient) ListPods(ctx context.Context, req *pb.Empty, _ ...grpc.CallOption) (*pb.ListPodsResponse, error) {
|
||||
var msg pb.ListPodsResponse
|
||||
err := c.apiRequest(ctx, "ListPods", req, &msg)
|
||||
return &msg, err
|
||||
}
|
||||
|
||||
func (c *client) Tap(ctx context.Context, req *pb.TapRequest, _ ...grpc.CallOption) (pb.Api_TapClient, error) {
|
||||
rsp, err := c.post(ctx, "Tap", req)
|
||||
func (c *grpcOverHttpClient) Tap(ctx context.Context, req *pb.TapRequest, _ ...grpc.CallOption) (pb.Api_TapClient, error) {
|
||||
url := c.endpointNameToPublicApiUrl("Tap")
|
||||
rsp, err := c.post(ctx, url, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -68,7 +76,6 @@ func (c *client) Tap(ctx context.Context, req *pb.TapRequest, _ ...grpc.CallOpti
|
|||
|
||||
return &tapClient{ctx: ctx, reader: bufio.NewReader(rsp.Body)}, nil
|
||||
}
|
||||
|
||||
func (c tapClient) Recv() (*common.TapEvent, error) {
|
||||
var msg common.TapEvent
|
||||
err := fromByteStreamToProtocolBuffers(c.reader, "", &msg)
|
||||
|
|
@ -83,11 +90,19 @@ func (c tapClient) Context() context.Context { return c.ctx }
|
|||
func (c tapClient) SendMsg(interface{}) error { return nil }
|
||||
func (c tapClient) RecvMsg(interface{}) error { return nil }
|
||||
|
||||
func (c *client) apiRequest(ctx context.Context, endpoint string, req proto.Message, rsp proto.Message) error {
|
||||
httpRsp, err := c.post(ctx, endpoint, req)
|
||||
func (c *grpcOverHttpClient) apiRequest(ctx context.Context, endpoint string, req proto.Message, rsp proto.Message) error {
|
||||
url := c.endpointNameToPublicApiUrl(endpoint)
|
||||
|
||||
httpRsp, err := c.post(ctx, url, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
clientSideErrorStatusCode := httpRsp.StatusCode >= 400 && httpRsp.StatusCode <= 499
|
||||
if clientSideErrorStatusCode {
|
||||
return fmt.Errorf("POST to Conduit API endpoint [%s] returned HTTP status [%s]", url, httpRsp.Status)
|
||||
}
|
||||
|
||||
defer httpRsp.Body.Close()
|
||||
|
||||
reader := bufio.NewReader(httpRsp.Body)
|
||||
|
|
@ -95,9 +110,7 @@ func (c *client) apiRequest(ctx context.Context, endpoint string, req proto.Mess
|
|||
return fromByteStreamToProtocolBuffers(reader, errorMsg, rsp)
|
||||
}
|
||||
|
||||
func (c *client) post(ctx context.Context, endpoint string, req proto.Message) (*http.Response, error) {
|
||||
url := c.serverURL.ResolveReference(&url.URL{Path: endpoint})
|
||||
|
||||
func (c *grpcOverHttpClient) post(ctx context.Context, url *url.URL, req proto.Message) (*http.Response, error) {
|
||||
reqBytes, err := proto.Marshal(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -112,7 +125,11 @@ func (c *client) post(ctx context.Context, endpoint string, req proto.Message) (
|
|||
return nil, err
|
||||
}
|
||||
|
||||
return c.client.Do(httpReq.WithContext(ctx))
|
||||
return c.httpClient.Do(httpReq.WithContext(ctx))
|
||||
}
|
||||
|
||||
func (c *grpcOverHttpClient) endpointNameToPublicApiUrl(endpoint string) *url.URL {
|
||||
return c.serverURL.ResolveReference(&url.URL{Path: endpoint})
|
||||
}
|
||||
|
||||
func NewInternalClient(kubernetesApiHost string) (pb.ApiClient, error) {
|
||||
|
|
@ -149,9 +166,9 @@ func newClient(apiURL *url.URL, httpClientToUse *http.Client) (pb.ApiClient, err
|
|||
return nil, fmt.Errorf("server URL must be absolute, was [%s]", apiURL.String())
|
||||
}
|
||||
|
||||
return &client{
|
||||
serverURL: apiURL.ResolveReference(&url.URL{Path: ApiPrefix}),
|
||||
client: httpClientToUse,
|
||||
return &grpcOverHttpClient{
|
||||
serverURL: apiURL.ResolveReference(&url.URL{Path: ApiPrefix}),
|
||||
httpClient: httpClientToUse,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,9 +10,11 @@ import (
|
|||
|
||||
"github.com/runconduit/conduit/controller"
|
||||
"github.com/runconduit/conduit/controller/api/util"
|
||||
common "github.com/runconduit/conduit/controller/gen/common"
|
||||
tapPb "github.com/runconduit/conduit/controller/gen/controller/tap"
|
||||
telemPb "github.com/runconduit/conduit/controller/gen/controller/telemetry"
|
||||
pb "github.com/runconduit/conduit/controller/gen/public"
|
||||
"github.com/runconduit/conduit/pkg/healthcheck"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
|
|
@ -32,19 +34,20 @@ type (
|
|||
)
|
||||
|
||||
const (
|
||||
countQuery = "sum(irate(responses_total{%s}[%s])) by (%s)"
|
||||
countHttpQuery = "sum(irate(http_requests_total{%s}[%s])) by (%s)"
|
||||
countGrpcQuery = "sum(irate(grpc_server_handled_total{%s}[%s])) by (%s)"
|
||||
latencyQuery = "sum(irate(response_latency_ms_bucket{%s}[%s])) by (%s)"
|
||||
quantileQuery = "histogram_quantile(%s, %s)"
|
||||
defaultVectorRange = "1m"
|
||||
|
||||
targetPodLabel = "target"
|
||||
targetDeployLabel = "target_deployment"
|
||||
sourcePodLabel = "source"
|
||||
sourceDeployLabel = "source_deployment"
|
||||
jobLabel = "job"
|
||||
pathLabel = "path"
|
||||
countQuery = "sum(irate(responses_total{%s}[%s])) by (%s)"
|
||||
countHttpQuery = "sum(irate(http_requests_total{%s}[%s])) by (%s)"
|
||||
countGrpcQuery = "sum(irate(grpc_server_handled_total{%s}[%s])) by (%s)"
|
||||
latencyQuery = "sum(irate(response_latency_ms_bucket{%s}[%s])) by (%s)"
|
||||
quantileQuery = "histogram_quantile(%s, %s)"
|
||||
defaultVectorRange = "1m"
|
||||
targetPodLabel = "target"
|
||||
targetDeployLabel = "target_deployment"
|
||||
sourcePodLabel = "source"
|
||||
sourceDeployLabel = "source_deployment"
|
||||
jobLabel = "job"
|
||||
pathLabel = "path"
|
||||
TelemetryClientSubsystemName = "telemetry"
|
||||
TelemetryClientCheckDescription = "control plane can use telemetry service"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -128,6 +131,31 @@ func (s *grpcServer) ListPods(ctx context.Context, req *pb.Empty) (*pb.ListPodsR
|
|||
return resp, nil
|
||||
}
|
||||
|
||||
func (s *grpcServer) SelfCheck(ctx context.Context, in *common.SelfCheckRequest) (*common.SelfCheckResponse, error) {
|
||||
telemetryClientCheck := &common.CheckResult{
|
||||
SubsystemName: TelemetryClientSubsystemName,
|
||||
CheckDescription: TelemetryClientCheckDescription,
|
||||
Status: string(healthcheck.CheckError),
|
||||
}
|
||||
|
||||
_, err := s.telemetryClient.ListPods(ctx, &telemPb.ListPodsRequest{})
|
||||
if err != nil {
|
||||
telemetryClientCheck.Status = string(healthcheck.CheckError)
|
||||
telemetryClientCheck.FriendlyMessageToUser = fmt.Sprintf("Error talking to telemetry service from control plane: %s", err.Error())
|
||||
} else {
|
||||
telemetryClientCheck.Status = string(healthcheck.CheckOk)
|
||||
}
|
||||
|
||||
//TODO: check other services
|
||||
|
||||
response := &common.SelfCheckResponse{
|
||||
Results: []*common.CheckResult{
|
||||
telemetryClientCheck,
|
||||
},
|
||||
}
|
||||
return response, nil
|
||||
}
|
||||
|
||||
// Pass through to tap service
|
||||
func (s *grpcServer) Tap(req *pb.TapRequest, stream pb.Api_TapServer) error {
|
||||
tapStream := stream.(tapServer)
|
||||
|
|
|
|||
|
|
@ -32,6 +32,11 @@ type (
|
|||
var (
|
||||
jsonMarshaler = jsonpb.Marshaler{EmitDefaults: true}
|
||||
jsonUnmarshaler = jsonpb.Unmarshaler{}
|
||||
statPath = fullUrlPathFor("Stat")
|
||||
versionPath = fullUrlPathFor("Version")
|
||||
listPodsPath = fullUrlPathFor("ListPods")
|
||||
tapPath = fullUrlPathFor("Tap")
|
||||
selfCheckPath = fullUrlPathFor("SelfCheck")
|
||||
)
|
||||
|
||||
func NewServer(addr string, telemetryClient telemPb.TelemetryClient, tapClient tapPb.TapClient) *http.Server {
|
||||
|
|
@ -73,14 +78,16 @@ func (h *handler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
|
||||
// Serve request
|
||||
switch req.URL.Path {
|
||||
case ApiRoot + ApiPrefix + "Stat":
|
||||
case statPath:
|
||||
h.handleStat(w, req)
|
||||
case ApiRoot + ApiPrefix + "Version":
|
||||
case versionPath:
|
||||
h.handleVersion(w, req)
|
||||
case ApiRoot + ApiPrefix + "ListPods":
|
||||
case listPodsPath:
|
||||
h.handleListPods(w, req)
|
||||
case ApiRoot + ApiPrefix + "Tap":
|
||||
case tapPath:
|
||||
h.handleTap(w, req)
|
||||
case selfCheckPath:
|
||||
h.handleSelfCheck(w, req)
|
||||
default:
|
||||
http.NotFound(w, req)
|
||||
}
|
||||
|
|
@ -128,6 +135,27 @@ func (h *handler) handleVersion(w http.ResponseWriter, req *http.Request) {
|
|||
}
|
||||
}
|
||||
|
||||
func (h *handler) handleSelfCheck(w http.ResponseWriter, req *http.Request) {
|
||||
var selfCheckRequest common.SelfCheckRequest
|
||||
err := serverUnmarshal(req, &selfCheckRequest)
|
||||
if err != nil {
|
||||
serverMarshalError(w, req, err, http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
rsp, err := h.grpcServer.SelfCheck(req.Context(), &selfCheckRequest)
|
||||
if err != nil {
|
||||
serverMarshalError(w, req, err, http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
err = serverMarshal(w, req, rsp)
|
||||
if err != nil {
|
||||
serverMarshalError(w, req, err, http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (h *handler) handleListPods(w http.ResponseWriter, req *http.Request) {
|
||||
var emptyRequest pb.Empty
|
||||
err := serverUnmarshal(req, &emptyRequest)
|
||||
|
|
@ -238,3 +266,7 @@ func (s tapServer) SetTrailer(metadata.MD) { return }
|
|||
func (s tapServer) Context() context.Context { return s.req.Context() }
|
||||
func (s tapServer) SendMsg(interface{}) error { return nil }
|
||||
func (s tapServer) RecvMsg(interface{}) error { return nil }
|
||||
|
||||
func fullUrlPathFor(method string) string {
|
||||
return ApiRoot + ApiPrefix + method
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,61 @@
|
|||
package public
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
|
||||
common "github.com/runconduit/conduit/controller/gen/common"
|
||||
pb "github.com/runconduit/conduit/controller/gen/public"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
type MockConduitApiClient struct {
|
||||
ErrorToReturn error
|
||||
VersionInfoToReturn *pb.VersionInfo
|
||||
ListPodsResponseToReturn *pb.ListPodsResponse
|
||||
MetricResponseToReturn *pb.MetricResponse
|
||||
SelfCheckResponseToReturn *common.SelfCheckResponse
|
||||
Api_TapClientToReturn pb.Api_TapClient
|
||||
}
|
||||
|
||||
func (c *MockConduitApiClient) Stat(ctx context.Context, in *pb.MetricRequest, opts ...grpc.CallOption) (*pb.MetricResponse, error) {
|
||||
return c.MetricResponseToReturn, c.ErrorToReturn
|
||||
}
|
||||
|
||||
func (c *MockConduitApiClient) Version(ctx context.Context, in *pb.Empty, opts ...grpc.CallOption) (*pb.VersionInfo, error) {
|
||||
return c.VersionInfoToReturn, c.ErrorToReturn
|
||||
}
|
||||
|
||||
func (c *MockConduitApiClient) ListPods(ctx context.Context, in *pb.Empty, opts ...grpc.CallOption) (*pb.ListPodsResponse, error) {
|
||||
return c.ListPodsResponseToReturn, c.ErrorToReturn
|
||||
}
|
||||
|
||||
func (c *MockConduitApiClient) Tap(ctx context.Context, in *pb.TapRequest, opts ...grpc.CallOption) (pb.Api_TapClient, error) {
|
||||
return c.Api_TapClientToReturn, c.ErrorToReturn
|
||||
}
|
||||
|
||||
func (c *MockConduitApiClient) SelfCheck(ctx context.Context, in *common.SelfCheckRequest, _ ...grpc.CallOption) (*common.SelfCheckResponse, error) {
|
||||
return c.SelfCheckResponseToReturn, c.ErrorToReturn
|
||||
}
|
||||
|
||||
type MockApi_TapClient struct {
|
||||
TapEventsToReturn []common.TapEvent
|
||||
ErrorsToReturn []error
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
func (a *MockApi_TapClient) Recv() (*common.TapEvent, error) {
|
||||
var eventPopped common.TapEvent
|
||||
var errorPopped error
|
||||
if len(a.TapEventsToReturn) == 0 && len(a.ErrorsToReturn) == 0 {
|
||||
return nil, io.EOF
|
||||
}
|
||||
if len(a.TapEventsToReturn) != 0 {
|
||||
eventPopped, a.TapEventsToReturn = a.TapEventsToReturn[0], a.TapEventsToReturn[1:]
|
||||
}
|
||||
if len(a.ErrorsToReturn) != 0 {
|
||||
errorPopped, a.ErrorsToReturn = a.ErrorsToReturn[0], a.ErrorsToReturn[1:]
|
||||
}
|
||||
|
||||
return &eventPopped, errorPopped
|
||||
}
|
||||
|
|
@ -15,6 +15,9 @@ It has these top-level messages:
|
|||
TcpAddress
|
||||
Destination
|
||||
TapEvent
|
||||
CheckResult
|
||||
SelfCheckRequest
|
||||
SelfCheckResponse
|
||||
*/
|
||||
package conduit_common
|
||||
|
||||
|
|
@ -944,6 +947,70 @@ func (m *TapEvent_Http_ResponseEnd) GetGrpcStatus() uint32 {
|
|||
return 0
|
||||
}
|
||||
|
||||
type CheckResult struct {
|
||||
SubsystemName string `protobuf:"bytes,1,opt,name=SubsystemName" json:"SubsystemName,omitempty"`
|
||||
CheckDescription string `protobuf:"bytes,2,opt,name=CheckDescription" json:"CheckDescription,omitempty"`
|
||||
Status string `protobuf:"bytes,3,opt,name=Status" json:"Status,omitempty"`
|
||||
FriendlyMessageToUser string `protobuf:"bytes,4,opt,name=FriendlyMessageToUser" json:"FriendlyMessageToUser,omitempty"`
|
||||
}
|
||||
|
||||
func (m *CheckResult) Reset() { *m = CheckResult{} }
|
||||
func (m *CheckResult) String() string { return proto.CompactTextString(m) }
|
||||
func (*CheckResult) ProtoMessage() {}
|
||||
func (*CheckResult) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} }
|
||||
|
||||
func (m *CheckResult) GetSubsystemName() string {
|
||||
if m != nil {
|
||||
return m.SubsystemName
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *CheckResult) GetCheckDescription() string {
|
||||
if m != nil {
|
||||
return m.CheckDescription
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *CheckResult) GetStatus() string {
|
||||
if m != nil {
|
||||
return m.Status
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *CheckResult) GetFriendlyMessageToUser() string {
|
||||
if m != nil {
|
||||
return m.FriendlyMessageToUser
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type SelfCheckRequest struct {
|
||||
}
|
||||
|
||||
func (m *SelfCheckRequest) Reset() { *m = SelfCheckRequest{} }
|
||||
func (m *SelfCheckRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*SelfCheckRequest) ProtoMessage() {}
|
||||
func (*SelfCheckRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} }
|
||||
|
||||
type SelfCheckResponse struct {
|
||||
Results []*CheckResult `protobuf:"bytes,1,rep,name=results" json:"results,omitempty"`
|
||||
}
|
||||
|
||||
func (m *SelfCheckResponse) Reset() { *m = SelfCheckResponse{} }
|
||||
func (m *SelfCheckResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*SelfCheckResponse) ProtoMessage() {}
|
||||
func (*SelfCheckResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} }
|
||||
|
||||
func (m *SelfCheckResponse) GetResults() []*CheckResult {
|
||||
if m != nil {
|
||||
return m.Results
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*HttpMethod)(nil), "conduit.common.HttpMethod")
|
||||
proto.RegisterType((*Scheme)(nil), "conduit.common.Scheme")
|
||||
|
|
@ -957,6 +1024,9 @@ func init() {
|
|||
proto.RegisterType((*TapEvent_Http_RequestInit)(nil), "conduit.common.TapEvent.Http.RequestInit")
|
||||
proto.RegisterType((*TapEvent_Http_ResponseInit)(nil), "conduit.common.TapEvent.Http.ResponseInit")
|
||||
proto.RegisterType((*TapEvent_Http_ResponseEnd)(nil), "conduit.common.TapEvent.Http.ResponseEnd")
|
||||
proto.RegisterType((*CheckResult)(nil), "conduit.common.CheckResult")
|
||||
proto.RegisterType((*SelfCheckRequest)(nil), "conduit.common.SelfCheckRequest")
|
||||
proto.RegisterType((*SelfCheckResponse)(nil), "conduit.common.SelfCheckResponse")
|
||||
proto.RegisterEnum("conduit.common.Protocol", Protocol_name, Protocol_value)
|
||||
proto.RegisterEnum("conduit.common.HttpMethod_Registered", HttpMethod_Registered_name, HttpMethod_Registered_value)
|
||||
proto.RegisterEnum("conduit.common.Scheme_Registered", Scheme_Registered_name, Scheme_Registered_value)
|
||||
|
|
@ -965,56 +1035,63 @@ func init() {
|
|||
func init() { proto.RegisterFile("common/common.proto", fileDescriptor0) }
|
||||
|
||||
var fileDescriptor0 = []byte{
|
||||
// 808 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x54, 0xdd, 0x6e, 0xe3, 0x54,
|
||||
0x10, 0x8e, 0x1d, 0xc7, 0x49, 0x26, 0x4d, 0x65, 0xce, 0x56, 0xab, 0x12, 0xb1, 0xb0, 0x1b, 0xb1,
|
||||
0x68, 0xdb, 0x0b, 0x17, 0x65, 0x51, 0x24, 0x2e, 0xf3, 0x63, 0x35, 0x11, 0x90, 0x98, 0x13, 0x73,
|
||||
0x5d, 0x39, 0xf6, 0xd9, 0xc4, 0x52, 0x63, 0x9b, 0x73, 0x8e, 0x2b, 0xf5, 0x65, 0x90, 0xe0, 0x09,
|
||||
0x78, 0x1f, 0x1e, 0x82, 0x0b, 0x5e, 0x00, 0x9d, 0x9f, 0x38, 0x4e, 0x77, 0x69, 0x11, 0x5c, 0xec,
|
||||
0x55, 0x66, 0x26, 0x33, 0x9f, 0xbf, 0xf9, 0x66, 0xce, 0xc0, 0xb3, 0x28, 0xdb, 0xed, 0xb2, 0xf4,
|
||||
0x4a, 0xfd, 0xb8, 0x39, 0xcd, 0x78, 0x86, 0x4e, 0xa3, 0x2c, 0x8d, 0x8b, 0x84, 0xbb, 0x2a, 0xda,
|
||||
0xfb, 0x7c, 0x93, 0x65, 0x9b, 0x5b, 0x72, 0x25, 0xff, 0x5d, 0x17, 0xef, 0xae, 0xe2, 0x82, 0x86,
|
||||
0x3c, 0xd9, 0xe7, 0xf7, 0xff, 0x32, 0x00, 0x66, 0x9c, 0xe7, 0x3f, 0x10, 0xbe, 0xcd, 0x62, 0x74,
|
||||
0x0d, 0x40, 0xc9, 0x26, 0x61, 0x9c, 0x50, 0x12, 0x9f, 0x1b, 0x2f, 0x8d, 0x37, 0xa7, 0x83, 0xd7,
|
||||
0xee, 0x31, 0xa6, 0x7b, 0xc8, 0x77, 0x71, 0x99, 0x3c, 0xab, 0xe1, 0x4a, 0x29, 0xfa, 0x12, 0x4e,
|
||||
0x8a, 0xb4, 0x02, 0x65, 0xbe, 0x34, 0xde, 0xb4, 0x67, 0x35, 0x7c, 0x14, 0xed, 0xa7, 0x00, 0x07,
|
||||
0x04, 0xd4, 0x84, 0xfa, 0xb5, 0x17, 0x38, 0x35, 0xd4, 0x02, 0xcb, 0x5f, 0xae, 0x02, 0xc7, 0x10,
|
||||
0x21, 0xff, 0xa7, 0xc0, 0x31, 0x11, 0x80, 0x3d, 0xf5, 0xbe, 0xf7, 0x02, 0xcf, 0xa9, 0xa3, 0x36,
|
||||
0x34, 0xfc, 0x51, 0x30, 0x99, 0x39, 0x16, 0xea, 0x40, 0x73, 0xe9, 0x07, 0xf3, 0xe5, 0x62, 0xe5,
|
||||
0x34, 0x84, 0x33, 0x59, 0x2e, 0x16, 0xde, 0x24, 0x70, 0x6c, 0x81, 0x31, 0xf3, 0x46, 0x53, 0xa7,
|
||||
0x29, 0xd2, 0x03, 0x3c, 0x9a, 0x78, 0x4e, 0x6b, 0x6c, 0x83, 0xc5, 0xef, 0x73, 0xd2, 0xff, 0xc5,
|
||||
0x00, 0x7b, 0x15, 0x6d, 0xc9, 0x8e, 0xa0, 0xc9, 0x07, 0x3a, 0x7e, 0xf5, 0xb0, 0x63, 0x95, 0xfb,
|
||||
0x7f, 0xbb, 0x7d, 0x75, 0xd4, 0xad, 0x20, 0x18, 0x04, 0xbe, 0x53, 0x13, 0x04, 0x85, 0xb5, 0x72,
|
||||
0x8c, 0x92, 0xe0, 0x0a, 0xda, 0x73, 0x7f, 0x14, 0xc7, 0x94, 0x30, 0x86, 0xce, 0xc0, 0x4a, 0xf2,
|
||||
0xbb, 0x6f, 0x24, 0xb9, 0xe6, 0xac, 0x86, 0xa5, 0x87, 0x2e, 0x65, 0x74, 0x28, 0xbf, 0xd5, 0x19,
|
||||
0x9c, 0x3d, 0xa4, 0x3c, 0xf7, 0xef, 0x86, 0x3a, 0x77, 0x38, 0xb6, 0xc0, 0x4c, 0xf2, 0xfe, 0xd7,
|
||||
0x60, 0x89, 0x28, 0x3a, 0x83, 0xc6, 0xbb, 0x84, 0x32, 0x2e, 0x01, 0x6d, 0xac, 0x1c, 0x84, 0xc0,
|
||||
0xba, 0x0d, 0x19, 0x97, 0x78, 0x36, 0x96, 0x76, 0xff, 0x3b, 0x80, 0x20, 0xca, 0xf7, 0x3c, 0x2e,
|
||||
0x04, 0x8a, 0x2c, 0xea, 0x0c, 0x3e, 0x7d, 0xff, 0x7b, 0x3a, 0x0d, 0x9b, 0x49, 0x2e, 0xc0, 0xf2,
|
||||
0x8c, 0x2a, 0xb0, 0x2e, 0x96, 0x76, 0xff, 0x5b, 0xe8, 0x4c, 0x09, 0xe3, 0x49, 0x2a, 0xf7, 0x0f,
|
||||
0x3d, 0x07, 0x9b, 0x49, 0x59, 0x25, 0x62, 0x1b, 0x6b, 0x4f, 0x96, 0x86, 0x7c, 0xab, 0x34, 0xc4,
|
||||
0xd2, 0xee, 0xff, 0xd6, 0x86, 0x56, 0x10, 0xe6, 0xde, 0x1d, 0x49, 0x39, 0x1a, 0x80, 0xcd, 0xb2,
|
||||
0x82, 0x46, 0x44, 0x53, 0xe9, 0x3d, 0xa4, 0x72, 0xa0, 0x8c, 0x75, 0xa6, 0xa8, 0xe1, 0x21, 0xdd,
|
||||
0x10, 0xae, 0xe5, 0x7a, 0xb4, 0x46, 0x65, 0xa2, 0xb7, 0x60, 0x6d, 0x39, 0xcf, 0xcf, 0xeb, 0xb2,
|
||||
0xe2, 0xc5, 0x7b, 0x15, 0x9a, 0x8f, 0x7c, 0x0e, 0x42, 0x69, 0x91, 0xdc, 0xfb, 0xb3, 0x09, 0x96,
|
||||
0x08, 0xa0, 0x05, 0x9c, 0x50, 0xf2, 0x73, 0x41, 0x18, 0xbf, 0x49, 0xd2, 0x84, 0x6b, 0xae, 0x17,
|
||||
0x8f, 0xa2, 0xb8, 0x58, 0x55, 0xcc, 0xd3, 0x84, 0xcf, 0x6a, 0xb8, 0x43, 0x0f, 0x2e, 0xfa, 0x11,
|
||||
0xba, 0x94, 0xb0, 0x3c, 0x4b, 0x19, 0x51, 0x80, 0xaa, 0x91, 0xcb, 0xa7, 0x00, 0x55, 0x89, 0x46,
|
||||
0x3c, 0xa1, 0x15, 0x5f, 0x51, 0xd4, 0x90, 0x24, 0x8d, 0x75, 0xa3, 0x17, 0xff, 0x0e, 0xd1, 0x4b,
|
||||
0x63, 0x45, 0xb1, 0x74, 0x7b, 0x43, 0x68, 0xad, 0x38, 0x25, 0xe1, 0x6e, 0x1e, 0x8b, 0x29, 0xae,
|
||||
0x43, 0xa6, 0x46, 0xd4, 0xc5, 0xd2, 0x96, 0x13, 0x97, 0xff, 0x4b, 0xee, 0x16, 0xd6, 0x5e, 0xef,
|
||||
0x0f, 0x03, 0x3a, 0x95, 0xce, 0xd1, 0x10, 0xcc, 0x24, 0xd6, 0x82, 0x7d, 0xf5, 0x38, 0x9b, 0xfd,
|
||||
0xf7, 0xb0, 0x99, 0xc4, 0x62, 0xc8, 0x3b, 0x79, 0x96, 0xfe, 0x69, 0xc8, 0x87, 0xc3, 0x85, 0x75,
|
||||
0x26, 0x72, 0xcb, 0x2d, 0x54, 0xdd, 0x3f, 0xff, 0xf0, 0xd3, 0x2f, 0xb7, 0xf3, 0x33, 0x68, 0x87,
|
||||
0x05, 0xdf, 0x66, 0x34, 0xe1, 0xf7, 0xe7, 0x96, 0x5c, 0xd1, 0x43, 0xa0, 0xdc, 0xdd, 0xc6, 0x61,
|
||||
0x77, 0x7b, 0xbf, 0x1b, 0x70, 0x52, 0x1d, 0xc3, 0x7f, 0x6e, 0xef, 0x1a, 0x10, 0x4b, 0xd2, 0x88,
|
||||
0xdc, 0x1c, 0xed, 0x95, 0xa9, 0x9f, 0xa3, 0xba, 0xf3, 0xee, 0xfe, 0xce, 0xbb, 0x53, 0x7d, 0xe7,
|
||||
0xb1, 0x23, 0x8b, 0xaa, 0xfa, 0x7e, 0x01, 0x1d, 0xb1, 0xab, 0x37, 0x8c, 0x87, 0xbc, 0x60, 0xb2,
|
||||
0xf1, 0x2e, 0x06, 0x11, 0x5a, 0xc9, 0x48, 0xef, 0x57, 0x53, 0x0c, 0xa4, 0x1c, 0xec, 0xc7, 0x67,
|
||||
0x3c, 0x87, 0x67, 0x7b, 0xa0, 0xea, 0x13, 0xa8, 0x3f, 0x85, 0xf4, 0x89, 0x46, 0xaa, 0xa8, 0xff,
|
||||
0x1a, 0x4e, 0x4b, 0x90, 0xf5, 0x3d, 0x27, 0x4c, 0x4e, 0xd1, 0xc2, 0xe5, 0xeb, 0x1a, 0x8b, 0xa0,
|
||||
0xd0, 0x68, 0x43, 0xf3, 0x68, 0xaf, 0x51, 0x43, 0x69, 0x24, 0x42, 0x4a, 0xa3, 0x71, 0x13, 0x1a,
|
||||
0x44, 0xb4, 0x5d, 0x1a, 0x97, 0x2f, 0xa0, 0xe5, 0x0b, 0x06, 0x51, 0x76, 0x5b, 0x39, 0xee, 0x4d,
|
||||
0xa8, 0x07, 0x13, 0xdf, 0x31, 0xd6, 0xb6, 0xa4, 0xf7, 0xf6, 0xef, 0x00, 0x00, 0x00, 0xff, 0xff,
|
||||
0x2d, 0x99, 0x17, 0xde, 0xb7, 0x07, 0x00, 0x00,
|
||||
// 924 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x55, 0xdd, 0x6e, 0xe3, 0x44,
|
||||
0x14, 0x8e, 0x13, 0xe7, 0xef, 0xa4, 0xa9, 0xbc, 0xb3, 0x65, 0x55, 0x02, 0x0b, 0x5d, 0x6b, 0x17,
|
||||
0xb5, 0xbd, 0x48, 0x51, 0x76, 0x89, 0xc4, 0x65, 0x9b, 0x84, 0x26, 0xc0, 0xa6, 0x66, 0xec, 0xbd,
|
||||
0xae, 0x1c, 0x7b, 0x9a, 0x58, 0x24, 0xb6, 0x99, 0x19, 0x57, 0xca, 0xcb, 0x20, 0xc1, 0x3d, 0x12,
|
||||
0xef, 0xc3, 0x43, 0x70, 0xc1, 0x0b, 0xa0, 0xf9, 0x89, 0xe3, 0xb4, 0xa5, 0x8b, 0xe0, 0x62, 0xaf,
|
||||
0x32, 0xe7, 0xf3, 0x39, 0xdf, 0x7c, 0xe7, 0x67, 0x4e, 0xe0, 0x69, 0x90, 0xac, 0x56, 0x49, 0x7c,
|
||||
0xa6, 0x7e, 0xba, 0x29, 0x4d, 0x78, 0x82, 0xf6, 0x83, 0x24, 0x0e, 0xb3, 0x88, 0x77, 0x15, 0xda,
|
||||
0xf9, 0x6c, 0x9e, 0x24, 0xf3, 0x25, 0x39, 0x93, 0x5f, 0x67, 0xd9, 0xcd, 0x59, 0x98, 0x51, 0x9f,
|
||||
0x47, 0x1b, 0x7f, 0xfb, 0x2f, 0x03, 0x60, 0xcc, 0x79, 0xfa, 0x96, 0xf0, 0x45, 0x12, 0xa2, 0x4b,
|
||||
0x00, 0x4a, 0xe6, 0x11, 0xe3, 0x84, 0x92, 0xf0, 0xd0, 0x38, 0x32, 0x8e, 0xf7, 0x7b, 0xaf, 0xba,
|
||||
0xbb, 0x9c, 0xdd, 0xad, 0x7f, 0x17, 0xe7, 0xce, 0xe3, 0x12, 0x2e, 0x84, 0xa2, 0x97, 0xb0, 0x97,
|
||||
0xc5, 0x05, 0xaa, 0xf2, 0x91, 0x71, 0xdc, 0x1c, 0x97, 0xf0, 0x0e, 0x6a, 0xc7, 0x00, 0x5b, 0x06,
|
||||
0x54, 0x87, 0xca, 0xe5, 0xc8, 0xb3, 0x4a, 0xa8, 0x01, 0xa6, 0x73, 0xe5, 0x7a, 0x96, 0x21, 0x20,
|
||||
0xe7, 0x9d, 0x67, 0x95, 0x11, 0x40, 0x6d, 0x38, 0xfa, 0x7e, 0xe4, 0x8d, 0xac, 0x0a, 0x6a, 0x42,
|
||||
0xd5, 0x39, 0xf7, 0x06, 0x63, 0xcb, 0x44, 0x2d, 0xa8, 0x5f, 0x39, 0xde, 0xe4, 0x6a, 0xea, 0x5a,
|
||||
0x55, 0x61, 0x0c, 0xae, 0xa6, 0xd3, 0xd1, 0xc0, 0xb3, 0x6a, 0x82, 0x63, 0x3c, 0x3a, 0x1f, 0x5a,
|
||||
0x75, 0xe1, 0xee, 0xe1, 0xf3, 0xc1, 0xc8, 0x6a, 0x5c, 0xd4, 0xc0, 0xe4, 0xeb, 0x94, 0xd8, 0x3f,
|
||||
0x1b, 0x50, 0x73, 0x83, 0x05, 0x59, 0x11, 0x34, 0x78, 0x20, 0xe3, 0x17, 0x77, 0x33, 0x56, 0xbe,
|
||||
0xff, 0x37, 0xdb, 0x17, 0x3b, 0xd9, 0x0a, 0x81, 0x9e, 0xe7, 0x58, 0x25, 0x21, 0x50, 0x9c, 0x5c,
|
||||
0xcb, 0xc8, 0x05, 0xba, 0xd0, 0x9c, 0x38, 0xe7, 0x61, 0x48, 0x09, 0x63, 0xe8, 0x00, 0xcc, 0x28,
|
||||
0xbd, 0x7d, 0x23, 0xc5, 0xd5, 0xc7, 0x25, 0x2c, 0x2d, 0x74, 0x2a, 0xd1, 0xbe, 0xbc, 0xab, 0xd5,
|
||||
0x3b, 0xb8, 0x2b, 0x79, 0xe2, 0xdc, 0xf6, 0xb5, 0x6f, 0xff, 0xc2, 0x84, 0x72, 0x94, 0xda, 0x5f,
|
||||
0x82, 0x29, 0x50, 0x74, 0x00, 0xd5, 0x9b, 0x88, 0x32, 0x2e, 0x09, 0x6b, 0x58, 0x19, 0x08, 0x81,
|
||||
0xb9, 0xf4, 0x19, 0x97, 0x7c, 0x35, 0x2c, 0xcf, 0xf6, 0x77, 0x00, 0x5e, 0x90, 0x6e, 0x74, 0x9c,
|
||||
0x08, 0x16, 0x19, 0xd4, 0xea, 0x7d, 0x7c, 0xff, 0x3e, 0xed, 0x86, 0xcb, 0x51, 0x2a, 0xc8, 0xd2,
|
||||
0x84, 0x2a, 0xb2, 0x36, 0x96, 0x67, 0xfb, 0x6b, 0x68, 0x0d, 0x09, 0xe3, 0x51, 0x2c, 0xe7, 0x0f,
|
||||
0x3d, 0x83, 0x1a, 0x93, 0x65, 0x95, 0x8c, 0x4d, 0xac, 0x2d, 0x19, 0xea, 0xf3, 0x85, 0xaa, 0x21,
|
||||
0x96, 0x67, 0xfb, 0xd7, 0x26, 0x34, 0x3c, 0x3f, 0x1d, 0xdd, 0x92, 0x98, 0xa3, 0x1e, 0xd4, 0x58,
|
||||
0x92, 0xd1, 0x80, 0x68, 0x29, 0x9d, 0xbb, 0x52, 0xb6, 0x92, 0xb1, 0xf6, 0x14, 0x31, 0xdc, 0xa7,
|
||||
0x73, 0xc2, 0x75, 0xb9, 0x1e, 0x8d, 0x51, 0x9e, 0xe8, 0x35, 0x98, 0x0b, 0xce, 0xd3, 0xc3, 0x8a,
|
||||
0x8c, 0x78, 0x7e, 0x2f, 0x42, 0xeb, 0x91, 0xcf, 0x41, 0x54, 0x5a, 0x38, 0x77, 0xfe, 0xac, 0x83,
|
||||
0x29, 0x00, 0x34, 0x85, 0x3d, 0x4a, 0x7e, 0xca, 0x08, 0xe3, 0xd7, 0x51, 0x1c, 0x71, 0xad, 0xf5,
|
||||
0xe4, 0x51, 0x96, 0x2e, 0x56, 0x11, 0x93, 0x38, 0xe2, 0xe3, 0x12, 0x6e, 0xd1, 0xad, 0x89, 0x7e,
|
||||
0x80, 0x36, 0x25, 0x2c, 0x4d, 0x62, 0x46, 0x14, 0xa1, 0x4a, 0xe4, 0xf4, 0x7d, 0x84, 0x2a, 0x44,
|
||||
0x33, 0xee, 0xd1, 0x82, 0xad, 0x24, 0x6a, 0x4a, 0x12, 0x87, 0x3a, 0xd1, 0x93, 0x7f, 0xc7, 0x38,
|
||||
0x8a, 0x43, 0x25, 0x31, 0x37, 0x3b, 0x7d, 0x68, 0xb8, 0x9c, 0x12, 0x7f, 0x35, 0x09, 0x45, 0x17,
|
||||
0x67, 0x3e, 0x53, 0x2d, 0x6a, 0x63, 0x79, 0x96, 0x1d, 0x97, 0xdf, 0xa5, 0x76, 0x13, 0x6b, 0xab,
|
||||
0xf3, 0x87, 0x01, 0xad, 0x42, 0xe6, 0xa8, 0x0f, 0xe5, 0x28, 0xd4, 0x05, 0xfb, 0xe2, 0x71, 0x35,
|
||||
0x9b, 0xfb, 0x70, 0x39, 0x0a, 0x45, 0x93, 0x57, 0x72, 0x2d, 0xfd, 0x53, 0x93, 0xb7, 0x8b, 0x0b,
|
||||
0x6b, 0x4f, 0xd4, 0xcd, 0xa7, 0x50, 0x65, 0xff, 0xec, 0xe1, 0xa7, 0x9f, 0x4f, 0xe7, 0xa7, 0xd0,
|
||||
0xf4, 0x33, 0xbe, 0x48, 0x68, 0xc4, 0xd7, 0x87, 0xa6, 0x1c, 0xd1, 0x2d, 0x90, 0xcf, 0x6e, 0x75,
|
||||
0x3b, 0xbb, 0x9d, 0xdf, 0x0d, 0xd8, 0x2b, 0xb6, 0xe1, 0x3f, 0xa7, 0x77, 0x09, 0x88, 0x45, 0x71,
|
||||
0x40, 0xae, 0x77, 0xe6, 0xaa, 0xac, 0x9f, 0xa3, 0xda, 0xf3, 0xdd, 0xcd, 0x9e, 0xef, 0x0e, 0xf5,
|
||||
0x9e, 0xc7, 0x96, 0x0c, 0x2a, 0xd6, 0xf7, 0x73, 0x68, 0x89, 0x59, 0xbd, 0x66, 0xdc, 0xe7, 0x19,
|
||||
0x93, 0x89, 0xb7, 0x31, 0x08, 0xc8, 0x95, 0x48, 0xe7, 0x97, 0xb2, 0x68, 0x48, 0xde, 0xd8, 0x0f,
|
||||
0xaf, 0x78, 0x02, 0x4f, 0x37, 0x44, 0xc5, 0x27, 0x50, 0x79, 0x1f, 0xd3, 0x13, 0xcd, 0x54, 0xa8,
|
||||
0xfe, 0x2b, 0xd8, 0xcf, 0x49, 0x66, 0x6b, 0x4e, 0x98, 0xec, 0xa2, 0x89, 0xf3, 0xd7, 0x75, 0x21,
|
||||
0x40, 0x51, 0xa3, 0x39, 0x4d, 0x83, 0x4d, 0x8d, 0xaa, 0xaa, 0x46, 0x02, 0x52, 0x35, 0xba, 0xa8,
|
||||
0x43, 0x95, 0x88, 0xb4, 0xf3, 0x83, 0xfd, 0x9b, 0x01, 0xad, 0xc1, 0x82, 0x04, 0x3f, 0x62, 0xc2,
|
||||
0xb2, 0x25, 0x47, 0x2f, 0xa1, 0xed, 0x66, 0x33, 0xb6, 0x66, 0x9c, 0xac, 0xa6, 0x7e, 0xbe, 0xe7,
|
||||
0x76, 0x41, 0x74, 0x0a, 0x96, 0x0c, 0x1a, 0x12, 0x16, 0xd0, 0x28, 0x15, 0xb2, 0xf5, 0xea, 0xbb,
|
||||
0x87, 0x8b, 0x07, 0xe4, 0x6e, 0x7b, 0xd6, 0xc4, 0xda, 0x42, 0x6f, 0xe0, 0xa3, 0x6f, 0x68, 0x44,
|
||||
0xe2, 0x70, 0xb9, 0x7e, 0x4b, 0x18, 0xf3, 0xe7, 0xc4, 0x4b, 0xde, 0x31, 0x42, 0xf5, 0x80, 0x3e,
|
||||
0xfc, 0xd1, 0x46, 0x60, 0xb9, 0x64, 0x79, 0xa3, 0x25, 0xcb, 0x62, 0xdb, 0xdf, 0xc2, 0x93, 0x02,
|
||||
0xa6, 0x0a, 0x82, 0xbe, 0x82, 0x3a, 0x95, 0x29, 0xb1, 0x43, 0xe3, 0xa8, 0x72, 0xdc, 0xea, 0x7d,
|
||||
0x72, 0x77, 0x06, 0x0a, 0x69, 0xe3, 0x8d, 0xef, 0xe9, 0x73, 0x68, 0x38, 0xa2, 0x23, 0x41, 0xb2,
|
||||
0x2c, 0xfc, 0xd9, 0xd5, 0xa1, 0xe2, 0x0d, 0x1c, 0xcb, 0x98, 0xd5, 0x64, 0xbb, 0x5e, 0xff, 0x1d,
|
||||
0x00, 0x00, 0xff, 0xff, 0x92, 0x14, 0x84, 0x25, 0xc7, 0x08, 0x00, 0x00,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -884,6 +884,7 @@ type ApiClient interface {
|
|||
Stat(ctx context.Context, in *MetricRequest, opts ...grpc.CallOption) (*MetricResponse, error)
|
||||
Version(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*VersionInfo, error)
|
||||
ListPods(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*ListPodsResponse, error)
|
||||
SelfCheck(ctx context.Context, in *conduit_common.SelfCheckRequest, opts ...grpc.CallOption) (*conduit_common.SelfCheckResponse, error)
|
||||
Tap(ctx context.Context, in *TapRequest, opts ...grpc.CallOption) (Api_TapClient, error)
|
||||
}
|
||||
|
||||
|
|
@ -922,6 +923,15 @@ func (c *apiClient) ListPods(ctx context.Context, in *Empty, opts ...grpc.CallOp
|
|||
return out, nil
|
||||
}
|
||||
|
||||
func (c *apiClient) SelfCheck(ctx context.Context, in *conduit_common.SelfCheckRequest, opts ...grpc.CallOption) (*conduit_common.SelfCheckResponse, error) {
|
||||
out := new(conduit_common.SelfCheckResponse)
|
||||
err := grpc.Invoke(ctx, "/conduit.public.Api/SelfCheck", in, out, c.cc, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *apiClient) Tap(ctx context.Context, in *TapRequest, opts ...grpc.CallOption) (Api_TapClient, error) {
|
||||
stream, err := grpc.NewClientStream(ctx, &_Api_serviceDesc.Streams[0], c.cc, "/conduit.public.Api/Tap", opts...)
|
||||
if err != nil {
|
||||
|
|
@ -960,6 +970,7 @@ type ApiServer interface {
|
|||
Stat(context.Context, *MetricRequest) (*MetricResponse, error)
|
||||
Version(context.Context, *Empty) (*VersionInfo, error)
|
||||
ListPods(context.Context, *Empty) (*ListPodsResponse, error)
|
||||
SelfCheck(context.Context, *conduit_common.SelfCheckRequest) (*conduit_common.SelfCheckResponse, error)
|
||||
Tap(*TapRequest, Api_TapServer) error
|
||||
}
|
||||
|
||||
|
|
@ -1021,6 +1032,24 @@ func _Api_ListPods_Handler(srv interface{}, ctx context.Context, dec func(interf
|
|||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Api_SelfCheck_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(conduit_common.SelfCheckRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ApiServer).SelfCheck(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/conduit.public.Api/SelfCheck",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ApiServer).SelfCheck(ctx, req.(*conduit_common.SelfCheckRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Api_Tap_Handler(srv interface{}, stream grpc.ServerStream) error {
|
||||
m := new(TapRequest)
|
||||
if err := stream.RecvMsg(m); err != nil {
|
||||
|
|
@ -1058,6 +1087,10 @@ var _Api_serviceDesc = grpc.ServiceDesc{
|
|||
MethodName: "ListPods",
|
||||
Handler: _Api_ListPods_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "SelfCheck",
|
||||
Handler: _Api_SelfCheck_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{
|
||||
{
|
||||
|
|
@ -1072,80 +1105,81 @@ var _Api_serviceDesc = grpc.ServiceDesc{
|
|||
func init() { proto.RegisterFile("public/api.proto", fileDescriptor0) }
|
||||
|
||||
var fileDescriptor0 = []byte{
|
||||
// 1188 bytes of a gzipped FileDescriptorProto
|
||||
// 1213 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x56, 0xcb, 0x6e, 0xdb, 0x46,
|
||||
0x14, 0x15, 0x45, 0xc9, 0x92, 0xae, 0x6c, 0x85, 0x9d, 0xa4, 0x81, 0xaa, 0xa6, 0xae, 0xca, 0x45,
|
||||
0x6b, 0x78, 0x21, 0xa7, 0x6e, 0x12, 0xc0, 0x2d, 0x82, 0x40, 0x96, 0x89, 0xc8, 0x80, 0x1f, 0xec,
|
||||
0x88, 0x4e, 0x5b, 0xa0, 0x80, 0x31, 0x16, 0xc7, 0x34, 0x51, 0x92, 0xc3, 0x90, 0xc3, 0xa4, 0xee,
|
||||
0xbe, 0xdb, 0x6e, 0xdb, 0x2f, 0xe8, 0x4f, 0x74, 0xdf, 0xef, 0x2a, 0xe6, 0x41, 0x4a, 0x56, 0x94,
|
||||
0xa0, 0x2b, 0xcf, 0x3d, 0xf7, 0xcc, 0xe1, 0x7d, 0xcd, 0xb5, 0xc0, 0x4a, 0x8b, 0xab, 0x28, 0x9c,
|
||||
0xef, 0x91, 0x34, 0x1c, 0xa5, 0x19, 0xe3, 0x0c, 0xf5, 0xe6, 0x2c, 0xf1, 0x8b, 0x90, 0x8f, 0x94,
|
||||
0x67, 0xb0, 0x1d, 0x30, 0x16, 0x44, 0x74, 0x4f, 0x7a, 0xaf, 0x8a, 0xeb, 0x3d, 0xbf, 0xc8, 0x08,
|
||||
0x0f, 0x59, 0xa2, 0xf8, 0x83, 0xfb, 0x73, 0x16, 0xc7, 0x2c, 0xd9, 0x53, 0x7f, 0x14, 0x68, 0xff,
|
||||
0x0c, 0xbd, 0x69, 0x98, 0x73, 0x16, 0x64, 0x24, 0x7e, 0x45, 0xa2, 0x82, 0xa2, 0x27, 0xd0, 0x8c,
|
||||
0xc8, 0x15, 0x8d, 0xfa, 0xc6, 0xd0, 0xd8, 0xe9, 0xed, 0x6f, 0x8f, 0xee, 0x7e, 0x66, 0x54, 0xd1,
|
||||
0x4f, 0x04, 0x0b, 0x2b, 0x32, 0x7a, 0x00, 0xcd, 0x37, 0xe2, 0x7a, 0xbf, 0x3e, 0x34, 0x76, 0x4c,
|
||||
0xac, 0x0c, 0x7b, 0x02, 0x9d, 0x8a, 0x8e, 0x9e, 0xc1, 0x86, 0x44, 0xf3, 0xbe, 0x31, 0x34, 0x77,
|
||||
0xba, 0x1f, 0x50, 0x96, 0x81, 0x60, 0xcd, 0xb6, 0x7f, 0x37, 0xa0, 0x7b, 0x4a, 0x79, 0x16, 0xce,
|
||||
0x55, 0x80, 0x03, 0x68, 0xcd, 0x59, 0x91, 0x70, 0x9a, 0xc9, 0x10, 0xcd, 0x69, 0x0d, 0x97, 0x00,
|
||||
0x7a, 0x08, 0xcd, 0x80, 0x14, 0x81, 0x0a, 0xc3, 0x98, 0xd6, 0xb0, 0x32, 0xd1, 0x01, 0x74, 0x6e,
|
||||
0x4a, 0xf5, 0xbe, 0x39, 0x34, 0x76, 0xba, 0xfb, 0x9f, 0xbc, 0xf7, 0xf3, 0xd3, 0x1a, 0x5e, 0xb0,
|
||||
0x0f, 0x5b, 0x3a, 0x33, 0x3b, 0x80, 0x7b, 0x2a, 0x8c, 0x23, 0xc2, 0x49, 0xca, 0xc2, 0x84, 0xa3,
|
||||
0xaf, 0xcb, 0xac, 0x0d, 0x29, 0xf9, 0xe9, 0xaa, 0xe4, 0x52, 0xd8, 0xba, 0x24, 0xe8, 0x0b, 0xd8,
|
||||
0xe4, 0x61, 0x4c, 0x73, 0x4e, 0xe2, 0xf4, 0x32, 0xce, 0x75, 0xbd, 0xba, 0x15, 0x76, 0x9a, 0xdb,
|
||||
0xff, 0x18, 0xb0, 0xa9, 0x6e, 0xce, 0x68, 0x16, 0xd2, 0x1c, 0x8d, 0xa0, 0x91, 0x90, 0x98, 0xea,
|
||||
0x8e, 0x0c, 0xd6, 0x7f, 0xe5, 0x8c, 0xc4, 0x14, 0x4b, 0x1e, 0xfa, 0x16, 0xda, 0x31, 0xe5, 0xc4,
|
||||
0x27, 0x9c, 0x48, 0xfd, 0x35, 0xb5, 0x56, 0x77, 0x4e, 0x35, 0x0b, 0x57, 0x7c, 0xf4, 0x02, 0xc0,
|
||||
0x2f, 0xf3, 0xcb, 0xfb, 0xa6, 0xec, 0xd4, 0xe7, 0xeb, 0x6f, 0x57, 0x75, 0xc0, 0x4b, 0x57, 0xec,
|
||||
0x7f, 0x0d, 0xe8, 0xdd, 0x55, 0x47, 0x8f, 0xa0, 0xc3, 0x49, 0x16, 0x50, 0xee, 0x32, 0x5f, 0x26,
|
||||
0xd1, 0xc1, 0x0b, 0x00, 0xd9, 0xb0, 0xa9, 0x8c, 0x23, 0x9a, 0x46, 0xec, 0x56, 0x46, 0xdc, 0xc1,
|
||||
0x77, 0x30, 0xa1, 0x90, 0xb3, 0x22, 0x9b, 0x53, 0xa1, 0x60, 0x2a, 0x85, 0x0a, 0x10, 0x0a, 0xca,
|
||||
0xd0, 0x0a, 0x0d, 0xa5, 0xb0, 0x8c, 0x09, 0x85, 0x39, 0x8b, 0x53, 0x96, 0xd0, 0x84, 0xf7, 0x9b,
|
||||
0x4a, 0xa1, 0x02, 0x10, 0x82, 0x46, 0x4a, 0xf8, 0x4d, 0x7f, 0x43, 0x3a, 0xe4, 0xd9, 0x9e, 0x96,
|
||||
0x79, 0x60, 0x9a, 0xa7, 0x2c, 0xc9, 0x29, 0x7a, 0x06, 0xad, 0x58, 0x22, 0xe5, 0x08, 0x3f, 0x5a,
|
||||
0x5f, 0x18, 0xd5, 0x36, 0x5c, 0x92, 0xed, 0x3f, 0xea, 0xb0, 0x55, 0x4a, 0xbd, 0x2e, 0x68, 0xce,
|
||||
0xd1, 0x93, 0xbb, 0x4a, 0x1f, 0x6e, 0x6a, 0x49, 0x45, 0xfb, 0xb0, 0xf1, 0x36, 0x4c, 0x7c, 0xf6,
|
||||
0x56, 0xd6, 0x68, 0xcd, 0x25, 0x2f, 0x8c, 0xe9, 0x0f, 0x92, 0x81, 0x35, 0x13, 0x1d, 0x40, 0x2b,
|
||||
0xc8, 0x58, 0x91, 0x1e, 0xde, 0xca, 0xba, 0xf5, 0xde, 0x6d, 0xe6, 0x38, 0x08, 0x32, 0x1a, 0xc8,
|
||||
0x4d, 0xe1, 0xdd, 0xa6, 0x14, 0x97, 0x7c, 0x31, 0x46, 0xd7, 0x61, 0xc4, 0x69, 0x76, 0xa8, 0x4a,
|
||||
0xfa, 0x3f, 0xc6, 0xa8, 0xe4, 0xcb, 0x86, 0x15, 0x71, 0x4c, 0xb2, 0xf0, 0x37, 0x2a, 0xcb, 0xdd,
|
||||
0xc6, 0x0b, 0xc0, 0x6e, 0x41, 0xd3, 0x89, 0x53, 0x7e, 0x6b, 0xbf, 0x86, 0xee, 0x2b, 0x9a, 0xe5,
|
||||
0x21, 0x4b, 0x8e, 0x93, 0x6b, 0x26, 0x6e, 0x05, 0x4c, 0x03, 0xe5, 0xa0, 0x54, 0x80, 0xf0, 0x5e,
|
||||
0x15, 0x61, 0xe4, 0x1f, 0x11, 0x4e, 0xf5, 0x94, 0x2c, 0x00, 0xf4, 0x25, 0xf4, 0x32, 0x1a, 0x51,
|
||||
0x92, 0xd3, 0x52, 0x40, 0xcd, 0xc9, 0x0a, 0x6a, 0x7f, 0x07, 0xd6, 0x49, 0x98, 0x8b, 0xc9, 0xcb,
|
||||
0xab, 0xc6, 0x7e, 0x05, 0x8d, 0x94, 0xf9, 0x65, 0x57, 0xef, 0xaf, 0x66, 0xe9, 0x32, 0x1f, 0x4b,
|
||||
0x82, 0xfd, 0x57, 0x1d, 0x4c, 0x31, 0x71, 0x68, 0xe9, 0x45, 0x76, 0xf4, 0xab, 0x7b, 0x00, 0xcd,
|
||||
0x94, 0xf9, 0xc7, 0xae, 0x0e, 0x4d, 0x19, 0x68, 0x1b, 0xc0, 0x97, 0x13, 0x18, 0x8b, 0xc1, 0x53,
|
||||
0x21, 0x2d, 0x21, 0xe8, 0x21, 0x6c, 0xe4, 0x9c, 0xf0, 0x22, 0xd7, 0x53, 0xab, 0x2d, 0xa1, 0x46,
|
||||
0x7c, 0x9f, 0xfa, 0xba, 0x78, 0xca, 0x40, 0x13, 0xb8, 0x97, 0x87, 0xc9, 0x9c, 0x9e, 0x90, 0x9c,
|
||||
0x63, 0x9a, 0xb2, 0x8c, 0xcb, 0x91, 0x15, 0xdb, 0x4c, 0x6d, 0xff, 0x51, 0xb9, 0xfd, 0x47, 0x47,
|
||||
0x7a, 0xfb, 0xe3, 0xd5, 0x1b, 0xe8, 0x31, 0xdc, 0x9f, 0xb3, 0x84, 0x67, 0x2c, 0x8a, 0x68, 0x26,
|
||||
0x26, 0x2c, 0x4f, 0xc9, 0x9c, 0xf6, 0x5b, 0xf2, 0xfb, 0xeb, 0x5c, 0xe2, 0x81, 0x69, 0xd8, 0x8d,
|
||||
0x48, 0x42, 0xfb, 0x6d, 0x19, 0xd3, 0x1d, 0xcc, 0xfe, 0xbb, 0x0e, 0xe0, 0x91, 0xb4, 0x9c, 0x70,
|
||||
0x04, 0x66, 0x5a, 0xbe, 0xf6, 0x69, 0x0d, 0x0b, 0x03, 0x0d, 0xef, 0xd4, 0xa2, 0xae, 0x5d, 0x2b,
|
||||
0xd5, 0x88, 0xc9, 0xaf, 0x38, 0xcd, 0x65, 0xa5, 0xea, 0x58, 0x5b, 0x02, 0xe7, 0xcc, 0x15, 0xe9,
|
||||
0x8a, 0x2a, 0x6d, 0x61, 0x6d, 0x89, 0x3e, 0x70, 0x76, 0xec, 0xea, 0x07, 0x2d, 0xcf, 0x68, 0x00,
|
||||
0xed, 0xeb, 0x8c, 0xc5, 0x6e, 0x59, 0x9c, 0x2d, 0x5c, 0xd9, 0x42, 0x47, 0x9c, 0x8f, 0x5d, 0x9d,
|
||||
0xad, 0xb6, 0x64, 0x17, 0xe6, 0x37, 0x34, 0x56, 0xa9, 0x89, 0x2e, 0x48, 0x4b, 0xc6, 0x43, 0xf9,
|
||||
0x0d, 0xf3, 0xfb, 0x1d, 0x85, 0x2b, 0x4b, 0x8c, 0x22, 0x29, 0xf8, 0x0d, 0xcb, 0x42, 0x7e, 0xdb,
|
||||
0x07, 0x35, 0x8a, 0x15, 0x50, 0x6d, 0x93, 0xee, 0x62, 0x9b, 0x1c, 0xb6, 0x61, 0x43, 0x6d, 0x34,
|
||||
0x7b, 0x08, 0xed, 0x71, 0x1a, 0x3a, 0x59, 0xc6, 0x32, 0xd1, 0x65, 0x2a, 0x0e, 0x7a, 0x90, 0x94,
|
||||
0xb1, 0xfb, 0x1c, 0x60, 0xf1, 0xfc, 0x91, 0x05, 0x9b, 0xd8, 0xf9, 0xfe, 0xc2, 0x99, 0x79, 0x97,
|
||||
0x78, 0xec, 0x39, 0x56, 0x0d, 0x75, 0xa1, 0x75, 0x32, 0xf6, 0x9c, 0xb3, 0xc9, 0x4f, 0x96, 0x21,
|
||||
0xdc, 0xb3, 0x8b, 0xc9, 0xc4, 0x99, 0xcd, 0x94, 0xbb, 0xbe, 0x3b, 0x06, 0x58, 0x2c, 0x02, 0x41,
|
||||
0xf6, 0x9c, 0xb3, 0xcb, 0x99, 0x33, 0x51, 0x37, 0xcf, 0xcf, 0x9c, 0xcb, 0xd3, 0xe3, 0x33, 0xcb,
|
||||
0x28, 0x3d, 0xc2, 0xa8, 0xa3, 0x4d, 0x68, 0x0b, 0xcf, 0xf4, 0xfc, 0x02, 0x5b, 0xe6, 0xee, 0x2f,
|
||||
0x70, 0x6f, 0x65, 0x2d, 0xa0, 0x1e, 0x80, 0x37, 0xc6, 0x2f, 0x1d, 0xef, 0xd2, 0x3d, 0x3f, 0xb2,
|
||||
0x6a, 0xe8, 0x23, 0xd8, 0xd2, 0xf6, 0x91, 0xe3, 0x9e, 0x9c, 0x8b, 0x50, 0x7a, 0x00, 0xb3, 0xf3,
|
||||
0x0b, 0x3c, 0x71, 0x24, 0xa5, 0x2e, 0x28, 0xda, 0xd6, 0x14, 0x13, 0xb5, 0xa1, 0x71, 0xea, 0xcc,
|
||||
0xa6, 0x56, 0x43, 0x9c, 0xdc, 0xb1, 0x37, 0xb5, 0x9a, 0xbb, 0xcf, 0x97, 0x7e, 0x83, 0xc8, 0x1f,
|
||||
0x15, 0xa8, 0x05, 0xa6, 0x88, 0xaa, 0x26, 0x0e, 0xee, 0xd3, 0xc7, 0x96, 0x21, 0x0f, 0x07, 0x4f,
|
||||
0xad, 0xba, 0x3a, 0x1c, 0x58, 0xa6, 0xe4, 0x8c, 0x7f, 0xb4, 0x1a, 0xfb, 0x7f, 0xd6, 0xc1, 0x1c,
|
||||
0xa7, 0x21, 0x7a, 0x09, 0x8d, 0x19, 0x27, 0x1c, 0x7d, 0xb6, 0x7e, 0x49, 0xe9, 0xc1, 0x1c, 0x6c,
|
||||
0xbf, 0xcf, 0xad, 0x76, 0x81, 0x5d, 0x43, 0x2f, 0xa0, 0x55, 0xae, 0x9c, 0x8f, 0x57, 0xc9, 0x72,
|
||||
0x6d, 0x0d, 0xde, 0xf9, 0x47, 0xbf, 0xb4, 0xc4, 0xec, 0x1a, 0x72, 0xa0, 0x5d, 0xae, 0x98, 0xf7,
|
||||
0x29, 0x0c, 0x57, 0xe1, 0xd5, 0x9d, 0x24, 0xe3, 0x30, 0x3d, 0x92, 0xa2, 0x77, 0xb7, 0x7c, 0xf5,
|
||||
0xca, 0x06, 0xfd, 0xca, 0xa7, 0x7f, 0xd5, 0x79, 0x24, 0x75, 0xde, 0xd0, 0x84, 0xdb, 0xb5, 0xc7,
|
||||
0xc6, 0xd5, 0x86, 0x5c, 0x06, 0xdf, 0xfc, 0x17, 0x00, 0x00, 0xff, 0xff, 0x94, 0xcb, 0xaa, 0x8d,
|
||||
0x3c, 0x0a, 0x00, 0x00,
|
||||
0x14, 0x15, 0x45, 0xc9, 0x92, 0xae, 0x6c, 0x85, 0x9d, 0xa4, 0x81, 0xaa, 0xa6, 0xae, 0xc2, 0x45,
|
||||
0x6b, 0x78, 0x21, 0xa7, 0x6e, 0x12, 0xc0, 0x2d, 0x82, 0x40, 0x96, 0x89, 0xc8, 0x80, 0x1f, 0xea,
|
||||
0x48, 0x4e, 0x5b, 0xa0, 0x80, 0x31, 0x26, 0xc7, 0x34, 0x11, 0x92, 0xc3, 0x90, 0xc3, 0xa4, 0xee,
|
||||
0xbe, 0xdb, 0xae, 0xfb, 0x05, 0xfd, 0x89, 0xee, 0xfb, 0x33, 0xfd, 0x89, 0x62, 0x1e, 0xa4, 0x1e,
|
||||
0x51, 0x8c, 0xae, 0x3c, 0xf7, 0xdc, 0x33, 0x87, 0xf7, 0x35, 0xd7, 0x02, 0x2b, 0xc9, 0xaf, 0xc2,
|
||||
0xc0, 0xdd, 0x23, 0x49, 0x30, 0x48, 0x52, 0xc6, 0x19, 0xea, 0xb8, 0x2c, 0xf6, 0xf2, 0x80, 0x0f,
|
||||
0x94, 0xa7, 0xb7, 0xed, 0x33, 0xe6, 0x87, 0x74, 0x4f, 0x7a, 0xaf, 0xf2, 0xeb, 0x3d, 0x2f, 0x4f,
|
||||
0x09, 0x0f, 0x58, 0xac, 0xf8, 0xbd, 0xfb, 0x2e, 0x8b, 0x22, 0x16, 0xef, 0xa9, 0x3f, 0x0a, 0xb4,
|
||||
0x7f, 0x81, 0xce, 0x38, 0xc8, 0x38, 0xf3, 0x53, 0x12, 0xbd, 0x26, 0x61, 0x4e, 0xd1, 0x53, 0xa8,
|
||||
0x87, 0xe4, 0x8a, 0x86, 0x5d, 0xa3, 0x6f, 0xec, 0x74, 0xf6, 0xb7, 0x07, 0xcb, 0x9f, 0x19, 0x94,
|
||||
0xf4, 0x13, 0xc1, 0xc2, 0x8a, 0x8c, 0x1e, 0x40, 0xfd, 0x9d, 0xb8, 0xde, 0xad, 0xf6, 0x8d, 0x1d,
|
||||
0x13, 0x2b, 0xc3, 0x1e, 0x41, 0xab, 0xa4, 0xa3, 0xe7, 0xb0, 0x21, 0xd1, 0xac, 0x6b, 0xf4, 0xcd,
|
||||
0x9d, 0xf6, 0x1d, 0xca, 0x32, 0x10, 0xac, 0xd9, 0xf6, 0xef, 0x06, 0xb4, 0x4f, 0x29, 0x4f, 0x03,
|
||||
0x57, 0x05, 0xd8, 0x83, 0x86, 0xcb, 0xf2, 0x98, 0xd3, 0x54, 0x86, 0x68, 0x8e, 0x2b, 0xb8, 0x00,
|
||||
0xd0, 0x43, 0xa8, 0xfb, 0x24, 0xf7, 0x55, 0x18, 0xc6, 0xb8, 0x82, 0x95, 0x89, 0x0e, 0xa0, 0x75,
|
||||
0x53, 0xa8, 0x77, 0xcd, 0xbe, 0xb1, 0xd3, 0xde, 0xff, 0xec, 0xa3, 0x9f, 0x1f, 0x57, 0xf0, 0x9c,
|
||||
0x7d, 0xd8, 0xd0, 0x99, 0xd9, 0x3e, 0xdc, 0x53, 0x61, 0x1c, 0x11, 0x4e, 0x12, 0x16, 0xc4, 0x1c,
|
||||
0x7d, 0x53, 0x64, 0x6d, 0x48, 0xc9, 0xcf, 0x57, 0x25, 0x17, 0xc2, 0xd6, 0x25, 0x41, 0x8f, 0x61,
|
||||
0x93, 0x07, 0x11, 0xcd, 0x38, 0x89, 0x92, 0xcb, 0x28, 0xd3, 0xf5, 0x6a, 0x97, 0xd8, 0x69, 0x66,
|
||||
0xff, 0x6d, 0xc0, 0xa6, 0xba, 0x39, 0xa5, 0x69, 0x40, 0x33, 0x34, 0x80, 0x5a, 0x4c, 0x22, 0xaa,
|
||||
0x3b, 0xd2, 0x5b, 0xff, 0x95, 0x33, 0x12, 0x51, 0x2c, 0x79, 0xe8, 0x3b, 0x68, 0x46, 0x94, 0x13,
|
||||
0x8f, 0x70, 0x22, 0xf5, 0xd7, 0xd4, 0x5a, 0xdd, 0x39, 0xd5, 0x2c, 0x5c, 0xf2, 0xd1, 0x4b, 0x00,
|
||||
0xaf, 0xc8, 0x2f, 0xeb, 0x9a, 0xb2, 0x53, 0x5f, 0xae, 0xbf, 0x5d, 0xd6, 0x01, 0x2f, 0x5c, 0xb1,
|
||||
0xff, 0x31, 0xa0, 0xb3, 0xac, 0x8e, 0x1e, 0x41, 0x8b, 0x93, 0xd4, 0xa7, 0x7c, 0xc2, 0x3c, 0x99,
|
||||
0x44, 0x0b, 0xcf, 0x01, 0x64, 0xc3, 0xa6, 0x32, 0x8e, 0x68, 0x12, 0xb2, 0x5b, 0x19, 0x71, 0x0b,
|
||||
0x2f, 0x61, 0x42, 0x21, 0x63, 0x79, 0xea, 0x52, 0xa1, 0x60, 0x2a, 0x85, 0x12, 0x10, 0x0a, 0xca,
|
||||
0xd0, 0x0a, 0x35, 0xa5, 0xb0, 0x88, 0x09, 0x05, 0x97, 0x45, 0x09, 0x8b, 0x69, 0xcc, 0xbb, 0x75,
|
||||
0xa5, 0x50, 0x02, 0x08, 0x41, 0x2d, 0x21, 0xfc, 0xa6, 0xbb, 0x21, 0x1d, 0xf2, 0x6c, 0x8f, 0x8b,
|
||||
0x3c, 0x30, 0xcd, 0x12, 0x16, 0x67, 0x14, 0x3d, 0x87, 0x46, 0x24, 0x91, 0x62, 0x84, 0x1f, 0xad,
|
||||
0x2f, 0x8c, 0x6a, 0x1b, 0x2e, 0xc8, 0xf6, 0x1f, 0x55, 0xd8, 0x2a, 0xa4, 0xde, 0xe6, 0x34, 0xe3,
|
||||
0xe8, 0xe9, 0xb2, 0xd2, 0xdd, 0x4d, 0x2d, 0xa8, 0x68, 0x1f, 0x36, 0xde, 0x07, 0xb1, 0xc7, 0xde,
|
||||
0xcb, 0x1a, 0xad, 0xb9, 0x34, 0x0b, 0x22, 0xfa, 0xa3, 0x64, 0x60, 0xcd, 0x44, 0x07, 0xd0, 0xf0,
|
||||
0x53, 0x96, 0x27, 0x87, 0xb7, 0xb2, 0x6e, 0x9d, 0x0f, 0x9b, 0x39, 0xf4, 0xfd, 0x94, 0xfa, 0x72,
|
||||
0x53, 0xcc, 0x6e, 0x13, 0x8a, 0x0b, 0xbe, 0x18, 0xa3, 0xeb, 0x20, 0xe4, 0x34, 0x3d, 0x54, 0x25,
|
||||
0xfd, 0x1f, 0x63, 0x54, 0xf0, 0x65, 0xc3, 0xf2, 0x28, 0x22, 0x69, 0xf0, 0x1b, 0x95, 0xe5, 0x6e,
|
||||
0xe2, 0x39, 0x60, 0x37, 0xa0, 0xee, 0x44, 0x09, 0xbf, 0xb5, 0xdf, 0x42, 0xfb, 0x35, 0x4d, 0xb3,
|
||||
0x80, 0xc5, 0xc7, 0xf1, 0x35, 0x13, 0xb7, 0x7c, 0xa6, 0x81, 0x62, 0x50, 0x4a, 0x40, 0x78, 0xaf,
|
||||
0xf2, 0x20, 0xf4, 0x8e, 0x08, 0xa7, 0x7a, 0x4a, 0xe6, 0x00, 0xfa, 0x0a, 0x3a, 0x29, 0x0d, 0x29,
|
||||
0xc9, 0x68, 0x21, 0xa0, 0xe6, 0x64, 0x05, 0xb5, 0xbf, 0x07, 0xeb, 0x24, 0xc8, 0xc4, 0xe4, 0x65,
|
||||
0x65, 0x63, 0xbf, 0x86, 0x5a, 0xc2, 0xbc, 0xa2, 0xab, 0xf7, 0x57, 0xb3, 0x9c, 0x30, 0x0f, 0x4b,
|
||||
0x82, 0xfd, 0x67, 0x15, 0x4c, 0x31, 0x71, 0x68, 0xe1, 0x45, 0xb6, 0xf4, 0xab, 0x7b, 0x00, 0xf5,
|
||||
0x84, 0x79, 0xc7, 0x13, 0x1d, 0x9a, 0x32, 0xd0, 0x36, 0x80, 0x27, 0x27, 0x30, 0x12, 0x83, 0xa7,
|
||||
0x42, 0x5a, 0x40, 0xd0, 0x43, 0xd8, 0xc8, 0x38, 0xe1, 0x79, 0xa6, 0xa7, 0x56, 0x5b, 0x42, 0x8d,
|
||||
0x78, 0x1e, 0xf5, 0x74, 0xf1, 0x94, 0x81, 0x46, 0x70, 0x2f, 0x0b, 0x62, 0x97, 0x9e, 0x90, 0x8c,
|
||||
0x63, 0x9a, 0xb0, 0x94, 0xcb, 0x91, 0x15, 0xdb, 0x4c, 0x6d, 0xff, 0x41, 0xb1, 0xfd, 0x07, 0x47,
|
||||
0x7a, 0xfb, 0xe3, 0xd5, 0x1b, 0xe8, 0x09, 0xdc, 0x77, 0x59, 0xcc, 0x53, 0x16, 0x86, 0x34, 0x15,
|
||||
0x13, 0x96, 0x25, 0xc4, 0xa5, 0xdd, 0x86, 0xfc, 0xfe, 0x3a, 0x97, 0x78, 0x60, 0x1a, 0x9e, 0x84,
|
||||
0x24, 0xa6, 0xdd, 0xa6, 0x8c, 0x69, 0x09, 0xb3, 0xff, 0xaa, 0x02, 0xcc, 0x48, 0x52, 0x4c, 0x38,
|
||||
0x02, 0x33, 0x29, 0x5e, 0xfb, 0xb8, 0x82, 0x85, 0x81, 0xfa, 0x4b, 0xb5, 0xa8, 0x6a, 0xd7, 0x4a,
|
||||
0x35, 0x22, 0xf2, 0x2b, 0x4e, 0x32, 0x59, 0xa9, 0x2a, 0xd6, 0x96, 0xc0, 0x39, 0x9b, 0x88, 0x74,
|
||||
0x45, 0x95, 0xb6, 0xb0, 0xb6, 0x44, 0x1f, 0x38, 0x3b, 0x9e, 0xe8, 0x07, 0x2d, 0xcf, 0xa8, 0x07,
|
||||
0xcd, 0xeb, 0x94, 0x45, 0x93, 0xa2, 0x38, 0x5b, 0xb8, 0xb4, 0x85, 0x8e, 0x38, 0x1f, 0x4f, 0x74,
|
||||
0xb6, 0xda, 0x92, 0x5d, 0x70, 0x6f, 0x68, 0xa4, 0x52, 0x13, 0x5d, 0x90, 0x96, 0x8c, 0x87, 0xf2,
|
||||
0x1b, 0xe6, 0x75, 0x5b, 0x0a, 0x57, 0x96, 0x18, 0x45, 0x92, 0xf3, 0x1b, 0x96, 0x06, 0xfc, 0xb6,
|
||||
0x0b, 0x6a, 0x14, 0x4b, 0xa0, 0xdc, 0x26, 0xed, 0xf9, 0x36, 0x39, 0x6c, 0xc2, 0x86, 0xda, 0x68,
|
||||
0x76, 0x1f, 0x9a, 0xc3, 0x24, 0x70, 0xd2, 0x94, 0xa5, 0xa2, 0xcb, 0x54, 0x1c, 0xf4, 0x20, 0x29,
|
||||
0x63, 0xf7, 0x05, 0xc0, 0xfc, 0xf9, 0x23, 0x0b, 0x36, 0xb1, 0xf3, 0xc3, 0x85, 0x33, 0x9d, 0x5d,
|
||||
0xe2, 0xe1, 0xcc, 0xb1, 0x2a, 0xa8, 0x0d, 0x8d, 0x93, 0xe1, 0xcc, 0x39, 0x1b, 0xfd, 0x6c, 0x19,
|
||||
0xc2, 0x3d, 0xbd, 0x18, 0x8d, 0x9c, 0xe9, 0x54, 0xb9, 0xab, 0xbb, 0x43, 0x80, 0xf9, 0x22, 0x10,
|
||||
0xe4, 0x99, 0x73, 0x76, 0x39, 0x75, 0x46, 0xea, 0xe6, 0xf9, 0x99, 0x73, 0x79, 0x7a, 0x7c, 0x66,
|
||||
0x19, 0x85, 0x47, 0x18, 0x55, 0xb4, 0x09, 0x4d, 0xe1, 0x19, 0x9f, 0x5f, 0x60, 0xcb, 0xdc, 0x7d,
|
||||
0x03, 0xf7, 0x56, 0xd6, 0x02, 0xea, 0x00, 0xcc, 0x86, 0xf8, 0x95, 0x33, 0xbb, 0x9c, 0x9c, 0x1f,
|
||||
0x59, 0x15, 0xf4, 0x09, 0x6c, 0x69, 0xfb, 0xc8, 0x99, 0x9c, 0x9c, 0x8b, 0x50, 0x3a, 0x00, 0xd3,
|
||||
0xf3, 0x0b, 0x3c, 0x72, 0x24, 0xa5, 0x2a, 0x28, 0xda, 0xd6, 0x14, 0x13, 0x35, 0xa1, 0x76, 0xea,
|
||||
0x4c, 0xc7, 0x56, 0x4d, 0x9c, 0x26, 0xc3, 0xd9, 0xd8, 0xaa, 0xef, 0xbe, 0x58, 0xf8, 0x0d, 0x22,
|
||||
0x7f, 0x54, 0xa0, 0x06, 0x98, 0x22, 0xaa, 0x8a, 0x38, 0x4c, 0x9e, 0x3d, 0xb1, 0x0c, 0x79, 0x38,
|
||||
0x78, 0x66, 0x55, 0xd5, 0xe1, 0xc0, 0x32, 0x25, 0x67, 0xf8, 0x93, 0x55, 0xdb, 0xff, 0xb7, 0x0a,
|
||||
0xe6, 0x30, 0x09, 0xd0, 0x2b, 0xa8, 0x4d, 0x39, 0xe1, 0xe8, 0x8b, 0xf5, 0x4b, 0x4a, 0x0f, 0x66,
|
||||
0x6f, 0xfb, 0x63, 0x6e, 0xb5, 0x0b, 0xec, 0x0a, 0x7a, 0x09, 0x8d, 0x62, 0xe5, 0x7c, 0xba, 0x4a,
|
||||
0x96, 0x6b, 0xab, 0xf7, 0xc1, 0x3f, 0xfa, 0x85, 0x25, 0x66, 0x57, 0x90, 0x03, 0xcd, 0x62, 0xc5,
|
||||
0x7c, 0x4c, 0xa1, 0xbf, 0x0a, 0xaf, 0xee, 0x24, 0xbb, 0x82, 0x30, 0xb4, 0xa6, 0x34, 0xbc, 0x1e,
|
||||
0xdd, 0x50, 0xf7, 0x0d, 0x9a, 0x5f, 0xd0, 0xbf, 0xdf, 0x4a, 0x57, 0x91, 0xd8, 0xe3, 0x3b, 0x18,
|
||||
0x0b, 0xb9, 0x99, 0x33, 0x92, 0xa0, 0x0f, 0xff, 0x73, 0x94, 0x2f, 0xb7, 0xd7, 0x5d, 0xd5, 0x99,
|
||||
0x91, 0xc4, 0x79, 0x47, 0x63, 0x6e, 0x57, 0x9e, 0x18, 0x57, 0x1b, 0x72, 0xc1, 0x7c, 0xfb, 0x5f,
|
||||
0x00, 0x00, 0x00, 0xff, 0xff, 0x70, 0x89, 0x4d, 0xe0, 0x90, 0x0a, 0x00, 0x00,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,68 @@
|
|||
package healthcheck
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
pb "github.com/runconduit/conduit/controller/gen/common"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
type grpcStatusChecker interface {
|
||||
SelfCheck(ctx context.Context, in *pb.SelfCheckRequest, opts ...grpc.CallOption) (*pb.SelfCheckResponse, error)
|
||||
}
|
||||
|
||||
type statusCheckerProxy struct {
|
||||
delegate grpcStatusChecker
|
||||
prefix string
|
||||
}
|
||||
|
||||
func (proxy *statusCheckerProxy) SelfCheck() ([]CheckResult, error) {
|
||||
translatedResults := make([]CheckResult, 0)
|
||||
|
||||
canConnectViaGrpcCheck := CheckResult{
|
||||
SubsystemName: proxy.prefix,
|
||||
CheckDescription: "can retrieve status via gRPC",
|
||||
Status: CheckError,
|
||||
}
|
||||
selfCheckResponse, err := proxy.delegate.SelfCheck(context.Background(), &pb.SelfCheckRequest{})
|
||||
if err != nil {
|
||||
canConnectViaGrpcCheck.Status = CheckError
|
||||
canConnectViaGrpcCheck.FriendlyMessageToUser = err.Error()
|
||||
} else {
|
||||
canConnectViaGrpcCheck.Status = CheckOk
|
||||
|
||||
for _, check := range selfCheckResponse.Results {
|
||||
fullSubsystemName := fmt.Sprintf("%s[%s]", proxy.prefix, check.SubsystemName)
|
||||
|
||||
var status CheckStatus
|
||||
|
||||
switch CheckStatus(check.Status) {
|
||||
case CheckOk, CheckFailed, CheckError:
|
||||
status = CheckStatus(check.Status)
|
||||
default:
|
||||
status = CheckError
|
||||
}
|
||||
|
||||
translatedResults = append(translatedResults, CheckResult{
|
||||
SubsystemName: fullSubsystemName,
|
||||
CheckDescription: check.CheckDescription,
|
||||
Status: status,
|
||||
FriendlyMessageToUser: check.FriendlyMessageToUser,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
subsystemResults := []CheckResult{
|
||||
canConnectViaGrpcCheck,
|
||||
}
|
||||
subsystemResults = append(subsystemResults, translatedResults...)
|
||||
return subsystemResults, nil
|
||||
}
|
||||
|
||||
func NewGrpcStatusChecker(name string, grpClient grpcStatusChecker) StatusChecker {
|
||||
return &statusCheckerProxy{
|
||||
prefix: name,
|
||||
delegate: grpClient,
|
||||
}
|
||||
}
|
||||
|
|
@ -11,10 +11,10 @@ const (
|
|||
)
|
||||
|
||||
type CheckResult struct {
|
||||
SubsystemName string
|
||||
CheckDescription string
|
||||
Status CheckStatus
|
||||
NextSteps string
|
||||
SubsystemName string
|
||||
CheckDescription string
|
||||
Status CheckStatus
|
||||
FriendlyMessageToUser string
|
||||
}
|
||||
|
||||
type Check struct {
|
||||
|
|
@ -49,7 +49,7 @@ func (hC *HealthChecker) PerformCheck(observer CheckObserver) Check {
|
|||
for _, checker := range hC.subsystemsToCheck {
|
||||
results, err := checker.SelfCheck()
|
||||
if err != nil {
|
||||
log.Errorf("Error checking [%s]: %s", checker, err)
|
||||
log.Errorf("Error checking [%s]: %s", checker, err.Error())
|
||||
check.OverallStatus = CheckError
|
||||
continue
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ func (kubeapi *kubernetesApi) SelfCheck() ([]healthcheck.CheckResult, error) {
|
|||
client, err := kubeapi.NewClient()
|
||||
if err != nil {
|
||||
apiConnectivityCheck.Status = healthcheck.CheckError
|
||||
apiConnectivityCheck.NextSteps = fmt.Sprintf("Error connecting to the API. Error message is [%s]", err.Error())
|
||||
apiConnectivityCheck.FriendlyMessageToUser = fmt.Sprintf("Error connecting to the API. Error message is [%s]", err.Error())
|
||||
} else {
|
||||
apiConnectivityCheck.Status = healthcheck.CheckOk
|
||||
}
|
||||
|
|
@ -65,13 +65,13 @@ func (kubeapi *kubernetesApi) SelfCheck() ([]healthcheck.CheckResult, error) {
|
|||
endpointToCheck, err := generateBaseKubernetesApiUrl(kubeapi.apiSchemeHostAndPort)
|
||||
if err != nil {
|
||||
apiAccessCheck.Status = healthcheck.CheckError
|
||||
apiAccessCheck.NextSteps = fmt.Sprintf("Error querying Kubernetes API. Configured host is [%s], error message is [%s]", kubeapi.apiSchemeHostAndPort, err.Error())
|
||||
apiAccessCheck.FriendlyMessageToUser = fmt.Sprintf("Error querying Kubernetes API. Configured host is [%s], error message is [%s]", kubeapi.apiSchemeHostAndPort, err.Error())
|
||||
} else {
|
||||
if client != nil {
|
||||
resp, err := client.Get(endpointToCheck.String())
|
||||
if err != nil {
|
||||
apiAccessCheck.Status = healthcheck.CheckError
|
||||
apiAccessCheck.NextSteps = fmt.Sprintf("HTTP GET request to endpoint [%s] resulted in error: [%s]", endpointToCheck, err.Error())
|
||||
apiAccessCheck.FriendlyMessageToUser = fmt.Sprintf("HTTP GET request to endpoint [%s] resulted in error: [%s]", endpointToCheck, err.Error())
|
||||
} else {
|
||||
statusCodeReturnedIsWithinSuccessRange := resp.StatusCode < 400
|
||||
if statusCodeReturnedIsWithinSuccessRange {
|
||||
|
|
@ -80,12 +80,12 @@ func (kubeapi *kubernetesApi) SelfCheck() ([]healthcheck.CheckResult, error) {
|
|||
bytes, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
apiAccessCheck.Status = healthcheck.CheckError
|
||||
apiAccessCheck.NextSteps = fmt.Sprintf("HTTP GET request to endpoint [%s] resulted in invalid response: [%v]", endpointToCheck, resp)
|
||||
apiAccessCheck.FriendlyMessageToUser = fmt.Sprintf("HTTP GET request to endpoint [%s] resulted in invalid response: [%v]", endpointToCheck, resp)
|
||||
} else {
|
||||
body := string(bytes)
|
||||
|
||||
apiAccessCheck.Status = healthcheck.CheckFailed
|
||||
apiAccessCheck.NextSteps = fmt.Sprintf("HTTP GET request to endpoint [%s] resulted in Status: [%s], body: [%s]", endpointToCheck, resp.Status, body)
|
||||
apiAccessCheck.FriendlyMessageToUser = fmt.Sprintf("HTTP GET request to endpoint [%s] resulted in Status: [%s], body: [%s]", endpointToCheck, resp.Status, body)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ func (kctl *kubectl) SelfCheck() ([]healthcheck.CheckResult, error) {
|
|||
_, err := kctl.sh.CombinedOutput("kubectl", "config")
|
||||
if err != nil {
|
||||
kubectlOnPathCheck.Status = healthcheck.CheckFailed
|
||||
kubectlOnPathCheck.NextSteps = fmt.Sprintf("Could not run the command `kubectl`. The error message is: [%s] and the current $PATH is: %s", err.Error(), kctl.sh.Path())
|
||||
kubectlOnPathCheck.FriendlyMessageToUser = fmt.Sprintf("Could not run the command `kubectl`. The error message is: [%s] and the current $PATH is: %s", err.Error(), kctl.sh.Path())
|
||||
} else {
|
||||
kubectlOnPathCheck.Status = healthcheck.CheckOk
|
||||
}
|
||||
|
|
@ -134,13 +134,13 @@ func (kctl *kubectl) SelfCheck() ([]healthcheck.CheckResult, error) {
|
|||
actualVersion, err := kctl.Version()
|
||||
if err != nil {
|
||||
kubectlVersionCheck.Status = healthcheck.CheckError
|
||||
kubectlVersionCheck.NextSteps = fmt.Sprintf("Error getting version from kubectl. The error message is: [%s].", err.Error())
|
||||
kubectlVersionCheck.FriendlyMessageToUser = fmt.Sprintf("Error getting version from kubectl. The error message is: [%s].", err.Error())
|
||||
} else {
|
||||
if isCompatibleVersion(minimumKubectlVersionExpected, actualVersion) {
|
||||
kubectlVersionCheck.Status = healthcheck.CheckOk
|
||||
} else {
|
||||
kubectlVersionCheck.Status = healthcheck.CheckFailed
|
||||
kubectlVersionCheck.NextSteps = fmt.Sprintf("Kubectl is on version [%d.%d.%d], but version [%d.%d.%d] or more recent is required.",
|
||||
kubectlVersionCheck.FriendlyMessageToUser = fmt.Sprintf("Kubectl is on version [%d.%d.%d], but version [%d.%d.%d] or more recent is required.",
|
||||
actualVersion[0], actualVersion[1], actualVersion[2],
|
||||
minimumKubectlVersionExpected[0], minimumKubectlVersionExpected[1], minimumKubectlVersionExpected[2])
|
||||
}
|
||||
|
|
@ -154,7 +154,7 @@ func (kctl *kubectl) SelfCheck() ([]healthcheck.CheckResult, error) {
|
|||
output, err := kctl.sh.CombinedOutput("kubectl", "get", "pods")
|
||||
if err != nil {
|
||||
kubectlApiAccessCheck.Status = healthcheck.CheckFailed
|
||||
kubectlApiAccessCheck.NextSteps = output
|
||||
kubectlApiAccessCheck.FriendlyMessageToUser = output
|
||||
} else {
|
||||
kubectlApiAccessCheck.Status = healthcheck.CheckOk
|
||||
}
|
||||
|
|
|
|||
|
|
@ -112,4 +112,17 @@ message TapEvent {
|
|||
enum Protocol {
|
||||
HTTP = 0;
|
||||
TCP = 1;
|
||||
}
|
||||
}
|
||||
|
||||
message CheckResult {
|
||||
string SubsystemName = 1;
|
||||
string CheckDescription = 2;
|
||||
string Status = 3;
|
||||
string FriendlyMessageToUser = 4;
|
||||
}
|
||||
|
||||
message SelfCheckRequest {}
|
||||
|
||||
message SelfCheckResponse {
|
||||
repeated CheckResult results = 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -133,5 +133,6 @@ service Api {
|
|||
rpc Stat(MetricRequest) returns (MetricResponse) {}
|
||||
rpc Version(Empty) returns (VersionInfo) {}
|
||||
rpc ListPods(Empty) returns (ListPodsResponse) {}
|
||||
rpc SelfCheck(common.SelfCheckRequest) returns (common.SelfCheckResponse) {}
|
||||
rpc Tap(TapRequest) returns (stream common.TapEvent) {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,10 +9,18 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/julienschmidt/httprouter"
|
||||
"github.com/runconduit/conduit/controller/api/public"
|
||||
pb "github.com/runconduit/conduit/controller/gen/public"
|
||||
)
|
||||
|
||||
func TestHandleApiVersion(t *testing.T) {
|
||||
var mockApiClient MockApiClient
|
||||
mockApiClient := &public.MockConduitApiClient{
|
||||
VersionInfoToReturn: &pb.VersionInfo{
|
||||
GoVersion: "the best one",
|
||||
BuildDate: "never",
|
||||
ReleaseVersion: "0.3.3",
|
||||
},
|
||||
}
|
||||
server := FakeServer()
|
||||
|
||||
handler := &handler{
|
||||
|
|
@ -48,7 +56,9 @@ func TestHandleApiVersion(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestHandleApiMetrics(t *testing.T) {
|
||||
var mockApiClient MockApiClient
|
||||
mockApiClient := &public.MockConduitApiClient{
|
||||
MetricResponseToReturn: &pb.MetricResponse{},
|
||||
}
|
||||
server := FakeServer()
|
||||
|
||||
handler := &handler{
|
||||
|
|
|
|||
|
|
@ -8,10 +8,19 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/julienschmidt/httprouter"
|
||||
"github.com/runconduit/conduit/controller/api/public"
|
||||
pb "github.com/runconduit/conduit/controller/gen/public"
|
||||
)
|
||||
|
||||
func TestHandleIndex(t *testing.T) {
|
||||
var mockApiClient MockApiClient
|
||||
mockApiClient := &public.MockConduitApiClient{
|
||||
VersionInfoToReturn: &pb.VersionInfo{
|
||||
GoVersion: "the best one",
|
||||
BuildDate: "never",
|
||||
ReleaseVersion: "0.3.3",
|
||||
},
|
||||
}
|
||||
|
||||
server := FakeServer()
|
||||
|
||||
handler := &handler{
|
||||
|
|
|
|||
|
|
@ -1,33 +1,5 @@
|
|||
package srv
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
pb "github.com/runconduit/conduit/controller/gen/public"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
type MockApiClient struct{}
|
||||
|
||||
func (m MockApiClient) Stat(ctx context.Context, in *pb.MetricRequest, opts ...grpc.CallOption) (*pb.MetricResponse, error) {
|
||||
return &pb.MetricResponse{}, nil
|
||||
}
|
||||
func (m MockApiClient) Version(ctx context.Context, in *pb.Empty, opts ...grpc.CallOption) (*pb.VersionInfo, error) {
|
||||
version := &pb.VersionInfo{
|
||||
GoVersion: "the best one",
|
||||
BuildDate: "never",
|
||||
ReleaseVersion: "0.3.3",
|
||||
}
|
||||
return version, nil
|
||||
}
|
||||
func (m MockApiClient) ListPods(ctx context.Context, in *pb.Empty, opts ...grpc.CallOption) (*pb.ListPodsResponse, error) {
|
||||
return &pb.ListPodsResponse{}, nil
|
||||
}
|
||||
|
||||
func (m MockApiClient) Tap(context.Context, *pb.TapRequest, ...grpc.CallOption) (pb.Api_TapClient, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func FakeServer() Server {
|
||||
return Server{
|
||||
templateDir: "../templates",
|
||||
|
|
|
|||
Loading…
Reference in New Issue