diff --git a/.github/workflows/api-tests.yml b/.github/workflows/api-tests.yml new file mode 100644 index 0000000000..897e725e01 --- /dev/null +++ b/.github/workflows/api-tests.yml @@ -0,0 +1,156 @@ +name: 'API' + +on: + # NOTE: no action on `push` and `pull_request` since the API tests need to be run + # against a container that has the latest changes from your code. Therefore, the + # PMM_SERVER_IMAGE should either be the one from your feature build or the local + # devcontainer. One more scenario is when we want to run the API tests on dev-latest + # to see if the tests are in a good shape. + # That said, this workflow is mostly a convenience if you prefer Github to Jenkins. + # https://github.com/Percona-Lab/jenkins-pipelines/blob/master/pmm/pmm2-api-tests.groovy + + workflow_dispatch: + inputs: + MYSQL_IMAGE: + description: "MYSQL image version" + default: "percona:5.7" + required: true + type: string + POSTGRESQL_IMAGE: + description: "POSTGRESQL image version" + default: "postgres:12" + required: true + type: string + MONGODB_IMAGE: + description: "MONGODB image version" + default: "percona/percona-server-mongodb:4.4" + required: true + type: string + PMM_SERVER_IMAGE: + description: "PMM Server image version" + default: "perconalab/pmm-server:dev-latest" + required: true + type: string + + workflow_call: + inputs: + BRANCH: + description: "The branch to source API tests from" + default: "main" + required: true + type: string + MYSQL_IMAGE: + description: "MYSQL image version" + default: "percona:5.7" + required: true + type: string + POSTGRESQL_IMAGE: + description: "POSTGRESQL image version" + default: "postgres:12" + required: true + type: string + MONGODB_IMAGE: + description: "MONGODB image version" + default: "percona/percona-server-mongodb:4.4" + required: true + type: string + PMM_SERVER_IMAGE: + description: "PMM Server image version" + default: "perconalab/pmm-server:dev-latest" + required: true + type: string + +jobs: + test: + name: Tests + runs-on: ubuntu-22.04 + env: + PMM_URL: http://admin:admin@127.0.0.1 + BRANCH: ${{ github.event.inputs.BRANCH || 'main' }} + MYSQL_IMAGE: ${{ github.event.inputs.MYSQL_IMAGE || 'percona:5.7' }} + POSTGRESQL_IMAGE: ${{ github.event.inputs.POSTGRESQL_IMAGE || 'postgres:12' }} + MONGODB_IMAGE: ${{ github.event.inputs.MONGODB_IMAGE || 'percona/percona-server-mongodb:4.4' }} + PMM_SERVER_IMAGE: ${{ github.event.inputs.PMM_SERVER_IMAGE || 'perconalab/pmm-server:dev-latest' }} + + steps: + - name: Check out code + uses: actions/checkout@v4 + with: + ref: ${{ env.BRANCH }} + + - name: Login to docker.io registry + uses: docker/login-action@v3 + with: + registry: docker.io + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_PASSWORD }} + + - name: Run PMM Server + run: | + cat <<-EOF > compose.pmm-server-test.yml + services: + pmm-server: + image: ${{ env.PMM_SERVER_IMAGE }} + container_name: pmm-agent_pmm-server + environment: + - PMM_DEBUG=1 + - PERCONA_TEST_CHECKS_INTERVAL=10s + - PERCONA_TEST_PLATFORM_ADDRESS=https://check-dev.percona.com + - PERCONA_TEST_PLATFORM_PUBLIC_KEY=RWTg+ZmCCjt7O8eWeAmTLAqW+1ozUbpRSKSwNTmO+exlS5KEIPYWuYdX + ports: + - 80:80 + - 443:443 + volumes: + - ./managed/testdata/checks:/srv/checks + EOF + + # Run it and wait until it's healthy + docker compose -f compose.pmm-server-test.yml up -d --wait --wait-timeout=100 + + - name: Build the test image + shell: bash + run: | + docker build -t percona/pmm-api-tests . + + - name: Run DB containers + shell: bash + run: | + pushd api-tests + docker compose up test_db # no daemon mode + # TODO: review the provisions below (copied from the Jenkins pipeline) + # MYSQL_IMAGE=${{env.MYSQL_IMAGE}} docker compose up -d mysql + # MONGO_IMAGE=${{env.MONGODB_IMAGE}} docker compose up -d mongo + # POSTGRES_IMAGE=${{env.POSTGRESQL_IMAGE}} docker compose up -d postgres + # docker compose up -d sysbench + popd + + - name: Check connectivity to PMM Server + shell: bash + run: curl -f ${{env.PMM_URL}}/ping + + - name: Run API tests + shell: bash + run: | + docker run -e PMM_SERVER_URL=${{env.PMM_URL}} \ + -e PMM_RUN_UPDATE_TEST=0 \ + -e PMM_RUN_STT_TESTS=0 \ + --name pmm-api-tests \ + --network host \ + percona/pmm-api-tests + + - name: Get PMM logs + if: ${{ failure() }} + run: curl --insecure ${{env.PMM_URL}}/logs.zip --output ${{ github.workspace }}/logs.zip || true + + - name: Upload the logs on failure + if: ${{ failure() }} + uses: actions/upload-artifact@v3 + with: + name: "logs.zip" + path: ${{ github.workspace }}/logs.zip + + - name: Run debug commands on failure + if: ${{ failure() }} + run: | + echo "----- ENVIRONMENT VARIABLES -----" + env | sort diff --git a/Makefile.include b/Makefile.include index c1db671b3e..1d691eb6f7 100644 --- a/Makefile.include +++ b/Makefile.include @@ -49,7 +49,7 @@ gen-api: ## Generate PMM API bin/buf generate -v api - for API in api/agentlocalpb api/serverpb api/inventorypb api/managementpb api/managementpb/alerting api/managementpb/backup api/managementpb/azure api/managementpb/role api/qanpb api/managementpb/agent api/managementpb/node api/managementpb/service api/platformpb api/userpb; do \ + for API in api/agentlocalpb api/serverpb api/inventorypb api/managementpb api/managementpb/alerting api/managementpb/backup api/managementpb/dump api/managementpb/azure api/managementpb/role api/qanpb api/managementpb/agent api/managementpb/node api/managementpb/service api/platformpb api/userpb; do \ set -x ; \ bin/swagger mixin $$API/json/header.json $$API/*.swagger.json --output=$$API/json/$$(basename $$API).json --keep-spec-order; \ bin/swagger flatten --with-flatten=expand --with-flatten=remove-unused $$API/json/$$(basename $$API).json --output=$$API/json/$$(basename $$API).json ; \ @@ -91,6 +91,7 @@ gen-api: ## Generate PMM API api/managementpb/json/managementpb.json \ api/managementpb/alerting/json/alerting.json \ api/managementpb/backup/json/backup.json \ + api/managementpb/dump/json/dump.json \ api/managementpb/azure/json/azure.json \ api/managementpb/role/json/role.json \ api/managementpb/agent/json/agent.json \ @@ -127,7 +128,7 @@ clean: clean_swagger ## Remove generated files find api -name '*.pb.gw.go' -print -delete find api -name '*.validate.go' -print -delete - for API in api/agentlocalpb api/serverpb api/inventorypb api/managementpb api/managementpb/alerting api/managementpb/backup api/managementpb/role api/managementpb/agent api/managementpb/node api/managementpb/service api/qanpb api/platformpb ; do \ + for API in api/agentlocalpb api/serverpb api/inventorypb api/managementpb api/managementpb/alerting api/managementpb/backup api/management/dump api/managementpb/role api/managementpb/agent api/managementpb/node api/managementpb/service api/qanpb api/platformpb ; do \ rm -fr $$API/json/client $$API/json/models $$API/json/$$(basename $$API).json ; \ done rm -f api/swagger/swagger.json api/swagger/swagger-dev.json diff --git a/agent/cmd/pmm-agent-entrypoint/main.go b/agent/cmd/pmm-agent-entrypoint/main.go index 29205c30d4..a8d222673b 100644 --- a/agent/cmd/pmm-agent-entrypoint/main.go +++ b/agent/cmd/pmm-agent-entrypoint/main.go @@ -73,7 +73,7 @@ var ( var pmmAgentProcessID = 0 func runPmmAgent(ctx context.Context, commandLineArgs []string, restartPolicy restartPolicy, l *logrus.Entry, pmmAgentSidecarSleep int) int { - pmmAgentFullCommand := "pmm-admin " + strings.Join(commandLineArgs, " ") + pmmAgentFullCommand := "pmm-agent " + strings.Join(commandLineArgs, " ") for { select { case <-ctx.Done(): @@ -81,7 +81,7 @@ func runPmmAgent(ctx context.Context, commandLineArgs []string, restartPolicy re default: } var exitCode int - l.Infof("Starting 'pmm-admin %s'...", strings.Join(commandLineArgs, " ")) + l.Infof("Starting 'pmm-agent %s'...", strings.Join(commandLineArgs, " ")) cmd := commandPmmAgent(commandLineArgs) if err := cmd.Start(); err != nil { l.Errorf("Can't run: '%s', Error: %s", commandLineArgs, err) diff --git a/api/managementpb/dump/dump.pb.go b/api/managementpb/dump/dump.pb.go new file mode 100644 index 0000000000..19e895a780 --- /dev/null +++ b/api/managementpb/dump/dump.pb.go @@ -0,0 +1,1200 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.31.0-devel +// protoc (unknown) +// source: managementpb/dump/dump.proto + +package dumpv1beta1 + +import ( + reflect "reflect" + sync "sync" + + _ "github.com/envoyproxy/protoc-gen-validate/validate" + _ "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options" + _ "google.golang.org/genproto/googleapis/api/annotations" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type DumpStatus int32 + +const ( + DumpStatus_DUMP_STATUS_INVALID DumpStatus = 0 + DumpStatus_DUMP_STATUS_IN_PROGRESS DumpStatus = 1 + DumpStatus_DUMP_STATUS_SUCCESS DumpStatus = 2 + DumpStatus_DUMP_STATUS_ERROR DumpStatus = 3 +) + +// Enum value maps for DumpStatus. +var ( + DumpStatus_name = map[int32]string{ + 0: "DUMP_STATUS_INVALID", + 1: "DUMP_STATUS_IN_PROGRESS", + 2: "DUMP_STATUS_SUCCESS", + 3: "DUMP_STATUS_ERROR", + } + DumpStatus_value = map[string]int32{ + "DUMP_STATUS_INVALID": 0, + "DUMP_STATUS_IN_PROGRESS": 1, + "DUMP_STATUS_SUCCESS": 2, + "DUMP_STATUS_ERROR": 3, + } +) + +func (x DumpStatus) Enum() *DumpStatus { + p := new(DumpStatus) + *p = x + return p +} + +func (x DumpStatus) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (DumpStatus) Descriptor() protoreflect.EnumDescriptor { + return file_managementpb_dump_dump_proto_enumTypes[0].Descriptor() +} + +func (DumpStatus) Type() protoreflect.EnumType { + return &file_managementpb_dump_dump_proto_enumTypes[0] +} + +func (x DumpStatus) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use DumpStatus.Descriptor instead. +func (DumpStatus) EnumDescriptor() ([]byte, []int) { + return file_managementpb_dump_dump_proto_rawDescGZIP(), []int{0} +} + +type Dump struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DumpId string `protobuf:"bytes,1,opt,name=dump_id,json=dumpId,proto3" json:"dump_id,omitempty"` + Status DumpStatus `protobuf:"varint,2,opt,name=status,proto3,enum=dump.v1beta1.DumpStatus" json:"status,omitempty"` + ServiceNames []string `protobuf:"bytes,3,rep,name=service_names,json=serviceNames,proto3" json:"service_names,omitempty"` + StartTime *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=start_time,json=startTime,proto3" json:"start_time,omitempty"` + EndTime *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=end_time,json=endTime,proto3" json:"end_time,omitempty"` + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` +} + +func (x *Dump) Reset() { + *x = Dump{} + if protoimpl.UnsafeEnabled { + mi := &file_managementpb_dump_dump_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Dump) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Dump) ProtoMessage() {} + +func (x *Dump) ProtoReflect() protoreflect.Message { + mi := &file_managementpb_dump_dump_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Dump.ProtoReflect.Descriptor instead. +func (*Dump) Descriptor() ([]byte, []int) { + return file_managementpb_dump_dump_proto_rawDescGZIP(), []int{0} +} + +func (x *Dump) GetDumpId() string { + if x != nil { + return x.DumpId + } + return "" +} + +func (x *Dump) GetStatus() DumpStatus { + if x != nil { + return x.Status + } + return DumpStatus_DUMP_STATUS_INVALID +} + +func (x *Dump) GetServiceNames() []string { + if x != nil { + return x.ServiceNames + } + return nil +} + +func (x *Dump) GetStartTime() *timestamppb.Timestamp { + if x != nil { + return x.StartTime + } + return nil +} + +func (x *Dump) GetEndTime() *timestamppb.Timestamp { + if x != nil { + return x.EndTime + } + return nil +} + +func (x *Dump) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +type StartDumpRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ServiceNames []string `protobuf:"bytes,1,rep,name=service_names,json=serviceNames,proto3" json:"service_names,omitempty"` + StartTime *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=start_time,json=startTime,proto3" json:"start_time,omitempty"` + EndTime *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=end_time,json=endTime,proto3" json:"end_time,omitempty"` + ExportQan bool `protobuf:"varint,4,opt,name=export_qan,json=exportQan,proto3" json:"export_qan,omitempty"` + IgnoreLoad bool `protobuf:"varint,5,opt,name=ignore_load,json=ignoreLoad,proto3" json:"ignore_load,omitempty"` +} + +func (x *StartDumpRequest) Reset() { + *x = StartDumpRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_managementpb_dump_dump_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StartDumpRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StartDumpRequest) ProtoMessage() {} + +func (x *StartDumpRequest) ProtoReflect() protoreflect.Message { + mi := &file_managementpb_dump_dump_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StartDumpRequest.ProtoReflect.Descriptor instead. +func (*StartDumpRequest) Descriptor() ([]byte, []int) { + return file_managementpb_dump_dump_proto_rawDescGZIP(), []int{1} +} + +func (x *StartDumpRequest) GetServiceNames() []string { + if x != nil { + return x.ServiceNames + } + return nil +} + +func (x *StartDumpRequest) GetStartTime() *timestamppb.Timestamp { + if x != nil { + return x.StartTime + } + return nil +} + +func (x *StartDumpRequest) GetEndTime() *timestamppb.Timestamp { + if x != nil { + return x.EndTime + } + return nil +} + +func (x *StartDumpRequest) GetExportQan() bool { + if x != nil { + return x.ExportQan + } + return false +} + +func (x *StartDumpRequest) GetIgnoreLoad() bool { + if x != nil { + return x.IgnoreLoad + } + return false +} + +type StartDumpResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DumpId string `protobuf:"bytes,1,opt,name=dump_id,json=dumpId,proto3" json:"dump_id,omitempty"` +} + +func (x *StartDumpResponse) Reset() { + *x = StartDumpResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_managementpb_dump_dump_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StartDumpResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StartDumpResponse) ProtoMessage() {} + +func (x *StartDumpResponse) ProtoReflect() protoreflect.Message { + mi := &file_managementpb_dump_dump_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StartDumpResponse.ProtoReflect.Descriptor instead. +func (*StartDumpResponse) Descriptor() ([]byte, []int) { + return file_managementpb_dump_dump_proto_rawDescGZIP(), []int{2} +} + +func (x *StartDumpResponse) GetDumpId() string { + if x != nil { + return x.DumpId + } + return "" +} + +type ListDumpsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ListDumpsRequest) Reset() { + *x = ListDumpsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_managementpb_dump_dump_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListDumpsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListDumpsRequest) ProtoMessage() {} + +func (x *ListDumpsRequest) ProtoReflect() protoreflect.Message { + mi := &file_managementpb_dump_dump_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListDumpsRequest.ProtoReflect.Descriptor instead. +func (*ListDumpsRequest) Descriptor() ([]byte, []int) { + return file_managementpb_dump_dump_proto_rawDescGZIP(), []int{3} +} + +type ListDumpsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Dumps []*Dump `protobuf:"bytes,1,rep,name=dumps,proto3" json:"dumps,omitempty"` +} + +func (x *ListDumpsResponse) Reset() { + *x = ListDumpsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_managementpb_dump_dump_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListDumpsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListDumpsResponse) ProtoMessage() {} + +func (x *ListDumpsResponse) ProtoReflect() protoreflect.Message { + mi := &file_managementpb_dump_dump_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListDumpsResponse.ProtoReflect.Descriptor instead. +func (*ListDumpsResponse) Descriptor() ([]byte, []int) { + return file_managementpb_dump_dump_proto_rawDescGZIP(), []int{4} +} + +func (x *ListDumpsResponse) GetDumps() []*Dump { + if x != nil { + return x.Dumps + } + return nil +} + +type DeleteDumpRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DumpIds []string `protobuf:"bytes,1,rep,name=dump_ids,json=dumpIds,proto3" json:"dump_ids,omitempty"` +} + +func (x *DeleteDumpRequest) Reset() { + *x = DeleteDumpRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_managementpb_dump_dump_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteDumpRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteDumpRequest) ProtoMessage() {} + +func (x *DeleteDumpRequest) ProtoReflect() protoreflect.Message { + mi := &file_managementpb_dump_dump_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteDumpRequest.ProtoReflect.Descriptor instead. +func (*DeleteDumpRequest) Descriptor() ([]byte, []int) { + return file_managementpb_dump_dump_proto_rawDescGZIP(), []int{5} +} + +func (x *DeleteDumpRequest) GetDumpIds() []string { + if x != nil { + return x.DumpIds + } + return nil +} + +type DeleteDumpResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *DeleteDumpResponse) Reset() { + *x = DeleteDumpResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_managementpb_dump_dump_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteDumpResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteDumpResponse) ProtoMessage() {} + +func (x *DeleteDumpResponse) ProtoReflect() protoreflect.Message { + mi := &file_managementpb_dump_dump_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteDumpResponse.ProtoReflect.Descriptor instead. +func (*DeleteDumpResponse) Descriptor() ([]byte, []int) { + return file_managementpb_dump_dump_proto_rawDescGZIP(), []int{6} +} + +type GetLogsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DumpId string `protobuf:"bytes,1,opt,name=dump_id,json=dumpId,proto3" json:"dump_id,omitempty"` + Offset uint32 `protobuf:"varint,2,opt,name=offset,proto3" json:"offset,omitempty"` + Limit uint32 `protobuf:"varint,3,opt,name=limit,proto3" json:"limit,omitempty"` +} + +func (x *GetLogsRequest) Reset() { + *x = GetLogsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_managementpb_dump_dump_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetLogsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetLogsRequest) ProtoMessage() {} + +func (x *GetLogsRequest) ProtoReflect() protoreflect.Message { + mi := &file_managementpb_dump_dump_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetLogsRequest.ProtoReflect.Descriptor instead. +func (*GetLogsRequest) Descriptor() ([]byte, []int) { + return file_managementpb_dump_dump_proto_rawDescGZIP(), []int{7} +} + +func (x *GetLogsRequest) GetDumpId() string { + if x != nil { + return x.DumpId + } + return "" +} + +func (x *GetLogsRequest) GetOffset() uint32 { + if x != nil { + return x.Offset + } + return 0 +} + +func (x *GetLogsRequest) GetLimit() uint32 { + if x != nil { + return x.Limit + } + return 0 +} + +type GetLogsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Logs []*LogChunk `protobuf:"bytes,1,rep,name=logs,proto3" json:"logs,omitempty"` + End bool `protobuf:"varint,2,opt,name=end,proto3" json:"end,omitempty"` +} + +func (x *GetLogsResponse) Reset() { + *x = GetLogsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_managementpb_dump_dump_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetLogsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetLogsResponse) ProtoMessage() {} + +func (x *GetLogsResponse) ProtoReflect() protoreflect.Message { + mi := &file_managementpb_dump_dump_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetLogsResponse.ProtoReflect.Descriptor instead. +func (*GetLogsResponse) Descriptor() ([]byte, []int) { + return file_managementpb_dump_dump_proto_rawDescGZIP(), []int{8} +} + +func (x *GetLogsResponse) GetLogs() []*LogChunk { + if x != nil { + return x.Logs + } + return nil +} + +func (x *GetLogsResponse) GetEnd() bool { + if x != nil { + return x.End + } + return false +} + +// LogChunk represent one chunk of logs. +type LogChunk struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ChunkId uint32 `protobuf:"varint,1,opt,name=chunk_id,json=chunkId,proto3" json:"chunk_id,omitempty"` + Data string `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` +} + +func (x *LogChunk) Reset() { + *x = LogChunk{} + if protoimpl.UnsafeEnabled { + mi := &file_managementpb_dump_dump_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *LogChunk) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LogChunk) ProtoMessage() {} + +func (x *LogChunk) ProtoReflect() protoreflect.Message { + mi := &file_managementpb_dump_dump_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LogChunk.ProtoReflect.Descriptor instead. +func (*LogChunk) Descriptor() ([]byte, []int) { + return file_managementpb_dump_dump_proto_rawDescGZIP(), []int{9} +} + +func (x *LogChunk) GetChunkId() uint32 { + if x != nil { + return x.ChunkId + } + return 0 +} + +func (x *LogChunk) GetData() string { + if x != nil { + return x.Data + } + return "" +} + +type SFTPParameters struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` + User string `protobuf:"bytes,2,opt,name=user,proto3" json:"user,omitempty"` + Password string `protobuf:"bytes,3,opt,name=password,proto3" json:"password,omitempty"` + Directory string `protobuf:"bytes,4,opt,name=directory,proto3" json:"directory,omitempty"` +} + +func (x *SFTPParameters) Reset() { + *x = SFTPParameters{} + if protoimpl.UnsafeEnabled { + mi := &file_managementpb_dump_dump_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SFTPParameters) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SFTPParameters) ProtoMessage() {} + +func (x *SFTPParameters) ProtoReflect() protoreflect.Message { + mi := &file_managementpb_dump_dump_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SFTPParameters.ProtoReflect.Descriptor instead. +func (*SFTPParameters) Descriptor() ([]byte, []int) { + return file_managementpb_dump_dump_proto_rawDescGZIP(), []int{10} +} + +func (x *SFTPParameters) GetAddress() string { + if x != nil { + return x.Address + } + return "" +} + +func (x *SFTPParameters) GetUser() string { + if x != nil { + return x.User + } + return "" +} + +func (x *SFTPParameters) GetPassword() string { + if x != nil { + return x.Password + } + return "" +} + +func (x *SFTPParameters) GetDirectory() string { + if x != nil { + return x.Directory + } + return "" +} + +type UploadDumpRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DumpIds []string `protobuf:"bytes,1,rep,name=dump_ids,json=dumpIds,proto3" json:"dump_ids,omitempty"` + // SFTP upload parameters. + SftpParameters *SFTPParameters `protobuf:"bytes,2,opt,name=sftp_parameters,json=sftpParameters,proto3" json:"sftp_parameters,omitempty"` +} + +func (x *UploadDumpRequest) Reset() { + *x = UploadDumpRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_managementpb_dump_dump_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UploadDumpRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UploadDumpRequest) ProtoMessage() {} + +func (x *UploadDumpRequest) ProtoReflect() protoreflect.Message { + mi := &file_managementpb_dump_dump_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UploadDumpRequest.ProtoReflect.Descriptor instead. +func (*UploadDumpRequest) Descriptor() ([]byte, []int) { + return file_managementpb_dump_dump_proto_rawDescGZIP(), []int{11} +} + +func (x *UploadDumpRequest) GetDumpIds() []string { + if x != nil { + return x.DumpIds + } + return nil +} + +func (x *UploadDumpRequest) GetSftpParameters() *SFTPParameters { + if x != nil { + return x.SftpParameters + } + return nil +} + +type UploadDumpResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *UploadDumpResponse) Reset() { + *x = UploadDumpResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_managementpb_dump_dump_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UploadDumpResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UploadDumpResponse) ProtoMessage() {} + +func (x *UploadDumpResponse) ProtoReflect() protoreflect.Message { + mi := &file_managementpb_dump_dump_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UploadDumpResponse.ProtoReflect.Descriptor instead. +func (*UploadDumpResponse) Descriptor() ([]byte, []int) { + return file_managementpb_dump_dump_proto_rawDescGZIP(), []int{12} +} + +var File_managementpb_dump_dump_proto protoreflect.FileDescriptor + +var file_managementpb_dump_dump_proto_rawDesc = []byte{ + 0x0a, 0x1c, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2f, 0x64, + 0x75, 0x6d, 0x70, 0x2f, 0x64, 0x75, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, + 0x64, 0x75, 0x6d, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x1a, 0x1c, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, + 0x32, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x76, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x65, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa3, 0x02, 0x0a, 0x04, 0x44, 0x75, 0x6d, 0x70, 0x12, 0x17, 0x0a, + 0x07, 0x64, 0x75, 0x6d, 0x70, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x64, 0x75, 0x6d, 0x70, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x64, 0x75, 0x6d, 0x70, 0x2e, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x75, 0x6d, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x0c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x39, 0x0a, + 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x73, + 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x5f, + 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x07, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x12, + 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, + 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x22, 0xe9, 0x01, 0x0a, 0x10, 0x53, + 0x74, 0x61, 0x72, 0x74, 0x44, 0x75, 0x6d, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x23, 0x0a, 0x0d, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4e, + 0x61, 0x6d, 0x65, 0x73, 0x12, 0x39, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, + 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, + 0x35, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x07, 0x65, + 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, + 0x5f, 0x71, 0x61, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x65, 0x78, 0x70, 0x6f, + 0x72, 0x74, 0x51, 0x61, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x5f, + 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x69, 0x67, 0x6e, 0x6f, + 0x72, 0x65, 0x4c, 0x6f, 0x61, 0x64, 0x22, 0x2c, 0x0a, 0x11, 0x53, 0x74, 0x61, 0x72, 0x74, 0x44, + 0x75, 0x6d, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x64, + 0x75, 0x6d, 0x70, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x75, + 0x6d, 0x70, 0x49, 0x64, 0x22, 0x12, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x75, 0x6d, 0x70, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x3d, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, + 0x44, 0x75, 0x6d, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x28, 0x0a, + 0x05, 0x64, 0x75, 0x6d, 0x70, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x64, + 0x75, 0x6d, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x75, 0x6d, 0x70, + 0x52, 0x05, 0x64, 0x75, 0x6d, 0x70, 0x73, 0x22, 0x3a, 0x0a, 0x11, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x44, 0x75, 0x6d, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x25, 0x0a, 0x08, + 0x64, 0x75, 0x6d, 0x70, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x42, 0x0a, + 0xfa, 0x42, 0x07, 0x92, 0x01, 0x04, 0x08, 0x01, 0x18, 0x01, 0x52, 0x07, 0x64, 0x75, 0x6d, 0x70, + 0x49, 0x64, 0x73, 0x22, 0x14, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, 0x75, 0x6d, + 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x60, 0x0a, 0x0e, 0x47, 0x65, 0x74, + 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x07, 0x64, + 0x75, 0x6d, 0x70, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, + 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x06, 0x64, 0x75, 0x6d, 0x70, 0x49, 0x64, 0x12, 0x16, 0x0a, + 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x6f, + 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x22, 0x4f, 0x0a, 0x0f, 0x47, + 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, + 0x0a, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x64, + 0x75, 0x6d, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x6f, 0x67, 0x43, + 0x68, 0x75, 0x6e, 0x6b, 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x65, 0x6e, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x65, 0x6e, 0x64, 0x22, 0x39, 0x0a, 0x08, + 0x4c, 0x6f, 0x67, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x75, 0x6e, + 0x6b, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x63, 0x68, 0x75, 0x6e, + 0x6b, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x93, 0x01, 0x0a, 0x0e, 0x53, 0x46, 0x54, 0x50, + 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x21, 0x0a, 0x07, 0x61, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, + 0x72, 0x02, 0x10, 0x01, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1b, 0x0a, + 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, + 0x72, 0x02, 0x10, 0x01, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x23, 0x0a, 0x08, 0x70, 0x61, + 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, + 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, + 0x1c, 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x8b, 0x01, + 0x0a, 0x11, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x44, 0x75, 0x6d, 0x70, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x25, 0x0a, 0x08, 0x64, 0x75, 0x6d, 0x70, 0x5f, 0x69, 0x64, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x09, 0x42, 0x0a, 0xfa, 0x42, 0x07, 0x92, 0x01, 0x04, 0x08, 0x01, 0x18, + 0x01, 0x52, 0x07, 0x64, 0x75, 0x6d, 0x70, 0x49, 0x64, 0x73, 0x12, 0x4f, 0x0a, 0x0f, 0x73, 0x66, + 0x74, 0x70, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x64, 0x75, 0x6d, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, + 0x61, 0x31, 0x2e, 0x53, 0x46, 0x54, 0x50, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, + 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0e, 0x73, 0x66, 0x74, + 0x70, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x22, 0x14, 0x0a, 0x12, 0x55, + 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x44, 0x75, 0x6d, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x2a, 0x72, 0x0a, 0x0a, 0x44, 0x75, 0x6d, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, + 0x17, 0x0a, 0x13, 0x44, 0x55, 0x4d, 0x50, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x49, + 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x00, 0x12, 0x1b, 0x0a, 0x17, 0x44, 0x55, 0x4d, 0x50, + 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x49, 0x4e, 0x5f, 0x50, 0x52, 0x4f, 0x47, 0x52, + 0x45, 0x53, 0x53, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, 0x44, 0x55, 0x4d, 0x50, 0x5f, 0x53, 0x54, + 0x41, 0x54, 0x55, 0x53, 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x02, 0x12, 0x15, + 0x0a, 0x11, 0x44, 0x55, 0x4d, 0x50, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x45, 0x52, + 0x52, 0x4f, 0x52, 0x10, 0x03, 0x32, 0xf0, 0x04, 0x0a, 0x05, 0x44, 0x75, 0x6d, 0x70, 0x73, 0x12, + 0x78, 0x0a, 0x09, 0x53, 0x74, 0x61, 0x72, 0x74, 0x44, 0x75, 0x6d, 0x70, 0x12, 0x1e, 0x2e, 0x64, + 0x75, 0x6d, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x72, + 0x74, 0x44, 0x75, 0x6d, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x64, + 0x75, 0x6d, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x72, + 0x74, 0x44, 0x75, 0x6d, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x3a, 0x01, 0x2a, 0x22, 0x1f, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, + 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x64, 0x75, 0x6d, 0x70, 0x2f, 0x44, 0x75, + 0x6d, 0x70, 0x73, 0x2f, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x77, 0x0a, 0x09, 0x4c, 0x69, 0x73, + 0x74, 0x44, 0x75, 0x6d, 0x70, 0x73, 0x12, 0x1e, 0x2e, 0x64, 0x75, 0x6d, 0x70, 0x2e, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x75, 0x6d, 0x70, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x64, 0x75, 0x6d, 0x70, 0x2e, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x75, 0x6d, 0x70, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x29, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x23, 0x3a, + 0x01, 0x2a, 0x22, 0x1e, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x2f, 0x64, 0x75, 0x6d, 0x70, 0x2f, 0x44, 0x75, 0x6d, 0x70, 0x73, 0x2f, 0x4c, 0x69, + 0x73, 0x74, 0x12, 0x7c, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, 0x75, 0x6d, 0x70, + 0x12, 0x1f, 0x2e, 0x64, 0x75, 0x6d, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, 0x75, 0x6d, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x20, 0x2e, 0x64, 0x75, 0x6d, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, + 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, 0x75, 0x6d, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x2b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x25, 0x3a, 0x01, 0x2a, 0x22, 0x20, + 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x64, + 0x75, 0x6d, 0x70, 0x2f, 0x44, 0x75, 0x6d, 0x70, 0x73, 0x2f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x12, 0x78, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x44, 0x75, 0x6d, 0x70, 0x4c, 0x6f, 0x67, 0x73, 0x12, + 0x1c, 0x2e, 0x64, 0x75, 0x6d, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, + 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, + 0x64, 0x75, 0x6d, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, + 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2c, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x26, 0x3a, 0x01, 0x2a, 0x22, 0x21, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x6e, + 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x64, 0x75, 0x6d, 0x70, 0x2f, 0x44, 0x75, 0x6d, + 0x70, 0x73, 0x2f, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x7c, 0x0a, 0x0a, 0x55, 0x70, + 0x6c, 0x6f, 0x61, 0x64, 0x44, 0x75, 0x6d, 0x70, 0x12, 0x1f, 0x2e, 0x64, 0x75, 0x6d, 0x70, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x44, 0x75, + 0x6d, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x64, 0x75, 0x6d, 0x70, + 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x44, + 0x75, 0x6d, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2b, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x25, 0x3a, 0x01, 0x2a, 0x22, 0x20, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x6e, 0x61, + 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x64, 0x75, 0x6d, 0x70, 0x2f, 0x44, 0x75, 0x6d, 0x70, + 0x73, 0x2f, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0xa8, 0x01, 0x0a, 0x10, 0x63, 0x6f, 0x6d, + 0x2e, 0x64, 0x75, 0x6d, 0x70, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x09, 0x44, + 0x75, 0x6d, 0x70, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x38, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x61, 0x2f, 0x70, + 0x6d, 0x6d, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x70, 0x62, 0x2f, 0x64, 0x75, 0x6d, 0x70, 0x3b, 0x64, 0x75, 0x6d, 0x70, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x44, 0x58, 0x58, 0xaa, 0x02, 0x0c, 0x44, 0x75, 0x6d, + 0x70, 0x2e, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x0c, 0x44, 0x75, 0x6d, 0x70, + 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x18, 0x44, 0x75, 0x6d, 0x70, 0x5c, + 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0xea, 0x02, 0x0d, 0x44, 0x75, 0x6d, 0x70, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_managementpb_dump_dump_proto_rawDescOnce sync.Once + file_managementpb_dump_dump_proto_rawDescData = file_managementpb_dump_dump_proto_rawDesc +) + +func file_managementpb_dump_dump_proto_rawDescGZIP() []byte { + file_managementpb_dump_dump_proto_rawDescOnce.Do(func() { + file_managementpb_dump_dump_proto_rawDescData = protoimpl.X.CompressGZIP(file_managementpb_dump_dump_proto_rawDescData) + }) + return file_managementpb_dump_dump_proto_rawDescData +} + +var ( + file_managementpb_dump_dump_proto_enumTypes = make([]protoimpl.EnumInfo, 1) + file_managementpb_dump_dump_proto_msgTypes = make([]protoimpl.MessageInfo, 13) + file_managementpb_dump_dump_proto_goTypes = []interface{}{ + (DumpStatus)(0), // 0: dump.v1beta1.DumpStatus + (*Dump)(nil), // 1: dump.v1beta1.Dump + (*StartDumpRequest)(nil), // 2: dump.v1beta1.StartDumpRequest + (*StartDumpResponse)(nil), // 3: dump.v1beta1.StartDumpResponse + (*ListDumpsRequest)(nil), // 4: dump.v1beta1.ListDumpsRequest + (*ListDumpsResponse)(nil), // 5: dump.v1beta1.ListDumpsResponse + (*DeleteDumpRequest)(nil), // 6: dump.v1beta1.DeleteDumpRequest + (*DeleteDumpResponse)(nil), // 7: dump.v1beta1.DeleteDumpResponse + (*GetLogsRequest)(nil), // 8: dump.v1beta1.GetLogsRequest + (*GetLogsResponse)(nil), // 9: dump.v1beta1.GetLogsResponse + (*LogChunk)(nil), // 10: dump.v1beta1.LogChunk + (*SFTPParameters)(nil), // 11: dump.v1beta1.SFTPParameters + (*UploadDumpRequest)(nil), // 12: dump.v1beta1.UploadDumpRequest + (*UploadDumpResponse)(nil), // 13: dump.v1beta1.UploadDumpResponse + (*timestamppb.Timestamp)(nil), // 14: google.protobuf.Timestamp + } +) + +var file_managementpb_dump_dump_proto_depIdxs = []int32{ + 0, // 0: dump.v1beta1.Dump.status:type_name -> dump.v1beta1.DumpStatus + 14, // 1: dump.v1beta1.Dump.start_time:type_name -> google.protobuf.Timestamp + 14, // 2: dump.v1beta1.Dump.end_time:type_name -> google.protobuf.Timestamp + 14, // 3: dump.v1beta1.Dump.created_at:type_name -> google.protobuf.Timestamp + 14, // 4: dump.v1beta1.StartDumpRequest.start_time:type_name -> google.protobuf.Timestamp + 14, // 5: dump.v1beta1.StartDumpRequest.end_time:type_name -> google.protobuf.Timestamp + 1, // 6: dump.v1beta1.ListDumpsResponse.dumps:type_name -> dump.v1beta1.Dump + 10, // 7: dump.v1beta1.GetLogsResponse.logs:type_name -> dump.v1beta1.LogChunk + 11, // 8: dump.v1beta1.UploadDumpRequest.sftp_parameters:type_name -> dump.v1beta1.SFTPParameters + 2, // 9: dump.v1beta1.Dumps.StartDump:input_type -> dump.v1beta1.StartDumpRequest + 4, // 10: dump.v1beta1.Dumps.ListDumps:input_type -> dump.v1beta1.ListDumpsRequest + 6, // 11: dump.v1beta1.Dumps.DeleteDump:input_type -> dump.v1beta1.DeleteDumpRequest + 8, // 12: dump.v1beta1.Dumps.GetDumpLogs:input_type -> dump.v1beta1.GetLogsRequest + 12, // 13: dump.v1beta1.Dumps.UploadDump:input_type -> dump.v1beta1.UploadDumpRequest + 3, // 14: dump.v1beta1.Dumps.StartDump:output_type -> dump.v1beta1.StartDumpResponse + 5, // 15: dump.v1beta1.Dumps.ListDumps:output_type -> dump.v1beta1.ListDumpsResponse + 7, // 16: dump.v1beta1.Dumps.DeleteDump:output_type -> dump.v1beta1.DeleteDumpResponse + 9, // 17: dump.v1beta1.Dumps.GetDumpLogs:output_type -> dump.v1beta1.GetLogsResponse + 13, // 18: dump.v1beta1.Dumps.UploadDump:output_type -> dump.v1beta1.UploadDumpResponse + 14, // [14:19] is the sub-list for method output_type + 9, // [9:14] is the sub-list for method input_type + 9, // [9:9] is the sub-list for extension type_name + 9, // [9:9] is the sub-list for extension extendee + 0, // [0:9] is the sub-list for field type_name +} + +func init() { file_managementpb_dump_dump_proto_init() } +func file_managementpb_dump_dump_proto_init() { + if File_managementpb_dump_dump_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_managementpb_dump_dump_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Dump); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_managementpb_dump_dump_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StartDumpRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_managementpb_dump_dump_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StartDumpResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_managementpb_dump_dump_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListDumpsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_managementpb_dump_dump_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListDumpsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_managementpb_dump_dump_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteDumpRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_managementpb_dump_dump_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteDumpResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_managementpb_dump_dump_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetLogsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_managementpb_dump_dump_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetLogsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_managementpb_dump_dump_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*LogChunk); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_managementpb_dump_dump_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SFTPParameters); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_managementpb_dump_dump_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UploadDumpRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_managementpb_dump_dump_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UploadDumpResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_managementpb_dump_dump_proto_rawDesc, + NumEnums: 1, + NumMessages: 13, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_managementpb_dump_dump_proto_goTypes, + DependencyIndexes: file_managementpb_dump_dump_proto_depIdxs, + EnumInfos: file_managementpb_dump_dump_proto_enumTypes, + MessageInfos: file_managementpb_dump_dump_proto_msgTypes, + }.Build() + File_managementpb_dump_dump_proto = out.File + file_managementpb_dump_dump_proto_rawDesc = nil + file_managementpb_dump_dump_proto_goTypes = nil + file_managementpb_dump_dump_proto_depIdxs = nil +} diff --git a/api/managementpb/dump/dump.pb.gw.go b/api/managementpb/dump/dump.pb.gw.go new file mode 100644 index 0000000000..97f94a9292 --- /dev/null +++ b/api/managementpb/dump/dump.pb.gw.go @@ -0,0 +1,491 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: managementpb/dump/dump.proto + +/* +Package dumpv1beta1 is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package dumpv1beta1 + +import ( + "context" + "io" + "net/http" + + "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" + "github.com/grpc-ecosystem/grpc-gateway/v2/utilities" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/proto" +) + +// Suppress "imported and not used" errors +var ( + _ codes.Code + _ io.Reader + _ status.Status + _ = runtime.String + _ = utilities.NewDoubleArray + _ = metadata.Join +) + +func request_Dumps_StartDump_0(ctx context.Context, marshaler runtime.Marshaler, client DumpsClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq StartDumpRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.StartDump(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err +} + +func local_request_Dumps_StartDump_0(ctx context.Context, marshaler runtime.Marshaler, server DumpsServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq StartDumpRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.StartDump(ctx, &protoReq) + return msg, metadata, err +} + +func request_Dumps_ListDumps_0(ctx context.Context, marshaler runtime.Marshaler, client DumpsClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ListDumpsRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.ListDumps(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err +} + +func local_request_Dumps_ListDumps_0(ctx context.Context, marshaler runtime.Marshaler, server DumpsServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ListDumpsRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.ListDumps(ctx, &protoReq) + return msg, metadata, err +} + +func request_Dumps_DeleteDump_0(ctx context.Context, marshaler runtime.Marshaler, client DumpsClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq DeleteDumpRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.DeleteDump(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err +} + +func local_request_Dumps_DeleteDump_0(ctx context.Context, marshaler runtime.Marshaler, server DumpsServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq DeleteDumpRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.DeleteDump(ctx, &protoReq) + return msg, metadata, err +} + +func request_Dumps_GetDumpLogs_0(ctx context.Context, marshaler runtime.Marshaler, client DumpsClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetLogsRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.GetDumpLogs(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err +} + +func local_request_Dumps_GetDumpLogs_0(ctx context.Context, marshaler runtime.Marshaler, server DumpsServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetLogsRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.GetDumpLogs(ctx, &protoReq) + return msg, metadata, err +} + +func request_Dumps_UploadDump_0(ctx context.Context, marshaler runtime.Marshaler, client DumpsClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq UploadDumpRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.UploadDump(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err +} + +func local_request_Dumps_UploadDump_0(ctx context.Context, marshaler runtime.Marshaler, server DumpsServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq UploadDumpRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.UploadDump(ctx, &protoReq) + return msg, metadata, err +} + +// RegisterDumpsHandlerServer registers the http handlers for service Dumps to "mux". +// UnaryRPC :call DumpsServer directly. +// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterDumpsHandlerFromEndpoint instead. +func RegisterDumpsHandlerServer(ctx context.Context, mux *runtime.ServeMux, server DumpsServer) error { + mux.Handle("POST", pattern_Dumps_StartDump_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/dump.v1beta1.Dumps/StartDump", runtime.WithHTTPPathPattern("/v1/management/dump/Dumps/Start")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Dumps_StartDump_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_Dumps_StartDump_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) + + mux.Handle("POST", pattern_Dumps_ListDumps_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/dump.v1beta1.Dumps/ListDumps", runtime.WithHTTPPathPattern("/v1/management/dump/Dumps/List")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Dumps_ListDumps_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_Dumps_ListDumps_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) + + mux.Handle("POST", pattern_Dumps_DeleteDump_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/dump.v1beta1.Dumps/DeleteDump", runtime.WithHTTPPathPattern("/v1/management/dump/Dumps/Delete")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Dumps_DeleteDump_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_Dumps_DeleteDump_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) + + mux.Handle("POST", pattern_Dumps_GetDumpLogs_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/dump.v1beta1.Dumps/GetDumpLogs", runtime.WithHTTPPathPattern("/v1/management/dump/Dumps/GetLogs")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Dumps_GetDumpLogs_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_Dumps_GetDumpLogs_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) + + mux.Handle("POST", pattern_Dumps_UploadDump_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/dump.v1beta1.Dumps/UploadDump", runtime.WithHTTPPathPattern("/v1/management/dump/Dumps/Upload")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Dumps_UploadDump_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_Dumps_UploadDump_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) + + return nil +} + +// RegisterDumpsHandlerFromEndpoint is same as RegisterDumpsHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterDumpsHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.DialContext(ctx, endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterDumpsHandler(ctx, mux, conn) +} + +// RegisterDumpsHandler registers the http handlers for service Dumps to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterDumpsHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterDumpsHandlerClient(ctx, mux, NewDumpsClient(conn)) +} + +// RegisterDumpsHandlerClient registers the http handlers for service Dumps +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "DumpsClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "DumpsClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "DumpsClient" to call the correct interceptors. +func RegisterDumpsHandlerClient(ctx context.Context, mux *runtime.ServeMux, client DumpsClient) error { + mux.Handle("POST", pattern_Dumps_StartDump_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/dump.v1beta1.Dumps/StartDump", runtime.WithHTTPPathPattern("/v1/management/dump/Dumps/Start")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Dumps_StartDump_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_Dumps_StartDump_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) + + mux.Handle("POST", pattern_Dumps_ListDumps_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/dump.v1beta1.Dumps/ListDumps", runtime.WithHTTPPathPattern("/v1/management/dump/Dumps/List")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Dumps_ListDumps_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_Dumps_ListDumps_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) + + mux.Handle("POST", pattern_Dumps_DeleteDump_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/dump.v1beta1.Dumps/DeleteDump", runtime.WithHTTPPathPattern("/v1/management/dump/Dumps/Delete")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Dumps_DeleteDump_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_Dumps_DeleteDump_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) + + mux.Handle("POST", pattern_Dumps_GetDumpLogs_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/dump.v1beta1.Dumps/GetDumpLogs", runtime.WithHTTPPathPattern("/v1/management/dump/Dumps/GetLogs")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Dumps_GetDumpLogs_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_Dumps_GetDumpLogs_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) + + mux.Handle("POST", pattern_Dumps_UploadDump_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/dump.v1beta1.Dumps/UploadDump", runtime.WithHTTPPathPattern("/v1/management/dump/Dumps/Upload")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Dumps_UploadDump_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_Dumps_UploadDump_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) + + return nil +} + +var ( + pattern_Dumps_StartDump_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"v1", "management", "dump", "Dumps", "Start"}, "")) + + pattern_Dumps_ListDumps_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"v1", "management", "dump", "Dumps", "List"}, "")) + + pattern_Dumps_DeleteDump_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"v1", "management", "dump", "Dumps", "Delete"}, "")) + + pattern_Dumps_GetDumpLogs_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"v1", "management", "dump", "Dumps", "GetLogs"}, "")) + + pattern_Dumps_UploadDump_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"v1", "management", "dump", "Dumps", "Upload"}, "")) +) + +var ( + forward_Dumps_StartDump_0 = runtime.ForwardResponseMessage + + forward_Dumps_ListDumps_0 = runtime.ForwardResponseMessage + + forward_Dumps_DeleteDump_0 = runtime.ForwardResponseMessage + + forward_Dumps_GetDumpLogs_0 = runtime.ForwardResponseMessage + + forward_Dumps_UploadDump_0 = runtime.ForwardResponseMessage +) diff --git a/api/managementpb/dump/dump.pb.validate.go b/api/managementpb/dump/dump.pb.validate.go new file mode 100644 index 0000000000..68148db850 --- /dev/null +++ b/api/managementpb/dump/dump.pb.validate.go @@ -0,0 +1,1728 @@ +// Code generated by protoc-gen-validate. DO NOT EDIT. +// source: managementpb/dump/dump.proto + +package dumpv1beta1 + +import ( + "bytes" + "errors" + "fmt" + "net" + "net/mail" + "net/url" + "regexp" + "sort" + "strings" + "time" + "unicode/utf8" + + "google.golang.org/protobuf/types/known/anypb" +) + +// ensure the imports are used +var ( + _ = bytes.MinRead + _ = errors.New("") + _ = fmt.Print + _ = utf8.UTFMax + _ = (*regexp.Regexp)(nil) + _ = (*strings.Reader)(nil) + _ = net.IPv4len + _ = time.Duration(0) + _ = (*url.URL)(nil) + _ = (*mail.Address)(nil) + _ = anypb.Any{} + _ = sort.Sort +) + +// Validate checks the field values on Dump with the rules defined in the proto +// definition for this message. If any rules are violated, the first error +// encountered is returned, or nil if there are no violations. +func (m *Dump) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on Dump with the rules defined in the +// proto definition for this message. If any rules are violated, the result is +// a list of violation errors wrapped in DumpMultiError, or nil if none found. +func (m *Dump) ValidateAll() error { + return m.validate(true) +} + +func (m *Dump) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for DumpId + + // no validation rules for Status + + if all { + switch v := interface{}(m.GetStartTime()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, DumpValidationError{ + field: "StartTime", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, DumpValidationError{ + field: "StartTime", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetStartTime()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return DumpValidationError{ + field: "StartTime", + reason: "embedded message failed validation", + cause: err, + } + } + } + + if all { + switch v := interface{}(m.GetEndTime()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, DumpValidationError{ + field: "EndTime", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, DumpValidationError{ + field: "EndTime", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetEndTime()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return DumpValidationError{ + field: "EndTime", + reason: "embedded message failed validation", + cause: err, + } + } + } + + if all { + switch v := interface{}(m.GetCreatedAt()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, DumpValidationError{ + field: "CreatedAt", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, DumpValidationError{ + field: "CreatedAt", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetCreatedAt()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return DumpValidationError{ + field: "CreatedAt", + reason: "embedded message failed validation", + cause: err, + } + } + } + + if len(errors) > 0 { + return DumpMultiError(errors) + } + + return nil +} + +// DumpMultiError is an error wrapping multiple validation errors returned by +// Dump.ValidateAll() if the designated constraints aren't met. +type DumpMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m DumpMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m DumpMultiError) AllErrors() []error { return m } + +// DumpValidationError is the validation error returned by Dump.Validate if the +// designated constraints aren't met. +type DumpValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e DumpValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e DumpValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e DumpValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e DumpValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e DumpValidationError) ErrorName() string { return "DumpValidationError" } + +// Error satisfies the builtin error interface +func (e DumpValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sDump.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = DumpValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = DumpValidationError{} + +// Validate checks the field values on StartDumpRequest with the rules defined +// in the proto definition for this message. If any rules are violated, the +// first error encountered is returned, or nil if there are no violations. +func (m *StartDumpRequest) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on StartDumpRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// StartDumpRequestMultiError, or nil if none found. +func (m *StartDumpRequest) ValidateAll() error { + return m.validate(true) +} + +func (m *StartDumpRequest) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if all { + switch v := interface{}(m.GetStartTime()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, StartDumpRequestValidationError{ + field: "StartTime", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, StartDumpRequestValidationError{ + field: "StartTime", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetStartTime()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return StartDumpRequestValidationError{ + field: "StartTime", + reason: "embedded message failed validation", + cause: err, + } + } + } + + if all { + switch v := interface{}(m.GetEndTime()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, StartDumpRequestValidationError{ + field: "EndTime", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, StartDumpRequestValidationError{ + field: "EndTime", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetEndTime()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return StartDumpRequestValidationError{ + field: "EndTime", + reason: "embedded message failed validation", + cause: err, + } + } + } + + // no validation rules for ExportQan + + // no validation rules for IgnoreLoad + + if len(errors) > 0 { + return StartDumpRequestMultiError(errors) + } + + return nil +} + +// StartDumpRequestMultiError is an error wrapping multiple validation errors +// returned by StartDumpRequest.ValidateAll() if the designated constraints +// aren't met. +type StartDumpRequestMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m StartDumpRequestMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m StartDumpRequestMultiError) AllErrors() []error { return m } + +// StartDumpRequestValidationError is the validation error returned by +// StartDumpRequest.Validate if the designated constraints aren't met. +type StartDumpRequestValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e StartDumpRequestValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e StartDumpRequestValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e StartDumpRequestValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e StartDumpRequestValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e StartDumpRequestValidationError) ErrorName() string { return "StartDumpRequestValidationError" } + +// Error satisfies the builtin error interface +func (e StartDumpRequestValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sStartDumpRequest.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = StartDumpRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = StartDumpRequestValidationError{} + +// Validate checks the field values on StartDumpResponse with the rules defined +// in the proto definition for this message. If any rules are violated, the +// first error encountered is returned, or nil if there are no violations. +func (m *StartDumpResponse) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on StartDumpResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// StartDumpResponseMultiError, or nil if none found. +func (m *StartDumpResponse) ValidateAll() error { + return m.validate(true) +} + +func (m *StartDumpResponse) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for DumpId + + if len(errors) > 0 { + return StartDumpResponseMultiError(errors) + } + + return nil +} + +// StartDumpResponseMultiError is an error wrapping multiple validation errors +// returned by StartDumpResponse.ValidateAll() if the designated constraints +// aren't met. +type StartDumpResponseMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m StartDumpResponseMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m StartDumpResponseMultiError) AllErrors() []error { return m } + +// StartDumpResponseValidationError is the validation error returned by +// StartDumpResponse.Validate if the designated constraints aren't met. +type StartDumpResponseValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e StartDumpResponseValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e StartDumpResponseValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e StartDumpResponseValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e StartDumpResponseValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e StartDumpResponseValidationError) ErrorName() string { + return "StartDumpResponseValidationError" +} + +// Error satisfies the builtin error interface +func (e StartDumpResponseValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sStartDumpResponse.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = StartDumpResponseValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = StartDumpResponseValidationError{} + +// Validate checks the field values on ListDumpsRequest with the rules defined +// in the proto definition for this message. If any rules are violated, the +// first error encountered is returned, or nil if there are no violations. +func (m *ListDumpsRequest) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on ListDumpsRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// ListDumpsRequestMultiError, or nil if none found. +func (m *ListDumpsRequest) ValidateAll() error { + return m.validate(true) +} + +func (m *ListDumpsRequest) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if len(errors) > 0 { + return ListDumpsRequestMultiError(errors) + } + + return nil +} + +// ListDumpsRequestMultiError is an error wrapping multiple validation errors +// returned by ListDumpsRequest.ValidateAll() if the designated constraints +// aren't met. +type ListDumpsRequestMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m ListDumpsRequestMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m ListDumpsRequestMultiError) AllErrors() []error { return m } + +// ListDumpsRequestValidationError is the validation error returned by +// ListDumpsRequest.Validate if the designated constraints aren't met. +type ListDumpsRequestValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e ListDumpsRequestValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e ListDumpsRequestValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e ListDumpsRequestValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e ListDumpsRequestValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e ListDumpsRequestValidationError) ErrorName() string { return "ListDumpsRequestValidationError" } + +// Error satisfies the builtin error interface +func (e ListDumpsRequestValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sListDumpsRequest.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = ListDumpsRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = ListDumpsRequestValidationError{} + +// Validate checks the field values on ListDumpsResponse with the rules defined +// in the proto definition for this message. If any rules are violated, the +// first error encountered is returned, or nil if there are no violations. +func (m *ListDumpsResponse) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on ListDumpsResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// ListDumpsResponseMultiError, or nil if none found. +func (m *ListDumpsResponse) ValidateAll() error { + return m.validate(true) +} + +func (m *ListDumpsResponse) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + for idx, item := range m.GetDumps() { + _, _ = idx, item + + if all { + switch v := interface{}(item).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, ListDumpsResponseValidationError{ + field: fmt.Sprintf("Dumps[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, ListDumpsResponseValidationError{ + field: fmt.Sprintf("Dumps[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(item).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return ListDumpsResponseValidationError{ + field: fmt.Sprintf("Dumps[%v]", idx), + reason: "embedded message failed validation", + cause: err, + } + } + } + + } + + if len(errors) > 0 { + return ListDumpsResponseMultiError(errors) + } + + return nil +} + +// ListDumpsResponseMultiError is an error wrapping multiple validation errors +// returned by ListDumpsResponse.ValidateAll() if the designated constraints +// aren't met. +type ListDumpsResponseMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m ListDumpsResponseMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m ListDumpsResponseMultiError) AllErrors() []error { return m } + +// ListDumpsResponseValidationError is the validation error returned by +// ListDumpsResponse.Validate if the designated constraints aren't met. +type ListDumpsResponseValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e ListDumpsResponseValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e ListDumpsResponseValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e ListDumpsResponseValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e ListDumpsResponseValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e ListDumpsResponseValidationError) ErrorName() string { + return "ListDumpsResponseValidationError" +} + +// Error satisfies the builtin error interface +func (e ListDumpsResponseValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sListDumpsResponse.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = ListDumpsResponseValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = ListDumpsResponseValidationError{} + +// Validate checks the field values on DeleteDumpRequest with the rules defined +// in the proto definition for this message. If any rules are violated, the +// first error encountered is returned, or nil if there are no violations. +func (m *DeleteDumpRequest) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on DeleteDumpRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// DeleteDumpRequestMultiError, or nil if none found. +func (m *DeleteDumpRequest) ValidateAll() error { + return m.validate(true) +} + +func (m *DeleteDumpRequest) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if len(m.GetDumpIds()) < 1 { + err := DeleteDumpRequestValidationError{ + field: "DumpIds", + reason: "value must contain at least 1 item(s)", + } + if !all { + return err + } + errors = append(errors, err) + } + + _DeleteDumpRequest_DumpIds_Unique := make(map[string]struct{}, len(m.GetDumpIds())) + + for idx, item := range m.GetDumpIds() { + _, _ = idx, item + + if _, exists := _DeleteDumpRequest_DumpIds_Unique[item]; exists { + err := DeleteDumpRequestValidationError{ + field: fmt.Sprintf("DumpIds[%v]", idx), + reason: "repeated value must contain unique items", + } + if !all { + return err + } + errors = append(errors, err) + } else { + _DeleteDumpRequest_DumpIds_Unique[item] = struct{}{} + } + + // no validation rules for DumpIds[idx] + } + + if len(errors) > 0 { + return DeleteDumpRequestMultiError(errors) + } + + return nil +} + +// DeleteDumpRequestMultiError is an error wrapping multiple validation errors +// returned by DeleteDumpRequest.ValidateAll() if the designated constraints +// aren't met. +type DeleteDumpRequestMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m DeleteDumpRequestMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m DeleteDumpRequestMultiError) AllErrors() []error { return m } + +// DeleteDumpRequestValidationError is the validation error returned by +// DeleteDumpRequest.Validate if the designated constraints aren't met. +type DeleteDumpRequestValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e DeleteDumpRequestValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e DeleteDumpRequestValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e DeleteDumpRequestValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e DeleteDumpRequestValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e DeleteDumpRequestValidationError) ErrorName() string { + return "DeleteDumpRequestValidationError" +} + +// Error satisfies the builtin error interface +func (e DeleteDumpRequestValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sDeleteDumpRequest.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = DeleteDumpRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = DeleteDumpRequestValidationError{} + +// Validate checks the field values on DeleteDumpResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *DeleteDumpResponse) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on DeleteDumpResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// DeleteDumpResponseMultiError, or nil if none found. +func (m *DeleteDumpResponse) ValidateAll() error { + return m.validate(true) +} + +func (m *DeleteDumpResponse) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if len(errors) > 0 { + return DeleteDumpResponseMultiError(errors) + } + + return nil +} + +// DeleteDumpResponseMultiError is an error wrapping multiple validation errors +// returned by DeleteDumpResponse.ValidateAll() if the designated constraints +// aren't met. +type DeleteDumpResponseMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m DeleteDumpResponseMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m DeleteDumpResponseMultiError) AllErrors() []error { return m } + +// DeleteDumpResponseValidationError is the validation error returned by +// DeleteDumpResponse.Validate if the designated constraints aren't met. +type DeleteDumpResponseValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e DeleteDumpResponseValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e DeleteDumpResponseValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e DeleteDumpResponseValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e DeleteDumpResponseValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e DeleteDumpResponseValidationError) ErrorName() string { + return "DeleteDumpResponseValidationError" +} + +// Error satisfies the builtin error interface +func (e DeleteDumpResponseValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sDeleteDumpResponse.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = DeleteDumpResponseValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = DeleteDumpResponseValidationError{} + +// Validate checks the field values on GetLogsRequest with the rules defined in +// the proto definition for this message. If any rules are violated, the first +// error encountered is returned, or nil if there are no violations. +func (m *GetLogsRequest) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on GetLogsRequest with the rules defined +// in the proto definition for this message. If any rules are violated, the +// result is a list of violation errors wrapped in GetLogsRequestMultiError, +// or nil if none found. +func (m *GetLogsRequest) ValidateAll() error { + return m.validate(true) +} + +func (m *GetLogsRequest) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if utf8.RuneCountInString(m.GetDumpId()) < 1 { + err := GetLogsRequestValidationError{ + field: "DumpId", + reason: "value length must be at least 1 runes", + } + if !all { + return err + } + errors = append(errors, err) + } + + // no validation rules for Offset + + // no validation rules for Limit + + if len(errors) > 0 { + return GetLogsRequestMultiError(errors) + } + + return nil +} + +// GetLogsRequestMultiError is an error wrapping multiple validation errors +// returned by GetLogsRequest.ValidateAll() if the designated constraints +// aren't met. +type GetLogsRequestMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m GetLogsRequestMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m GetLogsRequestMultiError) AllErrors() []error { return m } + +// GetLogsRequestValidationError is the validation error returned by +// GetLogsRequest.Validate if the designated constraints aren't met. +type GetLogsRequestValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e GetLogsRequestValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e GetLogsRequestValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e GetLogsRequestValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e GetLogsRequestValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e GetLogsRequestValidationError) ErrorName() string { return "GetLogsRequestValidationError" } + +// Error satisfies the builtin error interface +func (e GetLogsRequestValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sGetLogsRequest.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = GetLogsRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = GetLogsRequestValidationError{} + +// Validate checks the field values on GetLogsResponse with the rules defined +// in the proto definition for this message. If any rules are violated, the +// first error encountered is returned, or nil if there are no violations. +func (m *GetLogsResponse) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on GetLogsResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// GetLogsResponseMultiError, or nil if none found. +func (m *GetLogsResponse) ValidateAll() error { + return m.validate(true) +} + +func (m *GetLogsResponse) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + for idx, item := range m.GetLogs() { + _, _ = idx, item + + if all { + switch v := interface{}(item).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, GetLogsResponseValidationError{ + field: fmt.Sprintf("Logs[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, GetLogsResponseValidationError{ + field: fmt.Sprintf("Logs[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(item).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return GetLogsResponseValidationError{ + field: fmt.Sprintf("Logs[%v]", idx), + reason: "embedded message failed validation", + cause: err, + } + } + } + + } + + // no validation rules for End + + if len(errors) > 0 { + return GetLogsResponseMultiError(errors) + } + + return nil +} + +// GetLogsResponseMultiError is an error wrapping multiple validation errors +// returned by GetLogsResponse.ValidateAll() if the designated constraints +// aren't met. +type GetLogsResponseMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m GetLogsResponseMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m GetLogsResponseMultiError) AllErrors() []error { return m } + +// GetLogsResponseValidationError is the validation error returned by +// GetLogsResponse.Validate if the designated constraints aren't met. +type GetLogsResponseValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e GetLogsResponseValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e GetLogsResponseValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e GetLogsResponseValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e GetLogsResponseValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e GetLogsResponseValidationError) ErrorName() string { return "GetLogsResponseValidationError" } + +// Error satisfies the builtin error interface +func (e GetLogsResponseValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sGetLogsResponse.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = GetLogsResponseValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = GetLogsResponseValidationError{} + +// Validate checks the field values on LogChunk with the rules defined in the +// proto definition for this message. If any rules are violated, the first +// error encountered is returned, or nil if there are no violations. +func (m *LogChunk) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on LogChunk with the rules defined in +// the proto definition for this message. If any rules are violated, the +// result is a list of violation errors wrapped in LogChunkMultiError, or nil +// if none found. +func (m *LogChunk) ValidateAll() error { + return m.validate(true) +} + +func (m *LogChunk) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for ChunkId + + // no validation rules for Data + + if len(errors) > 0 { + return LogChunkMultiError(errors) + } + + return nil +} + +// LogChunkMultiError is an error wrapping multiple validation errors returned +// by LogChunk.ValidateAll() if the designated constraints aren't met. +type LogChunkMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m LogChunkMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m LogChunkMultiError) AllErrors() []error { return m } + +// LogChunkValidationError is the validation error returned by +// LogChunk.Validate if the designated constraints aren't met. +type LogChunkValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e LogChunkValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e LogChunkValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e LogChunkValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e LogChunkValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e LogChunkValidationError) ErrorName() string { return "LogChunkValidationError" } + +// Error satisfies the builtin error interface +func (e LogChunkValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sLogChunk.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = LogChunkValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = LogChunkValidationError{} + +// Validate checks the field values on SFTPParameters with the rules defined in +// the proto definition for this message. If any rules are violated, the first +// error encountered is returned, or nil if there are no violations. +func (m *SFTPParameters) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on SFTPParameters with the rules defined +// in the proto definition for this message. If any rules are violated, the +// result is a list of violation errors wrapped in SFTPParametersMultiError, +// or nil if none found. +func (m *SFTPParameters) ValidateAll() error { + return m.validate(true) +} + +func (m *SFTPParameters) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if utf8.RuneCountInString(m.GetAddress()) < 1 { + err := SFTPParametersValidationError{ + field: "Address", + reason: "value length must be at least 1 runes", + } + if !all { + return err + } + errors = append(errors, err) + } + + if utf8.RuneCountInString(m.GetUser()) < 1 { + err := SFTPParametersValidationError{ + field: "User", + reason: "value length must be at least 1 runes", + } + if !all { + return err + } + errors = append(errors, err) + } + + if utf8.RuneCountInString(m.GetPassword()) < 1 { + err := SFTPParametersValidationError{ + field: "Password", + reason: "value length must be at least 1 runes", + } + if !all { + return err + } + errors = append(errors, err) + } + + // no validation rules for Directory + + if len(errors) > 0 { + return SFTPParametersMultiError(errors) + } + + return nil +} + +// SFTPParametersMultiError is an error wrapping multiple validation errors +// returned by SFTPParameters.ValidateAll() if the designated constraints +// aren't met. +type SFTPParametersMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m SFTPParametersMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m SFTPParametersMultiError) AllErrors() []error { return m } + +// SFTPParametersValidationError is the validation error returned by +// SFTPParameters.Validate if the designated constraints aren't met. +type SFTPParametersValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e SFTPParametersValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e SFTPParametersValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e SFTPParametersValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e SFTPParametersValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e SFTPParametersValidationError) ErrorName() string { return "SFTPParametersValidationError" } + +// Error satisfies the builtin error interface +func (e SFTPParametersValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sSFTPParameters.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = SFTPParametersValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = SFTPParametersValidationError{} + +// Validate checks the field values on UploadDumpRequest with the rules defined +// in the proto definition for this message. If any rules are violated, the +// first error encountered is returned, or nil if there are no violations. +func (m *UploadDumpRequest) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on UploadDumpRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// UploadDumpRequestMultiError, or nil if none found. +func (m *UploadDumpRequest) ValidateAll() error { + return m.validate(true) +} + +func (m *UploadDumpRequest) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if len(m.GetDumpIds()) < 1 { + err := UploadDumpRequestValidationError{ + field: "DumpIds", + reason: "value must contain at least 1 item(s)", + } + if !all { + return err + } + errors = append(errors, err) + } + + _UploadDumpRequest_DumpIds_Unique := make(map[string]struct{}, len(m.GetDumpIds())) + + for idx, item := range m.GetDumpIds() { + _, _ = idx, item + + if _, exists := _UploadDumpRequest_DumpIds_Unique[item]; exists { + err := UploadDumpRequestValidationError{ + field: fmt.Sprintf("DumpIds[%v]", idx), + reason: "repeated value must contain unique items", + } + if !all { + return err + } + errors = append(errors, err) + } else { + _UploadDumpRequest_DumpIds_Unique[item] = struct{}{} + } + + // no validation rules for DumpIds[idx] + } + + if m.GetSftpParameters() == nil { + err := UploadDumpRequestValidationError{ + field: "SftpParameters", + reason: "value is required", + } + if !all { + return err + } + errors = append(errors, err) + } + + if all { + switch v := interface{}(m.GetSftpParameters()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, UploadDumpRequestValidationError{ + field: "SftpParameters", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, UploadDumpRequestValidationError{ + field: "SftpParameters", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetSftpParameters()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return UploadDumpRequestValidationError{ + field: "SftpParameters", + reason: "embedded message failed validation", + cause: err, + } + } + } + + if len(errors) > 0 { + return UploadDumpRequestMultiError(errors) + } + + return nil +} + +// UploadDumpRequestMultiError is an error wrapping multiple validation errors +// returned by UploadDumpRequest.ValidateAll() if the designated constraints +// aren't met. +type UploadDumpRequestMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m UploadDumpRequestMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m UploadDumpRequestMultiError) AllErrors() []error { return m } + +// UploadDumpRequestValidationError is the validation error returned by +// UploadDumpRequest.Validate if the designated constraints aren't met. +type UploadDumpRequestValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e UploadDumpRequestValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e UploadDumpRequestValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e UploadDumpRequestValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e UploadDumpRequestValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e UploadDumpRequestValidationError) ErrorName() string { + return "UploadDumpRequestValidationError" +} + +// Error satisfies the builtin error interface +func (e UploadDumpRequestValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sUploadDumpRequest.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = UploadDumpRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = UploadDumpRequestValidationError{} + +// Validate checks the field values on UploadDumpResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *UploadDumpResponse) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on UploadDumpResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// UploadDumpResponseMultiError, or nil if none found. +func (m *UploadDumpResponse) ValidateAll() error { + return m.validate(true) +} + +func (m *UploadDumpResponse) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if len(errors) > 0 { + return UploadDumpResponseMultiError(errors) + } + + return nil +} + +// UploadDumpResponseMultiError is an error wrapping multiple validation errors +// returned by UploadDumpResponse.ValidateAll() if the designated constraints +// aren't met. +type UploadDumpResponseMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m UploadDumpResponseMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m UploadDumpResponseMultiError) AllErrors() []error { return m } + +// UploadDumpResponseValidationError is the validation error returned by +// UploadDumpResponse.Validate if the designated constraints aren't met. +type UploadDumpResponseValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e UploadDumpResponseValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e UploadDumpResponseValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e UploadDumpResponseValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e UploadDumpResponseValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e UploadDumpResponseValidationError) ErrorName() string { + return "UploadDumpResponseValidationError" +} + +// Error satisfies the builtin error interface +func (e UploadDumpResponseValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sUploadDumpResponse.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = UploadDumpResponseValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = UploadDumpResponseValidationError{} diff --git a/api/managementpb/dump/dump.proto b/api/managementpb/dump/dump.proto new file mode 100644 index 0000000000..4328af81fc --- /dev/null +++ b/api/managementpb/dump/dump.proto @@ -0,0 +1,127 @@ +syntax = "proto3"; + +package dump.v1beta1; + +import "google/api/annotations.proto"; +import "google/protobuf/timestamp.proto"; +import "protoc-gen-openapiv2/options/annotations.proto"; +import "validate/validate.proto"; + +option go_package = "api/managementpb/dump;dumpv1beta1"; + +enum DumpStatus { + DUMP_STATUS_INVALID = 0; + DUMP_STATUS_IN_PROGRESS = 1; + DUMP_STATUS_SUCCESS = 2; + DUMP_STATUS_ERROR = 3; +} + +message Dump { + string dump_id = 1; + DumpStatus status = 2; + repeated string service_names = 3; + google.protobuf.Timestamp start_time = 4; + google.protobuf.Timestamp end_time = 5; + google.protobuf.Timestamp created_at = 7; +} + +message StartDumpRequest { + repeated string service_names = 1; + google.protobuf.Timestamp start_time = 2; + google.protobuf.Timestamp end_time = 3; + bool export_qan = 4; + bool ignore_load = 5; +} + +message StartDumpResponse { + string dump_id = 1; +} + +message ListDumpsRequest {} + +message ListDumpsResponse { + repeated Dump dumps = 1; +} + +message DeleteDumpRequest { + repeated string dump_ids = 1 [(validate.rules).repeated = { + min_items: 1, + unique: true + }]; +} + +message DeleteDumpResponse {} + +message GetLogsRequest { + string dump_id = 1 [(validate.rules).string.min_len = 1]; + uint32 offset = 2; + uint32 limit = 3; +} + +message GetLogsResponse { + repeated LogChunk logs = 1; + bool end = 2; +} + +// LogChunk represent one chunk of logs. +message LogChunk { + uint32 chunk_id = 1; + string data = 2; +} + +message SFTPParameters { + string address = 1 [(validate.rules).string.min_len = 1]; + string user = 2 [(validate.rules).string.min_len = 1]; + string password = 3 [(validate.rules).string.min_len = 1]; + string directory = 4; +} + +message UploadDumpRequest { + repeated string dump_ids = 1 [(validate.rules).repeated = { + min_items: 1, + unique: true + }]; + + // SFTP upload parameters. + SFTPParameters sftp_parameters = 2 [(validate.rules).message.required = true]; +} + +message UploadDumpResponse {} + +service Dumps { + // StartDump request creates pmm dump. + rpc StartDump(StartDumpRequest) returns (StartDumpResponse) { + option (google.api.http) = { + post: "/v1/management/dump/Dumps/Start" + body: "*" + }; + } + // ListDumps returns a list of all pmm dumps. + rpc ListDumps(ListDumpsRequest) returns (ListDumpsResponse) { + option (google.api.http) = { + post: "/v1/management/dump/Dumps/List" + body: "*" + }; + } + // DeleteDump deletes specified pmm dump. + rpc DeleteDump(DeleteDumpRequest) returns (DeleteDumpResponse) { + option (google.api.http) = { + post: "/v1/management/dump/Dumps/Delete" + body: "*" + }; + } + // GetLogs returns logs from pmm-dump tool. + rpc GetDumpLogs(GetLogsRequest) returns (GetLogsResponse) { + option (google.api.http) = { + post: "/v1/management/dump/Dumps/GetLogs" + body: "*" + }; + } + // UploadDump uploads selected dumps to remote server. + rpc UploadDump(UploadDumpRequest) returns (UploadDumpResponse) { + option (google.api.http) = { + post: "/v1/management/dump/Dumps/Upload" + body: "*" + }; + } +} diff --git a/api/managementpb/dump/dump_grpc.pb.go b/api/managementpb/dump/dump_grpc.pb.go new file mode 100644 index 0000000000..5b60dc27d6 --- /dev/null +++ b/api/managementpb/dump/dump_grpc.pb.go @@ -0,0 +1,271 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc (unknown) +// source: managementpb/dump/dump.proto + +package dumpv1beta1 + +import ( + context "context" + + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + Dumps_StartDump_FullMethodName = "/dump.v1beta1.Dumps/StartDump" + Dumps_ListDumps_FullMethodName = "/dump.v1beta1.Dumps/ListDumps" + Dumps_DeleteDump_FullMethodName = "/dump.v1beta1.Dumps/DeleteDump" + Dumps_GetDumpLogs_FullMethodName = "/dump.v1beta1.Dumps/GetDumpLogs" + Dumps_UploadDump_FullMethodName = "/dump.v1beta1.Dumps/UploadDump" +) + +// DumpsClient is the client API for Dumps service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type DumpsClient interface { + // StartDump request creates pmm dump. + StartDump(ctx context.Context, in *StartDumpRequest, opts ...grpc.CallOption) (*StartDumpResponse, error) + // ListDumps returns a list of all pmm dumps. + ListDumps(ctx context.Context, in *ListDumpsRequest, opts ...grpc.CallOption) (*ListDumpsResponse, error) + // DeleteDump deletes specified pmm dump. + DeleteDump(ctx context.Context, in *DeleteDumpRequest, opts ...grpc.CallOption) (*DeleteDumpResponse, error) + // GetLogs returns logs from pmm-dump tool. + GetDumpLogs(ctx context.Context, in *GetLogsRequest, opts ...grpc.CallOption) (*GetLogsResponse, error) + // UploadDump uploads selected dumps to remote server. + UploadDump(ctx context.Context, in *UploadDumpRequest, opts ...grpc.CallOption) (*UploadDumpResponse, error) +} + +type dumpsClient struct { + cc grpc.ClientConnInterface +} + +func NewDumpsClient(cc grpc.ClientConnInterface) DumpsClient { + return &dumpsClient{cc} +} + +func (c *dumpsClient) StartDump(ctx context.Context, in *StartDumpRequest, opts ...grpc.CallOption) (*StartDumpResponse, error) { + out := new(StartDumpResponse) + err := c.cc.Invoke(ctx, Dumps_StartDump_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *dumpsClient) ListDumps(ctx context.Context, in *ListDumpsRequest, opts ...grpc.CallOption) (*ListDumpsResponse, error) { + out := new(ListDumpsResponse) + err := c.cc.Invoke(ctx, Dumps_ListDumps_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *dumpsClient) DeleteDump(ctx context.Context, in *DeleteDumpRequest, opts ...grpc.CallOption) (*DeleteDumpResponse, error) { + out := new(DeleteDumpResponse) + err := c.cc.Invoke(ctx, Dumps_DeleteDump_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *dumpsClient) GetDumpLogs(ctx context.Context, in *GetLogsRequest, opts ...grpc.CallOption) (*GetLogsResponse, error) { + out := new(GetLogsResponse) + err := c.cc.Invoke(ctx, Dumps_GetDumpLogs_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *dumpsClient) UploadDump(ctx context.Context, in *UploadDumpRequest, opts ...grpc.CallOption) (*UploadDumpResponse, error) { + out := new(UploadDumpResponse) + err := c.cc.Invoke(ctx, Dumps_UploadDump_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// DumpsServer is the server API for Dumps service. +// All implementations must embed UnimplementedDumpsServer +// for forward compatibility +type DumpsServer interface { + // StartDump request creates pmm dump. + StartDump(context.Context, *StartDumpRequest) (*StartDumpResponse, error) + // ListDumps returns a list of all pmm dumps. + ListDumps(context.Context, *ListDumpsRequest) (*ListDumpsResponse, error) + // DeleteDump deletes specified pmm dump. + DeleteDump(context.Context, *DeleteDumpRequest) (*DeleteDumpResponse, error) + // GetLogs returns logs from pmm-dump tool. + GetDumpLogs(context.Context, *GetLogsRequest) (*GetLogsResponse, error) + // UploadDump uploads selected dumps to remote server. + UploadDump(context.Context, *UploadDumpRequest) (*UploadDumpResponse, error) + mustEmbedUnimplementedDumpsServer() +} + +// UnimplementedDumpsServer must be embedded to have forward compatible implementations. +type UnimplementedDumpsServer struct{} + +func (UnimplementedDumpsServer) StartDump(context.Context, *StartDumpRequest) (*StartDumpResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method StartDump not implemented") +} + +func (UnimplementedDumpsServer) ListDumps(context.Context, *ListDumpsRequest) (*ListDumpsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListDumps not implemented") +} + +func (UnimplementedDumpsServer) DeleteDump(context.Context, *DeleteDumpRequest) (*DeleteDumpResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteDump not implemented") +} + +func (UnimplementedDumpsServer) GetDumpLogs(context.Context, *GetLogsRequest) (*GetLogsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetDumpLogs not implemented") +} + +func (UnimplementedDumpsServer) UploadDump(context.Context, *UploadDumpRequest) (*UploadDumpResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UploadDump not implemented") +} +func (UnimplementedDumpsServer) mustEmbedUnimplementedDumpsServer() {} + +// UnsafeDumpsServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to DumpsServer will +// result in compilation errors. +type UnsafeDumpsServer interface { + mustEmbedUnimplementedDumpsServer() +} + +func RegisterDumpsServer(s grpc.ServiceRegistrar, srv DumpsServer) { + s.RegisterService(&Dumps_ServiceDesc, srv) +} + +func _Dumps_StartDump_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(StartDumpRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DumpsServer).StartDump(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Dumps_StartDump_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DumpsServer).StartDump(ctx, req.(*StartDumpRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dumps_ListDumps_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListDumpsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DumpsServer).ListDumps(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Dumps_ListDumps_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DumpsServer).ListDumps(ctx, req.(*ListDumpsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dumps_DeleteDump_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteDumpRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DumpsServer).DeleteDump(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Dumps_DeleteDump_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DumpsServer).DeleteDump(ctx, req.(*DeleteDumpRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dumps_GetDumpLogs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetLogsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DumpsServer).GetDumpLogs(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Dumps_GetDumpLogs_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DumpsServer).GetDumpLogs(ctx, req.(*GetLogsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dumps_UploadDump_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UploadDumpRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DumpsServer).UploadDump(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Dumps_UploadDump_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DumpsServer).UploadDump(ctx, req.(*UploadDumpRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// Dumps_ServiceDesc is the grpc.ServiceDesc for Dumps service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var Dumps_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "dump.v1beta1.Dumps", + HandlerType: (*DumpsServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "StartDump", + Handler: _Dumps_StartDump_Handler, + }, + { + MethodName: "ListDumps", + Handler: _Dumps_ListDumps_Handler, + }, + { + MethodName: "DeleteDump", + Handler: _Dumps_DeleteDump_Handler, + }, + { + MethodName: "GetDumpLogs", + Handler: _Dumps_GetDumpLogs_Handler, + }, + { + MethodName: "UploadDump", + Handler: _Dumps_UploadDump_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "managementpb/dump/dump.proto", +} diff --git a/api/managementpb/dump/json/client/dumps/delete_dump_parameters.go b/api/managementpb/dump/json/client/dumps/delete_dump_parameters.go new file mode 100644 index 0000000000..d61a07c02d --- /dev/null +++ b/api/managementpb/dump/json/client/dumps/delete_dump_parameters.go @@ -0,0 +1,144 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package dumps + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + "time" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + cr "github.com/go-openapi/runtime/client" + "github.com/go-openapi/strfmt" +) + +// NewDeleteDumpParams creates a new DeleteDumpParams object, +// with the default timeout for this client. +// +// Default values are not hydrated, since defaults are normally applied by the API server side. +// +// To enforce default values in parameter, use SetDefaults or WithDefaults. +func NewDeleteDumpParams() *DeleteDumpParams { + return &DeleteDumpParams{ + timeout: cr.DefaultTimeout, + } +} + +// NewDeleteDumpParamsWithTimeout creates a new DeleteDumpParams object +// with the ability to set a timeout on a request. +func NewDeleteDumpParamsWithTimeout(timeout time.Duration) *DeleteDumpParams { + return &DeleteDumpParams{ + timeout: timeout, + } +} + +// NewDeleteDumpParamsWithContext creates a new DeleteDumpParams object +// with the ability to set a context for a request. +func NewDeleteDumpParamsWithContext(ctx context.Context) *DeleteDumpParams { + return &DeleteDumpParams{ + Context: ctx, + } +} + +// NewDeleteDumpParamsWithHTTPClient creates a new DeleteDumpParams object +// with the ability to set a custom HTTPClient for a request. +func NewDeleteDumpParamsWithHTTPClient(client *http.Client) *DeleteDumpParams { + return &DeleteDumpParams{ + HTTPClient: client, + } +} + +/* +DeleteDumpParams contains all the parameters to send to the API endpoint + + for the delete dump operation. + + Typically these are written to a http.Request. +*/ +type DeleteDumpParams struct { + // Body. + Body DeleteDumpBody + + timeout time.Duration + Context context.Context + HTTPClient *http.Client +} + +// WithDefaults hydrates default values in the delete dump params (not the query body). +// +// All values with no default are reset to their zero value. +func (o *DeleteDumpParams) WithDefaults() *DeleteDumpParams { + o.SetDefaults() + return o +} + +// SetDefaults hydrates default values in the delete dump params (not the query body). +// +// All values with no default are reset to their zero value. +func (o *DeleteDumpParams) SetDefaults() { + // no default values defined for this parameter +} + +// WithTimeout adds the timeout to the delete dump params +func (o *DeleteDumpParams) WithTimeout(timeout time.Duration) *DeleteDumpParams { + o.SetTimeout(timeout) + return o +} + +// SetTimeout adds the timeout to the delete dump params +func (o *DeleteDumpParams) SetTimeout(timeout time.Duration) { + o.timeout = timeout +} + +// WithContext adds the context to the delete dump params +func (o *DeleteDumpParams) WithContext(ctx context.Context) *DeleteDumpParams { + o.SetContext(ctx) + return o +} + +// SetContext adds the context to the delete dump params +func (o *DeleteDumpParams) SetContext(ctx context.Context) { + o.Context = ctx +} + +// WithHTTPClient adds the HTTPClient to the delete dump params +func (o *DeleteDumpParams) WithHTTPClient(client *http.Client) *DeleteDumpParams { + o.SetHTTPClient(client) + return o +} + +// SetHTTPClient adds the HTTPClient to the delete dump params +func (o *DeleteDumpParams) SetHTTPClient(client *http.Client) { + o.HTTPClient = client +} + +// WithBody adds the body to the delete dump params +func (o *DeleteDumpParams) WithBody(body DeleteDumpBody) *DeleteDumpParams { + o.SetBody(body) + return o +} + +// SetBody adds the body to the delete dump params +func (o *DeleteDumpParams) SetBody(body DeleteDumpBody) { + o.Body = body +} + +// WriteToRequest writes these params to a swagger request +func (o *DeleteDumpParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error { + if err := r.SetTimeout(o.timeout); err != nil { + return err + } + var res []error + if err := r.SetBodyParam(o.Body); err != nil { + return err + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/api/managementpb/dump/json/client/dumps/delete_dump_responses.go b/api/managementpb/dump/json/client/dumps/delete_dump_responses.go new file mode 100644 index 0000000000..2dc075dfa7 --- /dev/null +++ b/api/managementpb/dump/json/client/dumps/delete_dump_responses.go @@ -0,0 +1,295 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package dumps + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "fmt" + "io" + "strconv" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" +) + +// DeleteDumpReader is a Reader for the DeleteDump structure. +type DeleteDumpReader struct { + formats strfmt.Registry +} + +// ReadResponse reads a server response into the received o. +func (o *DeleteDumpReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) { + switch response.Code() { + case 200: + result := NewDeleteDumpOK() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return result, nil + default: + result := NewDeleteDumpDefault(response.Code()) + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + if response.Code()/100 == 2 { + return result, nil + } + return nil, result + } +} + +// NewDeleteDumpOK creates a DeleteDumpOK with default headers values +func NewDeleteDumpOK() *DeleteDumpOK { + return &DeleteDumpOK{} +} + +/* +DeleteDumpOK describes a response with status code 200, with default header values. + +A successful response. +*/ +type DeleteDumpOK struct { + Payload interface{} +} + +func (o *DeleteDumpOK) Error() string { + return fmt.Sprintf("[POST /v1/management/dump/Dumps/Delete][%d] deleteDumpOk %+v", 200, o.Payload) +} + +func (o *DeleteDumpOK) GetPayload() interface{} { + return o.Payload +} + +func (o *DeleteDumpOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + // response payload + if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} + +// NewDeleteDumpDefault creates a DeleteDumpDefault with default headers values +func NewDeleteDumpDefault(code int) *DeleteDumpDefault { + return &DeleteDumpDefault{ + _statusCode: code, + } +} + +/* +DeleteDumpDefault describes a response with status code -1, with default header values. + +An unexpected error response. +*/ +type DeleteDumpDefault struct { + _statusCode int + + Payload *DeleteDumpDefaultBody +} + +// Code gets the status code for the delete dump default response +func (o *DeleteDumpDefault) Code() int { + return o._statusCode +} + +func (o *DeleteDumpDefault) Error() string { + return fmt.Sprintf("[POST /v1/management/dump/Dumps/Delete][%d] DeleteDump default %+v", o._statusCode, o.Payload) +} + +func (o *DeleteDumpDefault) GetPayload() *DeleteDumpDefaultBody { + return o.Payload +} + +func (o *DeleteDumpDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + o.Payload = new(DeleteDumpDefaultBody) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} + +/* +DeleteDumpBody delete dump body +swagger:model DeleteDumpBody +*/ +type DeleteDumpBody struct { + // dump ids + DumpIds []string `json:"dump_ids"` +} + +// Validate validates this delete dump body +func (o *DeleteDumpBody) Validate(formats strfmt.Registry) error { + return nil +} + +// ContextValidate validates this delete dump body based on context it is used +func (o *DeleteDumpBody) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (o *DeleteDumpBody) MarshalBinary() ([]byte, error) { + if o == nil { + return nil, nil + } + return swag.WriteJSON(o) +} + +// UnmarshalBinary interface implementation +func (o *DeleteDumpBody) UnmarshalBinary(b []byte) error { + var res DeleteDumpBody + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *o = res + return nil +} + +/* +DeleteDumpDefaultBody delete dump default body +swagger:model DeleteDumpDefaultBody +*/ +type DeleteDumpDefaultBody struct { + // code + Code int32 `json:"code,omitempty"` + + // message + Message string `json:"message,omitempty"` + + // details + Details []*DeleteDumpDefaultBodyDetailsItems0 `json:"details"` +} + +// Validate validates this delete dump default body +func (o *DeleteDumpDefaultBody) Validate(formats strfmt.Registry) error { + var res []error + + if err := o.validateDetails(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *DeleteDumpDefaultBody) validateDetails(formats strfmt.Registry) error { + if swag.IsZero(o.Details) { // not required + return nil + } + + for i := 0; i < len(o.Details); i++ { + if swag.IsZero(o.Details[i]) { // not required + continue + } + + if o.Details[i] != nil { + if err := o.Details[i].Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("DeleteDump default" + "." + "details" + "." + strconv.Itoa(i)) + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("DeleteDump default" + "." + "details" + "." + strconv.Itoa(i)) + } + return err + } + } + + } + + return nil +} + +// ContextValidate validate this delete dump default body based on the context it is used +func (o *DeleteDumpDefaultBody) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + var res []error + + if err := o.contextValidateDetails(ctx, formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *DeleteDumpDefaultBody) contextValidateDetails(ctx context.Context, formats strfmt.Registry) error { + for i := 0; i < len(o.Details); i++ { + if o.Details[i] != nil { + if err := o.Details[i].ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("DeleteDump default" + "." + "details" + "." + strconv.Itoa(i)) + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("DeleteDump default" + "." + "details" + "." + strconv.Itoa(i)) + } + return err + } + } + } + + return nil +} + +// MarshalBinary interface implementation +func (o *DeleteDumpDefaultBody) MarshalBinary() ([]byte, error) { + if o == nil { + return nil, nil + } + return swag.WriteJSON(o) +} + +// UnmarshalBinary interface implementation +func (o *DeleteDumpDefaultBody) UnmarshalBinary(b []byte) error { + var res DeleteDumpDefaultBody + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *o = res + return nil +} + +/* +DeleteDumpDefaultBodyDetailsItems0 delete dump default body details items0 +swagger:model DeleteDumpDefaultBodyDetailsItems0 +*/ +type DeleteDumpDefaultBodyDetailsItems0 struct { + // at type + AtType string `json:"@type,omitempty"` +} + +// Validate validates this delete dump default body details items0 +func (o *DeleteDumpDefaultBodyDetailsItems0) Validate(formats strfmt.Registry) error { + return nil +} + +// ContextValidate validates this delete dump default body details items0 based on context it is used +func (o *DeleteDumpDefaultBodyDetailsItems0) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (o *DeleteDumpDefaultBodyDetailsItems0) MarshalBinary() ([]byte, error) { + if o == nil { + return nil, nil + } + return swag.WriteJSON(o) +} + +// UnmarshalBinary interface implementation +func (o *DeleteDumpDefaultBodyDetailsItems0) UnmarshalBinary(b []byte) error { + var res DeleteDumpDefaultBodyDetailsItems0 + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *o = res + return nil +} diff --git a/api/managementpb/dump/json/client/dumps/dumps_client.go b/api/managementpb/dump/json/client/dumps/dumps_client.go new file mode 100644 index 0000000000..b0b7dea6e1 --- /dev/null +++ b/api/managementpb/dump/json/client/dumps/dumps_client.go @@ -0,0 +1,232 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package dumps + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "github.com/go-openapi/runtime" + "github.com/go-openapi/strfmt" +) + +// New creates a new dumps API client. +func New(transport runtime.ClientTransport, formats strfmt.Registry) ClientService { + return &Client{transport: transport, formats: formats} +} + +/* +Client for dumps API +*/ +type Client struct { + transport runtime.ClientTransport + formats strfmt.Registry +} + +// ClientOption is the option for Client methods +type ClientOption func(*runtime.ClientOperation) + +// ClientService is the interface for Client methods +type ClientService interface { + DeleteDump(params *DeleteDumpParams, opts ...ClientOption) (*DeleteDumpOK, error) + + GetDumpLogs(params *GetDumpLogsParams, opts ...ClientOption) (*GetDumpLogsOK, error) + + ListDumps(params *ListDumpsParams, opts ...ClientOption) (*ListDumpsOK, error) + + StartDump(params *StartDumpParams, opts ...ClientOption) (*StartDumpOK, error) + + UploadDump(params *UploadDumpParams, opts ...ClientOption) (*UploadDumpOK, error) + + SetTransport(transport runtime.ClientTransport) +} + +/* +DeleteDump deletes dump deletes specified pmm dump +*/ +func (a *Client) DeleteDump(params *DeleteDumpParams, opts ...ClientOption) (*DeleteDumpOK, error) { + // TODO: Validate the params before sending + if params == nil { + params = NewDeleteDumpParams() + } + op := &runtime.ClientOperation{ + ID: "DeleteDump", + Method: "POST", + PathPattern: "/v1/management/dump/Dumps/Delete", + ProducesMediaTypes: []string{"application/json"}, + ConsumesMediaTypes: []string{"application/json"}, + Schemes: []string{"http", "https"}, + Params: params, + Reader: &DeleteDumpReader{formats: a.formats}, + Context: params.Context, + Client: params.HTTPClient, + } + for _, opt := range opts { + opt(op) + } + + result, err := a.transport.Submit(op) + if err != nil { + return nil, err + } + success, ok := result.(*DeleteDumpOK) + if ok { + return success, nil + } + // unexpected success response + unexpectedSuccess := result.(*DeleteDumpDefault) + return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) +} + +/* +GetDumpLogs gets logs returns logs from pmm dump tool +*/ +func (a *Client) GetDumpLogs(params *GetDumpLogsParams, opts ...ClientOption) (*GetDumpLogsOK, error) { + // TODO: Validate the params before sending + if params == nil { + params = NewGetDumpLogsParams() + } + op := &runtime.ClientOperation{ + ID: "GetDumpLogs", + Method: "POST", + PathPattern: "/v1/management/dump/Dumps/GetLogs", + ProducesMediaTypes: []string{"application/json"}, + ConsumesMediaTypes: []string{"application/json"}, + Schemes: []string{"http", "https"}, + Params: params, + Reader: &GetDumpLogsReader{formats: a.formats}, + Context: params.Context, + Client: params.HTTPClient, + } + for _, opt := range opts { + opt(op) + } + + result, err := a.transport.Submit(op) + if err != nil { + return nil, err + } + success, ok := result.(*GetDumpLogsOK) + if ok { + return success, nil + } + // unexpected success response + unexpectedSuccess := result.(*GetDumpLogsDefault) + return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) +} + +/* +ListDumps lists dumps returns a list of all pmm dumps +*/ +func (a *Client) ListDumps(params *ListDumpsParams, opts ...ClientOption) (*ListDumpsOK, error) { + // TODO: Validate the params before sending + if params == nil { + params = NewListDumpsParams() + } + op := &runtime.ClientOperation{ + ID: "ListDumps", + Method: "POST", + PathPattern: "/v1/management/dump/Dumps/List", + ProducesMediaTypes: []string{"application/json"}, + ConsumesMediaTypes: []string{"application/json"}, + Schemes: []string{"http", "https"}, + Params: params, + Reader: &ListDumpsReader{formats: a.formats}, + Context: params.Context, + Client: params.HTTPClient, + } + for _, opt := range opts { + opt(op) + } + + result, err := a.transport.Submit(op) + if err != nil { + return nil, err + } + success, ok := result.(*ListDumpsOK) + if ok { + return success, nil + } + // unexpected success response + unexpectedSuccess := result.(*ListDumpsDefault) + return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) +} + +/* +StartDump starts dump request creates pmm dump +*/ +func (a *Client) StartDump(params *StartDumpParams, opts ...ClientOption) (*StartDumpOK, error) { + // TODO: Validate the params before sending + if params == nil { + params = NewStartDumpParams() + } + op := &runtime.ClientOperation{ + ID: "StartDump", + Method: "POST", + PathPattern: "/v1/management/dump/Dumps/Start", + ProducesMediaTypes: []string{"application/json"}, + ConsumesMediaTypes: []string{"application/json"}, + Schemes: []string{"http", "https"}, + Params: params, + Reader: &StartDumpReader{formats: a.formats}, + Context: params.Context, + Client: params.HTTPClient, + } + for _, opt := range opts { + opt(op) + } + + result, err := a.transport.Submit(op) + if err != nil { + return nil, err + } + success, ok := result.(*StartDumpOK) + if ok { + return success, nil + } + // unexpected success response + unexpectedSuccess := result.(*StartDumpDefault) + return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) +} + +/* +UploadDump uploads dump uploads selected dumps to remote server +*/ +func (a *Client) UploadDump(params *UploadDumpParams, opts ...ClientOption) (*UploadDumpOK, error) { + // TODO: Validate the params before sending + if params == nil { + params = NewUploadDumpParams() + } + op := &runtime.ClientOperation{ + ID: "UploadDump", + Method: "POST", + PathPattern: "/v1/management/dump/Dumps/Upload", + ProducesMediaTypes: []string{"application/json"}, + ConsumesMediaTypes: []string{"application/json"}, + Schemes: []string{"http", "https"}, + Params: params, + Reader: &UploadDumpReader{formats: a.formats}, + Context: params.Context, + Client: params.HTTPClient, + } + for _, opt := range opts { + opt(op) + } + + result, err := a.transport.Submit(op) + if err != nil { + return nil, err + } + success, ok := result.(*UploadDumpOK) + if ok { + return success, nil + } + // unexpected success response + unexpectedSuccess := result.(*UploadDumpDefault) + return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) +} + +// SetTransport changes the transport on the client +func (a *Client) SetTransport(transport runtime.ClientTransport) { + a.transport = transport +} diff --git a/api/managementpb/dump/json/client/dumps/get_dump_logs_parameters.go b/api/managementpb/dump/json/client/dumps/get_dump_logs_parameters.go new file mode 100644 index 0000000000..5664df29c3 --- /dev/null +++ b/api/managementpb/dump/json/client/dumps/get_dump_logs_parameters.go @@ -0,0 +1,144 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package dumps + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + "time" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + cr "github.com/go-openapi/runtime/client" + "github.com/go-openapi/strfmt" +) + +// NewGetDumpLogsParams creates a new GetDumpLogsParams object, +// with the default timeout for this client. +// +// Default values are not hydrated, since defaults are normally applied by the API server side. +// +// To enforce default values in parameter, use SetDefaults or WithDefaults. +func NewGetDumpLogsParams() *GetDumpLogsParams { + return &GetDumpLogsParams{ + timeout: cr.DefaultTimeout, + } +} + +// NewGetDumpLogsParamsWithTimeout creates a new GetDumpLogsParams object +// with the ability to set a timeout on a request. +func NewGetDumpLogsParamsWithTimeout(timeout time.Duration) *GetDumpLogsParams { + return &GetDumpLogsParams{ + timeout: timeout, + } +} + +// NewGetDumpLogsParamsWithContext creates a new GetDumpLogsParams object +// with the ability to set a context for a request. +func NewGetDumpLogsParamsWithContext(ctx context.Context) *GetDumpLogsParams { + return &GetDumpLogsParams{ + Context: ctx, + } +} + +// NewGetDumpLogsParamsWithHTTPClient creates a new GetDumpLogsParams object +// with the ability to set a custom HTTPClient for a request. +func NewGetDumpLogsParamsWithHTTPClient(client *http.Client) *GetDumpLogsParams { + return &GetDumpLogsParams{ + HTTPClient: client, + } +} + +/* +GetDumpLogsParams contains all the parameters to send to the API endpoint + + for the get dump logs operation. + + Typically these are written to a http.Request. +*/ +type GetDumpLogsParams struct { + // Body. + Body GetDumpLogsBody + + timeout time.Duration + Context context.Context + HTTPClient *http.Client +} + +// WithDefaults hydrates default values in the get dump logs params (not the query body). +// +// All values with no default are reset to their zero value. +func (o *GetDumpLogsParams) WithDefaults() *GetDumpLogsParams { + o.SetDefaults() + return o +} + +// SetDefaults hydrates default values in the get dump logs params (not the query body). +// +// All values with no default are reset to their zero value. +func (o *GetDumpLogsParams) SetDefaults() { + // no default values defined for this parameter +} + +// WithTimeout adds the timeout to the get dump logs params +func (o *GetDumpLogsParams) WithTimeout(timeout time.Duration) *GetDumpLogsParams { + o.SetTimeout(timeout) + return o +} + +// SetTimeout adds the timeout to the get dump logs params +func (o *GetDumpLogsParams) SetTimeout(timeout time.Duration) { + o.timeout = timeout +} + +// WithContext adds the context to the get dump logs params +func (o *GetDumpLogsParams) WithContext(ctx context.Context) *GetDumpLogsParams { + o.SetContext(ctx) + return o +} + +// SetContext adds the context to the get dump logs params +func (o *GetDumpLogsParams) SetContext(ctx context.Context) { + o.Context = ctx +} + +// WithHTTPClient adds the HTTPClient to the get dump logs params +func (o *GetDumpLogsParams) WithHTTPClient(client *http.Client) *GetDumpLogsParams { + o.SetHTTPClient(client) + return o +} + +// SetHTTPClient adds the HTTPClient to the get dump logs params +func (o *GetDumpLogsParams) SetHTTPClient(client *http.Client) { + o.HTTPClient = client +} + +// WithBody adds the body to the get dump logs params +func (o *GetDumpLogsParams) WithBody(body GetDumpLogsBody) *GetDumpLogsParams { + o.SetBody(body) + return o +} + +// SetBody adds the body to the get dump logs params +func (o *GetDumpLogsParams) SetBody(body GetDumpLogsBody) { + o.Body = body +} + +// WriteToRequest writes these params to a swagger request +func (o *GetDumpLogsParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error { + if err := r.SetTimeout(o.timeout); err != nil { + return err + } + var res []error + if err := r.SetBodyParam(o.Body); err != nil { + return err + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/api/managementpb/dump/json/client/dumps/get_dump_logs_responses.go b/api/managementpb/dump/json/client/dumps/get_dump_logs_responses.go new file mode 100644 index 0000000000..b1bbb6db80 --- /dev/null +++ b/api/managementpb/dump/json/client/dumps/get_dump_logs_responses.go @@ -0,0 +1,444 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package dumps + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "fmt" + "io" + "strconv" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" +) + +// GetDumpLogsReader is a Reader for the GetDumpLogs structure. +type GetDumpLogsReader struct { + formats strfmt.Registry +} + +// ReadResponse reads a server response into the received o. +func (o *GetDumpLogsReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) { + switch response.Code() { + case 200: + result := NewGetDumpLogsOK() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return result, nil + default: + result := NewGetDumpLogsDefault(response.Code()) + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + if response.Code()/100 == 2 { + return result, nil + } + return nil, result + } +} + +// NewGetDumpLogsOK creates a GetDumpLogsOK with default headers values +func NewGetDumpLogsOK() *GetDumpLogsOK { + return &GetDumpLogsOK{} +} + +/* +GetDumpLogsOK describes a response with status code 200, with default header values. + +A successful response. +*/ +type GetDumpLogsOK struct { + Payload *GetDumpLogsOKBody +} + +func (o *GetDumpLogsOK) Error() string { + return fmt.Sprintf("[POST /v1/management/dump/Dumps/GetLogs][%d] getDumpLogsOk %+v", 200, o.Payload) +} + +func (o *GetDumpLogsOK) GetPayload() *GetDumpLogsOKBody { + return o.Payload +} + +func (o *GetDumpLogsOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + o.Payload = new(GetDumpLogsOKBody) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} + +// NewGetDumpLogsDefault creates a GetDumpLogsDefault with default headers values +func NewGetDumpLogsDefault(code int) *GetDumpLogsDefault { + return &GetDumpLogsDefault{ + _statusCode: code, + } +} + +/* +GetDumpLogsDefault describes a response with status code -1, with default header values. + +An unexpected error response. +*/ +type GetDumpLogsDefault struct { + _statusCode int + + Payload *GetDumpLogsDefaultBody +} + +// Code gets the status code for the get dump logs default response +func (o *GetDumpLogsDefault) Code() int { + return o._statusCode +} + +func (o *GetDumpLogsDefault) Error() string { + return fmt.Sprintf("[POST /v1/management/dump/Dumps/GetLogs][%d] GetDumpLogs default %+v", o._statusCode, o.Payload) +} + +func (o *GetDumpLogsDefault) GetPayload() *GetDumpLogsDefaultBody { + return o.Payload +} + +func (o *GetDumpLogsDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + o.Payload = new(GetDumpLogsDefaultBody) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} + +/* +GetDumpLogsBody get dump logs body +swagger:model GetDumpLogsBody +*/ +type GetDumpLogsBody struct { + // dump id + DumpID string `json:"dump_id,omitempty"` + + // offset + Offset int64 `json:"offset,omitempty"` + + // limit + Limit int64 `json:"limit,omitempty"` +} + +// Validate validates this get dump logs body +func (o *GetDumpLogsBody) Validate(formats strfmt.Registry) error { + return nil +} + +// ContextValidate validates this get dump logs body based on context it is used +func (o *GetDumpLogsBody) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (o *GetDumpLogsBody) MarshalBinary() ([]byte, error) { + if o == nil { + return nil, nil + } + return swag.WriteJSON(o) +} + +// UnmarshalBinary interface implementation +func (o *GetDumpLogsBody) UnmarshalBinary(b []byte) error { + var res GetDumpLogsBody + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *o = res + return nil +} + +/* +GetDumpLogsDefaultBody get dump logs default body +swagger:model GetDumpLogsDefaultBody +*/ +type GetDumpLogsDefaultBody struct { + // code + Code int32 `json:"code,omitempty"` + + // message + Message string `json:"message,omitempty"` + + // details + Details []*GetDumpLogsDefaultBodyDetailsItems0 `json:"details"` +} + +// Validate validates this get dump logs default body +func (o *GetDumpLogsDefaultBody) Validate(formats strfmt.Registry) error { + var res []error + + if err := o.validateDetails(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *GetDumpLogsDefaultBody) validateDetails(formats strfmt.Registry) error { + if swag.IsZero(o.Details) { // not required + return nil + } + + for i := 0; i < len(o.Details); i++ { + if swag.IsZero(o.Details[i]) { // not required + continue + } + + if o.Details[i] != nil { + if err := o.Details[i].Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("GetDumpLogs default" + "." + "details" + "." + strconv.Itoa(i)) + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("GetDumpLogs default" + "." + "details" + "." + strconv.Itoa(i)) + } + return err + } + } + + } + + return nil +} + +// ContextValidate validate this get dump logs default body based on the context it is used +func (o *GetDumpLogsDefaultBody) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + var res []error + + if err := o.contextValidateDetails(ctx, formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *GetDumpLogsDefaultBody) contextValidateDetails(ctx context.Context, formats strfmt.Registry) error { + for i := 0; i < len(o.Details); i++ { + if o.Details[i] != nil { + if err := o.Details[i].ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("GetDumpLogs default" + "." + "details" + "." + strconv.Itoa(i)) + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("GetDumpLogs default" + "." + "details" + "." + strconv.Itoa(i)) + } + return err + } + } + } + + return nil +} + +// MarshalBinary interface implementation +func (o *GetDumpLogsDefaultBody) MarshalBinary() ([]byte, error) { + if o == nil { + return nil, nil + } + return swag.WriteJSON(o) +} + +// UnmarshalBinary interface implementation +func (o *GetDumpLogsDefaultBody) UnmarshalBinary(b []byte) error { + var res GetDumpLogsDefaultBody + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *o = res + return nil +} + +/* +GetDumpLogsDefaultBodyDetailsItems0 get dump logs default body details items0 +swagger:model GetDumpLogsDefaultBodyDetailsItems0 +*/ +type GetDumpLogsDefaultBodyDetailsItems0 struct { + // at type + AtType string `json:"@type,omitempty"` +} + +// Validate validates this get dump logs default body details items0 +func (o *GetDumpLogsDefaultBodyDetailsItems0) Validate(formats strfmt.Registry) error { + return nil +} + +// ContextValidate validates this get dump logs default body details items0 based on context it is used +func (o *GetDumpLogsDefaultBodyDetailsItems0) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (o *GetDumpLogsDefaultBodyDetailsItems0) MarshalBinary() ([]byte, error) { + if o == nil { + return nil, nil + } + return swag.WriteJSON(o) +} + +// UnmarshalBinary interface implementation +func (o *GetDumpLogsDefaultBodyDetailsItems0) UnmarshalBinary(b []byte) error { + var res GetDumpLogsDefaultBodyDetailsItems0 + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *o = res + return nil +} + +/* +GetDumpLogsOKBody get dump logs OK body +swagger:model GetDumpLogsOKBody +*/ +type GetDumpLogsOKBody struct { + // logs + Logs []*GetDumpLogsOKBodyLogsItems0 `json:"logs"` + + // end + End bool `json:"end,omitempty"` +} + +// Validate validates this get dump logs OK body +func (o *GetDumpLogsOKBody) Validate(formats strfmt.Registry) error { + var res []error + + if err := o.validateLogs(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *GetDumpLogsOKBody) validateLogs(formats strfmt.Registry) error { + if swag.IsZero(o.Logs) { // not required + return nil + } + + for i := 0; i < len(o.Logs); i++ { + if swag.IsZero(o.Logs[i]) { // not required + continue + } + + if o.Logs[i] != nil { + if err := o.Logs[i].Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("getDumpLogsOk" + "." + "logs" + "." + strconv.Itoa(i)) + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("getDumpLogsOk" + "." + "logs" + "." + strconv.Itoa(i)) + } + return err + } + } + + } + + return nil +} + +// ContextValidate validate this get dump logs OK body based on the context it is used +func (o *GetDumpLogsOKBody) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + var res []error + + if err := o.contextValidateLogs(ctx, formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *GetDumpLogsOKBody) contextValidateLogs(ctx context.Context, formats strfmt.Registry) error { + for i := 0; i < len(o.Logs); i++ { + if o.Logs[i] != nil { + if err := o.Logs[i].ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("getDumpLogsOk" + "." + "logs" + "." + strconv.Itoa(i)) + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("getDumpLogsOk" + "." + "logs" + "." + strconv.Itoa(i)) + } + return err + } + } + } + + return nil +} + +// MarshalBinary interface implementation +func (o *GetDumpLogsOKBody) MarshalBinary() ([]byte, error) { + if o == nil { + return nil, nil + } + return swag.WriteJSON(o) +} + +// UnmarshalBinary interface implementation +func (o *GetDumpLogsOKBody) UnmarshalBinary(b []byte) error { + var res GetDumpLogsOKBody + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *o = res + return nil +} + +/* +GetDumpLogsOKBodyLogsItems0 LogChunk represent one chunk of logs. +swagger:model GetDumpLogsOKBodyLogsItems0 +*/ +type GetDumpLogsOKBodyLogsItems0 struct { + // chunk id + ChunkID int64 `json:"chunk_id,omitempty"` + + // data + Data string `json:"data,omitempty"` +} + +// Validate validates this get dump logs OK body logs items0 +func (o *GetDumpLogsOKBodyLogsItems0) Validate(formats strfmt.Registry) error { + return nil +} + +// ContextValidate validates this get dump logs OK body logs items0 based on context it is used +func (o *GetDumpLogsOKBodyLogsItems0) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (o *GetDumpLogsOKBodyLogsItems0) MarshalBinary() ([]byte, error) { + if o == nil { + return nil, nil + } + return swag.WriteJSON(o) +} + +// UnmarshalBinary interface implementation +func (o *GetDumpLogsOKBodyLogsItems0) UnmarshalBinary(b []byte) error { + var res GetDumpLogsOKBodyLogsItems0 + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *o = res + return nil +} diff --git a/api/managementpb/dump/json/client/dumps/list_dumps_parameters.go b/api/managementpb/dump/json/client/dumps/list_dumps_parameters.go new file mode 100644 index 0000000000..4963d5c3d2 --- /dev/null +++ b/api/managementpb/dump/json/client/dumps/list_dumps_parameters.go @@ -0,0 +1,146 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package dumps + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + "time" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + cr "github.com/go-openapi/runtime/client" + "github.com/go-openapi/strfmt" +) + +// NewListDumpsParams creates a new ListDumpsParams object, +// with the default timeout for this client. +// +// Default values are not hydrated, since defaults are normally applied by the API server side. +// +// To enforce default values in parameter, use SetDefaults or WithDefaults. +func NewListDumpsParams() *ListDumpsParams { + return &ListDumpsParams{ + timeout: cr.DefaultTimeout, + } +} + +// NewListDumpsParamsWithTimeout creates a new ListDumpsParams object +// with the ability to set a timeout on a request. +func NewListDumpsParamsWithTimeout(timeout time.Duration) *ListDumpsParams { + return &ListDumpsParams{ + timeout: timeout, + } +} + +// NewListDumpsParamsWithContext creates a new ListDumpsParams object +// with the ability to set a context for a request. +func NewListDumpsParamsWithContext(ctx context.Context) *ListDumpsParams { + return &ListDumpsParams{ + Context: ctx, + } +} + +// NewListDumpsParamsWithHTTPClient creates a new ListDumpsParams object +// with the ability to set a custom HTTPClient for a request. +func NewListDumpsParamsWithHTTPClient(client *http.Client) *ListDumpsParams { + return &ListDumpsParams{ + HTTPClient: client, + } +} + +/* +ListDumpsParams contains all the parameters to send to the API endpoint + + for the list dumps operation. + + Typically these are written to a http.Request. +*/ +type ListDumpsParams struct { + // Body. + Body interface{} + + timeout time.Duration + Context context.Context + HTTPClient *http.Client +} + +// WithDefaults hydrates default values in the list dumps params (not the query body). +// +// All values with no default are reset to their zero value. +func (o *ListDumpsParams) WithDefaults() *ListDumpsParams { + o.SetDefaults() + return o +} + +// SetDefaults hydrates default values in the list dumps params (not the query body). +// +// All values with no default are reset to their zero value. +func (o *ListDumpsParams) SetDefaults() { + // no default values defined for this parameter +} + +// WithTimeout adds the timeout to the list dumps params +func (o *ListDumpsParams) WithTimeout(timeout time.Duration) *ListDumpsParams { + o.SetTimeout(timeout) + return o +} + +// SetTimeout adds the timeout to the list dumps params +func (o *ListDumpsParams) SetTimeout(timeout time.Duration) { + o.timeout = timeout +} + +// WithContext adds the context to the list dumps params +func (o *ListDumpsParams) WithContext(ctx context.Context) *ListDumpsParams { + o.SetContext(ctx) + return o +} + +// SetContext adds the context to the list dumps params +func (o *ListDumpsParams) SetContext(ctx context.Context) { + o.Context = ctx +} + +// WithHTTPClient adds the HTTPClient to the list dumps params +func (o *ListDumpsParams) WithHTTPClient(client *http.Client) *ListDumpsParams { + o.SetHTTPClient(client) + return o +} + +// SetHTTPClient adds the HTTPClient to the list dumps params +func (o *ListDumpsParams) SetHTTPClient(client *http.Client) { + o.HTTPClient = client +} + +// WithBody adds the body to the list dumps params +func (o *ListDumpsParams) WithBody(body interface{}) *ListDumpsParams { + o.SetBody(body) + return o +} + +// SetBody adds the body to the list dumps params +func (o *ListDumpsParams) SetBody(body interface{}) { + o.Body = body +} + +// WriteToRequest writes these params to a swagger request +func (o *ListDumpsParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error { + if err := r.SetTimeout(o.timeout); err != nil { + return err + } + var res []error + if o.Body != nil { + if err := r.SetBodyParam(o.Body); err != nil { + return err + } + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/api/managementpb/dump/json/client/dumps/list_dumps_responses.go b/api/managementpb/dump/json/client/dumps/list_dumps_responses.go new file mode 100644 index 0000000000..3cdce74f01 --- /dev/null +++ b/api/managementpb/dump/json/client/dumps/list_dumps_responses.go @@ -0,0 +1,521 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package dumps + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "encoding/json" + "fmt" + "io" + "strconv" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" + "github.com/go-openapi/validate" +) + +// ListDumpsReader is a Reader for the ListDumps structure. +type ListDumpsReader struct { + formats strfmt.Registry +} + +// ReadResponse reads a server response into the received o. +func (o *ListDumpsReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) { + switch response.Code() { + case 200: + result := NewListDumpsOK() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return result, nil + default: + result := NewListDumpsDefault(response.Code()) + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + if response.Code()/100 == 2 { + return result, nil + } + return nil, result + } +} + +// NewListDumpsOK creates a ListDumpsOK with default headers values +func NewListDumpsOK() *ListDumpsOK { + return &ListDumpsOK{} +} + +/* +ListDumpsOK describes a response with status code 200, with default header values. + +A successful response. +*/ +type ListDumpsOK struct { + Payload *ListDumpsOKBody +} + +func (o *ListDumpsOK) Error() string { + return fmt.Sprintf("[POST /v1/management/dump/Dumps/List][%d] listDumpsOk %+v", 200, o.Payload) +} + +func (o *ListDumpsOK) GetPayload() *ListDumpsOKBody { + return o.Payload +} + +func (o *ListDumpsOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + o.Payload = new(ListDumpsOKBody) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} + +// NewListDumpsDefault creates a ListDumpsDefault with default headers values +func NewListDumpsDefault(code int) *ListDumpsDefault { + return &ListDumpsDefault{ + _statusCode: code, + } +} + +/* +ListDumpsDefault describes a response with status code -1, with default header values. + +An unexpected error response. +*/ +type ListDumpsDefault struct { + _statusCode int + + Payload *ListDumpsDefaultBody +} + +// Code gets the status code for the list dumps default response +func (o *ListDumpsDefault) Code() int { + return o._statusCode +} + +func (o *ListDumpsDefault) Error() string { + return fmt.Sprintf("[POST /v1/management/dump/Dumps/List][%d] ListDumps default %+v", o._statusCode, o.Payload) +} + +func (o *ListDumpsDefault) GetPayload() *ListDumpsDefaultBody { + return o.Payload +} + +func (o *ListDumpsDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + o.Payload = new(ListDumpsDefaultBody) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} + +/* +ListDumpsDefaultBody list dumps default body +swagger:model ListDumpsDefaultBody +*/ +type ListDumpsDefaultBody struct { + // code + Code int32 `json:"code,omitempty"` + + // message + Message string `json:"message,omitempty"` + + // details + Details []*ListDumpsDefaultBodyDetailsItems0 `json:"details"` +} + +// Validate validates this list dumps default body +func (o *ListDumpsDefaultBody) Validate(formats strfmt.Registry) error { + var res []error + + if err := o.validateDetails(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *ListDumpsDefaultBody) validateDetails(formats strfmt.Registry) error { + if swag.IsZero(o.Details) { // not required + return nil + } + + for i := 0; i < len(o.Details); i++ { + if swag.IsZero(o.Details[i]) { // not required + continue + } + + if o.Details[i] != nil { + if err := o.Details[i].Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("ListDumps default" + "." + "details" + "." + strconv.Itoa(i)) + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("ListDumps default" + "." + "details" + "." + strconv.Itoa(i)) + } + return err + } + } + + } + + return nil +} + +// ContextValidate validate this list dumps default body based on the context it is used +func (o *ListDumpsDefaultBody) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + var res []error + + if err := o.contextValidateDetails(ctx, formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *ListDumpsDefaultBody) contextValidateDetails(ctx context.Context, formats strfmt.Registry) error { + for i := 0; i < len(o.Details); i++ { + if o.Details[i] != nil { + if err := o.Details[i].ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("ListDumps default" + "." + "details" + "." + strconv.Itoa(i)) + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("ListDumps default" + "." + "details" + "." + strconv.Itoa(i)) + } + return err + } + } + } + + return nil +} + +// MarshalBinary interface implementation +func (o *ListDumpsDefaultBody) MarshalBinary() ([]byte, error) { + if o == nil { + return nil, nil + } + return swag.WriteJSON(o) +} + +// UnmarshalBinary interface implementation +func (o *ListDumpsDefaultBody) UnmarshalBinary(b []byte) error { + var res ListDumpsDefaultBody + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *o = res + return nil +} + +/* +ListDumpsDefaultBodyDetailsItems0 list dumps default body details items0 +swagger:model ListDumpsDefaultBodyDetailsItems0 +*/ +type ListDumpsDefaultBodyDetailsItems0 struct { + // at type + AtType string `json:"@type,omitempty"` +} + +// Validate validates this list dumps default body details items0 +func (o *ListDumpsDefaultBodyDetailsItems0) Validate(formats strfmt.Registry) error { + return nil +} + +// ContextValidate validates this list dumps default body details items0 based on context it is used +func (o *ListDumpsDefaultBodyDetailsItems0) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (o *ListDumpsDefaultBodyDetailsItems0) MarshalBinary() ([]byte, error) { + if o == nil { + return nil, nil + } + return swag.WriteJSON(o) +} + +// UnmarshalBinary interface implementation +func (o *ListDumpsDefaultBodyDetailsItems0) UnmarshalBinary(b []byte) error { + var res ListDumpsDefaultBodyDetailsItems0 + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *o = res + return nil +} + +/* +ListDumpsOKBody list dumps OK body +swagger:model ListDumpsOKBody +*/ +type ListDumpsOKBody struct { + // dumps + Dumps []*ListDumpsOKBodyDumpsItems0 `json:"dumps"` +} + +// Validate validates this list dumps OK body +func (o *ListDumpsOKBody) Validate(formats strfmt.Registry) error { + var res []error + + if err := o.validateDumps(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *ListDumpsOKBody) validateDumps(formats strfmt.Registry) error { + if swag.IsZero(o.Dumps) { // not required + return nil + } + + for i := 0; i < len(o.Dumps); i++ { + if swag.IsZero(o.Dumps[i]) { // not required + continue + } + + if o.Dumps[i] != nil { + if err := o.Dumps[i].Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("listDumpsOk" + "." + "dumps" + "." + strconv.Itoa(i)) + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("listDumpsOk" + "." + "dumps" + "." + strconv.Itoa(i)) + } + return err + } + } + + } + + return nil +} + +// ContextValidate validate this list dumps OK body based on the context it is used +func (o *ListDumpsOKBody) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + var res []error + + if err := o.contextValidateDumps(ctx, formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *ListDumpsOKBody) contextValidateDumps(ctx context.Context, formats strfmt.Registry) error { + for i := 0; i < len(o.Dumps); i++ { + if o.Dumps[i] != nil { + if err := o.Dumps[i].ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("listDumpsOk" + "." + "dumps" + "." + strconv.Itoa(i)) + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("listDumpsOk" + "." + "dumps" + "." + strconv.Itoa(i)) + } + return err + } + } + } + + return nil +} + +// MarshalBinary interface implementation +func (o *ListDumpsOKBody) MarshalBinary() ([]byte, error) { + if o == nil { + return nil, nil + } + return swag.WriteJSON(o) +} + +// UnmarshalBinary interface implementation +func (o *ListDumpsOKBody) UnmarshalBinary(b []byte) error { + var res ListDumpsOKBody + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *o = res + return nil +} + +/* +ListDumpsOKBodyDumpsItems0 list dumps OK body dumps items0 +swagger:model ListDumpsOKBodyDumpsItems0 +*/ +type ListDumpsOKBodyDumpsItems0 struct { + // dump id + DumpID string `json:"dump_id,omitempty"` + + // status + // Enum: [DUMP_STATUS_INVALID DUMP_STATUS_IN_PROGRESS DUMP_STATUS_SUCCESS DUMP_STATUS_ERROR] + Status *string `json:"status,omitempty"` + + // service names + ServiceNames []string `json:"service_names"` + + // start time + // Format: date-time + StartTime strfmt.DateTime `json:"start_time,omitempty"` + + // end time + // Format: date-time + EndTime strfmt.DateTime `json:"end_time,omitempty"` + + // created at + // Format: date-time + CreatedAt strfmt.DateTime `json:"created_at,omitempty"` +} + +// Validate validates this list dumps OK body dumps items0 +func (o *ListDumpsOKBodyDumpsItems0) Validate(formats strfmt.Registry) error { + var res []error + + if err := o.validateStatus(formats); err != nil { + res = append(res, err) + } + + if err := o.validateStartTime(formats); err != nil { + res = append(res, err) + } + + if err := o.validateEndTime(formats); err != nil { + res = append(res, err) + } + + if err := o.validateCreatedAt(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +var listDumpsOkBodyDumpsItems0TypeStatusPropEnum []interface{} + +func init() { + var res []string + if err := json.Unmarshal([]byte(`["DUMP_STATUS_INVALID","DUMP_STATUS_IN_PROGRESS","DUMP_STATUS_SUCCESS","DUMP_STATUS_ERROR"]`), &res); err != nil { + panic(err) + } + for _, v := range res { + listDumpsOkBodyDumpsItems0TypeStatusPropEnum = append(listDumpsOkBodyDumpsItems0TypeStatusPropEnum, v) + } +} + +const ( + + // ListDumpsOKBodyDumpsItems0StatusDUMPSTATUSINVALID captures enum value "DUMP_STATUS_INVALID" + ListDumpsOKBodyDumpsItems0StatusDUMPSTATUSINVALID string = "DUMP_STATUS_INVALID" + + // ListDumpsOKBodyDumpsItems0StatusDUMPSTATUSINPROGRESS captures enum value "DUMP_STATUS_IN_PROGRESS" + ListDumpsOKBodyDumpsItems0StatusDUMPSTATUSINPROGRESS string = "DUMP_STATUS_IN_PROGRESS" + + // ListDumpsOKBodyDumpsItems0StatusDUMPSTATUSSUCCESS captures enum value "DUMP_STATUS_SUCCESS" + ListDumpsOKBodyDumpsItems0StatusDUMPSTATUSSUCCESS string = "DUMP_STATUS_SUCCESS" + + // ListDumpsOKBodyDumpsItems0StatusDUMPSTATUSERROR captures enum value "DUMP_STATUS_ERROR" + ListDumpsOKBodyDumpsItems0StatusDUMPSTATUSERROR string = "DUMP_STATUS_ERROR" +) + +// prop value enum +func (o *ListDumpsOKBodyDumpsItems0) validateStatusEnum(path, location string, value string) error { + if err := validate.EnumCase(path, location, value, listDumpsOkBodyDumpsItems0TypeStatusPropEnum, true); err != nil { + return err + } + return nil +} + +func (o *ListDumpsOKBodyDumpsItems0) validateStatus(formats strfmt.Registry) error { + if swag.IsZero(o.Status) { // not required + return nil + } + + // value enum + if err := o.validateStatusEnum("status", "body", *o.Status); err != nil { + return err + } + + return nil +} + +func (o *ListDumpsOKBodyDumpsItems0) validateStartTime(formats strfmt.Registry) error { + if swag.IsZero(o.StartTime) { // not required + return nil + } + + if err := validate.FormatOf("start_time", "body", "date-time", o.StartTime.String(), formats); err != nil { + return err + } + + return nil +} + +func (o *ListDumpsOKBodyDumpsItems0) validateEndTime(formats strfmt.Registry) error { + if swag.IsZero(o.EndTime) { // not required + return nil + } + + if err := validate.FormatOf("end_time", "body", "date-time", o.EndTime.String(), formats); err != nil { + return err + } + + return nil +} + +func (o *ListDumpsOKBodyDumpsItems0) validateCreatedAt(formats strfmt.Registry) error { + if swag.IsZero(o.CreatedAt) { // not required + return nil + } + + if err := validate.FormatOf("created_at", "body", "date-time", o.CreatedAt.String(), formats); err != nil { + return err + } + + return nil +} + +// ContextValidate validates this list dumps OK body dumps items0 based on context it is used +func (o *ListDumpsOKBodyDumpsItems0) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (o *ListDumpsOKBodyDumpsItems0) MarshalBinary() ([]byte, error) { + if o == nil { + return nil, nil + } + return swag.WriteJSON(o) +} + +// UnmarshalBinary interface implementation +func (o *ListDumpsOKBodyDumpsItems0) UnmarshalBinary(b []byte) error { + var res ListDumpsOKBodyDumpsItems0 + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *o = res + return nil +} diff --git a/api/managementpb/dump/json/client/dumps/start_dump_parameters.go b/api/managementpb/dump/json/client/dumps/start_dump_parameters.go new file mode 100644 index 0000000000..dbf0f8a734 --- /dev/null +++ b/api/managementpb/dump/json/client/dumps/start_dump_parameters.go @@ -0,0 +1,144 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package dumps + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + "time" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + cr "github.com/go-openapi/runtime/client" + "github.com/go-openapi/strfmt" +) + +// NewStartDumpParams creates a new StartDumpParams object, +// with the default timeout for this client. +// +// Default values are not hydrated, since defaults are normally applied by the API server side. +// +// To enforce default values in parameter, use SetDefaults or WithDefaults. +func NewStartDumpParams() *StartDumpParams { + return &StartDumpParams{ + timeout: cr.DefaultTimeout, + } +} + +// NewStartDumpParamsWithTimeout creates a new StartDumpParams object +// with the ability to set a timeout on a request. +func NewStartDumpParamsWithTimeout(timeout time.Duration) *StartDumpParams { + return &StartDumpParams{ + timeout: timeout, + } +} + +// NewStartDumpParamsWithContext creates a new StartDumpParams object +// with the ability to set a context for a request. +func NewStartDumpParamsWithContext(ctx context.Context) *StartDumpParams { + return &StartDumpParams{ + Context: ctx, + } +} + +// NewStartDumpParamsWithHTTPClient creates a new StartDumpParams object +// with the ability to set a custom HTTPClient for a request. +func NewStartDumpParamsWithHTTPClient(client *http.Client) *StartDumpParams { + return &StartDumpParams{ + HTTPClient: client, + } +} + +/* +StartDumpParams contains all the parameters to send to the API endpoint + + for the start dump operation. + + Typically these are written to a http.Request. +*/ +type StartDumpParams struct { + // Body. + Body StartDumpBody + + timeout time.Duration + Context context.Context + HTTPClient *http.Client +} + +// WithDefaults hydrates default values in the start dump params (not the query body). +// +// All values with no default are reset to their zero value. +func (o *StartDumpParams) WithDefaults() *StartDumpParams { + o.SetDefaults() + return o +} + +// SetDefaults hydrates default values in the start dump params (not the query body). +// +// All values with no default are reset to their zero value. +func (o *StartDumpParams) SetDefaults() { + // no default values defined for this parameter +} + +// WithTimeout adds the timeout to the start dump params +func (o *StartDumpParams) WithTimeout(timeout time.Duration) *StartDumpParams { + o.SetTimeout(timeout) + return o +} + +// SetTimeout adds the timeout to the start dump params +func (o *StartDumpParams) SetTimeout(timeout time.Duration) { + o.timeout = timeout +} + +// WithContext adds the context to the start dump params +func (o *StartDumpParams) WithContext(ctx context.Context) *StartDumpParams { + o.SetContext(ctx) + return o +} + +// SetContext adds the context to the start dump params +func (o *StartDumpParams) SetContext(ctx context.Context) { + o.Context = ctx +} + +// WithHTTPClient adds the HTTPClient to the start dump params +func (o *StartDumpParams) WithHTTPClient(client *http.Client) *StartDumpParams { + o.SetHTTPClient(client) + return o +} + +// SetHTTPClient adds the HTTPClient to the start dump params +func (o *StartDumpParams) SetHTTPClient(client *http.Client) { + o.HTTPClient = client +} + +// WithBody adds the body to the start dump params +func (o *StartDumpParams) WithBody(body StartDumpBody) *StartDumpParams { + o.SetBody(body) + return o +} + +// SetBody adds the body to the start dump params +func (o *StartDumpParams) SetBody(body StartDumpBody) { + o.Body = body +} + +// WriteToRequest writes these params to a swagger request +func (o *StartDumpParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error { + if err := r.SetTimeout(o.timeout); err != nil { + return err + } + var res []error + if err := r.SetBodyParam(o.Body); err != nil { + return err + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/api/managementpb/dump/json/client/dumps/start_dump_responses.go b/api/managementpb/dump/json/client/dumps/start_dump_responses.go new file mode 100644 index 0000000000..3b4e95fec9 --- /dev/null +++ b/api/managementpb/dump/json/client/dumps/start_dump_responses.go @@ -0,0 +1,386 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package dumps + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "fmt" + "io" + "strconv" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" + "github.com/go-openapi/validate" +) + +// StartDumpReader is a Reader for the StartDump structure. +type StartDumpReader struct { + formats strfmt.Registry +} + +// ReadResponse reads a server response into the received o. +func (o *StartDumpReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) { + switch response.Code() { + case 200: + result := NewStartDumpOK() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return result, nil + default: + result := NewStartDumpDefault(response.Code()) + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + if response.Code()/100 == 2 { + return result, nil + } + return nil, result + } +} + +// NewStartDumpOK creates a StartDumpOK with default headers values +func NewStartDumpOK() *StartDumpOK { + return &StartDumpOK{} +} + +/* +StartDumpOK describes a response with status code 200, with default header values. + +A successful response. +*/ +type StartDumpOK struct { + Payload *StartDumpOKBody +} + +func (o *StartDumpOK) Error() string { + return fmt.Sprintf("[POST /v1/management/dump/Dumps/Start][%d] startDumpOk %+v", 200, o.Payload) +} + +func (o *StartDumpOK) GetPayload() *StartDumpOKBody { + return o.Payload +} + +func (o *StartDumpOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + o.Payload = new(StartDumpOKBody) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} + +// NewStartDumpDefault creates a StartDumpDefault with default headers values +func NewStartDumpDefault(code int) *StartDumpDefault { + return &StartDumpDefault{ + _statusCode: code, + } +} + +/* +StartDumpDefault describes a response with status code -1, with default header values. + +An unexpected error response. +*/ +type StartDumpDefault struct { + _statusCode int + + Payload *StartDumpDefaultBody +} + +// Code gets the status code for the start dump default response +func (o *StartDumpDefault) Code() int { + return o._statusCode +} + +func (o *StartDumpDefault) Error() string { + return fmt.Sprintf("[POST /v1/management/dump/Dumps/Start][%d] StartDump default %+v", o._statusCode, o.Payload) +} + +func (o *StartDumpDefault) GetPayload() *StartDumpDefaultBody { + return o.Payload +} + +func (o *StartDumpDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + o.Payload = new(StartDumpDefaultBody) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} + +/* +StartDumpBody start dump body +swagger:model StartDumpBody +*/ +type StartDumpBody struct { + // service names + ServiceNames []string `json:"service_names"` + + // start time + // Format: date-time + StartTime strfmt.DateTime `json:"start_time,omitempty"` + + // end time + // Format: date-time + EndTime strfmt.DateTime `json:"end_time,omitempty"` + + // export qan + ExportQAN bool `json:"export_qan,omitempty"` + + // ignore load + IgnoreLoad bool `json:"ignore_load,omitempty"` +} + +// Validate validates this start dump body +func (o *StartDumpBody) Validate(formats strfmt.Registry) error { + var res []error + + if err := o.validateStartTime(formats); err != nil { + res = append(res, err) + } + + if err := o.validateEndTime(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *StartDumpBody) validateStartTime(formats strfmt.Registry) error { + if swag.IsZero(o.StartTime) { // not required + return nil + } + + if err := validate.FormatOf("body"+"."+"start_time", "body", "date-time", o.StartTime.String(), formats); err != nil { + return err + } + + return nil +} + +func (o *StartDumpBody) validateEndTime(formats strfmt.Registry) error { + if swag.IsZero(o.EndTime) { // not required + return nil + } + + if err := validate.FormatOf("body"+"."+"end_time", "body", "date-time", o.EndTime.String(), formats); err != nil { + return err + } + + return nil +} + +// ContextValidate validates this start dump body based on context it is used +func (o *StartDumpBody) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (o *StartDumpBody) MarshalBinary() ([]byte, error) { + if o == nil { + return nil, nil + } + return swag.WriteJSON(o) +} + +// UnmarshalBinary interface implementation +func (o *StartDumpBody) UnmarshalBinary(b []byte) error { + var res StartDumpBody + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *o = res + return nil +} + +/* +StartDumpDefaultBody start dump default body +swagger:model StartDumpDefaultBody +*/ +type StartDumpDefaultBody struct { + // code + Code int32 `json:"code,omitempty"` + + // message + Message string `json:"message,omitempty"` + + // details + Details []*StartDumpDefaultBodyDetailsItems0 `json:"details"` +} + +// Validate validates this start dump default body +func (o *StartDumpDefaultBody) Validate(formats strfmt.Registry) error { + var res []error + + if err := o.validateDetails(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *StartDumpDefaultBody) validateDetails(formats strfmt.Registry) error { + if swag.IsZero(o.Details) { // not required + return nil + } + + for i := 0; i < len(o.Details); i++ { + if swag.IsZero(o.Details[i]) { // not required + continue + } + + if o.Details[i] != nil { + if err := o.Details[i].Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("StartDump default" + "." + "details" + "." + strconv.Itoa(i)) + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("StartDump default" + "." + "details" + "." + strconv.Itoa(i)) + } + return err + } + } + + } + + return nil +} + +// ContextValidate validate this start dump default body based on the context it is used +func (o *StartDumpDefaultBody) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + var res []error + + if err := o.contextValidateDetails(ctx, formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *StartDumpDefaultBody) contextValidateDetails(ctx context.Context, formats strfmt.Registry) error { + for i := 0; i < len(o.Details); i++ { + if o.Details[i] != nil { + if err := o.Details[i].ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("StartDump default" + "." + "details" + "." + strconv.Itoa(i)) + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("StartDump default" + "." + "details" + "." + strconv.Itoa(i)) + } + return err + } + } + } + + return nil +} + +// MarshalBinary interface implementation +func (o *StartDumpDefaultBody) MarshalBinary() ([]byte, error) { + if o == nil { + return nil, nil + } + return swag.WriteJSON(o) +} + +// UnmarshalBinary interface implementation +func (o *StartDumpDefaultBody) UnmarshalBinary(b []byte) error { + var res StartDumpDefaultBody + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *o = res + return nil +} + +/* +StartDumpDefaultBodyDetailsItems0 start dump default body details items0 +swagger:model StartDumpDefaultBodyDetailsItems0 +*/ +type StartDumpDefaultBodyDetailsItems0 struct { + // at type + AtType string `json:"@type,omitempty"` +} + +// Validate validates this start dump default body details items0 +func (o *StartDumpDefaultBodyDetailsItems0) Validate(formats strfmt.Registry) error { + return nil +} + +// ContextValidate validates this start dump default body details items0 based on context it is used +func (o *StartDumpDefaultBodyDetailsItems0) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (o *StartDumpDefaultBodyDetailsItems0) MarshalBinary() ([]byte, error) { + if o == nil { + return nil, nil + } + return swag.WriteJSON(o) +} + +// UnmarshalBinary interface implementation +func (o *StartDumpDefaultBodyDetailsItems0) UnmarshalBinary(b []byte) error { + var res StartDumpDefaultBodyDetailsItems0 + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *o = res + return nil +} + +/* +StartDumpOKBody start dump OK body +swagger:model StartDumpOKBody +*/ +type StartDumpOKBody struct { + // dump id + DumpID string `json:"dump_id,omitempty"` +} + +// Validate validates this start dump OK body +func (o *StartDumpOKBody) Validate(formats strfmt.Registry) error { + return nil +} + +// ContextValidate validates this start dump OK body based on context it is used +func (o *StartDumpOKBody) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (o *StartDumpOKBody) MarshalBinary() ([]byte, error) { + if o == nil { + return nil, nil + } + return swag.WriteJSON(o) +} + +// UnmarshalBinary interface implementation +func (o *StartDumpOKBody) UnmarshalBinary(b []byte) error { + var res StartDumpOKBody + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *o = res + return nil +} diff --git a/api/managementpb/dump/json/client/dumps/upload_dump_parameters.go b/api/managementpb/dump/json/client/dumps/upload_dump_parameters.go new file mode 100644 index 0000000000..1aa1d22c60 --- /dev/null +++ b/api/managementpb/dump/json/client/dumps/upload_dump_parameters.go @@ -0,0 +1,144 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package dumps + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + "time" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + cr "github.com/go-openapi/runtime/client" + "github.com/go-openapi/strfmt" +) + +// NewUploadDumpParams creates a new UploadDumpParams object, +// with the default timeout for this client. +// +// Default values are not hydrated, since defaults are normally applied by the API server side. +// +// To enforce default values in parameter, use SetDefaults or WithDefaults. +func NewUploadDumpParams() *UploadDumpParams { + return &UploadDumpParams{ + timeout: cr.DefaultTimeout, + } +} + +// NewUploadDumpParamsWithTimeout creates a new UploadDumpParams object +// with the ability to set a timeout on a request. +func NewUploadDumpParamsWithTimeout(timeout time.Duration) *UploadDumpParams { + return &UploadDumpParams{ + timeout: timeout, + } +} + +// NewUploadDumpParamsWithContext creates a new UploadDumpParams object +// with the ability to set a context for a request. +func NewUploadDumpParamsWithContext(ctx context.Context) *UploadDumpParams { + return &UploadDumpParams{ + Context: ctx, + } +} + +// NewUploadDumpParamsWithHTTPClient creates a new UploadDumpParams object +// with the ability to set a custom HTTPClient for a request. +func NewUploadDumpParamsWithHTTPClient(client *http.Client) *UploadDumpParams { + return &UploadDumpParams{ + HTTPClient: client, + } +} + +/* +UploadDumpParams contains all the parameters to send to the API endpoint + + for the upload dump operation. + + Typically these are written to a http.Request. +*/ +type UploadDumpParams struct { + // Body. + Body UploadDumpBody + + timeout time.Duration + Context context.Context + HTTPClient *http.Client +} + +// WithDefaults hydrates default values in the upload dump params (not the query body). +// +// All values with no default are reset to their zero value. +func (o *UploadDumpParams) WithDefaults() *UploadDumpParams { + o.SetDefaults() + return o +} + +// SetDefaults hydrates default values in the upload dump params (not the query body). +// +// All values with no default are reset to their zero value. +func (o *UploadDumpParams) SetDefaults() { + // no default values defined for this parameter +} + +// WithTimeout adds the timeout to the upload dump params +func (o *UploadDumpParams) WithTimeout(timeout time.Duration) *UploadDumpParams { + o.SetTimeout(timeout) + return o +} + +// SetTimeout adds the timeout to the upload dump params +func (o *UploadDumpParams) SetTimeout(timeout time.Duration) { + o.timeout = timeout +} + +// WithContext adds the context to the upload dump params +func (o *UploadDumpParams) WithContext(ctx context.Context) *UploadDumpParams { + o.SetContext(ctx) + return o +} + +// SetContext adds the context to the upload dump params +func (o *UploadDumpParams) SetContext(ctx context.Context) { + o.Context = ctx +} + +// WithHTTPClient adds the HTTPClient to the upload dump params +func (o *UploadDumpParams) WithHTTPClient(client *http.Client) *UploadDumpParams { + o.SetHTTPClient(client) + return o +} + +// SetHTTPClient adds the HTTPClient to the upload dump params +func (o *UploadDumpParams) SetHTTPClient(client *http.Client) { + o.HTTPClient = client +} + +// WithBody adds the body to the upload dump params +func (o *UploadDumpParams) WithBody(body UploadDumpBody) *UploadDumpParams { + o.SetBody(body) + return o +} + +// SetBody adds the body to the upload dump params +func (o *UploadDumpParams) SetBody(body UploadDumpBody) { + o.Body = body +} + +// WriteToRequest writes these params to a swagger request +func (o *UploadDumpParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error { + if err := r.SetTimeout(o.timeout); err != nil { + return err + } + var res []error + if err := r.SetBodyParam(o.Body); err != nil { + return err + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/api/managementpb/dump/json/client/dumps/upload_dump_responses.go b/api/managementpb/dump/json/client/dumps/upload_dump_responses.go new file mode 100644 index 0000000000..77372e9d54 --- /dev/null +++ b/api/managementpb/dump/json/client/dumps/upload_dump_responses.go @@ -0,0 +1,396 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package dumps + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "fmt" + "io" + "strconv" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" +) + +// UploadDumpReader is a Reader for the UploadDump structure. +type UploadDumpReader struct { + formats strfmt.Registry +} + +// ReadResponse reads a server response into the received o. +func (o *UploadDumpReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) { + switch response.Code() { + case 200: + result := NewUploadDumpOK() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return result, nil + default: + result := NewUploadDumpDefault(response.Code()) + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + if response.Code()/100 == 2 { + return result, nil + } + return nil, result + } +} + +// NewUploadDumpOK creates a UploadDumpOK with default headers values +func NewUploadDumpOK() *UploadDumpOK { + return &UploadDumpOK{} +} + +/* +UploadDumpOK describes a response with status code 200, with default header values. + +A successful response. +*/ +type UploadDumpOK struct { + Payload interface{} +} + +func (o *UploadDumpOK) Error() string { + return fmt.Sprintf("[POST /v1/management/dump/Dumps/Upload][%d] uploadDumpOk %+v", 200, o.Payload) +} + +func (o *UploadDumpOK) GetPayload() interface{} { + return o.Payload +} + +func (o *UploadDumpOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + // response payload + if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} + +// NewUploadDumpDefault creates a UploadDumpDefault with default headers values +func NewUploadDumpDefault(code int) *UploadDumpDefault { + return &UploadDumpDefault{ + _statusCode: code, + } +} + +/* +UploadDumpDefault describes a response with status code -1, with default header values. + +An unexpected error response. +*/ +type UploadDumpDefault struct { + _statusCode int + + Payload *UploadDumpDefaultBody +} + +// Code gets the status code for the upload dump default response +func (o *UploadDumpDefault) Code() int { + return o._statusCode +} + +func (o *UploadDumpDefault) Error() string { + return fmt.Sprintf("[POST /v1/management/dump/Dumps/Upload][%d] UploadDump default %+v", o._statusCode, o.Payload) +} + +func (o *UploadDumpDefault) GetPayload() *UploadDumpDefaultBody { + return o.Payload +} + +func (o *UploadDumpDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + o.Payload = new(UploadDumpDefaultBody) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} + +/* +UploadDumpBody upload dump body +swagger:model UploadDumpBody +*/ +type UploadDumpBody struct { + // dump ids + DumpIds []string `json:"dump_ids"` + + // sftp parameters + SftpParameters *UploadDumpParamsBodySftpParameters `json:"sftp_parameters,omitempty"` +} + +// Validate validates this upload dump body +func (o *UploadDumpBody) Validate(formats strfmt.Registry) error { + var res []error + + if err := o.validateSftpParameters(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *UploadDumpBody) validateSftpParameters(formats strfmt.Registry) error { + if swag.IsZero(o.SftpParameters) { // not required + return nil + } + + if o.SftpParameters != nil { + if err := o.SftpParameters.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("body" + "." + "sftp_parameters") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("body" + "." + "sftp_parameters") + } + return err + } + } + + return nil +} + +// ContextValidate validate this upload dump body based on the context it is used +func (o *UploadDumpBody) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + var res []error + + if err := o.contextValidateSftpParameters(ctx, formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *UploadDumpBody) contextValidateSftpParameters(ctx context.Context, formats strfmt.Registry) error { + if o.SftpParameters != nil { + if err := o.SftpParameters.ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("body" + "." + "sftp_parameters") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("body" + "." + "sftp_parameters") + } + return err + } + } + + return nil +} + +// MarshalBinary interface implementation +func (o *UploadDumpBody) MarshalBinary() ([]byte, error) { + if o == nil { + return nil, nil + } + return swag.WriteJSON(o) +} + +// UnmarshalBinary interface implementation +func (o *UploadDumpBody) UnmarshalBinary(b []byte) error { + var res UploadDumpBody + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *o = res + return nil +} + +/* +UploadDumpDefaultBody upload dump default body +swagger:model UploadDumpDefaultBody +*/ +type UploadDumpDefaultBody struct { + // code + Code int32 `json:"code,omitempty"` + + // message + Message string `json:"message,omitempty"` + + // details + Details []*UploadDumpDefaultBodyDetailsItems0 `json:"details"` +} + +// Validate validates this upload dump default body +func (o *UploadDumpDefaultBody) Validate(formats strfmt.Registry) error { + var res []error + + if err := o.validateDetails(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *UploadDumpDefaultBody) validateDetails(formats strfmt.Registry) error { + if swag.IsZero(o.Details) { // not required + return nil + } + + for i := 0; i < len(o.Details); i++ { + if swag.IsZero(o.Details[i]) { // not required + continue + } + + if o.Details[i] != nil { + if err := o.Details[i].Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("UploadDump default" + "." + "details" + "." + strconv.Itoa(i)) + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("UploadDump default" + "." + "details" + "." + strconv.Itoa(i)) + } + return err + } + } + + } + + return nil +} + +// ContextValidate validate this upload dump default body based on the context it is used +func (o *UploadDumpDefaultBody) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + var res []error + + if err := o.contextValidateDetails(ctx, formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *UploadDumpDefaultBody) contextValidateDetails(ctx context.Context, formats strfmt.Registry) error { + for i := 0; i < len(o.Details); i++ { + if o.Details[i] != nil { + if err := o.Details[i].ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("UploadDump default" + "." + "details" + "." + strconv.Itoa(i)) + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("UploadDump default" + "." + "details" + "." + strconv.Itoa(i)) + } + return err + } + } + } + + return nil +} + +// MarshalBinary interface implementation +func (o *UploadDumpDefaultBody) MarshalBinary() ([]byte, error) { + if o == nil { + return nil, nil + } + return swag.WriteJSON(o) +} + +// UnmarshalBinary interface implementation +func (o *UploadDumpDefaultBody) UnmarshalBinary(b []byte) error { + var res UploadDumpDefaultBody + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *o = res + return nil +} + +/* +UploadDumpDefaultBodyDetailsItems0 upload dump default body details items0 +swagger:model UploadDumpDefaultBodyDetailsItems0 +*/ +type UploadDumpDefaultBodyDetailsItems0 struct { + // at type + AtType string `json:"@type,omitempty"` +} + +// Validate validates this upload dump default body details items0 +func (o *UploadDumpDefaultBodyDetailsItems0) Validate(formats strfmt.Registry) error { + return nil +} + +// ContextValidate validates this upload dump default body details items0 based on context it is used +func (o *UploadDumpDefaultBodyDetailsItems0) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (o *UploadDumpDefaultBodyDetailsItems0) MarshalBinary() ([]byte, error) { + if o == nil { + return nil, nil + } + return swag.WriteJSON(o) +} + +// UnmarshalBinary interface implementation +func (o *UploadDumpDefaultBodyDetailsItems0) UnmarshalBinary(b []byte) error { + var res UploadDumpDefaultBodyDetailsItems0 + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *o = res + return nil +} + +/* +UploadDumpParamsBodySftpParameters upload dump params body sftp parameters +swagger:model UploadDumpParamsBodySftpParameters +*/ +type UploadDumpParamsBodySftpParameters struct { + // address + Address string `json:"address,omitempty"` + + // user + User string `json:"user,omitempty"` + + // password + Password string `json:"password,omitempty"` + + // directory + Directory string `json:"directory,omitempty"` +} + +// Validate validates this upload dump params body sftp parameters +func (o *UploadDumpParamsBodySftpParameters) Validate(formats strfmt.Registry) error { + return nil +} + +// ContextValidate validates this upload dump params body sftp parameters based on context it is used +func (o *UploadDumpParamsBodySftpParameters) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (o *UploadDumpParamsBodySftpParameters) MarshalBinary() ([]byte, error) { + if o == nil { + return nil, nil + } + return swag.WriteJSON(o) +} + +// UnmarshalBinary interface implementation +func (o *UploadDumpParamsBodySftpParameters) UnmarshalBinary(b []byte) error { + var res UploadDumpParamsBodySftpParameters + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *o = res + return nil +} diff --git a/api/managementpb/dump/json/client/pmm_dump_api_client.go b/api/managementpb/dump/json/client/pmm_dump_api_client.go new file mode 100644 index 0000000000..de9c0078e7 --- /dev/null +++ b/api/managementpb/dump/json/client/pmm_dump_api_client.go @@ -0,0 +1,112 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package client + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "github.com/go-openapi/runtime" + httptransport "github.com/go-openapi/runtime/client" + "github.com/go-openapi/strfmt" + + "github.com/percona/pmm/api/managementpb/dump/json/client/dumps" +) + +// Default PMM dump API HTTP client. +var Default = NewHTTPClient(nil) + +const ( + // DefaultHost is the default Host + // found in Meta (info) section of spec file + DefaultHost string = "localhost" + // DefaultBasePath is the default BasePath + // found in Meta (info) section of spec file + DefaultBasePath string = "/" +) + +// DefaultSchemes are the default schemes found in Meta (info) section of spec file +var DefaultSchemes = []string{"http", "https"} + +// NewHTTPClient creates a new PMM dump API HTTP client. +func NewHTTPClient(formats strfmt.Registry) *PMMDumpAPI { + return NewHTTPClientWithConfig(formats, nil) +} + +// NewHTTPClientWithConfig creates a new PMM dump API HTTP client, +// using a customizable transport config. +func NewHTTPClientWithConfig(formats strfmt.Registry, cfg *TransportConfig) *PMMDumpAPI { + // ensure nullable parameters have default + if cfg == nil { + cfg = DefaultTransportConfig() + } + + // create transport and client + transport := httptransport.New(cfg.Host, cfg.BasePath, cfg.Schemes) + return New(transport, formats) +} + +// New creates a new PMM dump API client +func New(transport runtime.ClientTransport, formats strfmt.Registry) *PMMDumpAPI { + // ensure nullable parameters have default + if formats == nil { + formats = strfmt.Default + } + + cli := new(PMMDumpAPI) + cli.Transport = transport + cli.Dumps = dumps.New(transport, formats) + return cli +} + +// DefaultTransportConfig creates a TransportConfig with the +// default settings taken from the meta section of the spec file. +func DefaultTransportConfig() *TransportConfig { + return &TransportConfig{ + Host: DefaultHost, + BasePath: DefaultBasePath, + Schemes: DefaultSchemes, + } +} + +// TransportConfig contains the transport related info, +// found in the meta section of the spec file. +type TransportConfig struct { + Host string + BasePath string + Schemes []string +} + +// WithHost overrides the default host, +// provided by the meta section of the spec file. +func (cfg *TransportConfig) WithHost(host string) *TransportConfig { + cfg.Host = host + return cfg +} + +// WithBasePath overrides the default basePath, +// provided by the meta section of the spec file. +func (cfg *TransportConfig) WithBasePath(basePath string) *TransportConfig { + cfg.BasePath = basePath + return cfg +} + +// WithSchemes overrides the default schemes, +// provided by the meta section of the spec file. +func (cfg *TransportConfig) WithSchemes(schemes []string) *TransportConfig { + cfg.Schemes = schemes + return cfg +} + +// PMMDumpAPI is a client for PMM dump API +type PMMDumpAPI struct { + Dumps dumps.ClientService + + Transport runtime.ClientTransport +} + +// SetTransport changes the transport on the client and all its subresources +func (c *PMMDumpAPI) SetTransport(transport runtime.ClientTransport) { + c.Transport = transport + c.Dumps.SetTransport(transport) +} diff --git a/api/managementpb/dump/json/dump.json b/api/managementpb/dump/json/dump.json new file mode 100644 index 0000000000..9ac881873e --- /dev/null +++ b/api/managementpb/dump/json/dump.json @@ -0,0 +1,476 @@ +{ + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "https", + "http" + ], + "swagger": "2.0", + "info": { + "title": "PMM Dump API", + "version": "v1beta1" + }, + "paths": { + "/v1/management/dump/Dumps/Delete": { + "post": { + "tags": [ + "Dumps" + ], + "summary": "DeleteDump deletes specified pmm dump.", + "operationId": "DeleteDump", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "dump_ids": { + "type": "array", + "items": { + "type": "string" + }, + "x-order": 0 + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "type": "object" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32", + "x-order": 0 + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "@type": { + "type": "string", + "x-order": 0 + } + }, + "additionalProperties": false + }, + "x-order": 2 + }, + "message": { + "type": "string", + "x-order": 1 + } + } + } + } + } + } + }, + "/v1/management/dump/Dumps/GetLogs": { + "post": { + "tags": [ + "Dumps" + ], + "summary": "GetLogs returns logs from pmm-dump tool.", + "operationId": "GetDumpLogs", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "dump_id": { + "type": "string", + "x-order": 0 + }, + "limit": { + "type": "integer", + "format": "int64", + "x-order": 2 + }, + "offset": { + "type": "integer", + "format": "int64", + "x-order": 1 + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "type": "object", + "properties": { + "end": { + "type": "boolean", + "x-order": 1 + }, + "logs": { + "type": "array", + "items": { + "description": "LogChunk represent one chunk of logs.", + "type": "object", + "properties": { + "chunk_id": { + "type": "integer", + "format": "int64", + "x-order": 0 + }, + "data": { + "type": "string", + "x-order": 1 + } + } + }, + "x-order": 0 + } + } + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32", + "x-order": 0 + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "@type": { + "type": "string", + "x-order": 0 + } + }, + "additionalProperties": false + }, + "x-order": 2 + }, + "message": { + "type": "string", + "x-order": 1 + } + } + } + } + } + } + }, + "/v1/management/dump/Dumps/List": { + "post": { + "tags": [ + "Dumps" + ], + "summary": "ListDumps returns a list of all pmm dumps.", + "operationId": "ListDumps", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object" + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "type": "object", + "properties": { + "dumps": { + "type": "array", + "items": { + "type": "object", + "properties": { + "created_at": { + "type": "string", + "format": "date-time", + "x-order": 5 + }, + "dump_id": { + "type": "string", + "x-order": 0 + }, + "end_time": { + "type": "string", + "format": "date-time", + "x-order": 4 + }, + "service_names": { + "type": "array", + "items": { + "type": "string" + }, + "x-order": 2 + }, + "start_time": { + "type": "string", + "format": "date-time", + "x-order": 3 + }, + "status": { + "type": "string", + "default": "DUMP_STATUS_INVALID", + "enum": [ + "DUMP_STATUS_INVALID", + "DUMP_STATUS_IN_PROGRESS", + "DUMP_STATUS_SUCCESS", + "DUMP_STATUS_ERROR" + ], + "x-order": 1 + } + } + }, + "x-order": 0 + } + } + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32", + "x-order": 0 + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "@type": { + "type": "string", + "x-order": 0 + } + }, + "additionalProperties": false + }, + "x-order": 2 + }, + "message": { + "type": "string", + "x-order": 1 + } + } + } + } + } + } + }, + "/v1/management/dump/Dumps/Start": { + "post": { + "tags": [ + "Dumps" + ], + "summary": "StartDump request creates pmm dump.", + "operationId": "StartDump", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "end_time": { + "type": "string", + "format": "date-time", + "x-order": 2 + }, + "export_qan": { + "type": "boolean", + "x-order": 3 + }, + "ignore_load": { + "type": "boolean", + "x-order": 4 + }, + "service_names": { + "type": "array", + "items": { + "type": "string" + }, + "x-order": 0 + }, + "start_time": { + "type": "string", + "format": "date-time", + "x-order": 1 + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "type": "object", + "properties": { + "dump_id": { + "type": "string", + "x-order": 0 + } + } + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32", + "x-order": 0 + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "@type": { + "type": "string", + "x-order": 0 + } + }, + "additionalProperties": false + }, + "x-order": 2 + }, + "message": { + "type": "string", + "x-order": 1 + } + } + } + } + } + } + }, + "/v1/management/dump/Dumps/Upload": { + "post": { + "tags": [ + "Dumps" + ], + "summary": "UploadDump uploads selected dumps to remote server.", + "operationId": "UploadDump", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "dump_ids": { + "type": "array", + "items": { + "type": "string" + }, + "x-order": 0 + }, + "sftp_parameters": { + "type": "object", + "properties": { + "address": { + "type": "string", + "x-order": 0 + }, + "directory": { + "type": "string", + "x-order": 3 + }, + "password": { + "type": "string", + "x-order": 2 + }, + "user": { + "type": "string", + "x-order": 1 + } + }, + "x-order": 1 + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "type": "object" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32", + "x-order": 0 + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "@type": { + "type": "string", + "x-order": 0 + } + }, + "additionalProperties": false + }, + "x-order": 2 + }, + "message": { + "type": "string", + "x-order": 1 + } + } + } + } + } + } + } + }, + "tags": [ + { + "name": "Dumps" + } + ] +} \ No newline at end of file diff --git a/api/managementpb/dump/json/header.json b/api/managementpb/dump/json/header.json new file mode 100644 index 0000000000..4666b1236e --- /dev/null +++ b/api/managementpb/dump/json/header.json @@ -0,0 +1,11 @@ +{ + "swagger": "2.0", + "info": { + "title": "PMM Dump API", + "version": "v1beta1" + }, + "schemes": [ + "https", + "http" + ] +} diff --git a/api/serverpb/json/client/server/leader_health_check_parameters.go b/api/serverpb/json/client/server/leader_health_check_parameters.go new file mode 100644 index 0000000000..595d3d650d --- /dev/null +++ b/api/serverpb/json/client/server/leader_health_check_parameters.go @@ -0,0 +1,146 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package server + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + "time" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + cr "github.com/go-openapi/runtime/client" + "github.com/go-openapi/strfmt" +) + +// NewLeaderHealthCheckParams creates a new LeaderHealthCheckParams object, +// with the default timeout for this client. +// +// Default values are not hydrated, since defaults are normally applied by the API server side. +// +// To enforce default values in parameter, use SetDefaults or WithDefaults. +func NewLeaderHealthCheckParams() *LeaderHealthCheckParams { + return &LeaderHealthCheckParams{ + timeout: cr.DefaultTimeout, + } +} + +// NewLeaderHealthCheckParamsWithTimeout creates a new LeaderHealthCheckParams object +// with the ability to set a timeout on a request. +func NewLeaderHealthCheckParamsWithTimeout(timeout time.Duration) *LeaderHealthCheckParams { + return &LeaderHealthCheckParams{ + timeout: timeout, + } +} + +// NewLeaderHealthCheckParamsWithContext creates a new LeaderHealthCheckParams object +// with the ability to set a context for a request. +func NewLeaderHealthCheckParamsWithContext(ctx context.Context) *LeaderHealthCheckParams { + return &LeaderHealthCheckParams{ + Context: ctx, + } +} + +// NewLeaderHealthCheckParamsWithHTTPClient creates a new LeaderHealthCheckParams object +// with the ability to set a custom HTTPClient for a request. +func NewLeaderHealthCheckParamsWithHTTPClient(client *http.Client) *LeaderHealthCheckParams { + return &LeaderHealthCheckParams{ + HTTPClient: client, + } +} + +/* +LeaderHealthCheckParams contains all the parameters to send to the API endpoint + + for the leader health check operation. + + Typically these are written to a http.Request. +*/ +type LeaderHealthCheckParams struct { + // Body. + Body interface{} + + timeout time.Duration + Context context.Context + HTTPClient *http.Client +} + +// WithDefaults hydrates default values in the leader health check params (not the query body). +// +// All values with no default are reset to their zero value. +func (o *LeaderHealthCheckParams) WithDefaults() *LeaderHealthCheckParams { + o.SetDefaults() + return o +} + +// SetDefaults hydrates default values in the leader health check params (not the query body). +// +// All values with no default are reset to their zero value. +func (o *LeaderHealthCheckParams) SetDefaults() { + // no default values defined for this parameter +} + +// WithTimeout adds the timeout to the leader health check params +func (o *LeaderHealthCheckParams) WithTimeout(timeout time.Duration) *LeaderHealthCheckParams { + o.SetTimeout(timeout) + return o +} + +// SetTimeout adds the timeout to the leader health check params +func (o *LeaderHealthCheckParams) SetTimeout(timeout time.Duration) { + o.timeout = timeout +} + +// WithContext adds the context to the leader health check params +func (o *LeaderHealthCheckParams) WithContext(ctx context.Context) *LeaderHealthCheckParams { + o.SetContext(ctx) + return o +} + +// SetContext adds the context to the leader health check params +func (o *LeaderHealthCheckParams) SetContext(ctx context.Context) { + o.Context = ctx +} + +// WithHTTPClient adds the HTTPClient to the leader health check params +func (o *LeaderHealthCheckParams) WithHTTPClient(client *http.Client) *LeaderHealthCheckParams { + o.SetHTTPClient(client) + return o +} + +// SetHTTPClient adds the HTTPClient to the leader health check params +func (o *LeaderHealthCheckParams) SetHTTPClient(client *http.Client) { + o.HTTPClient = client +} + +// WithBody adds the body to the leader health check params +func (o *LeaderHealthCheckParams) WithBody(body interface{}) *LeaderHealthCheckParams { + o.SetBody(body) + return o +} + +// SetBody adds the body to the leader health check params +func (o *LeaderHealthCheckParams) SetBody(body interface{}) { + o.Body = body +} + +// WriteToRequest writes these params to a swagger request +func (o *LeaderHealthCheckParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error { + if err := r.SetTimeout(o.timeout); err != nil { + return err + } + var res []error + if o.Body != nil { + if err := r.SetBodyParam(o.Body); err != nil { + return err + } + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/api/serverpb/json/client/server/leader_health_check_responses.go b/api/serverpb/json/client/server/leader_health_check_responses.go new file mode 100644 index 0000000000..25152bbebd --- /dev/null +++ b/api/serverpb/json/client/server/leader_health_check_responses.go @@ -0,0 +1,369 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package server + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "fmt" + "io" + "strconv" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" +) + +// LeaderHealthCheckReader is a Reader for the LeaderHealthCheck structure. +type LeaderHealthCheckReader struct { + formats strfmt.Registry +} + +// ReadResponse reads a server response into the received o. +func (o *LeaderHealthCheckReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) { + switch response.Code() { + case 200: + result := NewLeaderHealthCheckOK() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return result, nil + default: + result := NewLeaderHealthCheckDefault(response.Code()) + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + if response.Code()/100 == 2 { + return result, nil + } + return nil, result + } +} + +// NewLeaderHealthCheckOK creates a LeaderHealthCheckOK with default headers values +func NewLeaderHealthCheckOK() *LeaderHealthCheckOK { + return &LeaderHealthCheckOK{} +} + +/* +LeaderHealthCheckOK describes a response with status code 200, with default header values. + +A successful response. +*/ +type LeaderHealthCheckOK struct { + Payload interface{} +} + +func (o *LeaderHealthCheckOK) Error() string { + return fmt.Sprintf("[POST /v1/leaderHealthCheck][%d] leaderHealthCheckOk %+v", 200, o.Payload) +} + +func (o *LeaderHealthCheckOK) GetPayload() interface{} { + return o.Payload +} + +func (o *LeaderHealthCheckOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + // response payload + if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} + +// NewLeaderHealthCheckDefault creates a LeaderHealthCheckDefault with default headers values +func NewLeaderHealthCheckDefault(code int) *LeaderHealthCheckDefault { + return &LeaderHealthCheckDefault{ + _statusCode: code, + } +} + +/* +LeaderHealthCheckDefault describes a response with status code -1, with default header values. + +An unexpected error response. +*/ +type LeaderHealthCheckDefault struct { + _statusCode int + + Payload *LeaderHealthCheckDefaultBody +} + +// Code gets the status code for the leader health check default response +func (o *LeaderHealthCheckDefault) Code() int { + return o._statusCode +} + +func (o *LeaderHealthCheckDefault) Error() string { + return fmt.Sprintf("[POST /v1/leaderHealthCheck][%d] LeaderHealthCheck default %+v", o._statusCode, o.Payload) +} + +func (o *LeaderHealthCheckDefault) GetPayload() *LeaderHealthCheckDefaultBody { + return o.Payload +} + +func (o *LeaderHealthCheckDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + o.Payload = new(LeaderHealthCheckDefaultBody) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} + +/* +LeaderHealthCheckDefaultBody leader health check default body +swagger:model LeaderHealthCheckDefaultBody +*/ +type LeaderHealthCheckDefaultBody struct { + // code + Code int32 `json:"code,omitempty"` + + // message + Message string `json:"message,omitempty"` + + // details + Details []*LeaderHealthCheckDefaultBodyDetailsItems0 `json:"details"` +} + +// Validate validates this leader health check default body +func (o *LeaderHealthCheckDefaultBody) Validate(formats strfmt.Registry) error { + var res []error + + if err := o.validateDetails(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *LeaderHealthCheckDefaultBody) validateDetails(formats strfmt.Registry) error { + if swag.IsZero(o.Details) { // not required + return nil + } + + for i := 0; i < len(o.Details); i++ { + if swag.IsZero(o.Details[i]) { // not required + continue + } + + if o.Details[i] != nil { + if err := o.Details[i].Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("LeaderHealthCheck default" + "." + "details" + "." + strconv.Itoa(i)) + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("LeaderHealthCheck default" + "." + "details" + "." + strconv.Itoa(i)) + } + return err + } + } + + } + + return nil +} + +// ContextValidate validate this leader health check default body based on the context it is used +func (o *LeaderHealthCheckDefaultBody) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + var res []error + + if err := o.contextValidateDetails(ctx, formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *LeaderHealthCheckDefaultBody) contextValidateDetails(ctx context.Context, formats strfmt.Registry) error { + for i := 0; i < len(o.Details); i++ { + if o.Details[i] != nil { + if err := o.Details[i].ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("LeaderHealthCheck default" + "." + "details" + "." + strconv.Itoa(i)) + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("LeaderHealthCheck default" + "." + "details" + "." + strconv.Itoa(i)) + } + return err + } + } + } + + return nil +} + +// MarshalBinary interface implementation +func (o *LeaderHealthCheckDefaultBody) MarshalBinary() ([]byte, error) { + if o == nil { + return nil, nil + } + return swag.WriteJSON(o) +} + +// UnmarshalBinary interface implementation +func (o *LeaderHealthCheckDefaultBody) UnmarshalBinary(b []byte) error { + var res LeaderHealthCheckDefaultBody + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *o = res + return nil +} + +/* +LeaderHealthCheckDefaultBodyDetailsItems0 `Any` contains an arbitrary serialized protocol buffer message along with a +// URL that describes the type of the serialized message. +// +// Protobuf library provides support to pack/unpack Any values in the form +// of utility functions or additional generated methods of the Any type. +// +// Example 1: Pack and unpack a message in C++. +// +// Foo foo = ...; +// Any any; +// any.PackFrom(foo); +// ... +// if (any.UnpackTo(&foo)) { +// ... +// } +// +// Example 2: Pack and unpack a message in Java. +// +// Foo foo = ...; +// Any any = Any.pack(foo); +// ... +// if (any.is(Foo.class)) { +// foo = any.unpack(Foo.class); +// } +// // or ... +// if (any.isSameTypeAs(Foo.getDefaultInstance())) { +// foo = any.unpack(Foo.getDefaultInstance()); +// } +// +// Example 3: Pack and unpack a message in Python. +// +// foo = Foo(...) +// any = Any() +// any.Pack(foo) +// ... +// if any.Is(Foo.DESCRIPTOR): +// any.Unpack(foo) +// ... +// +// Example 4: Pack and unpack a message in Go +// +// foo := &pb.Foo{...} +// any, err := anypb.New(foo) +// if err != nil { +// ... +// } +// ... +// foo := &pb.Foo{} +// if err := any.UnmarshalTo(foo); err != nil { +// ... +// } +// +// The pack methods provided by protobuf library will by default use +// 'type.googleapis.com/full.type.name' as the type URL and the unpack +// methods only use the fully qualified type name after the last '/' +// in the type URL, for example "foo.bar.com/x/y.z" will yield type +// name "y.z". +// +// JSON +// ==== +// The JSON representation of an `Any` value uses the regular +// representation of the deserialized, embedded message, with an +// additional field `@type` which contains the type URL. Example: +// +// package google.profile; +// message Person { +// string first_name = 1; +// string last_name = 2; +// } +// +// { +// "@type": "type.googleapis.com/google.profile.Person", +// "firstName": , +// "lastName": +// } +// +// If the embedded message type is well-known and has a custom JSON +// representation, that representation will be embedded adding a field +// `value` which holds the custom JSON in addition to the `@type` +// field. Example (for message [google.protobuf.Duration][]): +// +// { +// "@type": "type.googleapis.com/google.protobuf.Duration", +// "value": "1.212s" +// } +swagger:model LeaderHealthCheckDefaultBodyDetailsItems0 +*/ +type LeaderHealthCheckDefaultBodyDetailsItems0 struct { + // A URL/resource name that uniquely identifies the type of the serialized + // protocol buffer message. This string must contain at least + // one "/" character. The last segment of the URL's path must represent + // the fully qualified name of the type (as in + // `path/google.protobuf.Duration`). The name should be in a canonical form + // (e.g., leading "." is not accepted). + // + // In practice, teams usually precompile into the binary all types that they + // expect it to use in the context of Any. However, for URLs which use the + // scheme `http`, `https`, or no scheme, one can optionally set up a type + // server that maps type URLs to message definitions as follows: + // + // * If no scheme is provided, `https` is assumed. + // * An HTTP GET on the URL must yield a [google.protobuf.Type][] + // value in binary format, or produce an error. + // * Applications are allowed to cache lookup results based on the + // URL, or have them precompiled into a binary to avoid any + // lookup. Therefore, binary compatibility needs to be preserved + // on changes to types. (Use versioned type names to manage + // breaking changes.) + // + // Note: this functionality is not currently available in the official + // protobuf release, and it is not used for type URLs beginning with + // type.googleapis.com. As of May 2023, there are no widely used type server + // implementations and no plans to implement one. + // + // Schemes other than `http`, `https` (or the empty scheme) might be + // used with implementation specific semantics. + AtType string `json:"@type,omitempty"` +} + +// Validate validates this leader health check default body details items0 +func (o *LeaderHealthCheckDefaultBodyDetailsItems0) Validate(formats strfmt.Registry) error { + return nil +} + +// ContextValidate validates this leader health check default body details items0 based on context it is used +func (o *LeaderHealthCheckDefaultBodyDetailsItems0) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (o *LeaderHealthCheckDefaultBodyDetailsItems0) MarshalBinary() ([]byte, error) { + if o == nil { + return nil, nil + } + return swag.WriteJSON(o) +} + +// UnmarshalBinary interface implementation +func (o *LeaderHealthCheckDefaultBodyDetailsItems0) UnmarshalBinary(b []byte) error { + var res LeaderHealthCheckDefaultBodyDetailsItems0 + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *o = res + return nil +} diff --git a/api/serverpb/json/client/server/server_client.go b/api/serverpb/json/client/server/server_client.go index 4ea4103a70..0a2feac27a 100644 --- a/api/serverpb/json/client/server/server_client.go +++ b/api/serverpb/json/client/server/server_client.go @@ -38,6 +38,8 @@ type ClientService interface { GetSettings(params *GetSettingsParams, opts ...ClientOption) (*GetSettingsOK, error) + LeaderHealthCheck(params *LeaderHealthCheckParams, opts ...ClientOption) (*LeaderHealthCheckOK, error) + Logs(params *LogsParams, writer io.Writer, opts ...ClientOption) (*LogsOK, error) Readiness(params *ReadinessParams, opts ...ClientOption) (*ReadinessOK, error) @@ -207,6 +209,45 @@ func (a *Client) GetSettings(params *GetSettingsParams, opts ...ClientOption) (* return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) } +/* +LeaderHealthCheck checks leadership + +Checks if the instance is the leader in a cluster. Returns an error if the instance isn't the leader. +*/ +func (a *Client) LeaderHealthCheck(params *LeaderHealthCheckParams, opts ...ClientOption) (*LeaderHealthCheckOK, error) { + // TODO: Validate the params before sending + if params == nil { + params = NewLeaderHealthCheckParams() + } + op := &runtime.ClientOperation{ + ID: "LeaderHealthCheck", + Method: "POST", + PathPattern: "/v1/leaderHealthCheck", + ProducesMediaTypes: []string{"application/json"}, + ConsumesMediaTypes: []string{"application/json"}, + Schemes: []string{"http", "https"}, + Params: params, + Reader: &LeaderHealthCheckReader{formats: a.formats}, + Context: params.Context, + Client: params.HTTPClient, + } + for _, opt := range opts { + opt(op) + } + + result, err := a.transport.Submit(op) + if err != nil { + return nil, err + } + success, ok := result.(*LeaderHealthCheckOK) + if ok { + return success, nil + } + // unexpected success response + unexpectedSuccess := result.(*LeaderHealthCheckDefault) + return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) +} + /* Logs logs diff --git a/api/serverpb/json/serverpb.json b/api/serverpb/json/serverpb.json index dd551c9c1b..fbcff81f39 100644 --- a/api/serverpb/json/serverpb.json +++ b/api/serverpb/json/serverpb.json @@ -1000,6 +1000,68 @@ } } }, + "/v1/leaderHealthCheck": { + "post": { + "description": "Checks if the instance is the leader in a cluster. Returns an error if the instance isn't the leader.", + "tags": [ + "Server" + ], + "summary": "Check Leadership", + "operationId": "LeaderHealthCheck", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object" + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "description": "This probe is available without authentication, so it should not contain any data.", + "type": "object" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32", + "x-order": 0 + }, + "details": { + "type": "array", + "items": { + "description": "`Any` contains an arbitrary serialized protocol buffer message along with a\nURL that describes the type of the serialized message.\n\nProtobuf library provides support to pack/unpack Any values in the form\nof utility functions or additional generated methods of the Any type.\n\nExample 1: Pack and unpack a message in C++.\n\n Foo foo = ...;\n Any any;\n any.PackFrom(foo);\n ...\n if (any.UnpackTo(\u0026foo)) {\n ...\n }\n\nExample 2: Pack and unpack a message in Java.\n\n Foo foo = ...;\n Any any = Any.pack(foo);\n ...\n if (any.is(Foo.class)) {\n foo = any.unpack(Foo.class);\n }\n // or ...\n if (any.isSameTypeAs(Foo.getDefaultInstance())) {\n foo = any.unpack(Foo.getDefaultInstance());\n }\n\n Example 3: Pack and unpack a message in Python.\n\n foo = Foo(...)\n any = Any()\n any.Pack(foo)\n ...\n if any.Is(Foo.DESCRIPTOR):\n any.Unpack(foo)\n ...\n\n Example 4: Pack and unpack a message in Go\n\n foo := \u0026pb.Foo{...}\n any, err := anypb.New(foo)\n if err != nil {\n ...\n }\n ...\n foo := \u0026pb.Foo{}\n if err := any.UnmarshalTo(foo); err != nil {\n ...\n }\n\nThe pack methods provided by protobuf library will by default use\n'type.googleapis.com/full.type.name' as the type URL and the unpack\nmethods only use the fully qualified type name after the last '/'\nin the type URL, for example \"foo.bar.com/x/y.z\" will yield type\nname \"y.z\".\n\nJSON\n====\nThe JSON representation of an `Any` value uses the regular\nrepresentation of the deserialized, embedded message, with an\nadditional field `@type` which contains the type URL. Example:\n\n package google.profile;\n message Person {\n string first_name = 1;\n string last_name = 2;\n }\n\n {\n \"@type\": \"type.googleapis.com/google.profile.Person\",\n \"firstName\": \u003cstring\u003e,\n \"lastName\": \u003cstring\u003e\n }\n\nIf the embedded message type is well-known and has a custom JSON\nrepresentation, that representation will be embedded adding a field\n`value` which holds the custom JSON in addition to the `@type`\nfield. Example (for message [google.protobuf.Duration][]):\n\n {\n \"@type\": \"type.googleapis.com/google.protobuf.Duration\",\n \"value\": \"1.212s\"\n }", + "type": "object", + "properties": { + "@type": { + "description": "A URL/resource name that uniquely identifies the type of the serialized\nprotocol buffer message. This string must contain at least\none \"/\" character. The last segment of the URL's path must represent\nthe fully qualified name of the type (as in\n`path/google.protobuf.Duration`). The name should be in a canonical form\n(e.g., leading \".\" is not accepted).\n\nIn practice, teams usually precompile into the binary all types that they\nexpect it to use in the context of Any. However, for URLs which use the\nscheme `http`, `https`, or no scheme, one can optionally set up a type\nserver that maps type URLs to message definitions as follows:\n\n* If no scheme is provided, `https` is assumed.\n* An HTTP GET on the URL must yield a [google.protobuf.Type][]\n value in binary format, or produce an error.\n* Applications are allowed to cache lookup results based on the\n URL, or have them precompiled into a binary to avoid any\n lookup. Therefore, binary compatibility needs to be preserved\n on changes to types. (Use versioned type names to manage\n breaking changes.)\n\nNote: this functionality is not currently available in the official\nprotobuf release, and it is not used for type URLs beginning with\ntype.googleapis.com. As of May 2023, there are no widely used type server\nimplementations and no plans to implement one.\n\nSchemes other than `http`, `https` (or the empty scheme) might be\nused with implementation specific semantics.", + "type": "string", + "x-order": 0 + } + }, + "additionalProperties": false + }, + "x-order": 2 + }, + "message": { + "type": "string", + "x-order": 1 + } + } + } + } + } + } + }, "/v1/readyz": { "get": { "description": "Returns an error when Server components being restarted are not ready yet. Use this API for checking the health of Docker containers and for probing Kubernetes readiness.", diff --git a/api/serverpb/server.pb.go b/api/serverpb/server.pb.go index a4a52abe6e..693e7d7479 100644 --- a/api/serverpb/server.pb.go +++ b/api/serverpb/server.pb.go @@ -7,9 +7,6 @@ package serverpb import ( - reflect "reflect" - sync "sync" - _ "github.com/envoyproxy/protoc-gen-validate/validate" _ "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options" _ "google.golang.org/genproto/googleapis/api/annotations" @@ -17,6 +14,8 @@ import ( protoimpl "google.golang.org/protobuf/runtime/protoimpl" durationpb "google.golang.org/protobuf/types/known/durationpb" timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" ) const ( @@ -351,6 +350,82 @@ func (*ReadinessResponse) Descriptor() ([]byte, []int) { return file_serverpb_server_proto_rawDescGZIP(), []int{4} } +type LeaderHealthCheckRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *LeaderHealthCheckRequest) Reset() { + *x = LeaderHealthCheckRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_serverpb_server_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *LeaderHealthCheckRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LeaderHealthCheckRequest) ProtoMessage() {} + +func (x *LeaderHealthCheckRequest) ProtoReflect() protoreflect.Message { + mi := &file_serverpb_server_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LeaderHealthCheckRequest.ProtoReflect.Descriptor instead. +func (*LeaderHealthCheckRequest) Descriptor() ([]byte, []int) { + return file_serverpb_server_proto_rawDescGZIP(), []int{5} +} + +type LeaderHealthCheckResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *LeaderHealthCheckResponse) Reset() { + *x = LeaderHealthCheckResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_serverpb_server_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *LeaderHealthCheckResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LeaderHealthCheckResponse) ProtoMessage() {} + +func (x *LeaderHealthCheckResponse) ProtoReflect() protoreflect.Message { + mi := &file_serverpb_server_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LeaderHealthCheckResponse.ProtoReflect.Descriptor instead. +func (*LeaderHealthCheckResponse) Descriptor() ([]byte, []int) { + return file_serverpb_server_proto_rawDescGZIP(), []int{6} +} + type CheckUpdatesRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -365,7 +440,7 @@ type CheckUpdatesRequest struct { func (x *CheckUpdatesRequest) Reset() { *x = CheckUpdatesRequest{} if protoimpl.UnsafeEnabled { - mi := &file_serverpb_server_proto_msgTypes[5] + mi := &file_serverpb_server_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -378,7 +453,7 @@ func (x *CheckUpdatesRequest) String() string { func (*CheckUpdatesRequest) ProtoMessage() {} func (x *CheckUpdatesRequest) ProtoReflect() protoreflect.Message { - mi := &file_serverpb_server_proto_msgTypes[5] + mi := &file_serverpb_server_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -391,7 +466,7 @@ func (x *CheckUpdatesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CheckUpdatesRequest.ProtoReflect.Descriptor instead. func (*CheckUpdatesRequest) Descriptor() ([]byte, []int) { - return file_serverpb_server_proto_rawDescGZIP(), []int{5} + return file_serverpb_server_proto_rawDescGZIP(), []int{7} } func (x *CheckUpdatesRequest) GetForce() bool { @@ -428,7 +503,7 @@ type CheckUpdatesResponse struct { func (x *CheckUpdatesResponse) Reset() { *x = CheckUpdatesResponse{} if protoimpl.UnsafeEnabled { - mi := &file_serverpb_server_proto_msgTypes[6] + mi := &file_serverpb_server_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -441,7 +516,7 @@ func (x *CheckUpdatesResponse) String() string { func (*CheckUpdatesResponse) ProtoMessage() {} func (x *CheckUpdatesResponse) ProtoReflect() protoreflect.Message { - mi := &file_serverpb_server_proto_msgTypes[6] + mi := &file_serverpb_server_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -454,7 +529,7 @@ func (x *CheckUpdatesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CheckUpdatesResponse.ProtoReflect.Descriptor instead. func (*CheckUpdatesResponse) Descriptor() ([]byte, []int) { - return file_serverpb_server_proto_rawDescGZIP(), []int{6} + return file_serverpb_server_proto_rawDescGZIP(), []int{8} } func (x *CheckUpdatesResponse) GetInstalled() *VersionInfo { @@ -501,7 +576,7 @@ type StartUpdateRequest struct { func (x *StartUpdateRequest) Reset() { *x = StartUpdateRequest{} if protoimpl.UnsafeEnabled { - mi := &file_serverpb_server_proto_msgTypes[7] + mi := &file_serverpb_server_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -514,7 +589,7 @@ func (x *StartUpdateRequest) String() string { func (*StartUpdateRequest) ProtoMessage() {} func (x *StartUpdateRequest) ProtoReflect() protoreflect.Message { - mi := &file_serverpb_server_proto_msgTypes[7] + mi := &file_serverpb_server_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -527,7 +602,7 @@ func (x *StartUpdateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use StartUpdateRequest.ProtoReflect.Descriptor instead. func (*StartUpdateRequest) Descriptor() ([]byte, []int) { - return file_serverpb_server_proto_rawDescGZIP(), []int{7} + return file_serverpb_server_proto_rawDescGZIP(), []int{9} } type StartUpdateResponse struct { @@ -544,7 +619,7 @@ type StartUpdateResponse struct { func (x *StartUpdateResponse) Reset() { *x = StartUpdateResponse{} if protoimpl.UnsafeEnabled { - mi := &file_serverpb_server_proto_msgTypes[8] + mi := &file_serverpb_server_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -557,7 +632,7 @@ func (x *StartUpdateResponse) String() string { func (*StartUpdateResponse) ProtoMessage() {} func (x *StartUpdateResponse) ProtoReflect() protoreflect.Message { - mi := &file_serverpb_server_proto_msgTypes[8] + mi := &file_serverpb_server_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -570,7 +645,7 @@ func (x *StartUpdateResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use StartUpdateResponse.ProtoReflect.Descriptor instead. func (*StartUpdateResponse) Descriptor() ([]byte, []int) { - return file_serverpb_server_proto_rawDescGZIP(), []int{8} + return file_serverpb_server_proto_rawDescGZIP(), []int{10} } func (x *StartUpdateResponse) GetAuthToken() string { @@ -601,7 +676,7 @@ type UpdateStatusRequest struct { func (x *UpdateStatusRequest) Reset() { *x = UpdateStatusRequest{} if protoimpl.UnsafeEnabled { - mi := &file_serverpb_server_proto_msgTypes[9] + mi := &file_serverpb_server_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -614,7 +689,7 @@ func (x *UpdateStatusRequest) String() string { func (*UpdateStatusRequest) ProtoMessage() {} func (x *UpdateStatusRequest) ProtoReflect() protoreflect.Message { - mi := &file_serverpb_server_proto_msgTypes[9] + mi := &file_serverpb_server_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -627,7 +702,7 @@ func (x *UpdateStatusRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateStatusRequest.ProtoReflect.Descriptor instead. func (*UpdateStatusRequest) Descriptor() ([]byte, []int) { - return file_serverpb_server_proto_rawDescGZIP(), []int{9} + return file_serverpb_server_proto_rawDescGZIP(), []int{11} } func (x *UpdateStatusRequest) GetAuthToken() string { @@ -660,7 +735,7 @@ type UpdateStatusResponse struct { func (x *UpdateStatusResponse) Reset() { *x = UpdateStatusResponse{} if protoimpl.UnsafeEnabled { - mi := &file_serverpb_server_proto_msgTypes[10] + mi := &file_serverpb_server_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -673,7 +748,7 @@ func (x *UpdateStatusResponse) String() string { func (*UpdateStatusResponse) ProtoMessage() {} func (x *UpdateStatusResponse) ProtoReflect() protoreflect.Message { - mi := &file_serverpb_server_proto_msgTypes[10] + mi := &file_serverpb_server_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -686,7 +761,7 @@ func (x *UpdateStatusResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateStatusResponse.ProtoReflect.Descriptor instead. func (*UpdateStatusResponse) Descriptor() ([]byte, []int) { - return file_serverpb_server_proto_rawDescGZIP(), []int{10} + return file_serverpb_server_proto_rawDescGZIP(), []int{12} } func (x *UpdateStatusResponse) GetLogLines() []string { @@ -727,7 +802,7 @@ type MetricsResolutions struct { func (x *MetricsResolutions) Reset() { *x = MetricsResolutions{} if protoimpl.UnsafeEnabled { - mi := &file_serverpb_server_proto_msgTypes[11] + mi := &file_serverpb_server_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -740,7 +815,7 @@ func (x *MetricsResolutions) String() string { func (*MetricsResolutions) ProtoMessage() {} func (x *MetricsResolutions) ProtoReflect() protoreflect.Message { - mi := &file_serverpb_server_proto_msgTypes[11] + mi := &file_serverpb_server_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -753,7 +828,7 @@ func (x *MetricsResolutions) ProtoReflect() protoreflect.Message { // Deprecated: Use MetricsResolutions.ProtoReflect.Descriptor instead. func (*MetricsResolutions) Descriptor() ([]byte, []int) { - return file_serverpb_server_proto_rawDescGZIP(), []int{11} + return file_serverpb_server_proto_rawDescGZIP(), []int{13} } func (x *MetricsResolutions) GetHr() *durationpb.Duration { @@ -794,7 +869,7 @@ type STTCheckIntervals struct { func (x *STTCheckIntervals) Reset() { *x = STTCheckIntervals{} if protoimpl.UnsafeEnabled { - mi := &file_serverpb_server_proto_msgTypes[12] + mi := &file_serverpb_server_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -807,7 +882,7 @@ func (x *STTCheckIntervals) String() string { func (*STTCheckIntervals) ProtoMessage() {} func (x *STTCheckIntervals) ProtoReflect() protoreflect.Message { - mi := &file_serverpb_server_proto_msgTypes[12] + mi := &file_serverpb_server_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -820,7 +895,7 @@ func (x *STTCheckIntervals) ProtoReflect() protoreflect.Message { // Deprecated: Use STTCheckIntervals.ProtoReflect.Descriptor instead. func (*STTCheckIntervals) Descriptor() ([]byte, []int) { - return file_serverpb_server_proto_rawDescGZIP(), []int{12} + return file_serverpb_server_proto_rawDescGZIP(), []int{14} } func (x *STTCheckIntervals) GetStandardInterval() *durationpb.Duration { @@ -889,7 +964,7 @@ type Settings struct { func (x *Settings) Reset() { *x = Settings{} if protoimpl.UnsafeEnabled { - mi := &file_serverpb_server_proto_msgTypes[13] + mi := &file_serverpb_server_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -902,7 +977,7 @@ func (x *Settings) String() string { func (*Settings) ProtoMessage() {} func (x *Settings) ProtoReflect() protoreflect.Message { - mi := &file_serverpb_server_proto_msgTypes[13] + mi := &file_serverpb_server_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -915,7 +990,7 @@ func (x *Settings) ProtoReflect() protoreflect.Message { // Deprecated: Use Settings.ProtoReflect.Descriptor instead. func (*Settings) Descriptor() ([]byte, []int) { - return file_serverpb_server_proto_rawDescGZIP(), []int{13} + return file_serverpb_server_proto_rawDescGZIP(), []int{15} } func (x *Settings) GetUpdatesDisabled() bool { @@ -1060,7 +1135,7 @@ type GetSettingsRequest struct { func (x *GetSettingsRequest) Reset() { *x = GetSettingsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_serverpb_server_proto_msgTypes[14] + mi := &file_serverpb_server_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1073,7 +1148,7 @@ func (x *GetSettingsRequest) String() string { func (*GetSettingsRequest) ProtoMessage() {} func (x *GetSettingsRequest) ProtoReflect() protoreflect.Message { - mi := &file_serverpb_server_proto_msgTypes[14] + mi := &file_serverpb_server_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1086,7 +1161,7 @@ func (x *GetSettingsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSettingsRequest.ProtoReflect.Descriptor instead. func (*GetSettingsRequest) Descriptor() ([]byte, []int) { - return file_serverpb_server_proto_rawDescGZIP(), []int{14} + return file_serverpb_server_proto_rawDescGZIP(), []int{16} } type GetSettingsResponse struct { @@ -1100,7 +1175,7 @@ type GetSettingsResponse struct { func (x *GetSettingsResponse) Reset() { *x = GetSettingsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_serverpb_server_proto_msgTypes[15] + mi := &file_serverpb_server_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1113,7 +1188,7 @@ func (x *GetSettingsResponse) String() string { func (*GetSettingsResponse) ProtoMessage() {} func (x *GetSettingsResponse) ProtoReflect() protoreflect.Message { - mi := &file_serverpb_server_proto_msgTypes[15] + mi := &file_serverpb_server_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1126,7 +1201,7 @@ func (x *GetSettingsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSettingsResponse.ProtoReflect.Descriptor instead. func (*GetSettingsResponse) Descriptor() ([]byte, []int) { - return file_serverpb_server_proto_rawDescGZIP(), []int{15} + return file_serverpb_server_proto_rawDescGZIP(), []int{17} } func (x *GetSettingsResponse) GetSettings() *Settings { @@ -1188,7 +1263,7 @@ type ChangeSettingsRequest struct { func (x *ChangeSettingsRequest) Reset() { *x = ChangeSettingsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_serverpb_server_proto_msgTypes[16] + mi := &file_serverpb_server_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1201,7 +1276,7 @@ func (x *ChangeSettingsRequest) String() string { func (*ChangeSettingsRequest) ProtoMessage() {} func (x *ChangeSettingsRequest) ProtoReflect() protoreflect.Message { - mi := &file_serverpb_server_proto_msgTypes[16] + mi := &file_serverpb_server_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1214,7 +1289,7 @@ func (x *ChangeSettingsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ChangeSettingsRequest.ProtoReflect.Descriptor instead. func (*ChangeSettingsRequest) Descriptor() ([]byte, []int) { - return file_serverpb_server_proto_rawDescGZIP(), []int{16} + return file_serverpb_server_proto_rawDescGZIP(), []int{18} } func (x *ChangeSettingsRequest) GetEnableUpdates() bool { @@ -1403,7 +1478,7 @@ type ChangeSettingsResponse struct { func (x *ChangeSettingsResponse) Reset() { *x = ChangeSettingsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_serverpb_server_proto_msgTypes[17] + mi := &file_serverpb_server_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1416,7 +1491,7 @@ func (x *ChangeSettingsResponse) String() string { func (*ChangeSettingsResponse) ProtoMessage() {} func (x *ChangeSettingsResponse) ProtoReflect() protoreflect.Message { - mi := &file_serverpb_server_proto_msgTypes[17] + mi := &file_serverpb_server_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1429,7 +1504,7 @@ func (x *ChangeSettingsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ChangeSettingsResponse.ProtoReflect.Descriptor instead. func (*ChangeSettingsResponse) Descriptor() ([]byte, []int) { - return file_serverpb_server_proto_rawDescGZIP(), []int{17} + return file_serverpb_server_proto_rawDescGZIP(), []int{19} } func (x *ChangeSettingsResponse) GetSettings() *Settings { @@ -1451,7 +1526,7 @@ type AWSInstanceCheckRequest struct { func (x *AWSInstanceCheckRequest) Reset() { *x = AWSInstanceCheckRequest{} if protoimpl.UnsafeEnabled { - mi := &file_serverpb_server_proto_msgTypes[18] + mi := &file_serverpb_server_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1464,7 +1539,7 @@ func (x *AWSInstanceCheckRequest) String() string { func (*AWSInstanceCheckRequest) ProtoMessage() {} func (x *AWSInstanceCheckRequest) ProtoReflect() protoreflect.Message { - mi := &file_serverpb_server_proto_msgTypes[18] + mi := &file_serverpb_server_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1477,7 +1552,7 @@ func (x *AWSInstanceCheckRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use AWSInstanceCheckRequest.ProtoReflect.Descriptor instead. func (*AWSInstanceCheckRequest) Descriptor() ([]byte, []int) { - return file_serverpb_server_proto_rawDescGZIP(), []int{18} + return file_serverpb_server_proto_rawDescGZIP(), []int{20} } func (x *AWSInstanceCheckRequest) GetInstanceId() string { @@ -1496,7 +1571,7 @@ type AWSInstanceCheckResponse struct { func (x *AWSInstanceCheckResponse) Reset() { *x = AWSInstanceCheckResponse{} if protoimpl.UnsafeEnabled { - mi := &file_serverpb_server_proto_msgTypes[19] + mi := &file_serverpb_server_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1509,7 +1584,7 @@ func (x *AWSInstanceCheckResponse) String() string { func (*AWSInstanceCheckResponse) ProtoMessage() {} func (x *AWSInstanceCheckResponse) ProtoReflect() protoreflect.Message { - mi := &file_serverpb_server_proto_msgTypes[19] + mi := &file_serverpb_server_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1522,7 +1597,7 @@ func (x *AWSInstanceCheckResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use AWSInstanceCheckResponse.ProtoReflect.Descriptor instead. func (*AWSInstanceCheckResponse) Descriptor() ([]byte, []int) { - return file_serverpb_server_proto_rawDescGZIP(), []int{19} + return file_serverpb_server_proto_rawDescGZIP(), []int{21} } var File_serverpb_server_proto protoreflect.FileDescriptor @@ -1567,330 +1642,349 @@ var file_serverpb_server_proto_rawDesc = []byte{ 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x22, 0x12, 0x0a, 0x10, 0x52, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x13, 0x0a, 0x11, 0x52, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x61, 0x0a, 0x13, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, - 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, - 0x72, 0x63, 0x65, 0x12, 0x34, 0x0a, 0x16, 0x6f, 0x6e, 0x6c, 0x79, 0x5f, 0x69, 0x6e, 0x73, 0x74, - 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x14, 0x6f, 0x6e, 0x6c, 0x79, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, - 0x65, 0x64, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x84, 0x02, 0x0a, 0x14, 0x43, 0x68, - 0x65, 0x63, 0x6b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x31, 0x0a, 0x09, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x56, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x09, 0x69, 0x6e, 0x73, 0x74, - 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x12, 0x2b, 0x0a, 0x06, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x56, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x06, 0x6c, 0x61, 0x74, 0x65, - 0x73, 0x74, 0x12, 0x29, 0x0a, 0x10, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x61, 0x76, 0x61, - 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x75, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x26, 0x0a, - 0x0f, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x6e, 0x65, 0x77, 0x73, 0x5f, 0x75, 0x72, 0x6c, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x4e, 0x65, - 0x77, 0x73, 0x55, 0x72, 0x6c, 0x12, 0x39, 0x0a, 0x0a, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x63, 0x68, - 0x65, 0x63, 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x6c, 0x61, 0x73, 0x74, 0x43, 0x68, 0x65, 0x63, 0x6b, - 0x22, 0x14, 0x0a, 0x12, 0x53, 0x74, 0x61, 0x72, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x53, 0x0a, 0x13, 0x53, 0x74, 0x61, 0x72, 0x74, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, - 0x0a, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x09, 0x61, 0x75, 0x74, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, - 0x6c, 0x6f, 0x67, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x09, 0x6c, 0x6f, 0x67, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x22, 0x53, 0x0a, 0x13, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x75, 0x74, 0x68, 0x54, 0x6f, 0x6b, 0x65, - 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x6c, 0x6f, 0x67, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x6c, 0x6f, 0x67, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, - 0x22, 0x66, 0x0a, 0x14, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6c, 0x6f, 0x67, 0x5f, - 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f, 0x67, - 0x4c, 0x69, 0x6e, 0x65, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x6c, 0x6f, 0x67, 0x5f, 0x6f, 0x66, 0x66, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1a, 0x0a, 0x18, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, + 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x22, 0x1b, 0x0a, 0x19, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x48, 0x65, 0x61, 0x6c, + 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x61, 0x0a, 0x13, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x12, 0x34, 0x0a, 0x16, + 0x6f, 0x6e, 0x6c, 0x79, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x5f, 0x76, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x6f, 0x6e, + 0x6c, 0x79, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x56, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x22, 0x84, 0x02, 0x0a, 0x14, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, 0x09, 0x69, + 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, + 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x49, + 0x6e, 0x66, 0x6f, 0x52, 0x09, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x12, 0x2b, + 0x0a, 0x06, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, + 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x49, + 0x6e, 0x66, 0x6f, 0x52, 0x06, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x12, 0x29, 0x0a, 0x10, 0x75, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x76, 0x61, + 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x26, 0x0a, 0x0f, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, + 0x5f, 0x6e, 0x65, 0x77, 0x73, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0d, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x4e, 0x65, 0x77, 0x73, 0x55, 0x72, 0x6c, 0x12, 0x39, + 0x0a, 0x0a, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, + 0x6c, 0x61, 0x73, 0x74, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x22, 0x14, 0x0a, 0x12, 0x53, 0x74, 0x61, + 0x72, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, + 0x53, 0x0a, 0x13, 0x53, 0x74, 0x61, 0x72, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x74, + 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x75, 0x74, 0x68, + 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x6c, 0x6f, 0x67, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x6c, 0x6f, 0x67, 0x4f, 0x66, - 0x66, 0x73, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x6f, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x04, 0x64, 0x6f, 0x6e, 0x65, 0x22, 0x95, 0x01, 0x0a, 0x12, 0x4d, 0x65, 0x74, - 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, - 0x29, 0x0a, 0x02, 0x68, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x02, 0x68, 0x72, 0x12, 0x29, 0x0a, 0x02, 0x6d, 0x72, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x02, 0x6d, 0x72, 0x12, 0x29, 0x0a, 0x02, 0x6c, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x02, 0x6c, 0x72, - 0x22, 0xe3, 0x01, 0x0a, 0x11, 0x53, 0x54, 0x54, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x49, 0x6e, 0x74, - 0x65, 0x72, 0x76, 0x61, 0x6c, 0x73, 0x12, 0x46, 0x0a, 0x11, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, - 0x72, 0x64, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x10, 0x73, 0x74, - 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x3e, - 0x0a, 0x0d, 0x72, 0x61, 0x72, 0x65, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x52, 0x0c, 0x72, 0x61, 0x72, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x46, - 0x0a, 0x11, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x76, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x10, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, 0x49, 0x6e, - 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x22, 0xb7, 0x07, 0x0a, 0x08, 0x53, 0x65, 0x74, 0x74, 0x69, - 0x6e, 0x67, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x5f, 0x64, - 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x75, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x2b, - 0x0a, 0x11, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x5f, 0x65, 0x6e, 0x61, 0x62, - 0x6c, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x74, 0x65, 0x6c, 0x65, 0x6d, - 0x65, 0x74, 0x72, 0x79, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x4b, 0x0a, 0x13, 0x6d, - 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x12, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, - 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x40, 0x0a, 0x0e, 0x64, 0x61, 0x74, 0x61, - 0x5f, 0x72, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x64, 0x61, 0x74, - 0x61, 0x52, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x17, 0x0a, 0x07, 0x73, 0x73, - 0x68, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x73, 0x68, - 0x4b, 0x65, 0x79, 0x12, 0x25, 0x0a, 0x0e, 0x61, 0x77, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x69, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x61, 0x77, 0x73, - 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x61, 0x6c, - 0x65, 0x72, 0x74, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x5f, 0x75, 0x72, 0x6c, 0x18, - 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x4d, 0x61, 0x6e, 0x61, - 0x67, 0x65, 0x72, 0x55, 0x72, 0x6c, 0x12, 0x2e, 0x0a, 0x13, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x5f, - 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x08, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x11, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, - 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x74, 0x74, 0x5f, 0x65, 0x6e, - 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x73, 0x74, 0x74, - 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x6c, 0x61, 0x74, 0x66, - 0x6f, 0x72, 0x6d, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0d, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x29, - 0x0a, 0x10, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, - 0x65, 0x64, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x69, - 0x6e, 0x67, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x2c, 0x0a, 0x12, 0x70, 0x6d, 0x6d, - 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, - 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x70, 0x6d, 0x6d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, - 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x49, 0x0a, 0x13, 0x73, 0x74, 0x74, 0x5f, 0x63, - 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x73, 0x18, 0x10, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x54, - 0x54, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x73, 0x52, - 0x11, 0x73, 0x74, 0x74, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, - 0x6c, 0x73, 0x12, 0x3a, 0x0a, 0x19, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x6d, 0x61, 0x6e, - 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, - 0x12, 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x4d, 0x61, 0x6e, - 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x33, - 0x0a, 0x15, 0x61, 0x7a, 0x75, 0x72, 0x65, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, - 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x61, - 0x7a, 0x75, 0x72, 0x65, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x45, 0x6e, 0x61, 0x62, - 0x6c, 0x65, 0x64, 0x12, 0x32, 0x0a, 0x15, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, - 0x5f, 0x74, 0x6f, 0x5f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x13, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x13, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x54, 0x6f, 0x50, - 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x2f, 0x0a, 0x13, 0x74, 0x65, 0x6c, 0x65, 0x6d, - 0x65, 0x74, 0x72, 0x79, 0x5f, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x69, 0x65, 0x73, 0x18, 0x14, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x12, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x53, - 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x69, 0x65, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x65, 0x6e, 0x61, 0x62, - 0x6c, 0x65, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, - 0x6c, 0x18, 0x15, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x41, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x12, 0x26, 0x0a, 0x0f, - 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x18, - 0x16, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x52, 0x6f, - 0x6c, 0x65, 0x49, 0x64, 0x4a, 0x04, 0x08, 0x0d, 0x10, 0x0e, 0x4a, 0x04, 0x08, 0x0e, 0x10, 0x0f, - 0x22, 0x14, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x43, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x53, 0x65, 0x74, - 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, - 0x08, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x10, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, - 0x73, 0x52, 0x08, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x22, 0x88, 0x0a, 0x0a, 0x15, - 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, - 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x65, - 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x12, 0x27, 0x0a, 0x0f, - 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x18, - 0x1d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, - 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x0f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x54, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, - 0x12, 0x2b, 0x0a, 0x11, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x74, 0x65, 0x6c, 0x65, - 0x6d, 0x65, 0x74, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x64, 0x69, 0x73, - 0x61, 0x62, 0x6c, 0x65, 0x54, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x12, 0x4b, 0x0a, - 0x13, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x6f, 0x6c, - 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x12, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, - 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x40, 0x0a, 0x0e, 0x64, 0x61, - 0x74, 0x61, 0x5f, 0x72, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, + 0x66, 0x73, 0x65, 0x74, 0x22, 0x53, 0x0a, 0x13, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x61, + 0x75, 0x74, 0x68, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x61, 0x75, 0x74, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x6c, 0x6f, + 0x67, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, + 0x6c, 0x6f, 0x67, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x22, 0x66, 0x0a, 0x14, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6c, 0x6f, 0x67, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f, 0x67, 0x4c, 0x69, 0x6e, 0x65, 0x73, 0x12, 0x1d, + 0x0a, 0x0a, 0x6c, 0x6f, 0x67, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x09, 0x6c, 0x6f, 0x67, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x12, 0x0a, + 0x04, 0x64, 0x6f, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x64, 0x6f, 0x6e, + 0x65, 0x22, 0x95, 0x01, 0x0a, 0x12, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, + 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x29, 0x0a, 0x02, 0x68, 0x72, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x02, 0x68, 0x72, 0x12, 0x29, 0x0a, 0x02, 0x6d, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x02, 0x6d, 0x72, 0x12, 0x29, + 0x0a, 0x02, 0x6c, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x02, 0x6c, 0x72, 0x22, 0xe3, 0x01, 0x0a, 0x11, 0x53, 0x54, + 0x54, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x73, 0x12, + 0x46, 0x0a, 0x11, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x5f, 0x69, 0x6e, 0x74, 0x65, + 0x72, 0x76, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x10, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x49, + 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x3e, 0x0a, 0x0d, 0x72, 0x61, 0x72, 0x65, 0x5f, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x72, 0x61, 0x72, 0x65, 0x49, + 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x46, 0x0a, 0x11, 0x66, 0x72, 0x65, 0x71, 0x75, + 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x64, - 0x61, 0x74, 0x61, 0x52, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x17, 0x0a, 0x07, - 0x73, 0x73, 0x68, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, - 0x73, 0x68, 0x4b, 0x65, 0x79, 0x12, 0x25, 0x0a, 0x0e, 0x61, 0x77, 0x73, 0x5f, 0x70, 0x61, 0x72, - 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x61, - 0x77, 0x73, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2a, 0x0a, 0x11, - 0x61, 0x6c, 0x65, 0x72, 0x74, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x5f, 0x75, 0x72, - 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x4d, 0x61, - 0x6e, 0x61, 0x67, 0x65, 0x72, 0x55, 0x72, 0x6c, 0x12, 0x37, 0x0a, 0x18, 0x72, 0x65, 0x6d, 0x6f, - 0x76, 0x65, 0x5f, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, - 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x72, 0x65, 0x6d, 0x6f, - 0x76, 0x65, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x55, 0x72, - 0x6c, 0x12, 0x2e, 0x0a, 0x13, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, - 0x65, 0x72, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, - 0x61, 0x6c, 0x65, 0x72, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x52, 0x75, 0x6c, 0x65, - 0x73, 0x12, 0x3b, 0x0a, 0x1a, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x5f, 0x61, 0x6c, 0x65, 0x72, - 0x74, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, - 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x41, 0x6c, 0x65, - 0x72, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x1d, - 0x0a, 0x0a, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x74, 0x74, 0x18, 0x0b, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x09, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x74, 0x12, 0x1f, 0x0a, - 0x0b, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x74, 0x74, 0x18, 0x0c, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x0a, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x74, 0x12, 0x27, - 0x0a, 0x0f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x69, 0x6e, - 0x67, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x41, - 0x6c, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x29, 0x0a, 0x10, 0x64, 0x69, 0x73, 0x61, 0x62, - 0x6c, 0x65, 0x5f, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x18, 0x0e, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x0f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x69, - 0x6e, 0x67, 0x12, 0x2c, 0x0a, 0x12, 0x70, 0x6d, 0x6d, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, - 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x13, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x10, 0x66, + 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x22, + 0xb7, 0x07, 0x0a, 0x08, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x29, 0x0a, 0x10, + 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x44, + 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x2b, 0x0a, 0x11, 0x74, 0x65, 0x6c, 0x65, 0x6d, + 0x65, 0x74, 0x72, 0x79, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x10, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x45, 0x6e, 0x61, + 0x62, 0x6c, 0x65, 0x64, 0x12, 0x4b, 0x0a, 0x13, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x5f, + 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, + 0x63, 0x73, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x12, 0x6d, + 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x12, 0x40, 0x0a, 0x0e, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x65, 0x74, 0x65, 0x6e, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x74, 0x65, 0x6e, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x17, 0x0a, 0x07, 0x73, 0x73, 0x68, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x73, 0x68, 0x4b, 0x65, 0x79, 0x12, 0x25, 0x0a, 0x0e, + 0x61, 0x77, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x06, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x61, 0x77, 0x73, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x5f, 0x6d, 0x61, 0x6e, + 0x61, 0x67, 0x65, 0x72, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, + 0x61, 0x6c, 0x65, 0x72, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x55, 0x72, 0x6c, 0x12, + 0x2e, 0x0a, 0x13, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, + 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x61, 0x6c, + 0x65, 0x72, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, + 0x1f, 0x0a, 0x0b, 0x73, 0x74, 0x74, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x09, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x73, 0x74, 0x74, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, + 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x5f, 0x65, 0x6d, 0x61, + 0x69, 0x6c, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, + 0x72, 0x6d, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x29, 0x0a, 0x10, 0x61, 0x6c, 0x65, 0x72, 0x74, + 0x69, 0x6e, 0x67, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x0c, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x0f, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x45, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x64, 0x12, 0x2c, 0x0a, 0x12, 0x70, 0x6d, 0x6d, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x70, 0x6d, 0x6d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x12, 0x39, 0x0a, 0x19, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x5f, 0x70, 0x6d, 0x6d, 0x5f, 0x70, - 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x14, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x16, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x50, 0x6d, 0x6d, 0x50, 0x75, - 0x62, 0x6c, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x49, 0x0a, 0x13, 0x73, - 0x74, 0x74, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, - 0x6c, 0x73, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x2e, 0x53, 0x54, 0x54, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, - 0x61, 0x6c, 0x73, 0x52, 0x11, 0x73, 0x74, 0x74, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x49, 0x6e, 0x74, - 0x65, 0x72, 0x76, 0x61, 0x6c, 0x73, 0x12, 0x31, 0x0a, 0x14, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, - 0x5f, 0x61, 0x7a, 0x75, 0x72, 0x65, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x18, 0x16, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x41, 0x7a, 0x75, 0x72, - 0x65, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x12, 0x33, 0x0a, 0x15, 0x64, 0x69, 0x73, - 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x61, 0x7a, 0x75, 0x72, 0x65, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, - 0x65, 0x72, 0x18, 0x17, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, - 0x65, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x12, 0x38, - 0x0a, 0x18, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5f, - 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x18, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x16, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x4d, 0x61, - 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x3a, 0x0a, 0x19, 0x64, 0x69, 0x73, 0x61, - 0x62, 0x6c, 0x65, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, - 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x19, 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, 0x64, 0x69, 0x73, - 0x61, 0x62, 0x6c, 0x65, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, - 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x32, 0x0a, 0x15, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x61, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x18, 0x1e, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x13, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x41, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x12, 0x34, 0x0a, 0x16, 0x64, 0x69, 0x73, 0x61, - 0x62, 0x6c, 0x65, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x72, - 0x6f, 0x6c, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, - 0x65, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x4a, 0x04, - 0x08, 0x0f, 0x10, 0x10, 0x4a, 0x04, 0x08, 0x10, 0x10, 0x11, 0x4a, 0x04, 0x08, 0x11, 0x10, 0x12, - 0x4a, 0x04, 0x08, 0x12, 0x10, 0x13, 0x22, 0x46, 0x0a, 0x16, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, - 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x2c, 0x0a, 0x08, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x74, 0x74, - 0x69, 0x6e, 0x67, 0x73, 0x52, 0x08, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x22, 0x43, - 0x0a, 0x17, 0x41, 0x57, 0x53, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x68, 0x65, - 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, 0x0a, 0x0b, 0x69, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, - 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, - 0x65, 0x49, 0x64, 0x22, 0x1a, 0x0a, 0x18, 0x41, 0x57, 0x53, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, - 0x63, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2a, - 0x66, 0x0a, 0x12, 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x4d, - 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x1f, 0x0a, 0x1b, 0x44, 0x49, 0x53, 0x54, 0x52, 0x49, 0x42, - 0x55, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x49, 0x4e, 0x56, - 0x41, 0x4c, 0x49, 0x44, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x4f, 0x43, 0x4b, 0x45, 0x52, - 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, 0x4f, 0x56, 0x46, 0x10, 0x02, 0x12, 0x07, 0x0a, 0x03, 0x41, - 0x4d, 0x49, 0x10, 0x03, 0x12, 0x09, 0x0a, 0x05, 0x41, 0x5a, 0x55, 0x52, 0x45, 0x10, 0x04, 0x12, - 0x06, 0x0a, 0x02, 0x44, 0x4f, 0x10, 0x05, 0x32, 0xeb, 0x0a, 0x0a, 0x06, 0x53, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x12, 0x79, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x2e, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x56, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3d, - 0x92, 0x41, 0x27, 0x12, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x1a, 0x1c, 0x52, 0x65, - 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x50, 0x4d, 0x4d, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0d, - 0x12, 0x0b, 0x2f, 0x76, 0x31, 0x2f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x9e, 0x02, - 0x0a, 0x09, 0x52, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x12, 0x18, 0x2e, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x52, - 0x65, 0x61, 0x64, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0xdb, 0x01, 0x92, 0x41, 0xc5, 0x01, 0x12, 0x16, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x72, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x1a, - 0xaa, 0x01, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x61, 0x6e, 0x20, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x63, - 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x62, 0x65, 0x69, 0x6e, 0x67, 0x20, - 0x72, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x20, 0x61, 0x72, 0x65, 0x20, 0x6e, 0x6f, - 0x74, 0x20, 0x72, 0x65, 0x61, 0x64, 0x79, 0x20, 0x79, 0x65, 0x74, 0x2e, 0x20, 0x55, 0x73, 0x65, - 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x41, 0x50, 0x49, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x63, 0x68, - 0x65, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x68, 0x65, 0x61, 0x6c, 0x74, - 0x68, 0x20, 0x6f, 0x66, 0x20, 0x44, 0x6f, 0x63, 0x6b, 0x65, 0x72, 0x20, 0x63, 0x6f, 0x6e, 0x74, - 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x70, - 0x72, 0x6f, 0x62, 0x69, 0x6e, 0x67, 0x20, 0x4b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, - 0x73, 0x20, 0x72, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x2e, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x0c, 0x12, 0x0a, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x65, 0x61, 0x64, 0x79, 0x7a, 0x12, 0xa3, - 0x01, 0x0a, 0x0c, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x12, - 0x1b, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x58, 0x92, 0x41, 0x39, 0x12, - 0x0d, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x1a, 0x28, - 0x43, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x76, 0x61, 0x69, 0x6c, - 0x61, 0x62, 0x6c, 0x65, 0x20, 0x50, 0x4d, 0x4d, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, - 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x3a, 0x01, - 0x2a, 0x22, 0x11, 0x2f, 0x76, 0x31, 0x2f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x2f, 0x43, - 0x68, 0x65, 0x63, 0x6b, 0x12, 0x90, 0x01, 0x0a, 0x0b, 0x53, 0x74, 0x61, 0x72, 0x74, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x12, 0x1a, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x74, - 0x61, 0x72, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x1b, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x48, 0x92, - 0x41, 0x29, 0x12, 0x0c, 0x53, 0x74, 0x61, 0x72, 0x74, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x1a, 0x19, 0x53, 0x74, 0x61, 0x72, 0x74, 0x73, 0x20, 0x50, 0x4d, 0x4d, 0x20, 0x53, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x12, 0x49, 0x0a, 0x13, 0x73, 0x74, 0x74, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x69, 0x6e, + 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x73, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x54, 0x54, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x49, + 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x73, 0x52, 0x11, 0x73, 0x74, 0x74, 0x43, 0x68, 0x65, + 0x63, 0x6b, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x73, 0x12, 0x3a, 0x0a, 0x19, 0x62, + 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, + 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x33, 0x0a, 0x15, 0x61, 0x7a, 0x75, 0x72, 0x65, + 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, + 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x61, 0x7a, 0x75, 0x72, 0x65, 0x64, 0x69, 0x73, + 0x63, 0x6f, 0x76, 0x65, 0x72, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x32, 0x0a, 0x15, + 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x6f, 0x5f, 0x70, 0x6c, 0x61, + 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x13, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x63, 0x6f, 0x6e, + 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x54, 0x6f, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, + 0x12, 0x2f, 0x0a, 0x13, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x5f, 0x73, 0x75, + 0x6d, 0x6d, 0x61, 0x72, 0x69, 0x65, 0x73, 0x18, 0x14, 0x20, 0x03, 0x28, 0x09, 0x52, 0x12, 0x74, + 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x69, 0x65, + 0x73, 0x12, 0x32, 0x0a, 0x15, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x61, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x18, 0x15, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x13, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, + 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x12, 0x26, 0x0a, 0x0f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, + 0x5f, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, + 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x49, 0x64, 0x4a, 0x04, 0x08, + 0x0d, 0x10, 0x0e, 0x4a, 0x04, 0x08, 0x0e, 0x10, 0x0f, 0x22, 0x14, 0x0a, 0x12, 0x47, 0x65, 0x74, + 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, + 0x43, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x08, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, + 0x67, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x2e, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x08, 0x73, 0x65, 0x74, 0x74, + 0x69, 0x6e, 0x67, 0x73, 0x22, 0x88, 0x0a, 0x0a, 0x15, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, + 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x25, + 0x0a, 0x0e, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, + 0x18, 0x1c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, + 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, + 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x12, 0x29, + 0x0a, 0x10, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, + 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, + 0x54, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x12, 0x2b, 0x0a, 0x11, 0x64, 0x69, 0x73, + 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x54, 0x65, 0x6c, + 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x12, 0x4b, 0x0a, 0x13, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, + 0x73, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x4d, 0x65, 0x74, + 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, + 0x12, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x12, 0x40, 0x0a, 0x0e, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x65, 0x74, 0x65, + 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x74, 0x65, + 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x17, 0x0a, 0x07, 0x73, 0x73, 0x68, 0x5f, 0x6b, 0x65, 0x79, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x73, 0x68, 0x4b, 0x65, 0x79, 0x12, 0x25, + 0x0a, 0x0e, 0x61, 0x77, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x61, 0x77, 0x73, 0x50, 0x61, 0x72, 0x74, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x5f, 0x6d, + 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0f, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x55, 0x72, + 0x6c, 0x12, 0x37, 0x0a, 0x18, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x5f, 0x61, 0x6c, 0x65, 0x72, + 0x74, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x08, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x15, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x41, 0x6c, 0x65, 0x72, 0x74, + 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x55, 0x72, 0x6c, 0x12, 0x2e, 0x0a, 0x13, 0x61, 0x6c, + 0x65, 0x72, 0x74, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x5f, 0x72, 0x75, 0x6c, 0x65, + 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x4d, 0x61, + 0x6e, 0x61, 0x67, 0x65, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x3b, 0x0a, 0x1a, 0x72, 0x65, + 0x6d, 0x6f, 0x76, 0x65, 0x5f, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, + 0x65, 0x72, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, + 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, + 0x65, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x5f, 0x73, 0x74, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x65, 0x6e, 0x61, + 0x62, 0x6c, 0x65, 0x53, 0x74, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, + 0x65, 0x5f, 0x73, 0x74, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x64, 0x69, 0x73, + 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x65, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x5f, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0e, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x67, + 0x12, 0x29, 0x0a, 0x10, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x61, 0x6c, 0x65, 0x72, + 0x74, 0x69, 0x6e, 0x67, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x64, 0x69, 0x73, 0x61, + 0x62, 0x6c, 0x65, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x2c, 0x0a, 0x12, 0x70, + 0x6d, 0x6d, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x18, 0x13, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x70, 0x6d, 0x6d, 0x50, 0x75, 0x62, 0x6c, + 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x39, 0x0a, 0x19, 0x72, 0x65, 0x6d, + 0x6f, 0x76, 0x65, 0x5f, 0x70, 0x6d, 0x6d, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x61, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x14, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, 0x72, 0x65, + 0x6d, 0x6f, 0x76, 0x65, 0x50, 0x6d, 0x6d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x41, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x12, 0x49, 0x0a, 0x13, 0x73, 0x74, 0x74, 0x5f, 0x63, 0x68, 0x65, 0x63, + 0x6b, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x73, 0x18, 0x15, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x19, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x54, 0x54, 0x43, 0x68, + 0x65, 0x63, 0x6b, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x73, 0x52, 0x11, 0x73, 0x74, + 0x74, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x73, 0x12, + 0x31, 0x0a, 0x14, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x61, 0x7a, 0x75, 0x72, 0x65, 0x64, + 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x18, 0x16, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x65, + 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, + 0x65, 0x72, 0x12, 0x33, 0x0a, 0x15, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x61, 0x7a, + 0x75, 0x72, 0x65, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x18, 0x17, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x14, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x64, + 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x12, 0x38, 0x0a, 0x18, 0x65, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x18, 0x18, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, 0x65, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x12, 0x3a, 0x0a, 0x19, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x62, 0x61, 0x63, + 0x6b, 0x75, 0x70, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x19, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x42, 0x61, 0x63, + 0x6b, 0x75, 0x70, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x32, 0x0a, + 0x15, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, + 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x65, 0x6e, + 0x61, 0x62, 0x6c, 0x65, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, + 0x6c, 0x12, 0x34, 0x0a, 0x16, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x61, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x18, 0x1f, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x14, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x4a, 0x04, 0x08, 0x0f, 0x10, 0x10, 0x4a, 0x04, 0x08, + 0x10, 0x10, 0x11, 0x4a, 0x04, 0x08, 0x11, 0x10, 0x12, 0x4a, 0x04, 0x08, 0x12, 0x10, 0x13, 0x22, + 0x46, 0x0a, 0x16, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x08, 0x73, 0x65, 0x74, + 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x08, 0x73, + 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x22, 0x43, 0x0a, 0x17, 0x41, 0x57, 0x53, 0x49, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x28, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, + 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x22, 0x1a, 0x0a, 0x18, + 0x41, 0x57, 0x53, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2a, 0x66, 0x0a, 0x12, 0x44, 0x69, 0x73, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x1f, + 0x0a, 0x1b, 0x44, 0x49, 0x53, 0x54, 0x52, 0x49, 0x42, 0x55, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4d, + 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x00, 0x12, + 0x0a, 0x0a, 0x06, 0x44, 0x4f, 0x43, 0x4b, 0x45, 0x52, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, 0x4f, + 0x56, 0x46, 0x10, 0x02, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x4d, 0x49, 0x10, 0x03, 0x12, 0x09, 0x0a, + 0x05, 0x41, 0x5a, 0x55, 0x52, 0x45, 0x10, 0x04, 0x12, 0x06, 0x0a, 0x02, 0x44, 0x4f, 0x10, 0x05, + 0x32, 0xe5, 0x0c, 0x0a, 0x06, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x79, 0x0a, 0x07, 0x56, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, + 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3d, 0x92, 0x41, 0x27, 0x12, 0x07, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x1a, 0x1c, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x50, + 0x4d, 0x4d, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x73, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0d, 0x12, 0x0b, 0x2f, 0x76, 0x31, 0x2f, 0x76, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x9e, 0x02, 0x0a, 0x09, 0x52, 0x65, 0x61, 0x64, 0x69, + 0x6e, 0x65, 0x73, 0x73, 0x12, 0x18, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x52, 0x65, + 0x61, 0x64, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, + 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x65, 0x73, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xdb, 0x01, 0x92, 0x41, 0xc5, 0x01, + 0x12, 0x16, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x72, + 0x65, 0x61, 0x64, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x1a, 0xaa, 0x01, 0x52, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x73, 0x20, 0x61, 0x6e, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x77, 0x68, 0x65, 0x6e, + 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, + 0x74, 0x73, 0x20, 0x62, 0x65, 0x69, 0x6e, 0x67, 0x20, 0x72, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, + 0x65, 0x64, 0x20, 0x61, 0x72, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x72, 0x65, 0x61, 0x64, 0x79, + 0x20, 0x79, 0x65, 0x74, 0x2e, 0x20, 0x55, 0x73, 0x65, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x41, + 0x50, 0x49, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x20, 0x6f, 0x66, 0x20, 0x44, 0x6f, + 0x63, 0x6b, 0x65, 0x72, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x20, + 0x61, 0x6e, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x70, 0x72, 0x6f, 0x62, 0x69, 0x6e, 0x67, 0x20, + 0x4b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x20, 0x72, 0x65, 0x61, 0x64, 0x69, + 0x6e, 0x65, 0x73, 0x73, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0c, 0x12, 0x0a, 0x2f, 0x76, 0x31, + 0x2f, 0x72, 0x65, 0x61, 0x64, 0x79, 0x7a, 0x12, 0xf7, 0x01, 0x0a, 0x11, 0x4c, 0x65, 0x61, 0x64, + 0x65, 0x72, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x20, 0x2e, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x48, 0x65, 0x61, + 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x21, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x48, + 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x9c, 0x01, 0x92, 0x41, 0x79, 0x12, 0x10, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x20, + 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x1a, 0x65, 0x43, 0x68, 0x65, 0x63, + 0x6b, 0x73, 0x20, 0x69, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, + 0x63, 0x65, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x65, 0x61, 0x64, 0x65, 0x72, + 0x20, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x20, 0x52, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x61, 0x6e, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, + 0x69, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, + 0x69, 0x73, 0x6e, 0x27, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x65, 0x61, 0x64, 0x65, 0x72, + 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x3a, 0x01, 0x2a, 0x22, 0x15, 0x2f, 0x76, 0x31, 0x2f, + 0x6c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, + 0x6b, 0x12, 0xa3, 0x01, 0x0a, 0x0c, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x73, 0x12, 0x1b, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x43, 0x68, 0x65, 0x63, + 0x6b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x1c, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x58, 0x92, + 0x41, 0x39, 0x12, 0x0d, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x73, 0x1a, 0x28, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x76, + 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x50, 0x4d, 0x4d, 0x20, 0x53, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x3a, 0x01, 0x2a, 0x22, 0x11, 0x2f, 0x76, 0x31, 0x2f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x73, 0x2f, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x9d, 0x01, 0x0a, 0x0c, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1b, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x73, 0x2f, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x90, 0x01, 0x0a, 0x0b, 0x53, 0x74, 0x61, 0x72, + 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x1a, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x61, + 0x72, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x48, 0x92, 0x41, 0x29, 0x12, 0x0c, 0x53, 0x74, 0x61, 0x72, 0x74, 0x20, 0x75, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x1a, 0x19, 0x53, 0x74, 0x61, 0x72, 0x74, 0x73, 0x20, 0x50, 0x4d, 0x4d, 0x20, + 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x16, 0x3a, 0x01, 0x2a, 0x22, 0x11, 0x2f, 0x76, 0x31, 0x2f, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x73, 0x2f, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x9d, 0x01, 0x0a, 0x0c, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1b, 0x2e, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x52, 0x92, 0x41, 0x32, 0x12, 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x20, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x1a, 0x21, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, - 0x20, 0x50, 0x4d, 0x4d, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x75, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x20, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, - 0x3a, 0x01, 0x2a, 0x22, 0x12, 0x2f, 0x76, 0x31, 0x2f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, - 0x2f, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x9a, 0x01, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x53, - 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x1a, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x74, - 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x52, 0x92, 0x41, 0x34, 0x12, 0x0c, 0x47, 0x65, 0x74, 0x20, 0x73, 0x65, 0x74, 0x74, 0x69, - 0x6e, 0x67, 0x73, 0x1a, 0x24, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x63, 0x75, 0x72, - 0x72, 0x65, 0x6e, 0x74, 0x20, 0x50, 0x4d, 0x4d, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, - 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x3a, - 0x01, 0x2a, 0x22, 0x10, 0x2f, 0x76, 0x31, 0x2f, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, - 0x2f, 0x47, 0x65, 0x74, 0x12, 0xa1, 0x01, 0x0a, 0x0e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, - 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x1d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, - 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x50, 0x92, 0x41, 0x2f, 0x12, 0x0f, 0x43, 0x68, 0x61, - 0x6e, 0x67, 0x65, 0x20, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x1a, 0x1c, 0x43, 0x68, - 0x61, 0x6e, 0x67, 0x65, 0x73, 0x20, 0x50, 0x4d, 0x4d, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x20, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, - 0x3a, 0x01, 0x2a, 0x22, 0x13, 0x2f, 0x76, 0x31, 0x2f, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, - 0x73, 0x2f, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0xaa, 0x01, 0x0a, 0x10, 0x41, 0x57, 0x53, - 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x1f, 0x2e, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x41, 0x57, 0x53, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, - 0x63, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, - 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x41, 0x57, 0x53, 0x49, 0x6e, 0x73, 0x74, 0x61, - 0x6e, 0x63, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x53, 0x92, 0x41, 0x31, 0x12, 0x12, 0x41, 0x57, 0x53, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, - 0x6e, 0x63, 0x65, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x1a, 0x1b, 0x43, 0x68, 0x65, 0x63, 0x6b, - 0x73, 0x20, 0x41, 0x57, 0x53, 0x20, 0x45, 0x43, 0x32, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, - 0x63, 0x65, 0x20, 0x49, 0x44, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x3a, 0x01, 0x2a, 0x22, - 0x14, 0x2f, 0x76, 0x31, 0x2f, 0x41, 0x57, 0x53, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, - 0x43, 0x68, 0x65, 0x63, 0x6b, 0x42, 0x76, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x42, 0x0b, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, - 0x50, 0x01, 0x5a, 0x23, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, - 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x61, 0x2f, 0x70, 0x6d, 0x6d, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x70, 0x62, 0xa2, 0x02, 0x03, 0x53, 0x58, 0x58, 0xaa, 0x02, 0x06, - 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0xca, 0x02, 0x06, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0xe2, - 0x02, 0x12, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x06, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x52, 0x92, 0x41, 0x32, 0x12, 0x0d, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x20, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x1a, 0x21, 0x52, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x73, 0x20, 0x50, 0x4d, 0x4d, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x75, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x17, 0x3a, 0x01, 0x2a, 0x22, 0x12, 0x2f, 0x76, 0x31, 0x2f, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x73, 0x2f, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x9a, 0x01, 0x0a, 0x0b, 0x47, + 0x65, 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x1a, 0x2e, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, + 0x47, 0x65, 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x52, 0x92, 0x41, 0x34, 0x12, 0x0c, 0x47, 0x65, 0x74, 0x20, 0x73, 0x65, + 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x1a, 0x24, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, + 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x50, 0x4d, 0x4d, 0x20, 0x53, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x20, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x15, 0x3a, 0x01, 0x2a, 0x22, 0x10, 0x2f, 0x76, 0x31, 0x2f, 0x53, 0x65, 0x74, 0x74, 0x69, + 0x6e, 0x67, 0x73, 0x2f, 0x47, 0x65, 0x74, 0x12, 0xa1, 0x01, 0x0a, 0x0e, 0x43, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x1d, 0x2e, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, + 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x50, 0x92, 0x41, 0x2f, 0x12, 0x0f, + 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x1a, + 0x1c, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x20, 0x50, 0x4d, 0x4d, 0x20, 0x53, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x20, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x18, 0x3a, 0x01, 0x2a, 0x22, 0x13, 0x2f, 0x76, 0x31, 0x2f, 0x53, 0x65, 0x74, 0x74, + 0x69, 0x6e, 0x67, 0x73, 0x2f, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0xaa, 0x01, 0x0a, 0x10, + 0x41, 0x57, 0x53, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, + 0x12, 0x1f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x41, 0x57, 0x53, 0x49, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x20, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x41, 0x57, 0x53, 0x49, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x53, 0x92, 0x41, 0x31, 0x12, 0x12, 0x41, 0x57, 0x53, 0x20, 0x69, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x1a, 0x1b, 0x43, 0x68, + 0x65, 0x63, 0x6b, 0x73, 0x20, 0x41, 0x57, 0x53, 0x20, 0x45, 0x43, 0x32, 0x20, 0x69, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x49, 0x44, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x3a, + 0x01, 0x2a, 0x22, 0x14, 0x2f, 0x76, 0x31, 0x2f, 0x41, 0x57, 0x53, 0x49, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x42, 0x76, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x2e, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x42, 0x0b, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x50, 0x72, + 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x23, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x70, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x61, 0x2f, 0x70, 0x6d, 0x6d, 0x2f, 0x61, 0x70, + 0x69, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x70, 0x62, 0xa2, 0x02, 0x03, 0x53, 0x58, 0x58, + 0xaa, 0x02, 0x06, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0xca, 0x02, 0x06, 0x53, 0x65, 0x72, 0x76, + 0x65, 0x72, 0xe2, 0x02, 0x12, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5c, 0x47, 0x50, 0x42, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x06, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1905,76 +1999,77 @@ func file_serverpb_server_proto_rawDescGZIP() []byte { return file_serverpb_server_proto_rawDescData } -var ( - file_serverpb_server_proto_enumTypes = make([]protoimpl.EnumInfo, 1) - file_serverpb_server_proto_msgTypes = make([]protoimpl.MessageInfo, 20) - file_serverpb_server_proto_goTypes = []interface{}{ - (DistributionMethod)(0), // 0: server.DistributionMethod - (*VersionInfo)(nil), // 1: server.VersionInfo - (*VersionRequest)(nil), // 2: server.VersionRequest - (*VersionResponse)(nil), // 3: server.VersionResponse - (*ReadinessRequest)(nil), // 4: server.ReadinessRequest - (*ReadinessResponse)(nil), // 5: server.ReadinessResponse - (*CheckUpdatesRequest)(nil), // 6: server.CheckUpdatesRequest - (*CheckUpdatesResponse)(nil), // 7: server.CheckUpdatesResponse - (*StartUpdateRequest)(nil), // 8: server.StartUpdateRequest - (*StartUpdateResponse)(nil), // 9: server.StartUpdateResponse - (*UpdateStatusRequest)(nil), // 10: server.UpdateStatusRequest - (*UpdateStatusResponse)(nil), // 11: server.UpdateStatusResponse - (*MetricsResolutions)(nil), // 12: server.MetricsResolutions - (*STTCheckIntervals)(nil), // 13: server.STTCheckIntervals - (*Settings)(nil), // 14: server.Settings - (*GetSettingsRequest)(nil), // 15: server.GetSettingsRequest - (*GetSettingsResponse)(nil), // 16: server.GetSettingsResponse - (*ChangeSettingsRequest)(nil), // 17: server.ChangeSettingsRequest - (*ChangeSettingsResponse)(nil), // 18: server.ChangeSettingsResponse - (*AWSInstanceCheckRequest)(nil), // 19: server.AWSInstanceCheckRequest - (*AWSInstanceCheckResponse)(nil), // 20: server.AWSInstanceCheckResponse - (*timestamppb.Timestamp)(nil), // 21: google.protobuf.Timestamp - (*durationpb.Duration)(nil), // 22: google.protobuf.Duration - } -) - +var file_serverpb_server_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_serverpb_server_proto_msgTypes = make([]protoimpl.MessageInfo, 22) +var file_serverpb_server_proto_goTypes = []interface{}{ + (DistributionMethod)(0), // 0: server.DistributionMethod + (*VersionInfo)(nil), // 1: server.VersionInfo + (*VersionRequest)(nil), // 2: server.VersionRequest + (*VersionResponse)(nil), // 3: server.VersionResponse + (*ReadinessRequest)(nil), // 4: server.ReadinessRequest + (*ReadinessResponse)(nil), // 5: server.ReadinessResponse + (*LeaderHealthCheckRequest)(nil), // 6: server.LeaderHealthCheckRequest + (*LeaderHealthCheckResponse)(nil), // 7: server.LeaderHealthCheckResponse + (*CheckUpdatesRequest)(nil), // 8: server.CheckUpdatesRequest + (*CheckUpdatesResponse)(nil), // 9: server.CheckUpdatesResponse + (*StartUpdateRequest)(nil), // 10: server.StartUpdateRequest + (*StartUpdateResponse)(nil), // 11: server.StartUpdateResponse + (*UpdateStatusRequest)(nil), // 12: server.UpdateStatusRequest + (*UpdateStatusResponse)(nil), // 13: server.UpdateStatusResponse + (*MetricsResolutions)(nil), // 14: server.MetricsResolutions + (*STTCheckIntervals)(nil), // 15: server.STTCheckIntervals + (*Settings)(nil), // 16: server.Settings + (*GetSettingsRequest)(nil), // 17: server.GetSettingsRequest + (*GetSettingsResponse)(nil), // 18: server.GetSettingsResponse + (*ChangeSettingsRequest)(nil), // 19: server.ChangeSettingsRequest + (*ChangeSettingsResponse)(nil), // 20: server.ChangeSettingsResponse + (*AWSInstanceCheckRequest)(nil), // 21: server.AWSInstanceCheckRequest + (*AWSInstanceCheckResponse)(nil), // 22: server.AWSInstanceCheckResponse + (*timestamppb.Timestamp)(nil), // 23: google.protobuf.Timestamp + (*durationpb.Duration)(nil), // 24: google.protobuf.Duration +} var file_serverpb_server_proto_depIdxs = []int32{ - 21, // 0: server.VersionInfo.timestamp:type_name -> google.protobuf.Timestamp + 23, // 0: server.VersionInfo.timestamp:type_name -> google.protobuf.Timestamp 1, // 1: server.VersionResponse.server:type_name -> server.VersionInfo 1, // 2: server.VersionResponse.managed:type_name -> server.VersionInfo 0, // 3: server.VersionResponse.distribution_method:type_name -> server.DistributionMethod 1, // 4: server.CheckUpdatesResponse.installed:type_name -> server.VersionInfo 1, // 5: server.CheckUpdatesResponse.latest:type_name -> server.VersionInfo - 21, // 6: server.CheckUpdatesResponse.last_check:type_name -> google.protobuf.Timestamp - 22, // 7: server.MetricsResolutions.hr:type_name -> google.protobuf.Duration - 22, // 8: server.MetricsResolutions.mr:type_name -> google.protobuf.Duration - 22, // 9: server.MetricsResolutions.lr:type_name -> google.protobuf.Duration - 22, // 10: server.STTCheckIntervals.standard_interval:type_name -> google.protobuf.Duration - 22, // 11: server.STTCheckIntervals.rare_interval:type_name -> google.protobuf.Duration - 22, // 12: server.STTCheckIntervals.frequent_interval:type_name -> google.protobuf.Duration - 12, // 13: server.Settings.metrics_resolutions:type_name -> server.MetricsResolutions - 22, // 14: server.Settings.data_retention:type_name -> google.protobuf.Duration - 13, // 15: server.Settings.stt_check_intervals:type_name -> server.STTCheckIntervals - 14, // 16: server.GetSettingsResponse.settings:type_name -> server.Settings - 12, // 17: server.ChangeSettingsRequest.metrics_resolutions:type_name -> server.MetricsResolutions - 22, // 18: server.ChangeSettingsRequest.data_retention:type_name -> google.protobuf.Duration - 13, // 19: server.ChangeSettingsRequest.stt_check_intervals:type_name -> server.STTCheckIntervals - 14, // 20: server.ChangeSettingsResponse.settings:type_name -> server.Settings + 23, // 6: server.CheckUpdatesResponse.last_check:type_name -> google.protobuf.Timestamp + 24, // 7: server.MetricsResolutions.hr:type_name -> google.protobuf.Duration + 24, // 8: server.MetricsResolutions.mr:type_name -> google.protobuf.Duration + 24, // 9: server.MetricsResolutions.lr:type_name -> google.protobuf.Duration + 24, // 10: server.STTCheckIntervals.standard_interval:type_name -> google.protobuf.Duration + 24, // 11: server.STTCheckIntervals.rare_interval:type_name -> google.protobuf.Duration + 24, // 12: server.STTCheckIntervals.frequent_interval:type_name -> google.protobuf.Duration + 14, // 13: server.Settings.metrics_resolutions:type_name -> server.MetricsResolutions + 24, // 14: server.Settings.data_retention:type_name -> google.protobuf.Duration + 15, // 15: server.Settings.stt_check_intervals:type_name -> server.STTCheckIntervals + 16, // 16: server.GetSettingsResponse.settings:type_name -> server.Settings + 14, // 17: server.ChangeSettingsRequest.metrics_resolutions:type_name -> server.MetricsResolutions + 24, // 18: server.ChangeSettingsRequest.data_retention:type_name -> google.protobuf.Duration + 15, // 19: server.ChangeSettingsRequest.stt_check_intervals:type_name -> server.STTCheckIntervals + 16, // 20: server.ChangeSettingsResponse.settings:type_name -> server.Settings 2, // 21: server.Server.Version:input_type -> server.VersionRequest 4, // 22: server.Server.Readiness:input_type -> server.ReadinessRequest - 6, // 23: server.Server.CheckUpdates:input_type -> server.CheckUpdatesRequest - 8, // 24: server.Server.StartUpdate:input_type -> server.StartUpdateRequest - 10, // 25: server.Server.UpdateStatus:input_type -> server.UpdateStatusRequest - 15, // 26: server.Server.GetSettings:input_type -> server.GetSettingsRequest - 17, // 27: server.Server.ChangeSettings:input_type -> server.ChangeSettingsRequest - 19, // 28: server.Server.AWSInstanceCheck:input_type -> server.AWSInstanceCheckRequest - 3, // 29: server.Server.Version:output_type -> server.VersionResponse - 5, // 30: server.Server.Readiness:output_type -> server.ReadinessResponse - 7, // 31: server.Server.CheckUpdates:output_type -> server.CheckUpdatesResponse - 9, // 32: server.Server.StartUpdate:output_type -> server.StartUpdateResponse - 11, // 33: server.Server.UpdateStatus:output_type -> server.UpdateStatusResponse - 16, // 34: server.Server.GetSettings:output_type -> server.GetSettingsResponse - 18, // 35: server.Server.ChangeSettings:output_type -> server.ChangeSettingsResponse - 20, // 36: server.Server.AWSInstanceCheck:output_type -> server.AWSInstanceCheckResponse - 29, // [29:37] is the sub-list for method output_type - 21, // [21:29] is the sub-list for method input_type + 6, // 23: server.Server.LeaderHealthCheck:input_type -> server.LeaderHealthCheckRequest + 8, // 24: server.Server.CheckUpdates:input_type -> server.CheckUpdatesRequest + 10, // 25: server.Server.StartUpdate:input_type -> server.StartUpdateRequest + 12, // 26: server.Server.UpdateStatus:input_type -> server.UpdateStatusRequest + 17, // 27: server.Server.GetSettings:input_type -> server.GetSettingsRequest + 19, // 28: server.Server.ChangeSettings:input_type -> server.ChangeSettingsRequest + 21, // 29: server.Server.AWSInstanceCheck:input_type -> server.AWSInstanceCheckRequest + 3, // 30: server.Server.Version:output_type -> server.VersionResponse + 5, // 31: server.Server.Readiness:output_type -> server.ReadinessResponse + 7, // 32: server.Server.LeaderHealthCheck:output_type -> server.LeaderHealthCheckResponse + 9, // 33: server.Server.CheckUpdates:output_type -> server.CheckUpdatesResponse + 11, // 34: server.Server.StartUpdate:output_type -> server.StartUpdateResponse + 13, // 35: server.Server.UpdateStatus:output_type -> server.UpdateStatusResponse + 18, // 36: server.Server.GetSettings:output_type -> server.GetSettingsResponse + 20, // 37: server.Server.ChangeSettings:output_type -> server.ChangeSettingsResponse + 22, // 38: server.Server.AWSInstanceCheck:output_type -> server.AWSInstanceCheckResponse + 30, // [30:39] is the sub-list for method output_type + 21, // [21:30] is the sub-list for method input_type 21, // [21:21] is the sub-list for extension type_name 21, // [21:21] is the sub-list for extension extendee 0, // [0:21] is the sub-list for field type_name @@ -2047,7 +2142,7 @@ func file_serverpb_server_proto_init() { } } file_serverpb_server_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CheckUpdatesRequest); i { + switch v := v.(*LeaderHealthCheckRequest); i { case 0: return &v.state case 1: @@ -2059,7 +2154,7 @@ func file_serverpb_server_proto_init() { } } file_serverpb_server_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CheckUpdatesResponse); i { + switch v := v.(*LeaderHealthCheckResponse); i { case 0: return &v.state case 1: @@ -2071,7 +2166,7 @@ func file_serverpb_server_proto_init() { } } file_serverpb_server_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*StartUpdateRequest); i { + switch v := v.(*CheckUpdatesRequest); i { case 0: return &v.state case 1: @@ -2083,7 +2178,7 @@ func file_serverpb_server_proto_init() { } } file_serverpb_server_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*StartUpdateResponse); i { + switch v := v.(*CheckUpdatesResponse); i { case 0: return &v.state case 1: @@ -2095,7 +2190,7 @@ func file_serverpb_server_proto_init() { } } file_serverpb_server_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UpdateStatusRequest); i { + switch v := v.(*StartUpdateRequest); i { case 0: return &v.state case 1: @@ -2107,7 +2202,7 @@ func file_serverpb_server_proto_init() { } } file_serverpb_server_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UpdateStatusResponse); i { + switch v := v.(*StartUpdateResponse); i { case 0: return &v.state case 1: @@ -2119,7 +2214,7 @@ func file_serverpb_server_proto_init() { } } file_serverpb_server_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MetricsResolutions); i { + switch v := v.(*UpdateStatusRequest); i { case 0: return &v.state case 1: @@ -2131,7 +2226,7 @@ func file_serverpb_server_proto_init() { } } file_serverpb_server_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*STTCheckIntervals); i { + switch v := v.(*UpdateStatusResponse); i { case 0: return &v.state case 1: @@ -2143,7 +2238,7 @@ func file_serverpb_server_proto_init() { } } file_serverpb_server_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Settings); i { + switch v := v.(*MetricsResolutions); i { case 0: return &v.state case 1: @@ -2155,7 +2250,7 @@ func file_serverpb_server_proto_init() { } } file_serverpb_server_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetSettingsRequest); i { + switch v := v.(*STTCheckIntervals); i { case 0: return &v.state case 1: @@ -2167,7 +2262,7 @@ func file_serverpb_server_proto_init() { } } file_serverpb_server_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetSettingsResponse); i { + switch v := v.(*Settings); i { case 0: return &v.state case 1: @@ -2179,7 +2274,7 @@ func file_serverpb_server_proto_init() { } } file_serverpb_server_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ChangeSettingsRequest); i { + switch v := v.(*GetSettingsRequest); i { case 0: return &v.state case 1: @@ -2191,7 +2286,7 @@ func file_serverpb_server_proto_init() { } } file_serverpb_server_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ChangeSettingsResponse); i { + switch v := v.(*GetSettingsResponse); i { case 0: return &v.state case 1: @@ -2203,7 +2298,7 @@ func file_serverpb_server_proto_init() { } } file_serverpb_server_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AWSInstanceCheckRequest); i { + switch v := v.(*ChangeSettingsRequest); i { case 0: return &v.state case 1: @@ -2215,6 +2310,30 @@ func file_serverpb_server_proto_init() { } } file_serverpb_server_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ChangeSettingsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_serverpb_server_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AWSInstanceCheckRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_serverpb_server_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*AWSInstanceCheckResponse); i { case 0: return &v.state @@ -2233,7 +2352,7 @@ func file_serverpb_server_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_serverpb_server_proto_rawDesc, NumEnums: 1, - NumMessages: 20, + NumMessages: 22, NumExtensions: 0, NumServices: 1, }, diff --git a/api/serverpb/server.pb.gw.go b/api/serverpb/server.pb.gw.go index 3fa3295641..fc1eecf255 100644 --- a/api/serverpb/server.pb.gw.go +++ b/api/serverpb/server.pb.gw.go @@ -81,6 +81,38 @@ func local_request_Server_Readiness_0(ctx context.Context, marshaler runtime.Mar return msg, metadata, err } +func request_Server_LeaderHealthCheck_0(ctx context.Context, marshaler runtime.Marshaler, client ServerClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq LeaderHealthCheckRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.LeaderHealthCheck(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err +} + +func local_request_Server_LeaderHealthCheck_0(ctx context.Context, marshaler runtime.Marshaler, server ServerServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq LeaderHealthCheckRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.LeaderHealthCheck(ctx, &protoReq) + return msg, metadata, err +} + func request_Server_CheckUpdates_0(ctx context.Context, marshaler runtime.Marshaler, client ServerClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq CheckUpdatesRequest var metadata runtime.ServerMetadata @@ -326,6 +358,30 @@ func RegisterServerHandlerServer(ctx context.Context, mux *runtime.ServeMux, ser forward_Server_Readiness_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) + mux.Handle("POST", pattern_Server_LeaderHealthCheck_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/server.Server/LeaderHealthCheck", runtime.WithHTTPPathPattern("/v1/leaderHealthCheck")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Server_LeaderHealthCheck_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_Server_LeaderHealthCheck_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) + mux.Handle("POST", pattern_Server_CheckUpdates_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -552,6 +608,27 @@ func RegisterServerHandlerClient(ctx context.Context, mux *runtime.ServeMux, cli forward_Server_Readiness_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) + mux.Handle("POST", pattern_Server_LeaderHealthCheck_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/server.Server/LeaderHealthCheck", runtime.WithHTTPPathPattern("/v1/leaderHealthCheck")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Server_LeaderHealthCheck_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_Server_LeaderHealthCheck_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) + mux.Handle("POST", pattern_Server_CheckUpdates_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -686,6 +763,8 @@ var ( pattern_Server_Readiness_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "readyz"}, "")) + pattern_Server_LeaderHealthCheck_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "leaderHealthCheck"}, "")) + pattern_Server_CheckUpdates_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "Updates", "Check"}, "")) pattern_Server_StartUpdate_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "Updates", "Start"}, "")) @@ -704,6 +783,8 @@ var ( forward_Server_Readiness_0 = runtime.ForwardResponseMessage + forward_Server_LeaderHealthCheck_0 = runtime.ForwardResponseMessage + forward_Server_CheckUpdates_0 = runtime.ForwardResponseMessage forward_Server_StartUpdate_0 = runtime.ForwardResponseMessage diff --git a/api/serverpb/server.pb.validate.go b/api/serverpb/server.pb.validate.go index 155ee65797..112163358d 100644 --- a/api/serverpb/server.pb.validate.go +++ b/api/serverpb/server.pb.validate.go @@ -633,6 +633,210 @@ var _ interface { ErrorName() string } = ReadinessResponseValidationError{} +// Validate checks the field values on LeaderHealthCheckRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *LeaderHealthCheckRequest) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on LeaderHealthCheckRequest with the +// rules defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// LeaderHealthCheckRequestMultiError, or nil if none found. +func (m *LeaderHealthCheckRequest) ValidateAll() error { + return m.validate(true) +} + +func (m *LeaderHealthCheckRequest) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if len(errors) > 0 { + return LeaderHealthCheckRequestMultiError(errors) + } + + return nil +} + +// LeaderHealthCheckRequestMultiError is an error wrapping multiple validation +// errors returned by LeaderHealthCheckRequest.ValidateAll() if the designated +// constraints aren't met. +type LeaderHealthCheckRequestMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m LeaderHealthCheckRequestMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m LeaderHealthCheckRequestMultiError) AllErrors() []error { return m } + +// LeaderHealthCheckRequestValidationError is the validation error returned by +// LeaderHealthCheckRequest.Validate if the designated constraints aren't met. +type LeaderHealthCheckRequestValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e LeaderHealthCheckRequestValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e LeaderHealthCheckRequestValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e LeaderHealthCheckRequestValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e LeaderHealthCheckRequestValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e LeaderHealthCheckRequestValidationError) ErrorName() string { + return "LeaderHealthCheckRequestValidationError" +} + +// Error satisfies the builtin error interface +func (e LeaderHealthCheckRequestValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sLeaderHealthCheckRequest.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = LeaderHealthCheckRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = LeaderHealthCheckRequestValidationError{} + +// Validate checks the field values on LeaderHealthCheckResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *LeaderHealthCheckResponse) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on LeaderHealthCheckResponse with the +// rules defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// LeaderHealthCheckResponseMultiError, or nil if none found. +func (m *LeaderHealthCheckResponse) ValidateAll() error { + return m.validate(true) +} + +func (m *LeaderHealthCheckResponse) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if len(errors) > 0 { + return LeaderHealthCheckResponseMultiError(errors) + } + + return nil +} + +// LeaderHealthCheckResponseMultiError is an error wrapping multiple validation +// errors returned by LeaderHealthCheckResponse.ValidateAll() if the +// designated constraints aren't met. +type LeaderHealthCheckResponseMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m LeaderHealthCheckResponseMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m LeaderHealthCheckResponseMultiError) AllErrors() []error { return m } + +// LeaderHealthCheckResponseValidationError is the validation error returned by +// LeaderHealthCheckResponse.Validate if the designated constraints aren't met. +type LeaderHealthCheckResponseValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e LeaderHealthCheckResponseValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e LeaderHealthCheckResponseValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e LeaderHealthCheckResponseValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e LeaderHealthCheckResponseValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e LeaderHealthCheckResponseValidationError) ErrorName() string { + return "LeaderHealthCheckResponseValidationError" +} + +// Error satisfies the builtin error interface +func (e LeaderHealthCheckResponseValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sLeaderHealthCheckResponse.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = LeaderHealthCheckResponseValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = LeaderHealthCheckResponseValidationError{} + // Validate checks the field values on CheckUpdatesRequest with the rules // defined in the proto definition for this message. If any rules are // violated, the first error encountered is returned, or nil if there are no violations. diff --git a/api/serverpb/server.proto b/api/serverpb/server.proto index a8e5a694ff..c6dba265c2 100644 --- a/api/serverpb/server.proto +++ b/api/serverpb/server.proto @@ -53,6 +53,12 @@ message ReadinessResponse { // This probe is available without authentication, so it should not contain any data. } +message LeaderHealthCheckRequest {} + +message LeaderHealthCheckResponse { + // This probe is available without authentication, so it should not contain any data. +} + message CheckUpdatesRequest { // If false, cached information may be returned. bool force = 1; @@ -247,6 +253,17 @@ service Server { description: "Returns an error when Server components being restarted are not ready yet. Use this API for checking the health of Docker containers and for probing Kubernetes readiness." }; } + // LeaderHealthCheck checks if the instance is the leader in a cluster. + rpc LeaderHealthCheck(LeaderHealthCheckRequest) returns (LeaderHealthCheckResponse) { + option (google.api.http) = { + post: "/v1/leaderHealthCheck" + body: "*" + }; + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + summary: "Check Leadership" + description: "Checks if the instance is the leader in a cluster. Returns an error if the instance isn't the leader." + }; + } // CheckUpdates checks for available PMM Server updates. rpc CheckUpdates(CheckUpdatesRequest) returns (CheckUpdatesResponse) { option (google.api.http) = { diff --git a/api/serverpb/server_grpc.pb.go b/api/serverpb/server_grpc.pb.go index 70b49195fd..cd1ad1406f 100644 --- a/api/serverpb/server_grpc.pb.go +++ b/api/serverpb/server_grpc.pb.go @@ -8,7 +8,6 @@ package serverpb import ( context "context" - grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" @@ -20,14 +19,15 @@ import ( const _ = grpc.SupportPackageIsVersion7 const ( - Server_Version_FullMethodName = "/server.Server/Version" - Server_Readiness_FullMethodName = "/server.Server/Readiness" - Server_CheckUpdates_FullMethodName = "/server.Server/CheckUpdates" - Server_StartUpdate_FullMethodName = "/server.Server/StartUpdate" - Server_UpdateStatus_FullMethodName = "/server.Server/UpdateStatus" - Server_GetSettings_FullMethodName = "/server.Server/GetSettings" - Server_ChangeSettings_FullMethodName = "/server.Server/ChangeSettings" - Server_AWSInstanceCheck_FullMethodName = "/server.Server/AWSInstanceCheck" + Server_Version_FullMethodName = "/server.Server/Version" + Server_Readiness_FullMethodName = "/server.Server/Readiness" + Server_LeaderHealthCheck_FullMethodName = "/server.Server/LeaderHealthCheck" + Server_CheckUpdates_FullMethodName = "/server.Server/CheckUpdates" + Server_StartUpdate_FullMethodName = "/server.Server/StartUpdate" + Server_UpdateStatus_FullMethodName = "/server.Server/UpdateStatus" + Server_GetSettings_FullMethodName = "/server.Server/GetSettings" + Server_ChangeSettings_FullMethodName = "/server.Server/ChangeSettings" + Server_AWSInstanceCheck_FullMethodName = "/server.Server/AWSInstanceCheck" ) // ServerClient is the client API for Server service. @@ -39,6 +39,8 @@ type ServerClient interface { // Readiness returns an error when Server components being restarted are not ready yet. // Use this API for checking the health of Docker containers and for probing Kubernetes readiness. Readiness(ctx context.Context, in *ReadinessRequest, opts ...grpc.CallOption) (*ReadinessResponse, error) + // LeaderHealthCheck checks if the instance is the leader in a cluster. + LeaderHealthCheck(ctx context.Context, in *LeaderHealthCheckRequest, opts ...grpc.CallOption) (*LeaderHealthCheckResponse, error) // CheckUpdates checks for available PMM Server updates. CheckUpdates(ctx context.Context, in *CheckUpdatesRequest, opts ...grpc.CallOption) (*CheckUpdatesResponse, error) // StartUpdate starts PMM Server update. @@ -79,6 +81,15 @@ func (c *serverClient) Readiness(ctx context.Context, in *ReadinessRequest, opts return out, nil } +func (c *serverClient) LeaderHealthCheck(ctx context.Context, in *LeaderHealthCheckRequest, opts ...grpc.CallOption) (*LeaderHealthCheckResponse, error) { + out := new(LeaderHealthCheckResponse) + err := c.cc.Invoke(ctx, Server_LeaderHealthCheck_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *serverClient) CheckUpdates(ctx context.Context, in *CheckUpdatesRequest, opts ...grpc.CallOption) (*CheckUpdatesResponse, error) { out := new(CheckUpdatesResponse) err := c.cc.Invoke(ctx, Server_CheckUpdates_FullMethodName, in, out, opts...) @@ -142,6 +153,8 @@ type ServerServer interface { // Readiness returns an error when Server components being restarted are not ready yet. // Use this API for checking the health of Docker containers and for probing Kubernetes readiness. Readiness(context.Context, *ReadinessRequest) (*ReadinessResponse, error) + // LeaderHealthCheck checks if the instance is the leader in a cluster. + LeaderHealthCheck(context.Context, *LeaderHealthCheckRequest) (*LeaderHealthCheckResponse, error) // CheckUpdates checks for available PMM Server updates. CheckUpdates(context.Context, *CheckUpdatesRequest) (*CheckUpdatesResponse, error) // StartUpdate starts PMM Server update. @@ -158,36 +171,33 @@ type ServerServer interface { } // UnimplementedServerServer must be embedded to have forward compatible implementations. -type UnimplementedServerServer struct{} +type UnimplementedServerServer struct { +} func (UnimplementedServerServer) Version(context.Context, *VersionRequest) (*VersionResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Version not implemented") } - func (UnimplementedServerServer) Readiness(context.Context, *ReadinessRequest) (*ReadinessResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Readiness not implemented") } - +func (UnimplementedServerServer) LeaderHealthCheck(context.Context, *LeaderHealthCheckRequest) (*LeaderHealthCheckResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method LeaderHealthCheck not implemented") +} func (UnimplementedServerServer) CheckUpdates(context.Context, *CheckUpdatesRequest) (*CheckUpdatesResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method CheckUpdates not implemented") } - func (UnimplementedServerServer) StartUpdate(context.Context, *StartUpdateRequest) (*StartUpdateResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method StartUpdate not implemented") } - func (UnimplementedServerServer) UpdateStatus(context.Context, *UpdateStatusRequest) (*UpdateStatusResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method UpdateStatus not implemented") } - func (UnimplementedServerServer) GetSettings(context.Context, *GetSettingsRequest) (*GetSettingsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetSettings not implemented") } - func (UnimplementedServerServer) ChangeSettings(context.Context, *ChangeSettingsRequest) (*ChangeSettingsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ChangeSettings not implemented") } - func (UnimplementedServerServer) AWSInstanceCheck(context.Context, *AWSInstanceCheckRequest) (*AWSInstanceCheckResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method AWSInstanceCheck not implemented") } @@ -240,6 +250,24 @@ func _Server_Readiness_Handler(srv interface{}, ctx context.Context, dec func(in return interceptor(ctx, in, info, handler) } +func _Server_LeaderHealthCheck_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(LeaderHealthCheckRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ServerServer).LeaderHealthCheck(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Server_LeaderHealthCheck_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ServerServer).LeaderHealthCheck(ctx, req.(*LeaderHealthCheckRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _Server_CheckUpdates_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(CheckUpdatesRequest) if err := dec(in); err != nil { @@ -363,6 +391,10 @@ var Server_ServiceDesc = grpc.ServiceDesc{ MethodName: "Readiness", Handler: _Server_Readiness_Handler, }, + { + MethodName: "LeaderHealthCheck", + Handler: _Server_LeaderHealthCheck_Handler, + }, { MethodName: "CheckUpdates", Handler: _Server_CheckUpdates_Handler, diff --git a/api/swagger/swagger-dev.json b/api/swagger/swagger-dev.json index 0d1ac15e40..4d1d9edb6f 100644 --- a/api/swagger/swagger-dev.json +++ b/api/swagger/swagger-dev.json @@ -17502,6 +17502,68 @@ } } }, + "/v1/leaderHealthCheck": { + "post": { + "description": "Checks if the instance is the leader in a cluster. Returns an error if the instance isn't the leader.", + "tags": [ + "Server" + ], + "summary": "Check Leadership", + "operationId": "LeaderHealthCheck", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object" + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "description": "This probe is available without authentication, so it should not contain any data.", + "type": "object" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32", + "x-order": 0 + }, + "message": { + "type": "string", + "x-order": 1 + }, + "details": { + "type": "array", + "items": { + "description": "`Any` contains an arbitrary serialized protocol buffer message along with a\nURL that describes the type of the serialized message.\n\nProtobuf library provides support to pack/unpack Any values in the form\nof utility functions or additional generated methods of the Any type.\n\nExample 1: Pack and unpack a message in C++.\n\n Foo foo = ...;\n Any any;\n any.PackFrom(foo);\n ...\n if (any.UnpackTo(\u0026foo)) {\n ...\n }\n\nExample 2: Pack and unpack a message in Java.\n\n Foo foo = ...;\n Any any = Any.pack(foo);\n ...\n if (any.is(Foo.class)) {\n foo = any.unpack(Foo.class);\n }\n // or ...\n if (any.isSameTypeAs(Foo.getDefaultInstance())) {\n foo = any.unpack(Foo.getDefaultInstance());\n }\n\n Example 3: Pack and unpack a message in Python.\n\n foo = Foo(...)\n any = Any()\n any.Pack(foo)\n ...\n if any.Is(Foo.DESCRIPTOR):\n any.Unpack(foo)\n ...\n\n Example 4: Pack and unpack a message in Go\n\n foo := \u0026pb.Foo{...}\n any, err := anypb.New(foo)\n if err != nil {\n ...\n }\n ...\n foo := \u0026pb.Foo{}\n if err := any.UnmarshalTo(foo); err != nil {\n ...\n }\n\nThe pack methods provided by protobuf library will by default use\n'type.googleapis.com/full.type.name' as the type URL and the unpack\nmethods only use the fully qualified type name after the last '/'\nin the type URL, for example \"foo.bar.com/x/y.z\" will yield type\nname \"y.z\".\n\nJSON\n====\nThe JSON representation of an `Any` value uses the regular\nrepresentation of the deserialized, embedded message, with an\nadditional field `@type` which contains the type URL. Example:\n\n package google.profile;\n message Person {\n string first_name = 1;\n string last_name = 2;\n }\n\n {\n \"@type\": \"type.googleapis.com/google.profile.Person\",\n \"firstName\": \u003cstring\u003e,\n \"lastName\": \u003cstring\u003e\n }\n\nIf the embedded message type is well-known and has a custom JSON\nrepresentation, that representation will be embedded adding a field\n`value` which holds the custom JSON in addition to the `@type`\nfield. Example (for message [google.protobuf.Duration][]):\n\n {\n \"@type\": \"type.googleapis.com/google.protobuf.Duration\",\n \"value\": \"1.212s\"\n }", + "type": "object", + "properties": { + "@type": { + "description": "A URL/resource name that uniquely identifies the type of the serialized\nprotocol buffer message. This string must contain at least\none \"/\" character. The last segment of the URL's path must represent\nthe fully qualified name of the type (as in\n`path/google.protobuf.Duration`). The name should be in a canonical form\n(e.g., leading \".\" is not accepted).\n\nIn practice, teams usually precompile into the binary all types that they\nexpect it to use in the context of Any. However, for URLs which use the\nscheme `http`, `https`, or no scheme, one can optionally set up a type\nserver that maps type URLs to message definitions as follows:\n\n* If no scheme is provided, `https` is assumed.\n* An HTTP GET on the URL must yield a [google.protobuf.Type][]\n value in binary format, or produce an error.\n* Applications are allowed to cache lookup results based on the\n URL, or have them precompiled into a binary to avoid any\n lookup. Therefore, binary compatibility needs to be preserved\n on changes to types. (Use versioned type names to manage\n breaking changes.)\n\nNote: this functionality is not currently available in the official\nprotobuf release, and it is not used for type URLs beginning with\ntype.googleapis.com. As of May 2023, there are no widely used type server\nimplementations and no plans to implement one.\n\nSchemes other than `http`, `https` (or the empty scheme) might be\nused with implementation specific semantics.", + "type": "string", + "x-order": 0 + } + }, + "additionalProperties": false + }, + "x-order": 2 + } + } + } + } + } + } + }, "/v1/management/Actions/Cancel": { "post": { "description": "Stops an Action.", @@ -19026,7 +19088,7 @@ "Agent" ], "summary": "List Agents", - "operationId": "ListAgentsMixin8", + "operationId": "ListAgentsMixin9", "parameters": [ { "description": "Only one of the parameters below must be set.", @@ -21519,7 +21581,7 @@ "MgmtNode" ], "summary": "Get Node", - "operationId": "GetNodeMixin9", + "operationId": "GetNodeMixin10", "parameters": [ { "name": "body", @@ -21736,7 +21798,7 @@ "MgmtNode" ], "summary": "List Nodes", - "operationId": "ListNodesMixin9", + "operationId": "ListNodesMixin10", "parameters": [ { "name": "body", @@ -25849,7 +25911,7 @@ "MgmtService" ], "summary": "List Services", - "operationId": "ListServicesMixin10", + "operationId": "ListServicesMixin11", "parameters": [ { "name": "body", @@ -29503,6 +29565,458 @@ } } }, + "/v1/management/dump/Dumps/Delete": { + "post": { + "tags": [ + "Dumps" + ], + "summary": "DeleteDump deletes specified pmm dump.", + "operationId": "DeleteDump", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "dump_ids": { + "type": "array", + "items": { + "type": "string" + }, + "x-order": 0 + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "type": "object" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32", + "x-order": 0 + }, + "message": { + "type": "string", + "x-order": 1 + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "@type": { + "type": "string", + "x-order": 0 + } + }, + "additionalProperties": false + }, + "x-order": 2 + } + } + } + } + } + } + }, + "/v1/management/dump/Dumps/GetLogs": { + "post": { + "tags": [ + "Dumps" + ], + "summary": "GetLogs returns logs from pmm-dump tool.", + "operationId": "GetDumpLogs", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "dump_id": { + "type": "string", + "x-order": 0 + }, + "offset": { + "type": "integer", + "format": "int64", + "x-order": 1 + }, + "limit": { + "type": "integer", + "format": "int64", + "x-order": 2 + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "type": "object", + "properties": { + "logs": { + "type": "array", + "items": { + "description": "LogChunk represent one chunk of logs.", + "type": "object", + "properties": { + "chunk_id": { + "type": "integer", + "format": "int64", + "x-order": 0 + }, + "data": { + "type": "string", + "x-order": 1 + } + } + }, + "x-order": 0 + }, + "end": { + "type": "boolean", + "x-order": 1 + } + } + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32", + "x-order": 0 + }, + "message": { + "type": "string", + "x-order": 1 + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "@type": { + "type": "string", + "x-order": 0 + } + }, + "additionalProperties": false + }, + "x-order": 2 + } + } + } + } + } + } + }, + "/v1/management/dump/Dumps/List": { + "post": { + "tags": [ + "Dumps" + ], + "summary": "ListDumps returns a list of all pmm dumps.", + "operationId": "ListDumps", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object" + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "type": "object", + "properties": { + "dumps": { + "type": "array", + "items": { + "type": "object", + "properties": { + "dump_id": { + "type": "string", + "x-order": 0 + }, + "status": { + "type": "string", + "default": "DUMP_STATUS_INVALID", + "enum": [ + "DUMP_STATUS_INVALID", + "DUMP_STATUS_IN_PROGRESS", + "DUMP_STATUS_SUCCESS", + "DUMP_STATUS_ERROR" + ], + "x-order": 1 + }, + "service_names": { + "type": "array", + "items": { + "type": "string" + }, + "x-order": 2 + }, + "start_time": { + "type": "string", + "format": "date-time", + "x-order": 3 + }, + "end_time": { + "type": "string", + "format": "date-time", + "x-order": 4 + }, + "created_at": { + "type": "string", + "format": "date-time", + "x-order": 5 + } + } + }, + "x-order": 0 + } + } + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32", + "x-order": 0 + }, + "message": { + "type": "string", + "x-order": 1 + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "@type": { + "type": "string", + "x-order": 0 + } + }, + "additionalProperties": false + }, + "x-order": 2 + } + } + } + } + } + } + }, + "/v1/management/dump/Dumps/Start": { + "post": { + "tags": [ + "Dumps" + ], + "summary": "StartDump request creates pmm dump.", + "operationId": "StartDump", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "service_names": { + "type": "array", + "items": { + "type": "string" + }, + "x-order": 0 + }, + "start_time": { + "type": "string", + "format": "date-time", + "x-order": 1 + }, + "end_time": { + "type": "string", + "format": "date-time", + "x-order": 2 + }, + "export_qan": { + "type": "boolean", + "x-order": 3 + }, + "ignore_load": { + "type": "boolean", + "x-order": 4 + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "type": "object", + "properties": { + "dump_id": { + "type": "string", + "x-order": 0 + } + } + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32", + "x-order": 0 + }, + "message": { + "type": "string", + "x-order": 1 + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "@type": { + "type": "string", + "x-order": 0 + } + }, + "additionalProperties": false + }, + "x-order": 2 + } + } + } + } + } + } + }, + "/v1/management/dump/Dumps/Upload": { + "post": { + "tags": [ + "Dumps" + ], + "summary": "UploadDump uploads selected dumps to remote server.", + "operationId": "UploadDump", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "dump_ids": { + "type": "array", + "items": { + "type": "string" + }, + "x-order": 0 + }, + "sftp_parameters": { + "type": "object", + "properties": { + "address": { + "type": "string", + "x-order": 0 + }, + "user": { + "type": "string", + "x-order": 1 + }, + "password": { + "type": "string", + "x-order": 2 + }, + "directory": { + "type": "string", + "x-order": 3 + } + }, + "x-order": 1 + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "type": "object" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32", + "x-order": 0 + }, + "message": { + "type": "string", + "x-order": 1 + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "@type": { + "type": "string", + "x-order": 0 + } + }, + "additionalProperties": false + }, + "x-order": 2 + } + } + } + } + } + } + }, "/v1/readyz": { "get": { "description": "Returns an error when Server components being restarted are not ready yet. Use this API for checking the health of Docker containers and for probing Kubernetes readiness.", @@ -29987,6 +30501,9 @@ { "name": "RestoreHistory" }, + { + "name": "Dumps" + }, { "name": "AzureDatabase" }, diff --git a/api/swagger/swagger.json b/api/swagger/swagger.json index cda14e0ddf..699bf18239 100644 --- a/api/swagger/swagger.json +++ b/api/swagger/swagger.json @@ -14658,6 +14658,68 @@ } } }, + "/v1/leaderHealthCheck": { + "post": { + "description": "Checks if the instance is the leader in a cluster. Returns an error if the instance isn't the leader.", + "tags": [ + "Server" + ], + "summary": "Check Leadership", + "operationId": "LeaderHealthCheck", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object" + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "description": "This probe is available without authentication, so it should not contain any data.", + "type": "object" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32", + "x-order": 0 + }, + "message": { + "type": "string", + "x-order": 1 + }, + "details": { + "type": "array", + "items": { + "description": "`Any` contains an arbitrary serialized protocol buffer message along with a\nURL that describes the type of the serialized message.\n\nProtobuf library provides support to pack/unpack Any values in the form\nof utility functions or additional generated methods of the Any type.\n\nExample 1: Pack and unpack a message in C++.\n\n Foo foo = ...;\n Any any;\n any.PackFrom(foo);\n ...\n if (any.UnpackTo(\u0026foo)) {\n ...\n }\n\nExample 2: Pack and unpack a message in Java.\n\n Foo foo = ...;\n Any any = Any.pack(foo);\n ...\n if (any.is(Foo.class)) {\n foo = any.unpack(Foo.class);\n }\n // or ...\n if (any.isSameTypeAs(Foo.getDefaultInstance())) {\n foo = any.unpack(Foo.getDefaultInstance());\n }\n\n Example 3: Pack and unpack a message in Python.\n\n foo = Foo(...)\n any = Any()\n any.Pack(foo)\n ...\n if any.Is(Foo.DESCRIPTOR):\n any.Unpack(foo)\n ...\n\n Example 4: Pack and unpack a message in Go\n\n foo := \u0026pb.Foo{...}\n any, err := anypb.New(foo)\n if err != nil {\n ...\n }\n ...\n foo := \u0026pb.Foo{}\n if err := any.UnmarshalTo(foo); err != nil {\n ...\n }\n\nThe pack methods provided by protobuf library will by default use\n'type.googleapis.com/full.type.name' as the type URL and the unpack\nmethods only use the fully qualified type name after the last '/'\nin the type URL, for example \"foo.bar.com/x/y.z\" will yield type\nname \"y.z\".\n\nJSON\n====\nThe JSON representation of an `Any` value uses the regular\nrepresentation of the deserialized, embedded message, with an\nadditional field `@type` which contains the type URL. Example:\n\n package google.profile;\n message Person {\n string first_name = 1;\n string last_name = 2;\n }\n\n {\n \"@type\": \"type.googleapis.com/google.profile.Person\",\n \"firstName\": \u003cstring\u003e,\n \"lastName\": \u003cstring\u003e\n }\n\nIf the embedded message type is well-known and has a custom JSON\nrepresentation, that representation will be embedded adding a field\n`value` which holds the custom JSON in addition to the `@type`\nfield. Example (for message [google.protobuf.Duration][]):\n\n {\n \"@type\": \"type.googleapis.com/google.protobuf.Duration\",\n \"value\": \"1.212s\"\n }", + "type": "object", + "properties": { + "@type": { + "description": "A URL/resource name that uniquely identifies the type of the serialized\nprotocol buffer message. This string must contain at least\none \"/\" character. The last segment of the URL's path must represent\nthe fully qualified name of the type (as in\n`path/google.protobuf.Duration`). The name should be in a canonical form\n(e.g., leading \".\" is not accepted).\n\nIn practice, teams usually precompile into the binary all types that they\nexpect it to use in the context of Any. However, for URLs which use the\nscheme `http`, `https`, or no scheme, one can optionally set up a type\nserver that maps type URLs to message definitions as follows:\n\n* If no scheme is provided, `https` is assumed.\n* An HTTP GET on the URL must yield a [google.protobuf.Type][]\n value in binary format, or produce an error.\n* Applications are allowed to cache lookup results based on the\n URL, or have them precompiled into a binary to avoid any\n lookup. Therefore, binary compatibility needs to be preserved\n on changes to types. (Use versioned type names to manage\n breaking changes.)\n\nNote: this functionality is not currently available in the official\nprotobuf release, and it is not used for type URLs beginning with\ntype.googleapis.com. As of May 2023, there are no widely used type server\nimplementations and no plans to implement one.\n\nSchemes other than `http`, `https` (or the empty scheme) might be\nused with implementation specific semantics.", + "type": "string", + "x-order": 0 + } + }, + "additionalProperties": false + }, + "x-order": 2 + } + } + } + } + } + } + }, "/v1/management/Actions/Cancel": { "post": { "description": "Stops an Action.", diff --git a/build/packages/rpm/server/SPECS/pmm-dump.spec b/build/packages/rpm/server/SPECS/pmm-dump.spec index c4175cda2c..c8882aa25b 100644 --- a/build/packages/rpm/server/SPECS/pmm-dump.spec +++ b/build/packages/rpm/server/SPECS/pmm-dump.spec @@ -2,14 +2,14 @@ %global repo pmm-dump %global provider github.com/percona/%{repo} -%global commit 9cebba38ce90114f3199304f9091d620eff1d722 +%global commit 0d49b27729506dc62950f9fa59147d63df194db2 %global shortcommit %(c=%{commit}; echo ${c:0:7}) %define build_timestamp %(date -u +"%y%m%d%H%M") %define release 1 -%define rpm_release %{release}.%{build_timestamp}%{?dist} +%define rpm_release %{release}.%{build_timestamp}.%{shortcommit}%{?dist} Name: pmm-dump -Version: 0.6.0 +Version: 0.7.0 Release: %{rpm_release} Summary: Percona PMM Dump allows to export and import monitoring metrics and query analytics. @@ -37,5 +37,8 @@ install -p -m 0755 pmm-dump %{buildroot}%{_sbindir}/pmm-dump %changelog +* Tue Nov 23 2023 Artem Gavrilov - 0.7.0-ga +- PMM-12460 Update pmm-dump to v0.7.0-ga version + * Tue Mar 29 2022 Alex Tymchuk - 0.6.0-1 - Initial pmm-dump version diff --git a/cli-tests/package-lock.json b/cli-tests/package-lock.json index b34019a698..24981a881b 100644 --- a/cli-tests/package-lock.json +++ b/cli-tests/package-lock.json @@ -22,7 +22,7 @@ "@types/shelljs": "^0.8.12", "@typescript-eslint/eslint-plugin": "^6.10.0", "@typescript-eslint/parser": "^6.10.0", - "eslint": "8.53", + "eslint": "8.54", "eslint-config-airbnb-base": "^15.0.0", "eslint-config-airbnb-typescript": "^17.1.0", "eslint-plugin-import": "^2.29.0", @@ -86,9 +86,9 @@ } }, "node_modules/@eslint/js": { - "version": "8.53.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.53.0.tgz", - "integrity": "sha512-Kn7K8dx/5U6+cT1yEhpX1w4PCSg0M+XyRILPgvwcEBjerFWCwQj5sbr3/VmxqV0JGHCBCzyd6LxypEuehypY1w==", + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.54.0.tgz", + "integrity": "sha512-ut5V+D+fOoWPgGGNj83GGjnntO39xDy6DWxO0wb7Jp3DcMX0TfIqdzHF85VTQkerdyGmuuMD9AKAo5KiNlf/AQ==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -942,15 +942,15 @@ } }, "node_modules/eslint": { - "version": "8.53.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.53.0.tgz", - "integrity": "sha512-N4VuiPjXDUa4xVeV/GC/RV3hQW9Nw+Y463lkWaKKXKYMvmRiRDAtfpuPFLN+E1/6ZhyR8J2ig+eVREnYgUsiag==", + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.54.0.tgz", + "integrity": "sha512-NY0DfAkM8BIZDVl6PgSa1ttZbx3xHgJzSNJKYcQglem6CppHyMhRIQkBVSSMaSRnLhig3jsDbEzOjwCVt4AmmA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.3", - "@eslint/js": "8.53.0", + "@eslint/js": "8.54.0", "@humanwhocodes/config-array": "^0.11.13", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", diff --git a/cli-tests/package.json b/cli-tests/package.json index 9d6be03827..3d72e3f470 100644 --- a/cli-tests/package.json +++ b/cli-tests/package.json @@ -26,7 +26,7 @@ "@types/shelljs": "^0.8.12", "@typescript-eslint/eslint-plugin": "^6.10.0", "@typescript-eslint/parser": "^6.10.0", - "eslint": "8.53", + "eslint": "8.54", "eslint-config-airbnb-base": "^15.0.0", "eslint-config-airbnb-typescript": "^17.1.0", "eslint-plugin-import": "^2.29.0", diff --git a/docker-compose.yml b/docker-compose.yml index 945b7a51c3..f00ba6240e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,7 +9,7 @@ services: # build: # context: . # args: - # PMM_SERVER_IMAGE: ${PMM_SERVER_IMAGE:-perconalab/pmm-server:3-dev-latest} + # PMM_SERVER_IMAGE: ${PMM_SERVER_IMAGE:-perconalab/pmm-server:dev-latest} # dockerfile: devcontainer.Dockerfile container_name: pmm-server hostname: pmm-server @@ -18,11 +18,18 @@ services: environment: - PMM_RELEASE_PATH=/root/go/bin - REVIEWDOG_GITHUB_API_TOKEN=${REVIEWDOG_GITHUB_API_TOKEN} + - ENABLE_DBAAS=${ENABLE_DBAAS:-0} - AWS_ACCESS_KEY=${AWS_ACCESS_KEY} - AWS_SECRET_KEY=${AWS_SECRET_KEY} - ENABLE_RBAC=${ENABLE_RBAC:-0} - LESS_LOG_NOISE=1 - PERCONA_TEST_VERSION_SERVICE_URL=${PERCONA_TEST_VERSION_SERVICE_URL} + - DBAAS_VM_OP_CHANNEL=${DBAAS_VM_OP_CHANNEL} + - DBAAS_PXC_OP_CHANNEL=${DBAAS_PXC_OP_CHANNEL} + - DBAAS_PSMDB_OP_CHANNEL=${DBAAS_PSMDB_OP_CHANNEL} + - DBAAS_DBAAS_OP_CHANNEL=${DBAAS_DBAAS_OP_CHANNEL} + - DBAAS_ALLOW_UNSUPPORTED_OPERATORS=${DBAAS_ALLOW_UNSUPPORTED_OPERATORS:-0} + - PERCONA_TEST_DBAAS_PMM_CLIENT=${PERCONA_TEST_DBAAS_PMM_CLIENT} # - PERCONA_TEST_PLATFORM_ADDRESS=https://check.localhost # - PERCONA_TEST_PLATFORM_INSECURE=1 # - PERCONA_TEST_PLATFORM_PUBLIC_KEY= @@ -33,6 +40,7 @@ services: # - PERCONA_TEST_PMM_CLICKHOUSE_DATABASE=pmm # - PERCONA_TEST_PMM_CLICKHOUSE_BLOCK_SIZE=10000 # - PERCONA_TEST_PMM_CLICKHOUSE_POOL_SIZE=2 + # - PMM_DEBUG=1 # - PERCONA_TEST_CHECKS_FILE=/srv/checks/local-checks.yml # - PERCONA_TEST_POSTGRES_ADDR=pg # - PERCONA_TEST_POSTGRES_DBNAME=pmm-managed @@ -96,19 +104,23 @@ services: # PMM with external DBs ch: profiles: - - pmm-external-dbs - image: ${CH_IMAGE:-clickhouse/clickhouse-server:22.6.9.11-alpine} + - pmm-ha + image: ${CH_IMAGE:-clickhouse/clickhouse-server:23.8.2.7-alpine} platform: linux/amd64 hostname: ${CH_HOSTNAME:-ch} ports: - ${CH_PORT:-9000}:9000 networks: - - ${NETWORK:-default} + ha: + ipv4_address: 172.20.0.7 + volumes: + - chdata:/var/lib/clickhouse # Volume for ClickHouse data + victoriametrics: profiles: - - pmm-external-dbs + - pmm-ha hostname: ${VM_HOSTNAME:-victoriametrics} - image: victoriametrics/victoria-metrics:v1.88.1 + image: victoriametrics/victoria-metrics:v1.93.4 ports: - 8428:8428 - 8089:8089 @@ -125,21 +137,81 @@ services: - "--httpListenAddr=:8428" - "--influxListenAddr=:8089" networks: - - ${NETWORK:-default} - pmm-managed-server-ch: + ha: + ipv4_address: 172.20.0.4 + + # PMM with external Postgres DB + pg: + profiles: + - pmm-ha + build: + context: ./managed/testdata/pg + args: + POSTGRES_IMAGE: ${POSTGRES_IMAGE:-postgres:14} + dockerfile: Dockerfile +# image: postgres:14 + container_name: pg + environment: + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-pmm-password} + ports: + - ${POSTGRES_PORT:-5432}:5432 + command: | + postgres + -c shared_preload_libraries=pg_stat_statements + -c pg_stat_statements.max=10000 + -c pg_stat_statements.track=all + -c pg_stat_statements.save=off + -c fsync=off +# -c hba_file=/conf/pg_hba.conf +# -c ssl=on +# -c ssl_ca_file=/certs/root.crt +# -c ssl_cert_file=/certs/server.crt +# -c ssl_key_file=/certs/server.key + networks: + ha: + ipv4_address: 172.20.0.3 + volumes: + - pgdata:/var/lib/postgresql/data # Volume for PostgreSQL data + - ./managed/testdata/pg/conf/:/conf/ + - ./managed/testdata/pg/queries/:/docker-entrypoint-initdb.d/ + + haproxy: profiles: - - pmm-external-dbs + - pmm-ha + image: haproxy:latest + container_name: haproxy + hostname: haproxy + networks: + ha: + ipv4_address: 172.20.0.10 + volumes: + - ./managed/testdata/haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg + - ./managed/testdata/haproxy/localhost.pem:/etc/ssl/private/localhost.pem + ports: + - 80:80 + - 443:443 + depends_on: + - pmm-server-active + - pmm-server-passive + - pmm-server-passive-2 + + pmm-server-active: + profiles: + - pmm-ha depends_on: - ch - victoriametrics + - pg image: ${PMM_CONTAINER:-perconalab/pmm-server:3-dev-container} - container_name: pmm-server - hostname: pmm-server + container_name: pmm-server-active + hostname: pmm-server-active networks: - - ${NETWORK:-default} + ha: + ipv4_address: 172.20.0.5 environment: - - PMM_RELEASE_PATH=/root/go/bin + - PMM_RELEASE_PATH=/root/go/src/github.com/percona/pmm/bin - REVIEWDOG_GITHUB_API_TOKEN=${REVIEWDOG_GITHUB_API_TOKEN} + - ENABLE_DBAAS=${ENABLE_DBAAS:-0} - AWS_ACCESS_KEY=${AWS_ACCESS_KEY} - AWS_SECRET_KEY=${AWS_SECRET_KEY} - ENABLE_BACKUP_MANAGEMENT=1 @@ -153,9 +225,28 @@ services: - PERCONA_TEST_PMM_CLICKHOUSE_DATABASE=pmm - PERCONA_TEST_PMM_CLICKHOUSE_BLOCK_SIZE=10000 - PERCONA_TEST_PMM_CLICKHOUSE_POOL_SIZE=2 - # - PMM_DEBUG=1 + - PERCONA_TEST_PMM_DISABLE_BUILTIN_CLICKHOUSE=1 + - PERCONA_TEST_POSTGRES_ADDR=pg:5432 + - PERCONA_TEST_POSTGRES_USERNAME=pmm-managed + - PERCONA_TEST_POSTGRES_DBPASSWORD=pmm-managed + - PERCONA_TEST_PMM_DISABLE_BUILTIN_POSTGRES=1 +# - PERCONA_TEST_POSTGRES_SSL_MODE=require +# - PERCONA_TEST_POSTGRES_SSL_CA_PATH=/certs/root.crt +# - PERCONA_TEST_POSTGRES_SSL_KEY_PATH=/certs/pmm-managed.key +# - PERCONA_TEST_POSTGRES_SSL_CERT_PATH=/certs/pmm-managed.crt + - GF_DATABASE_URL=postgres://grafana:grafana@pg:5432/grafana +# - GF_DATABASE_SSL_MODE=require +# - PMM_DEBUG=1 + - GO_VERSION=1.20 - PMM_VM_URL=${PMM_VM_URL:-http://victoriametrics:8428/} - - PMM_DEBUG=1 + - PERCONA_TEST_DBAAS_PMM_CLIENT=perconalab/pmm-client:dev-latest + - PMM_TEST_HA_ENABLE=1 + - PMM_TEST_HA_BOOTSTRAP=1 + - PMM_TEST_HA_NODE_ID=pmm-server-active + - PMM_TEST_HA_ADVERTISE_ADDRESS=172.20.0.5 + - PMM_TEST_HA_PEERS=pmm-server-active,pmm-server-passive,pmm-server-passive-2 + - PMM_TEST_HA_GOSSIP_PORT=9096 + - PMM_TEST_HA_GRAFANA_GOSSIP_PORT=9094 extra_hosts: - host.docker.internal:host-gateway @@ -175,8 +266,8 @@ services: memlock: 67108864 ports: - - ${PMM_PORT_HTTP:-80}:80 - - ${PMM_PORT_HTTPS:-443}:443 + - ${PMM_PORT_HTTP:-8081}:80 + - ${PMM_PORT_HTTPS:-8441}:443 # For headless delve - ${PMM_PORT_DELVE:-2345}:2345 volumes: @@ -186,37 +277,189 @@ services: # caching - go-modules:/root/go/pkg/mod - root-cache:/root/.cache + - ./managed/testdata/pg/certs/:/certs/ + - ./update/ansible:/usr/share/pmm-update/ansible - # PMM with external Postgres DB - pg: + pmm-server-passive: profiles: - - pmm-pg - build: - context: ./managed/testdata/pg - args: - POSTGRES_IMAGE: ${POSTGRES_IMAGE:-postgres:14} - dockerfile: Dockerfile - container_name: pmm-pg + - pmm-ha + depends_on: + - ch + - pg + - victoriametrics + - pmm-server-active + image: ${PMM_CONTAINER:-perconalab/pmm-server:3-dev-container} + container_name: pmm-server-passive + hostname: pmm-server-passive + networks: + ha: + ipv4_address: 172.20.0.6 environment: - - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-pmm-password} + - PMM_RELEASE_PATH=/root/go/src/github.com/percona/pmm/bin + - REVIEWDOG_GITHUB_API_TOKEN=${REVIEWDOG_GITHUB_API_TOKEN} + - ENABLE_DBAAS=${ENABLE_DBAAS:-0} + - AWS_ACCESS_KEY=${AWS_ACCESS_KEY} + - AWS_SECRET_KEY=${AWS_SECRET_KEY} +# - PERCONA_TEST_PLATFORM_ADDRESS=https://check.localhost +# - PERCONA_TEST_PLATFORM_INSECURE=1 +# - PERCONA_TEST_PLATFORM_PUBLIC_KEY= +# - PERCONA_TEST_TELEMETRY_INTERVAL=10s +# - PERCONA_TEST_TELEMETRY_RETRY_BACKOFF=10s +# - PERCONA_TEST_TELEMETRY_DISABLE_START_DELAY=1 + - PERCONA_TEST_PMM_CLICKHOUSE_ADDR=${CH_HOSTNAME:-ch}:9000 + - PERCONA_TEST_PMM_CLICKHOUSE_DATABASE=pmm + - PERCONA_TEST_PMM_CLICKHOUSE_BLOCK_SIZE=10000 + - PERCONA_TEST_PMM_CLICKHOUSE_POOL_SIZE=2 + - PERCONA_TEST_PMM_DISABLE_BUILTIN_CLICKHOUSE=1 + - PERCONA_TEST_POSTGRES_ADDR=pg:5432 + - PERCONA_TEST_POSTGRES_USERNAME=pmm-managed + - PERCONA_TEST_POSTGRES_DBPASSWORD=pmm-managed + - PERCONA_TEST_PMM_DISABLE_BUILTIN_POSTGRES=1 +# - PERCONA_TEST_POSTGRES_SSL_MODE=require +# - PERCONA_TEST_POSTGRES_SSL_CA_PATH=/certs/root.crt +# - PERCONA_TEST_POSTGRES_SSL_KEY_PATH=/certs/pmm-managed.key +# - PERCONA_TEST_POSTGRES_SSL_CERT_PATH=/certs/pmm-managed.crt + - GF_DATABASE_URL=postgres://grafana:grafana@pg:5432/grafana +# - GF_DATABASE_SSL_MODE=require +# - PMM_DEBUG=1 + - GO_VERSION=1.20 + - PMM_VM_URL=${PMM_VM_URL:-http://victoriametrics:8428/} + - PERCONA_TEST_DBAAS_PMM_CLIENT=perconalab/pmm-client:dev-latest + - PMM_TEST_HA_ENABLE=1 + - PMM_TEST_HA_NODE_ID=pmm-server-passive + - PMM_TEST_HA_ADVERTISE_ADDRESS=172.20.0.6 + - PMM_TEST_HA_PEERS=pmm-server-active,pmm-server-passive,pmm-server-passive-2 + - PMM_TEST_HA_GOSSIP_PORT=9096 + - PMM_TEST_HA_GRAFANA_GOSSIP_PORT=9094 + + extra_hosts: + - host.docker.internal:host-gateway + # - portal.localhost:${PORTAL_HOST:-host-gateway} + # - check.localhost:${PORTAL_CHECK_HOST:-host-gateway} + # - pmm.localhost:${PORTAL_PMM_HOST:-host-gateway} + # - check-dev.percona.com:${PORTAL_PMM_HOST:-host-gateway} + + # for delve + cap_add: + - SYS_PTRACE + security_opt: + - seccomp:unconfined + + # see https://github.com/golang/go/wiki/LinuxKernelSignalVectorBug#what-to-do + ulimits: + memlock: 67108864 + ports: - - ${POSTGRES_PORT:-5432}:5432 - command: | - postgres - -c shared_preload_libraries=pg_stat_statements - -c pg_stat_statements.max=10000 - -c pg_stat_statements.track=all - -c pg_stat_statements.save=off - -c fsync=off - -c ssl=on - -c ssl_ca_file=/certs/root.crt - -c ssl_cert_file=/certs/server.crt - -c ssl_key_file=/certs/server.key - -c hba_file=/conf/pg_hba.conf + - ${PMM_PORT_HTTP:-8082}:80 + - ${PMM_PORT_HTTPS:-8432}:443 + # For headless delve + - ${PMM_PORT_DELVE:-12345}:2345 + volumes: + - ./:/root/go/src/github.com/percona/pmm +# - "../grafana/public:/usr/share/grafana/public" + - ./Makefile.devcontainer:/root/go/src/github.com/percona/pmm/Makefile:ro # change Makefile in devcontainer + # caching + - go-modules:/root/go/pkg/mod + - root-cache:/root/.cache + - ./managed/testdata/pg/certs/:/certs/ + - ./update/ansible:/usr/share/pmm-update/ansible + + pmm-server-passive-2: + profiles: + - pmm-ha + depends_on: + - ch + - pg + - victoriametrics + - pmm-server-active + image: ${PMM_CONTAINER:-perconalab/pmm-server:3-dev-container} + container_name: pmm-server-passive-2 + hostname: pmm-server-passive-2 networks: - - ${NETWORK:-default} + ha: + ipv4_address: 172.20.0.11 + environment: + - PMM_RELEASE_PATH=/root/go/src/github.com/percona/pmm/bin + - REVIEWDOG_GITHUB_API_TOKEN=${REVIEWDOG_GITHUB_API_TOKEN} + - ENABLE_DBAAS=${ENABLE_DBAAS:-0} + - AWS_ACCESS_KEY=${AWS_ACCESS_KEY} + - AWS_SECRET_KEY=${AWS_SECRET_KEY} + # - PERCONA_TEST_PLATFORM_ADDRESS=https://check.localhost + # - PERCONA_TEST_PLATFORM_INSECURE=1 + # - PERCONA_TEST_PLATFORM_PUBLIC_KEY= + # - PERCONA_TEST_TELEMETRY_INTERVAL=10s + # - PERCONA_TEST_TELEMETRY_RETRY_BACKOFF=10s + # - PERCONA_TEST_TELEMETRY_DISABLE_START_DELAY=1 + - PERCONA_TEST_PMM_CLICKHOUSE_ADDR=${CH_HOSTNAME:-ch}:9000 + - PERCONA_TEST_PMM_CLICKHOUSE_DATABASE=pmm + - PERCONA_TEST_PMM_CLICKHOUSE_BLOCK_SIZE=10000 + - PERCONA_TEST_PMM_CLICKHOUSE_POOL_SIZE=2 + - PERCONA_TEST_PMM_DISABLE_BUILTIN_CLICKHOUSE=1 + - PERCONA_TEST_POSTGRES_ADDR=pg:5432 + - PERCONA_TEST_POSTGRES_USERNAME=pmm-managed + - PERCONA_TEST_POSTGRES_DBPASSWORD=pmm-managed + - PERCONA_TEST_PMM_DISABLE_BUILTIN_POSTGRES=1 + # - PERCONA_TEST_POSTGRES_SSL_MODE=require + # - PERCONA_TEST_POSTGRES_SSL_CA_PATH=/certs/root.crt + # - PERCONA_TEST_POSTGRES_SSL_KEY_PATH=/certs/pmm-managed.key + # - PERCONA_TEST_POSTGRES_SSL_CERT_PATH=/certs/pmm-managed.crt + - GF_DATABASE_URL=postgres://grafana:grafana@pg:5432/grafana + # - GF_DATABASE_SSL_MODE=require + # - PMM_DEBUG=1 + - GO_VERSION=1.20 + - PMM_VM_URL=${PMM_VM_URL:-http://victoriametrics:8428/} + - PERCONA_TEST_DBAAS_PMM_CLIENT=perconalab/pmm-client:dev-latest + - PMM_TEST_HA_ENABLE=1 + - PMM_TEST_HA_NODE_ID=pmm-server-passive-2 + - PMM_TEST_HA_ADVERTISE_ADDRESS=172.20.0.11 + - PMM_TEST_HA_PEERS=pmm-server-active,pmm-server-passive,pmm-server-passive-2 + - PMM_TEST_HA_GOSSIP_PORT=9096 + - PMM_TEST_HA_GRAFANA_GOSSIP_PORT=9094 + + extra_hosts: + - host.docker.internal:host-gateway + # - portal.localhost:${PORTAL_HOST:-host-gateway} + # - check.localhost:${PORTAL_CHECK_HOST:-host-gateway} + # - pmm.localhost:${PORTAL_PMM_HOST:-host-gateway} + # - check-dev.percona.com:${PORTAL_PMM_HOST:-host-gateway} + + # for delve + cap_add: + - SYS_PTRACE + security_opt: + - seccomp:unconfined + + # see https://github.com/golang/go/wiki/LinuxKernelSignalVectorBug#what-to-do + ulimits: + memlock: 67108864 + + ports: + - ${PMM_PORT_HTTP:-8083}:80 + - ${PMM_PORT_HTTPS:-8433}:443 + # For headless delve +# - ${PMM_PORT_DELVE:-12345}:2345 + volumes: + - ./:/root/go/src/github.com/percona/pmm + # - "../grafana/public:/usr/share/grafana/public" + - ./Makefile.devcontainer:/root/go/src/github.com/percona/pmm/Makefile:ro # change Makefile in devcontainer + # caching + - go-modules:/root/go/pkg/mod + - root-cache:/root/.cache + - ./managed/testdata/pg/certs/:/certs/ + - ./update/ansible:/usr/share/pmm-update/ansible volumes: + chdata: # Volume for ClickHouse data + vmdata: # Volume for VictoriaMetrics data + pgdata: # Volume for PostgreSQL data go-modules: - vmdata: {} root-cache: + +networks: + minikube: + external: true + name: minikube + ha: + ipam: + config: + - subnet: 172.20.0.0/24 diff --git a/go.mod b/go.mod index f46422c526..87dc7e879c 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ replace github.com/go-openapi/spec => github.com/Percona-Lab/spec v0.20.5-percon replace gopkg.in/alecthomas/kingpin.v2 => github.com/Percona-Lab/kingpin v2.2.6-percona+incompatible -replace golang.org/x/crypto => github.com/percona-lab/crypto v0.0.0-20220811043533-d164de3c7f08 +replace golang.org/x/crypto => github.com/percona-lab/crypto v0.0.0-20231108144114-756dfb24eaf2 replace github.com/ClickHouse/clickhouse-go/151 => github.com/ClickHouse/clickhouse-go v1.5.1 // clickhouse-go/v2 cannot work with 1.5.1 which we need for QAN-API @@ -32,7 +32,7 @@ require ( github.com/docker/docker v24.0.6+incompatible github.com/docker/go-connections v0.4.0 github.com/envoyproxy/protoc-gen-validate v1.0.2 - github.com/go-co-op/gocron v1.35.1 + github.com/go-co-op/gocron v1.36.0 github.com/go-openapi/errors v0.20.4 github.com/go-openapi/runtime v0.26.0 github.com/go-openapi/strfmt v0.21.7 @@ -42,11 +42,12 @@ require ( github.com/golang-migrate/migrate/v4 v4.16.1 github.com/golang/protobuf v1.5.3 github.com/google/uuid v1.4.0 - github.com/grafana/grafana-api-golang-client v0.25.0 + github.com/grafana/grafana-api-golang-client v0.26.0 github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0 github.com/hashicorp/go-version v1.6.0 + github.com/hashicorp/raft v1.5.0 github.com/jhunters/bigqueue v1.2.7 github.com/jmoiron/sqlx v1.3.5 github.com/jotaen/kong-completion v0.0.5 @@ -59,6 +60,7 @@ require ( github.com/percona/promconfig v0.2.5 github.com/pganalyze/pg_query_go/v2 v2.2.0 github.com/pkg/errors v0.9.1 + github.com/pkg/sftp v1.13.6 github.com/pmezard/go-difflib v1.0.0 github.com/prometheus/client_golang v1.17.0 github.com/prometheus/common v0.45.0 @@ -69,11 +71,11 @@ require ( github.com/stretchr/testify v1.8.4 go.mongodb.org/mongo-driver v1.12.0 go.starlark.net v0.0.0-20230717150657-8a3343210976 - golang.org/x/crypto v0.14.0 - golang.org/x/sync v0.4.0 + golang.org/x/crypto v0.15.0 + golang.org/x/sync v0.5.0 golang.org/x/sys v0.14.0 golang.org/x/text v0.14.0 - golang.org/x/tools v0.14.0 + golang.org/x/tools v0.15.0 google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d google.golang.org/grpc v1.59.0 @@ -86,12 +88,20 @@ require ( require ( github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect + github.com/fatih/color v1.13.0 // indirect github.com/go-logr/logr v1.2.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect + github.com/google/btree v1.0.0 // indirect + github.com/hashicorp/go-hclog v1.5.0 // indirect + github.com/hashicorp/go-uuid v1.0.2 // indirect + github.com/kr/fs v0.1.0 // indirect + github.com/mattn/go-colorable v0.1.12 // indirect github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect + github.com/miekg/dns v1.1.26 // indirect github.com/mwitkow/go-proto-validators v0.3.2 // indirect github.com/posener/complete v1.2.3 // indirect github.com/riywo/loginshell v0.0.0-20200815045211-7d26008be1ab // indirect + github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 // indirect go.opentelemetry.io/otel/metric v1.19.0 // indirect go.uber.org/atomic v1.11.0 // indirect golang.org/x/time v0.3.0 // indirect @@ -111,6 +121,7 @@ require ( github.com/Microsoft/go-winio v0.6.1 // indirect github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect github.com/andybalholm/brotli v1.0.6 // indirect + github.com/armon/go-metrics v0.4.1 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/charmbracelet/harmonica v0.2.0 // indirect @@ -131,7 +142,12 @@ require ( github.com/golang/snappy v0.0.4 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect + github.com/hashicorp/go-immutable-radix v1.3.1 // indirect + github.com/hashicorp/go-msgpack v1.1.5 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/hashicorp/go-sockaddr v1.0.2 // indirect + github.com/hashicorp/golang-lru v0.6.0 // indirect + github.com/hashicorp/memberlist v0.5.0 github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect @@ -172,9 +188,9 @@ require ( github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect go.opentelemetry.io/otel v1.19.0 // indirect go.opentelemetry.io/otel/trace v1.19.0 // indirect - golang.org/x/mod v0.13.0 // indirect - golang.org/x/net v0.17.0 // indirect - golang.org/x/term v0.13.0 // indirect + golang.org/x/mod v0.14.0 // indirect + golang.org/x/net v0.18.0 // indirect + golang.org/x/term v0.14.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gotest.tools/v3 v3.3.0 // indirect ) diff --git a/go.sum b/go.sum index d2de24de5e..19802350de 100644 --- a/go.sum +++ b/go.sum @@ -58,6 +58,7 @@ github.com/ClickHouse/clickhouse-go/v2 v2.15.0 h1:G0hTKyO8fXXR1bGnZ0DY3vTG01xYfO github.com/ClickHouse/clickhouse-go/v2 v2.15.0/go.mod h1:kXt1SRq0PIRa6aKZD7TnFnY9PQKmc2b13sHtOYcK6cQ= github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= +github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/HdrHistogram/hdrhistogram-go v1.1.2 h1:5IcZpTvzydCQeHzK4Ef/D5rrSqwxob0t8PQPMybUNFM= github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= @@ -87,6 +88,10 @@ github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8V github.com/andybalholm/brotli v1.0.6 h1:Yf9fFpf49Zrxb9NlQaluyE92/+X7UVHlhMNJN2sxfOI= github.com/andybalholm/brotli v1.0.6/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= +github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= @@ -99,6 +104,7 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bkaradzic/go-lz4 v1.0.0 h1:RXc4wYsyz985CkXXeX04y4VnZFGG8Rd43pRaHsOXAKk= github.com/bkaradzic/go-lz4 v1.0.0/go.mod h1:0YdlkowM3VswSROI7qDxhRvJ3sLhlFrRRwjwegp5jy4= github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= @@ -122,6 +128,8 @@ github.com/charmbracelet/lipgloss v0.9.0/go.mod h1:h8KDyaivONasw1Bhb4nWiKlk4P1wH github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= +github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58 h1:F1EaeKL/ta07PY/k9Os/UFtwERei2/XzGemhpGnBKNg= github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58/go.mod h1:EOBUe0h4xcZ5GoxqC5SDxFQ8gwyZPKQoEzownBlhI80= @@ -155,9 +163,12 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v1.0.2 h1:QkIBuU5k+x7/QXPvPPnWXWlCdaBFApVqftFV6k087DA= github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= -github.com/go-co-op/gocron v1.35.1 h1:xi0tfAhxeAmGUKkjiA7bTIjh2VdBJpUYDJ+lPx/EPcM= -github.com/go-co-op/gocron v1.35.1/go.mod h1:NLi+bkm4rRSy1F8U7iacZOz0xPseMoIOnvabGoSe/no= +github.com/go-co-op/gocron v1.36.0 h1:sEmAwg57l4JWQgzaVWYfKZ+w13uHOqeOtwjo72Ll5Wc= +github.com/go-co-op/gocron v1.36.0/go.mod h1:3L/n6BkO7ABj+TrfSVXLRzsP26zmikL4ISkLQ0O8iNY= github.com/go-faster/city v1.0.1 h1:4WAxSZ3V2Ws4QRDrscLEDcibJY8uf41H6AhXDrNDcGw= github.com/go-faster/city v1.0.1/go.mod h1:jKcUJId49qdW3L1qKHH/3wPeUstCVpVSXTM6vO3VcTw= github.com/go-faster/errors v0.6.1 h1:nNIPOBkprlKzkThvS/0YaX8Zs9KewLCOSFQS5BU06FI= @@ -287,6 +298,7 @@ github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -312,15 +324,14 @@ github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/grafana/grafana-api-golang-client v0.25.0 h1:jDxnR0U5xgIwKzE+IliZJvjMUUTQxGq+c1s+3M46flI= -github.com/grafana/grafana-api-golang-client v0.25.0/go.mod h1:24W29gPe9yl0/3A9X624TPkAOR8DpHno490cPwnkv8E= +github.com/grafana/grafana-api-golang-client v0.26.0 h1:Eu2YsfUezYngy8ifvmLybgluIcn/2IS9u1xkzuYstEM= +github.com/grafana/grafana-api-golang-client v0.26.0/go.mod h1:uNLZEmgKtTjHBtCQMwNn3qsx2mpMb8zU+7T4Xv3NR9Y= github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI= github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8= github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0 h1:RtRsiaGvWxcwd8y3BiRZxsylPT8hLWZ5SPcfI+3IDNk= @@ -328,15 +339,38 @@ github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0/go.mod h1:TzP6duP4Py2pHLVPPQp4 github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= +github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= +github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= +github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-msgpack v1.1.5 h1:9byZdVjKTe5mce63pRVNP1L7UAmdHOTEMGehn6KvJWs= +github.com/hashicorp/go-msgpack v1.1.5/go.mod h1:gWVc3sv/wbDmR3rQsj1CAktEZzoz1YNK9NfGLXJ69/4= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc= +github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= +github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.6.0 h1:uL2shRDx7RTrOrTCUZEGP/wJUFiUI8QT6E7z5o8jga4= +github.com/hashicorp/golang-lru v0.6.0/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/memberlist v0.5.0 h1:EtYPN8DpAURiapus508I4n9CzHs2W+8NZGbmmR/prTM= +github.com/hashicorp/memberlist v0.5.0/go.mod h1:yvyXLpo0QaGE59Y7hDTsTzDD25JYBZ4mHgHUZ8lrOI0= +github.com/hashicorp/raft v1.5.0 h1:uNs9EfJ4FwiArZRxxfd/dQ5d33nV31/CdCHArH89hT8= +github.com/hashicorp/raft v1.5.0/go.mod h1:pKHB2mf/Y25u3AHNSXVRv+yT+WAnmeTX0BwVppVQV+M= github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= @@ -361,6 +395,7 @@ github.com/jotaen/kong-completion v0.0.5/go.mod h1:Pic1KtmJkOiWtr9XEVbyWXvn3AuCg github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= @@ -386,6 +421,8 @@ github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8t github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -412,6 +449,13 @@ github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0 github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98= github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4= @@ -427,12 +471,16 @@ github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= +github.com/miekg/dns v1.1.26 h1:gPxPSwALAeHJSjarOs00QjVdV9QoBvc1D2ujQUr5BzU= +github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34= github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM= github.com/minio/minio-go/v7 v7.0.55 h1:ZXqUO/8cgfHzI+08h/zGuTTFpISSA32BZmBE3FCLJas= github.com/minio/minio-go/v7 v7.0.55/go.mod h1:NUDy4A4oXPq1l2yK6LTSvCEzAMeIcoz9lcj5dbzSrRE= github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= @@ -474,12 +522,15 @@ github.com/opencontainers/image-spec v1.1.0-rc4/go.mod h1:X4pATf0uXsnn3g5aiGIsVn github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= +github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/paulmach/orb v0.10.0 h1:guVYVqzxHE/CQ1KpfGO077TR0ATHSNjp4s6XGLn3W9s= github.com/paulmach/orb v0.10.0/go.mod h1:5mULz1xQfs3bmQm63QEJA6lNGujuRafwA5S/EnuLaLU= github.com/paulmach/protoscan v0.2.1/go.mod h1:SpcSwydNLrxUGSDvXvO0P7g7AuhJ7lcKfDlhJCDw2gY= github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= -github.com/percona-lab/crypto v0.0.0-20220811043533-d164de3c7f08 h1:NprWeXddFZJSgtN8hmf/hhIgiZwB3GNaKnI88iAFgEc= -github.com/percona-lab/crypto v0.0.0-20220811043533-d164de3c7f08/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +github.com/percona-lab/crypto v0.0.0-20231108144114-756dfb24eaf2 h1:FaO5loTAkRzVhyKWYRHg/ii9oWXNsqv89H/kGl9Cb5I= +github.com/percona-lab/crypto v0.0.0-20231108144114-756dfb24eaf2/go.mod h1:aSyBXtGhRzSMdne9jbl3+PPMVS0IgOWF6Llc+HB5uUU= github.com/percona-platform/saas v0.0.0-20230728161159-ad6bdeb8a3d9 h1:KkOH+Y4sVRP7qvRtTDmfPFNjjQcwU2054/jNl9DZhEo= github.com/percona-platform/saas v0.0.0-20230728161159-ad6bdeb8a3d9/go.mod h1:lZuFcqj0EoQWx28SYkTcdhJOCQEbRcAyahYPfRMY7tc= github.com/percona/exporter_shared v0.7.4 h1:S+xnfK/CySiYqr4XqLiLAfO3rxgEOUFK+m6lCBi3mgc= @@ -503,12 +554,16 @@ github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/sftp v1.13.6 h1:JFZT4XbOU7l77xGSpOdW+pwIMqP044IyjXX6FGyEKFo= +github.com/pkg/sftp v1.13.6/go.mod h1:tz1ryNURKu77RL+GuCzmoJYxQczL3wLNNpPWagdg4Qk= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/posener/complete v1.2.3 h1:NP0eAhjcjImqslEwo/1hq7gpajME0fTLTezBKDqfXqo= github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q= @@ -520,6 +575,7 @@ github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6T github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16 h1:v7DLqVdK4VrYkVD5diGdl4sxJurKJEMnODWRJlxV9oM= github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.31.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= @@ -527,6 +583,7 @@ github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lne github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.11.1 h1:xRC8Iq1yyca5ypa9n1EZnWZkt7dwcoRPQwX/5gwaUuI= @@ -549,6 +606,9 @@ github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjR github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys= github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= @@ -578,12 +638,14 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= @@ -667,8 +729,9 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= -golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= +golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -683,6 +746,7 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -699,10 +763,11 @@ golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg= +golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -724,8 +789,10 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= -golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= +golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -740,11 +807,13 @@ golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -767,20 +836,30 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +golang.org/x/term v0.14.0 h1:LGK9IlZ8T9jvdy6cTdfKUCltatMFOehAQo9SRC46UQ8= +golang.org/x/term v0.14.0/go.mod h1:TySc+nGkYR6qt8km8wUhuFRTVSMIX3XPR58y2lC8vww= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -792,6 +871,8 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -811,6 +892,7 @@ golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190424220101-1e8e1cfdf96b/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= @@ -819,6 +901,7 @@ golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -851,8 +934,9 @@ golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= -golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.15.0 h1:zdAyfUGbYmuVokhzVmghFl2ZJh5QhcfebBgmVPFYA+8= +golang.org/x/tools v0.15.0/go.mod h1:hpksKq4dtpQWS1uQ61JkdqWM3LscIS6Slf+VVkm+wQk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/managed/cmd/pmm-managed-init/main.go b/managed/cmd/pmm-managed-init/main.go index 1d52155db1..8aa0046e3b 100644 --- a/managed/cmd/pmm-managed-init/main.go +++ b/managed/cmd/pmm-managed-init/main.go @@ -54,6 +54,7 @@ func main() { pmmConfigParams := make(map[string]any) pmmConfigParams["DisableInternalDB"], _ = strconv.ParseBool(os.Getenv("PERCONA_TEST_PMM_DISABLE_BUILTIN_POSTGRES")) + pmmConfigParams["DisableInternalClickhouse"], _ = strconv.ParseBool(os.Getenv("PERCONA_TEST_PMM_DISABLE_BUILTIN_CLICKHOUSE")) if err := supervisord.SavePMMConfig(pmmConfigParams); err != nil { logrus.Errorf("PMM Server configuration error: %s.", err) os.Exit(1) diff --git a/managed/cmd/pmm-managed/main.go b/managed/cmd/pmm-managed/main.go index e7b6846dd8..2269e0e65b 100644 --- a/managed/cmd/pmm-managed/main.go +++ b/managed/cmd/pmm-managed/main.go @@ -66,6 +66,7 @@ import ( alertingpb "github.com/percona/pmm/api/managementpb/alerting" azurev1beta1 "github.com/percona/pmm/api/managementpb/azure" backuppb "github.com/percona/pmm/api/managementpb/backup" + dumpv1beta1 "github.com/percona/pmm/api/managementpb/dump" nodev1beta1 "github.com/percona/pmm/api/managementpb/node" rolev1beta1 "github.com/percona/pmm/api/managementpb/role" servicev1beta1 "github.com/percona/pmm/api/managementpb/service" @@ -80,13 +81,16 @@ import ( "github.com/percona/pmm/managed/services/backup" "github.com/percona/pmm/managed/services/checks" "github.com/percona/pmm/managed/services/config" + "github.com/percona/pmm/managed/services/dump" "github.com/percona/pmm/managed/services/grafana" + "github.com/percona/pmm/managed/services/ha" "github.com/percona/pmm/managed/services/inventory" inventorygrpc "github.com/percona/pmm/managed/services/inventory/grpc" "github.com/percona/pmm/managed/services/management" "github.com/percona/pmm/managed/services/management/alerting" managementbackup "github.com/percona/pmm/managed/services/management/backup" "github.com/percona/pmm/managed/services/management/common" + managementdump "github.com/percona/pmm/managed/services/management/dump" managementgrpc "github.com/percona/pmm/managed/services/management/grpc" "github.com/percona/pmm/managed/services/minio" "github.com/percona/pmm/managed/services/platform" @@ -180,6 +184,7 @@ func addLogsHandler(mux *http.ServeMux, logs *supervisord.Logs) { type gRPCServerDeps struct { db *reform.DB + ha *ha.Service vmdb *victoriametrics.Service platformClient *platformClient.Client server *server.Server @@ -198,6 +203,7 @@ type gRPCServerDeps struct { jobsService *agents.JobsService schedulerService *scheduler.Service backupService *backup.Service + dumpService *dump.Service compatibilityService *backup.CompatibilityService backupRemovalService *backup.RemovalService pbmPITRService *backup.PBMPITRService @@ -293,6 +299,8 @@ func runGRPCServer(ctx context.Context, deps *gRPCServerDeps) { backuppb.RegisterArtifactsServer(gRPCServer, mgmtArtifactsService) backuppb.RegisterRestoreHistoryServer(gRPCServer, mgmtRestoreHistoryService) + dumpv1beta1.RegisterDumpsServer(gRPCServer, managementdump.New(deps.db, deps.grafanaClient, deps.dumpService)) + userpb.RegisterUserServer(gRPCServer, user.NewUserService(deps.db, deps.grafanaClient)) platformService := platform.New(deps.platformClient, deps.db, deps.supervisord, deps.checksService, deps.grafanaClient) @@ -401,6 +409,8 @@ func runHTTP1Server(ctx context.Context, deps *http1ServerDeps) { backuppb.RegisterArtifactsHandlerFromEndpoint, backuppb.RegisterRestoreHistoryHandlerFromEndpoint, + dumpv1beta1.RegisterDumpsHandlerFromEndpoint, + platformpb.RegisterPlatformHandlerFromEndpoint, uieventspb.RegisterUIEventsHandlerFromEndpoint, @@ -499,6 +509,7 @@ func runDebugServer(ctx context.Context) { type setupDeps struct { sqlDB *sql.DB + ha *ha.Service supervisord *supervisord.Service vmdb *victoriametrics.Service vmalert *vmalert.Service @@ -685,6 +696,34 @@ func main() { //nolint:cyclop,maintidx Envar("PERCONA_TEST_POSTGRES_SSL_CERT_PATH"). String() + haEnabled := kingpin.Flag("ha-enable", "Enable HA"). + Envar("PMM_TEST_HA_ENABLE"). + Bool() + haBootstrap := kingpin.Flag("ha-bootstrap", "Bootstrap HA cluster"). + Envar("PMM_TEST_HA_BOOTSTRAP"). + Bool() + haNodeID := kingpin.Flag("ha-node-id", "HA Node ID"). + Envar("PMM_TEST_HA_NODE_ID"). + String() + haAdvertiseAddress := kingpin.Flag("ha-advertise-address", "HA Advertise address"). + Envar("PMM_TEST_HA_ADVERTISE_ADDRESS"). + String() + haPeers := kingpin.Flag("ha-peers", "HA Peers"). + Envar("PMM_TEST_HA_PEERS"). + String() + haRaftPort := kingpin.Flag("ha-raft-port", "HA raft port"). + Envar("PMM_TEST_HA_RAFT_PORT"). + Default("9760"). + Int() + haGossipPort := kingpin.Flag("ha-gossip-port", "HA gossip port"). + Envar("PMM_TEST_HA_GOSSIP_PORT"). + Default("9761"). + Int() + haGrafanaGossipPort := kingpin.Flag("ha-grafana-gossip-port", "HA Grafana gossip port"). + Envar("PMM_TEST_HA_GRAFANA_GOSSIP_PORT"). + Default("9762"). + Int() + supervisordConfigDirF := kingpin.Flag("supervisord-config-dir", "Supervisord configuration directory").Required().String() logLevelF := kingpin.Flag("log-level", "Set logging level").Envar("PMM_LOG_LEVEL").Default("info").Enum("trace", "debug", "info", "warn", "error", "fatal") @@ -714,6 +753,22 @@ func main() { //nolint:cyclop,maintidx ctx = logger.Set(ctx, "main") defer l.Info("Done.") + var nodes []string + if *haPeers != "" { + nodes = strings.Split(*haPeers, ",") + } + haParams := &models.HAParams{ + Enabled: *haEnabled, + Bootstrap: *haBootstrap, + NodeID: *haNodeID, + AdvertiseAddress: *haAdvertiseAddress, + Nodes: nodes, + RaftPort: *haRaftPort, + GossipPort: *haGossipPort, + GrafanaGossipPort: *haGrafanaGossipPort, + } + haService := ha.New(haParams) + cfg := config.NewService() if err := cfg.Load(); err != nil { l.Panicf("Failed to load config: %+v", err) @@ -776,17 +831,21 @@ func main() { //nolint:cyclop,maintidx } defer sqlDB.Close() //nolint:errcheck - migrateDB(ctx, sqlDB, setupParams) + if haService.Bootstrap() { + migrateDB(ctx, sqlDB, setupParams) + } prom.MustRegister(sqlmetrics.NewCollector("postgres", *postgresDBNameF, sqlDB)) reformL := sqlmetrics.NewReform("postgres", *postgresDBNameF, logrus.WithField("component", "reform").Tracef) prom.MustRegister(reformL) db := reform.NewDB(sqlDB, postgresql.Dialect, reformL) - // Generate unique PMM Server ID if it's not already set. - err = models.SetPMMServerID(db) - if err != nil { - l.Panicf("failed to set PMM Server ID") + if haService.Bootstrap() { + // Generate unique PMM Server ID if it's not already set. + err = models.SetPMMServerID(db) + if err != nil { + l.Panicf("failed to set PMM Server ID") + } } cleaner := clean.New(db) @@ -806,6 +865,12 @@ func main() { //nolint:cyclop,maintidx qanClient := getQANClient(ctx, sqlDB, *postgresDBNameF, *qanAPIAddrF) agentsRegistry := agents.NewRegistry(db, vmParams) + + // TODO remove once PMM cluster will be Active-Active + haService.AddLeaderService(ha.NewStandardService("agentsRegistry", func(ctx context.Context) error { return nil }, func() { + agentsRegistry.KickAll(ctx) + })) + pbmPITRService := backup.NewPBMPITRService() backupRemovalService := backup.NewRemovalService(db, pbmPITRService) backupRetentionService := backup.NewRetentionService(db, backupRemovalService) @@ -830,19 +895,31 @@ func main() { //nolint:cyclop,maintidx supervisord := supervisord.New( *supervisordConfigDirF, pmmUpdateCheck, - vmParams, - models.PGParams{ - Addr: *postgresAddrF, - DBName: *postgresDBNameF, - DBUsername: *postgresDBUsernameF, - DBPassword: *postgresDBPasswordF, - SSLMode: *postgresSSLModeF, - SSLCAPath: *postgresSSLCAPathF, - SSLKeyPath: *postgresSSLKeyPathF, - SSLCertPath: *postgresSSLCertPathF, + &models.Params{ + VMParams: vmParams, + PGParams: &models.PGParams{ + Addr: *postgresAddrF, + DBName: *postgresDBNameF, + DBUsername: *postgresDBUsernameF, + DBPassword: *postgresDBPasswordF, + SSLMode: *postgresSSLModeF, + SSLCAPath: *postgresSSLCAPathF, + SSLKeyPath: *postgresSSLKeyPathF, + SSLCertPath: *postgresSSLCertPathF, + }, + HAParams: haParams, }, gRPCMessageMaxSize) + haService.AddLeaderService(ha.NewStandardService("pmm-agent-runner", func(ctx context.Context) error { + return supervisord.StartSupervisedService("pmm-agent") + }, func() { + err := supervisord.StopSupervisedService("pmm-agent") + if err != nil { + l.Warnf("couldn't stop pmm-agent: %q", err) + } + })) + platformAddress, err := envvars.GetPlatformAddress() if err != nil { l.Fatal(err) @@ -953,6 +1030,7 @@ func main() { //nolint:cyclop,maintidx // try synchronously once, then retry in the background deps := &setupDeps{ sqlDB: sqlDB, + ha: haService, supervisord: supervisord, vmdb: vmdb, vmalert: vmalert, @@ -980,13 +1058,6 @@ func main() { //nolint:cyclop,maintidx }() } - // Set all agents status to unknown at startup. The ones that are alive - // will get their status updated after they connect to the pmm-managed. - err = agentsHandler.SetAllAgentsStatusUnknown(ctx) - if err != nil { - l.Errorf("Failed to set status of all agents to invalid at startup: %s", err) - } - settings, err := models.GetSettings(sqlDB) if err != nil { l.Fatalf("Failed to get settings: %+v.", err) @@ -1020,11 +1091,10 @@ func main() { //nolint:cyclop,maintidx alertManager.Run(ctx) }() - wg.Add(1) - go func() { - defer wg.Done() + haService.AddLeaderService(ha.NewContextService("checks", func(ctx context.Context) error { checksService.Run(ctx) - }() + return nil + })) wg.Add(1) go func() { @@ -1033,22 +1103,21 @@ func main() { //nolint:cyclop,maintidx }() wg.Add(1) - go func() { + haService.AddLeaderService(ha.NewContextService("telemetry", func(ctx context.Context) error { defer wg.Done() telemetry.Run(ctx) - }() + return nil + })) - wg.Add(1) - go func() { - defer wg.Done() + haService.AddLeaderService(ha.NewContextService("scheduler", func(ctx context.Context) error { schedulerService.Run(ctx) - }() + return nil + })) - wg.Add(1) - go func() { - defer wg.Done() + haService.AddLeaderService(ha.NewContextService("versionCache", func(ctx context.Context) error { versionCache.Run(ctx) - }() + return nil + })) wg.Add(1) go func() { @@ -1067,8 +1136,10 @@ func main() { //nolint:cyclop,maintidx config: &cfg.Config, connectionCheck: connectionCheck, db: db, + dumpService: dumpService, grafanaClient: grafanaClient, handler: agentsHandler, + ha: haService, jobsService: jobsService, minioClient: minioClient, pbmPITRService: pbmPITRService, @@ -1083,6 +1154,7 @@ func main() { //nolint:cyclop,maintidx versionCache: versionCache, vmalert: vmalert, vmClient: &vmClient, + vmalert: vmalert, vmdb: vmdb, }) }() @@ -1102,10 +1174,17 @@ func main() { //nolint:cyclop,maintidx runDebugServer(ctx) }() + haService.AddLeaderService(ha.NewContextService("cleaner", func(ctx context.Context) error { + cleaner.Run(ctx, cleanInterval, cleanOlderThan) + }() + wg.Add(1) go func() { defer wg.Done() - cleaner.Run(ctx, cleanInterval, cleanOlderThan) + err := haService.Run(ctx) + if err != nil { + l.Panicf("cannot start high availability service: %+v", err) + } }() wg.Wait() diff --git a/managed/models/agentversion.go b/managed/models/agentversion.go index 4723b91af7..272b19e4de 100644 --- a/managed/models/agentversion.go +++ b/managed/models/agentversion.go @@ -33,7 +33,7 @@ type AgentNotSupportedError struct { MinAgentVersion string } -func (e *AgentNotSupportedError) Error() string { +func (e AgentNotSupportedError) Error() string { return fmt.Sprintf("'%s' functionality is not supported by pmm-agent %q version %q. Required minimum version is %q", e.Functionality, e.AgentID, e.AgentVersion, e.MinAgentVersion) } @@ -44,11 +44,11 @@ func PMMAgentSupported(q *reform.Querier, pmmAgentID, functionalityPrefix string if err != nil { return errors.Errorf("failed to get PMM Agent: %s", err) } - return isAgentSupported(pmmAgent, functionalityPrefix, pmmMinVersion) + return IsAgentSupported(pmmAgent, functionalityPrefix, pmmMinVersion) } -// isAgentSupported contains logic for PMMAgentSupported. -func isAgentSupported(agentModel *Agent, functionalityPrefix string, pmmMinVersion *version.Version) error { +// IsAgentSupported contains logic for PMMAgentSupported. +func IsAgentSupported(agentModel *Agent, functionalityPrefix string, pmmMinVersion *version.Version) error { if agentModel == nil { return errors.New("nil agent") } @@ -61,7 +61,7 @@ func isAgentSupported(agentModel *Agent, functionalityPrefix string, pmmMinVersi } if pmmAgentVersion.LessThan(pmmMinVersion) { - return errors.WithStack(&AgentNotSupportedError{ + return errors.WithStack(AgentNotSupportedError{ AgentID: agentModel.AgentID, Functionality: functionalityPrefix, AgentVersion: *agentModel.Version, @@ -74,7 +74,7 @@ func isAgentSupported(agentModel *Agent, functionalityPrefix string, pmmMinVersi func IsPostgreSQLSSLSniSupported(q *reform.Querier, pmmAgentID string) (bool, error) { err := PMMAgentSupported(q, pmmAgentID, "postgresql SSL sni check", PMMAgentMinVersionForPostgreSQLSSLSni) switch { - case errors.Is(err, &AgentNotSupportedError{}): + case errors.As(err, &AgentNotSupportedError{}): return false, nil case err == nil: return true, nil diff --git a/managed/models/agentversion_test.go b/managed/models/agentversion_test.go index e47ac1716f..665c0f3e72 100644 --- a/managed/models/agentversion_test.go +++ b/managed/models/agentversion_test.go @@ -13,14 +13,21 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -package models +package models_test import ( "testing" + "time" "github.com/AlekSi/pointer" "github.com/hashicorp/go-version" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "gopkg.in/reform.v1" + "gopkg.in/reform.v1/dialects/postgresql" + + "github.com/percona/pmm/managed/models" + "github.com/percona/pmm/managed/utils/testdb" ) func TestPMMAgentSupported(t *testing.T) { @@ -64,11 +71,11 @@ func TestPMMAgentSupported(t *testing.T) { test := test t.Run(test.name, func(t *testing.T) { t.Parallel() - agentModel := Agent{ + agentModel := models.Agent{ AgentID: "Test agent ID", Version: pointer.ToString(test.agentVersion), } - err := isAgentSupported(&agentModel, prefix, minVersion) + err := models.IsAgentSupported(&agentModel, prefix, minVersion) if test.errString == "" { assert.NoError(t, err) } else { @@ -78,12 +85,91 @@ func TestPMMAgentSupported(t *testing.T) { } t.Run("No version info", func(t *testing.T) { - err := isAgentSupported(&Agent{AgentID: "Test agent ID"}, prefix, version.Must(version.NewVersion("2.30.0"))) + err := models.IsAgentSupported(&models.Agent{AgentID: "Test agent ID"}, prefix, version.Must(version.NewVersion("2.30.0"))) assert.Contains(t, err.Error(), "has no version info") }) t.Run("Nil agent", func(t *testing.T) { - err := isAgentSupported(nil, prefix, version.Must(version.NewVersion("2.30.0"))) + err := models.IsAgentSupported(nil, prefix, version.Must(version.NewVersion("2.30.0"))) assert.Contains(t, err.Error(), "nil agent") }) } + +func TestIsPostgreSQLSSLSniSupported(t *testing.T) { + now, origNowF := models.Now(), models.Now + models.Now = func() time.Time { + return now + } + sqlDB := testdb.Open(t, models.SetupFixtures, nil) + defer func() { + models.Now = origNowF + require.NoError(t, sqlDB.Close()) + }() + + setup := func(t *testing.T) (q *reform.Querier, teardown func(t *testing.T)) { + t.Helper() + db := reform.NewDB(sqlDB, postgresql.Dialect, reform.NewPrintfLogger(t.Logf)) + tx, err := db.Begin() + require.NoError(t, err) + q = tx.Querier + + for _, str := range []reform.Struct{ + &models.Node{ + NodeID: "N1", + NodeType: models.GenericNodeType, + NodeName: "Generic Node", + }, + + &models.Agent{ + AgentID: "New", + AgentType: models.PMMAgentType, + RunsOnNodeID: pointer.ToString("N1"), + Version: pointer.ToString("2.41.0"), + }, + + &models.Agent{ + AgentID: "Old", + AgentType: models.PMMAgentType, + RunsOnNodeID: pointer.ToString("N1"), + Version: pointer.ToString("2.40.1"), + }, + } { + require.NoError(t, q.Insert(str), "failed to INSERT %+v", str) + } + + teardown = func(t *testing.T) { + t.Helper() + require.NoError(t, tx.Rollback()) + } + return + } + q, teardown := setup(t) + defer teardown(t) + + tests := []struct { + pmmAgentID string + expected bool + }{ + { + "New", + true, + }, + { + "Old", + false, + }, + } + for _, tt := range tests { + tt := tt + t.Run(tt.pmmAgentID, func(t *testing.T) { + actual, err := models.IsPostgreSQLSSLSniSupported(q, tt.pmmAgentID) + assert.Equal(t, tt.expected, actual) + assert.NoError(t, err) + }) + } + + t.Run("Non-existing ID", func(t *testing.T) { + _, err := models.IsPostgreSQLSSLSniSupported(q, "Not exist") + assert.Error(t, err) + }) +} diff --git a/managed/models/database.go b/managed/models/database.go index 76df9f627a..f8dba90418 100644 --- a/managed/models/database.go +++ b/managed/models/database.go @@ -925,6 +925,29 @@ var databaseSchema = [][]string{ `ALTER TABLE agents ALTER COLUMN expose_exporter DROP DEFAULT`, }, + 87: { + `CREATE TABLE dumps ( + id VARCHAR NOT NULL, + status VARCHAR NOT NULL CHECK (status <> ''), + service_names VARCHAR[], + start_time TIMESTAMP, + end_time TIMESTAMP, + export_qan BOOLEAN NOT NULL, + ignore_load BOOLEAN NOT NULL, + created_at TIMESTAMP NOT NULL, + updated_at TIMESTAMP NOT NULL, + + PRIMARY KEY (id) + )`, + + `CREATE TABLE dump_logs ( + dump_id VARCHAR NOT NULL, + chunk_id INTEGER NOT NULL, + data TEXT NOT NULL, + last_chunk BOOLEAN NOT NULL, + FOREIGN KEY (dump_id) REFERENCES dumps (id) ON DELETE CASCADE, + PRIMARY KEY (dump_id, chunk_id) + )`, 100: { `DROP TABLE kubernetes_clusters`, }, diff --git a/managed/models/dump.go b/managed/models/dump.go new file mode 100644 index 0000000000..d7adcee5c7 --- /dev/null +++ b/managed/models/dump.go @@ -0,0 +1,104 @@ +// Copyright (C) 2023 Percona LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package models + +import ( + "time" + + "github.com/lib/pq" + "gopkg.in/reform.v1" +) + +//go:generate ../../bin/reform + +type DumpStatus string + +const ( + DumpStatusInProgress = DumpStatus("in_progress") + DumpStatusSuccess = DumpStatus("success") + DumpStatusError = DumpStatus("error") +) + +// Validate validates Dumps status. +func (ds DumpStatus) Validate() error { + switch ds { + case DumpStatusInProgress: + case DumpStatusSuccess: + case DumpStatusError: + default: + return NewInvalidArgumentError("invalid dump status '%s'", ds) + } + + return nil +} + +// Pointer returns a pointer to status value. +func (ds DumpStatus) Pointer() *DumpStatus { + return &ds +} + +// Dump represents pmm dump artifact. +// +//reform:dumps +type Dump struct { + ID string `reform:"id,pk"` + Status DumpStatus `reform:"status"` + ServiceNames pq.StringArray `reform:"service_names"` + StartTime *time.Time `reform:"start_time"` + EndTime *time.Time `reform:"end_time"` + ExportQAN bool `reform:"export_qan"` + IgnoreLoad bool `reform:"ignore_load"` + CreatedAt time.Time `reform:"created_at"` + UpdatedAt time.Time `reform:"updated_at"` +} + +// BeforeInsert implements reform.BeforeInserter interface. +func (d *Dump) BeforeInsert() error { + now := Now() + d.CreatedAt = now + d.UpdatedAt = now + return nil +} + +// BeforeUpdate implements reform.BeforeUpdater interface. +func (d *Dump) BeforeUpdate() error { + d.UpdatedAt = Now() + return nil +} + +// AfterFind implements reform.AfterFinder interface. +func (d *Dump) AfterFind() error { + d.CreatedAt = d.CreatedAt.UTC() + d.UpdatedAt = d.UpdatedAt.UTC() + return nil +} + +// DumpLog stores chunk of logs from pmm-dump. +// +//reform:dump_logs +type DumpLog struct { + DumpID string `reform:"dump_id"` + ChunkID uint32 `reform:"chunk_id"` + Data string `reform:"data"` + LastChunk bool `reform:"last_chunk"` +} + +// check interfaces. +var ( + _ reform.BeforeInserter = (*Dump)(nil) + _ reform.BeforeUpdater = (*Dump)(nil) + _ reform.AfterFinder = (*Dump)(nil) +) diff --git a/managed/models/dump_helpers.go b/managed/models/dump_helpers.go new file mode 100644 index 0000000000..b5c0626ef1 --- /dev/null +++ b/managed/models/dump_helpers.go @@ -0,0 +1,247 @@ +// Copyright (C) 2023 Percona LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package models + +import ( + "fmt" + "strings" + "time" + + "github.com/google/uuid" + "github.com/pkg/errors" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + "gopkg.in/reform.v1" +) + +func checkUniqueDumpID(q *reform.Querier, id string) error { + if id == "" { + panic("empty dump ID") + } + + dump := &Dump{ID: id} + err := q.Reload(dump) + if err != nil { + if errors.Is(err, reform.ErrNoRows) { + return nil + } + return errors.WithStack(err) + } + + return status.Errorf(codes.AlreadyExists, "Dump with id %q already exists.", id) +} + +// DumpFilters represents filters for dumps list. +type DumpFilters struct { + // Return only dumps by specified status. + Status DumpStatus +} + +type CreateDumpParams struct { + ServiceNames []string + StartTime *time.Time + EndTime *time.Time + ExportQAN bool + IgnoreLoad bool +} + +func (p *CreateDumpParams) Validate() error { + if p.StartTime != nil && p.EndTime != nil && p.StartTime.After(*p.EndTime) { + return errors.Errorf("dump start time can't be greater than end time") + } + + return nil +} + +func CreateDump(q *reform.Querier, params CreateDumpParams) (*Dump, error) { + if err := params.Validate(); err != nil { + return nil, errors.Wrap(err, "invalid dump creation params") + } + + id := uuid.New().String() + if err := checkUniqueDumpID(q, id); err != nil { + return nil, err + } + + dump := &Dump{ + ID: id, + Status: DumpStatusInProgress, + ServiceNames: params.ServiceNames, + StartTime: params.StartTime, + EndTime: params.EndTime, + ExportQAN: params.ExportQAN, + IgnoreLoad: params.IgnoreLoad, + } + if err := q.Insert(dump); err != nil { + return nil, errors.WithStack(err) + } + + return dump, nil +} + +// FindDumps returns dumps list sorted by creation time in DESCENDING order. +func FindDumps(q *reform.Querier, filters DumpFilters) ([]*Dump, error) { + var conditions []string + var args []interface{} + var idx int + + if filters.Status != "" { + idx++ + conditions = append(conditions, fmt.Sprintf("status = %s", q.Placeholder(idx))) + args = append(args, filters.Status) + } + + var whereClause string + if len(conditions) != 0 { + whereClause = fmt.Sprintf("WHERE %s", strings.Join(conditions, " AND ")) + } + rows, err := q.SelectAllFrom(DumpTable, fmt.Sprintf("%s ORDER BY created_at DESC", whereClause), args...) + if err != nil { + return nil, errors.Wrap(err, "failed to select dumps") + } + + dumps := make([]*Dump, 0, len(rows)) + for _, r := range rows { + dumps = append(dumps, r.(*Dump)) //nolint:forcetypeassert + } + + return dumps, nil +} + +// FindDumpsByIDs finds dumps by IDs. +func FindDumpsByIDs(q *reform.Querier, ids []string) (map[string]*Dump, error) { + if len(ids) == 0 { + return make(map[string]*Dump), nil + } + + p := strings.Join(q.Placeholders(1, len(ids)), ", ") + tail := fmt.Sprintf("WHERE id IN (%s)", p) + args := make([]interface{}, 0, len(ids)) + for _, id := range ids { + args = append(args, id) + } + + all, err := q.SelectAllFrom(DumpTable, tail, args...) + if err != nil { + return nil, errors.WithStack(err) + } + + dumps := make(map[string]*Dump, len(all)) + for _, l := range all { + dump := l.(*Dump) //nolint:forcetypeassert + dumps[dump.ID] = dump + } + return dumps, nil +} + +// FindDumpByID returns dump by given ID if found, ErrNotFound if not. +func FindDumpByID(q *reform.Querier, id string) (*Dump, error) { + if id == "" { + return nil, errors.New("provided dump id is empty") + } + + dump := &Dump{ID: id} + err := q.Reload(dump) + if err != nil { + if errors.Is(err, reform.ErrNoRows) { + return nil, errors.Wrapf(ErrNotFound, "dump by id '%s'", id) + } + return nil, errors.WithStack(err) + } + + return dump, nil +} + +func UpdateDumpStatus(q *reform.Querier, id string, status DumpStatus) error { + dump, err := FindDumpByID(q, id) + if err != nil { + return err + } + + dump.Status = status + + if err = q.Update(dump); err != nil { + return errors.Wrap(err, "failed to update dump status") + } + + return nil +} + +// DeleteDump removes dump by ID. +func DeleteDump(q *reform.Querier, id string) error { + if _, err := FindDumpByID(q, id); err != nil { + return err + } + + if err := q.Delete(&Dump{ID: id}); err != nil { + return errors.Wrapf(err, "failed to delete dump by id '%s'", id) + } + return nil +} + +// CreateDumpLogParams are params for creating a new pmm-dump log. +type CreateDumpLogParams struct { + DumpID string + ChunkID uint32 + Data string + LastChunk bool +} + +// CreateDumpLog inserts new chunk log. +func CreateDumpLog(q *reform.Querier, params CreateDumpLogParams) (*DumpLog, error) { + log := &DumpLog{ + DumpID: params.DumpID, + ChunkID: params.ChunkID, + Data: params.Data, + LastChunk: params.LastChunk, + } + if err := q.Insert(log); err != nil { + return nil, errors.WithStack(err) + } + return log, nil +} + +// DumpLogsFilter represents filter for dump logs. +type DumpLogsFilter struct { + DumpID string + Offset int + Limit *int +} + +// FindDumpLogs returns logs that belongs to dump. +func FindDumpLogs(q *reform.Querier, filters DumpLogsFilter) ([]*DumpLog, error) { + limit := defaultLimit + tail := "WHERE dump_id = $1 AND chunk_id >= $2 ORDER BY chunk_id LIMIT $3" + if filters.Limit != nil { + limit = *filters.Limit + } + args := []interface{}{ + filters.DumpID, + filters.Offset, + limit, + } + + rows, err := q.SelectAllFrom(DumpLogView, tail, args...) + if err != nil { + return nil, errors.Wrap(err, "failed to select dump logs") + } + + logs := make([]*DumpLog, 0, len(rows)) + for _, r := range rows { + logs = append(logs, r.(*DumpLog)) //nolint:forcetypeassert + } + return logs, nil +} diff --git a/managed/models/dump_helpers_test.go b/managed/models/dump_helpers_test.go new file mode 100644 index 0000000000..5660c41302 --- /dev/null +++ b/managed/models/dump_helpers_test.go @@ -0,0 +1,280 @@ +// Copyright (C) 2023 Percona LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package models_test + +import ( + "sort" + "testing" + "time" + + "github.com/AlekSi/pointer" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "gopkg.in/reform.v1" + "gopkg.in/reform.v1/dialects/postgresql" + + "github.com/percona/pmm/managed/models" + "github.com/percona/pmm/managed/utils/testdb" +) + +func TestDumps(t *testing.T) { + sqlDB := testdb.Open(t, models.SkipFixtures, nil) + db := reform.NewDB(sqlDB, postgresql.Dialect, reform.NewPrintfLogger(t.Logf)) + tx, err := db.Begin() + require.NoError(t, err) + t.Cleanup(func() { + require.NoError(t, tx.Rollback()) + }) + + t.Run("create", func(t *testing.T) { + t.Run("normal", func(t *testing.T) { + endTime := time.Now() + startTime := endTime.Add(-10 * time.Minute) + + createDumpParams := models.CreateDumpParams{ + ServiceNames: []string{"foo", "bar"}, + StartTime: &startTime, + EndTime: &endTime, + ExportQAN: false, + IgnoreLoad: true, + } + dump, err := models.CreateDump(tx.Querier, createDumpParams) + require.NoError(t, err) + assert.NotEmpty(t, dump.ID) + assert.Equal(t, models.DumpStatusInProgress, dump.Status) + assert.ElementsMatch(t, createDumpParams.ServiceNames, dump.ServiceNames) + assert.Equal(t, createDumpParams.StartTime, dump.StartTime) + assert.Equal(t, createDumpParams.EndTime, dump.EndTime) + assert.Equal(t, createDumpParams.ExportQAN, dump.ExportQAN) + assert.Equal(t, createDumpParams.IgnoreLoad, dump.IgnoreLoad) + }) + + t.Run("invalid start and end time", func(t *testing.T) { + endTime := time.Now() + startTime := endTime.Add(10 * time.Minute) + + createDumpParams := models.CreateDumpParams{ + ServiceNames: []string{"foo", "bar"}, + StartTime: &startTime, + EndTime: &endTime, + ExportQAN: false, + IgnoreLoad: true, + } + _, err := models.CreateDump(tx.Querier, createDumpParams) + require.EqualError(t, err, "invalid dump creation params: dump start time can't be greater than end time") + }) + }) + + t.Run("find", func(t *testing.T) { + findTX, err := db.Begin() + require.NoError(t, err) + defer findTX.Rollback() //nolint:errcheck + + endTime := time.Now() + startTime := endTime.Add(-10 * time.Minute) + + dump1, err := models.CreateDump(findTX.Querier, models.CreateDumpParams{ + ServiceNames: []string{"foo", "bar"}, + StartTime: &startTime, + EndTime: &endTime, + ExportQAN: false, + IgnoreLoad: true, + }) + require.NoError(t, err) + + dump2, err := models.CreateDump(findTX.Querier, models.CreateDumpParams{ + ServiceNames: []string{"foo", "bar"}, + StartTime: &startTime, + EndTime: &endTime, + ExportQAN: false, + IgnoreLoad: true, + }) + require.NoError(t, err) + dump2.Status = models.DumpStatusSuccess + err = models.UpdateDumpStatus(findTX.Querier, dump2.ID, dump2.Status) + require.NoError(t, err) + + dump3, err := models.CreateDump(findTX.Querier, models.CreateDumpParams{ + ServiceNames: []string{"foo", "bar"}, + StartTime: &startTime, + EndTime: &endTime, + ExportQAN: false, + IgnoreLoad: true, + }) + require.NoError(t, err) + dump3.Status = models.DumpStatusError + err = findTX.Querier.Update(dump3) + require.NoError(t, err) + + type testCase struct { + Filters models.DumpFilters + Expect []string + } + + testCases := []testCase{ + { + Filters: models.DumpFilters{}, + Expect: []string{dump1.ID, dump2.ID, dump3.ID}, + }, + { + Filters: models.DumpFilters{ + Status: models.DumpStatusInProgress, + }, + Expect: []string{dump1.ID}, + }, + { + Filters: models.DumpFilters{ + Status: models.DumpStatusSuccess, + }, + Expect: []string{dump2.ID}, + }, + { + Filters: models.DumpFilters{ + Status: models.DumpStatusError, + }, + Expect: []string{dump3.ID}, + }, + } + + for _, tc := range testCases { + dumps, err := models.FindDumps(findTX.Querier, tc.Filters) + require.NoError(t, err) + ids := make([]string, len(dumps)) + for i := range dumps { + ids[i] = dumps[i].ID + } + sort.Strings(tc.Expect) + sort.Strings(ids) + assert.Equal(t, tc.Expect, ids) + } + }) +} + +func TestDumpLogs(t *testing.T) { + sqlDB := testdb.Open(t, models.SkipFixtures, nil) + db := reform.NewDB(sqlDB, postgresql.Dialect, reform.NewPrintfLogger(t.Logf)) + tx, err := db.Begin() + require.NoError(t, err) + t.Cleanup(func() { + require.NoError(t, tx.Rollback()) + require.NoError(t, sqlDB.Close()) + }) + + dump1, err := models.CreateDump(tx.Querier, models.CreateDumpParams{}) + require.NoError(t, err) + + dump2, err := models.CreateDump(tx.Querier, models.CreateDumpParams{}) + require.NoError(t, err) + + createRequests := []models.CreateDumpLogParams{ + { + DumpID: dump1.ID, + ChunkID: 0, + Data: "some log", + }, + { + DumpID: dump1.ID, + ChunkID: 1, + Data: "another log", + }, + { + DumpID: dump2.ID, + ChunkID: 0, + Data: "some log", + }, + } + + t.Run("create", func(t *testing.T) { + for _, req := range createRequests { + log, err := models.CreateDumpLog(tx.Querier, req) + require.NoError(t, err) + assert.Equal(t, req.DumpID, log.DumpID) + assert.Equal(t, req.ChunkID, log.ChunkID) + assert.Equal(t, req.Data, log.Data) + assert.False(t, log.LastChunk) + } + }) + + t.Run("find", func(t *testing.T) { + type expectLog struct { + DumpID string + ChunkID uint32 + } + type testCase struct { + Name string + Filters models.DumpLogsFilter + Expect []expectLog + } + testCases := []testCase{ + { + Name: "dump filter", + Filters: models.DumpLogsFilter{ + DumpID: dump1.ID, + }, + Expect: []expectLog{ + { + DumpID: dump1.ID, + ChunkID: 0, + }, + { + DumpID: dump1.ID, + ChunkID: 1, + }, + }, + }, + { + Name: "dump filter and limit", + Filters: models.DumpLogsFilter{ + DumpID: dump1.ID, + Limit: pointer.ToInt(1), + }, + Expect: []expectLog{ + { + DumpID: dump1.ID, + ChunkID: 0, + }, + }, + }, + { + Name: "dump filter. limit and offset", + Filters: models.DumpLogsFilter{ + DumpID: dump1.ID, + Offset: 1, + Limit: pointer.ToInt(1), + }, + Expect: []expectLog{ + { + DumpID: dump1.ID, + ChunkID: 1, + }, + }, + }, + } + + for _, tc := range testCases { + tc := tc + t.Run(tc.Name, func(t *testing.T) { + logs, err := models.FindDumpLogs(tx.Querier, tc.Filters) + require.NoError(t, err) + require.Len(t, logs, len(tc.Expect)) + for i := range logs { + assert.Equal(t, tc.Expect[i].DumpID, logs[i].DumpID) + assert.Equal(t, tc.Expect[i].ChunkID, logs[i].ChunkID) + } + }) + } + }) +} diff --git a/managed/models/dump_reform.go b/managed/models/dump_reform.go new file mode 100644 index 0000000000..a78ca52e9a --- /dev/null +++ b/managed/models/dump_reform.go @@ -0,0 +1,262 @@ +// Code generated by gopkg.in/reform.v1. DO NOT EDIT. + +package models + +import ( + "fmt" + "strings" + + "gopkg.in/reform.v1" + "gopkg.in/reform.v1/parse" +) + +type dumpTableType struct { + s parse.StructInfo + z []interface{} +} + +// Schema returns a schema name in SQL database (""). +func (v *dumpTableType) Schema() string { + return v.s.SQLSchema +} + +// Name returns a view or table name in SQL database ("dumps"). +func (v *dumpTableType) Name() string { + return v.s.SQLName +} + +// Columns returns a new slice of column names for that view or table in SQL database. +func (v *dumpTableType) Columns() []string { + return []string{ + "id", + "status", + "service_names", + "start_time", + "end_time", + "export_qan", + "ignore_load", + "created_at", + "updated_at", + } +} + +// NewStruct makes a new struct for that view or table. +func (v *dumpTableType) NewStruct() reform.Struct { + return new(Dump) +} + +// NewRecord makes a new record for that table. +func (v *dumpTableType) NewRecord() reform.Record { + return new(Dump) +} + +// PKColumnIndex returns an index of primary key column for that table in SQL database. +func (v *dumpTableType) PKColumnIndex() uint { + return uint(v.s.PKFieldIndex) +} + +// DumpTable represents dumps view or table in SQL database. +var DumpTable = &dumpTableType{ + s: parse.StructInfo{ + Type: "Dump", + SQLName: "dumps", + Fields: []parse.FieldInfo{ + {Name: "ID", Type: "string", Column: "id"}, + {Name: "Status", Type: "DumpStatus", Column: "status"}, + {Name: "ServiceNames", Type: "pq.StringArray", Column: "service_names"}, + {Name: "StartTime", Type: "*time.Time", Column: "start_time"}, + {Name: "EndTime", Type: "*time.Time", Column: "end_time"}, + {Name: "ExportQAN", Type: "bool", Column: "export_qan"}, + {Name: "IgnoreLoad", Type: "bool", Column: "ignore_load"}, + {Name: "CreatedAt", Type: "time.Time", Column: "created_at"}, + {Name: "UpdatedAt", Type: "time.Time", Column: "updated_at"}, + }, + PKFieldIndex: 0, + }, + z: new(Dump).Values(), +} + +// String returns a string representation of this struct or record. +func (s Dump) String() string { + res := make([]string, 9) + res[0] = "ID: " + reform.Inspect(s.ID, true) + res[1] = "Status: " + reform.Inspect(s.Status, true) + res[2] = "ServiceNames: " + reform.Inspect(s.ServiceNames, true) + res[3] = "StartTime: " + reform.Inspect(s.StartTime, true) + res[4] = "EndTime: " + reform.Inspect(s.EndTime, true) + res[5] = "ExportQAN: " + reform.Inspect(s.ExportQAN, true) + res[6] = "IgnoreLoad: " + reform.Inspect(s.IgnoreLoad, true) + res[7] = "CreatedAt: " + reform.Inspect(s.CreatedAt, true) + res[8] = "UpdatedAt: " + reform.Inspect(s.UpdatedAt, true) + return strings.Join(res, ", ") +} + +// Values returns a slice of struct or record field values. +// Returned interface{} values are never untyped nils. +func (s *Dump) Values() []interface{} { + return []interface{}{ + s.ID, + s.Status, + s.ServiceNames, + s.StartTime, + s.EndTime, + s.ExportQAN, + s.IgnoreLoad, + s.CreatedAt, + s.UpdatedAt, + } +} + +// Pointers returns a slice of pointers to struct or record fields. +// Returned interface{} values are never untyped nils. +func (s *Dump) Pointers() []interface{} { + return []interface{}{ + &s.ID, + &s.Status, + &s.ServiceNames, + &s.StartTime, + &s.EndTime, + &s.ExportQAN, + &s.IgnoreLoad, + &s.CreatedAt, + &s.UpdatedAt, + } +} + +// View returns View object for that struct. +func (s *Dump) View() reform.View { + return DumpTable +} + +// Table returns Table object for that record. +func (s *Dump) Table() reform.Table { + return DumpTable +} + +// PKValue returns a value of primary key for that record. +// Returned interface{} value is never untyped nil. +func (s *Dump) PKValue() interface{} { + return s.ID +} + +// PKPointer returns a pointer to primary key field for that record. +// Returned interface{} value is never untyped nil. +func (s *Dump) PKPointer() interface{} { + return &s.ID +} + +// HasPK returns true if record has non-zero primary key set, false otherwise. +func (s *Dump) HasPK() bool { + return s.ID != DumpTable.z[DumpTable.s.PKFieldIndex] +} + +// SetPK sets record primary key, if possible. +// +// Deprecated: prefer direct field assignment where possible: s.ID = pk. +func (s *Dump) SetPK(pk interface{}) { + reform.SetPK(s, pk) +} + +// check interfaces +var ( + _ reform.View = DumpTable + _ reform.Struct = (*Dump)(nil) + _ reform.Table = DumpTable + _ reform.Record = (*Dump)(nil) + _ fmt.Stringer = (*Dump)(nil) +) + +type dumpLogViewType struct { + s parse.StructInfo + z []interface{} +} + +// Schema returns a schema name in SQL database (""). +func (v *dumpLogViewType) Schema() string { + return v.s.SQLSchema +} + +// Name returns a view or table name in SQL database ("dump_logs"). +func (v *dumpLogViewType) Name() string { + return v.s.SQLName +} + +// Columns returns a new slice of column names for that view or table in SQL database. +func (v *dumpLogViewType) Columns() []string { + return []string{ + "dump_id", + "chunk_id", + "data", + "last_chunk", + } +} + +// NewStruct makes a new struct for that view or table. +func (v *dumpLogViewType) NewStruct() reform.Struct { + return new(DumpLog) +} + +// DumpLogView represents dump_logs view or table in SQL database. +var DumpLogView = &dumpLogViewType{ + s: parse.StructInfo{ + Type: "DumpLog", + SQLName: "dump_logs", + Fields: []parse.FieldInfo{ + {Name: "DumpID", Type: "string", Column: "dump_id"}, + {Name: "ChunkID", Type: "uint32", Column: "chunk_id"}, + {Name: "Data", Type: "string", Column: "data"}, + {Name: "LastChunk", Type: "bool", Column: "last_chunk"}, + }, + PKFieldIndex: -1, + }, + z: new(DumpLog).Values(), +} + +// String returns a string representation of this struct or record. +func (s DumpLog) String() string { + res := make([]string, 4) + res[0] = "DumpID: " + reform.Inspect(s.DumpID, true) + res[1] = "ChunkID: " + reform.Inspect(s.ChunkID, true) + res[2] = "Data: " + reform.Inspect(s.Data, true) + res[3] = "LastChunk: " + reform.Inspect(s.LastChunk, true) + return strings.Join(res, ", ") +} + +// Values returns a slice of struct or record field values. +// Returned interface{} values are never untyped nils. +func (s *DumpLog) Values() []interface{} { + return []interface{}{ + s.DumpID, + s.ChunkID, + s.Data, + s.LastChunk, + } +} + +// Pointers returns a slice of pointers to struct or record fields. +// Returned interface{} values are never untyped nils. +func (s *DumpLog) Pointers() []interface{} { + return []interface{}{ + &s.DumpID, + &s.ChunkID, + &s.Data, + &s.LastChunk, + } +} + +// View returns View object for that struct. +func (s *DumpLog) View() reform.View { + return DumpLogView +} + +// check interfaces +var ( + _ reform.View = DumpLogView + _ reform.Struct = (*DumpLog)(nil) + _ fmt.Stringer = (*DumpLog)(nil) +) + +func init() { + parse.AssertUpToDate(&DumpTable.s, new(Dump)) + parse.AssertUpToDate(&DumpLogView.s, new(DumpLog)) +} diff --git a/managed/models/params.go b/managed/models/params.go new file mode 100644 index 0000000000..8121686d70 --- /dev/null +++ b/managed/models/params.go @@ -0,0 +1,35 @@ +// Copyright (C) 2023 Percona LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package models + +// HAParams defines parameters related to High Availability. +type HAParams struct { + GrafanaGossipPort int + Enabled bool + Bootstrap bool + NodeID string + AdvertiseAddress string + Nodes []string + RaftPort int + GossipPort int +} + +// Params defines parameters for supervisor. +type Params struct { + HAParams *HAParams + VMParams *VictoriaMetricsParams + PGParams *PGParams +} diff --git a/managed/services/agents/agents.go b/managed/services/agents/agents.go index efcc7b967c..17ad039e26 100644 --- a/managed/services/agents/agents.go +++ b/managed/services/agents/agents.go @@ -145,11 +145,11 @@ func ensureAuthParams(exporter *models.Agent, params *agentpb.SetStateRequest_Ag // getExporterListenAddress returns the appropriate listen address to use for a given exporter. func getExporterListenAddress(node *models.Node, exporter *models.Agent) string { switch { - case !exporter.PushMetrics && node != nil: - return node.Address case exporter.ExposeExporter: return "0.0.0.0" - default: + case exporter.PushMetrics: return "127.0.0.1" + default: + return "0.0.0.0" } } diff --git a/managed/services/agents/agents_test.go b/managed/services/agents/agents_test.go index 86ffc95b54..4c3115a551 100644 --- a/managed/services/agents/agents_test.go +++ b/managed/services/agents/agents_test.go @@ -51,33 +51,43 @@ func TestPathsBaseForDifferentVersions(t *testing.T) { } func TestGetExporterListenAddress(t *testing.T) { - t.Run("uses node address in pull mode", func(t *testing.T) { + t.Run("uses 127.0.0.1 in push mode", func(t *testing.T) { node := &models.Node{ Address: "1.2.3.4", } - exporter := &models.Agent{} + exporter := &models.Agent{ + PushMetrics: true, + } - assert.Equal(t, "1.2.3.4", getExporterListenAddress(node, exporter)) + assert.Equal(t, "127.0.0.1", getExporterListenAddress(node, exporter)) }) - t.Run("uses 127.0.0.1 in push mode", func(t *testing.T) { + t.Run("exposes exporter address when enabled in push mode", func(t *testing.T) { node := &models.Node{ Address: "1.2.3.4", } exporter := &models.Agent{ - PushMetrics: true, + PushMetrics: true, + ExposeExporter: true, } - assert.Equal(t, "127.0.0.1", getExporterListenAddress(node, exporter)) + assert.Equal(t, "0.0.0.0", getExporterListenAddress(node, exporter)) }) - t.Run("exposes exporter address when enabled", func(t *testing.T) { + t.Run("exposes exporter address when enabled in pull mode", func(t *testing.T) { node := &models.Node{ Address: "1.2.3.4", } exporter := &models.Agent{ - PushMetrics: true, + PushMetrics: false, ExposeExporter: true, } assert.Equal(t, "0.0.0.0", getExporterListenAddress(node, exporter)) }) + t.Run("exposes exporter address if node IP is unavailable in pull mode", func(t *testing.T) { + exporter := &models.Agent{ + PushMetrics: false, + } + + assert.Equal(t, "0.0.0.0", getExporterListenAddress(nil, exporter)) + }) } diff --git a/managed/services/agents/channel/channel.go b/managed/services/agents/channel/channel.go index cb2b6a66b5..5e36142352 100644 --- a/managed/services/agents/channel/channel.go +++ b/managed/services/agents/channel/channel.go @@ -17,6 +17,7 @@ package channel import ( + "context" "sync" "sync/atomic" @@ -66,13 +67,18 @@ type Response struct { Error error } +type Stream interface { + Send(*agentpb.ServerMessage) error + Recv() (*agentpb.AgentMessage, error) +} + // Channel encapsulates two-way communication channel between pmm-managed and pmm-agent. // // All exported methods are thread-safe. // //nolint:maligned type Channel struct { - s agentpb.Agent_ConnectServer + s Stream mSent, mRecv uint32 @@ -94,7 +100,7 @@ type Channel struct { // New creates new two-way communication channel with given stream. // // Stream should not be used by the caller after channel is created. -func New(stream agentpb.Agent_ConnectServer) *Channel { +func New(ctx context.Context, stream Stream) *Channel { s := &Channel{ s: stream, @@ -103,7 +109,7 @@ func New(stream agentpb.Agent_ConnectServer) *Channel { closeWait: make(chan struct{}), - l: logger.Get(stream.Context()), + l: logger.Get(ctx), } go s.runReceiver() diff --git a/managed/services/agents/channel/channel_test.go b/managed/services/agents/channel/channel_test.go index 0944d85936..f6e3851f0f 100644 --- a/managed/services/agents/channel/channel_test.go +++ b/managed/services/agents/channel/channel_test.go @@ -70,7 +70,7 @@ func setup(t *testing.T, connect func(*Channel) error, expected ...error) (agent agentpb.RegisterAgentServer(server, &testServer{ connectFunc: func(stream agentpb.Agent_ConnectServer) error { - channel = New(stream) + channel = New(stream.Context(), stream) return connect(channel) }, }) diff --git a/managed/services/agents/handler.go b/managed/services/agents/handler.go index 011ce90a84..c174b340c3 100644 --- a/managed/services/agents/handler.go +++ b/managed/services/agents/handler.go @@ -90,7 +90,7 @@ func (h *Handler) Run(stream agentpb.Agent_ConnectServer) error { } // see unregister and Kick methods - case <-agent.kick: + case <-agent.kickChan: // already unregistered, no need to call unregister method l.Warn("Kicked.") disconnectReason = "kicked" @@ -105,7 +105,7 @@ func (h *Handler) Run(stream agentpb.Agent_ConnectServer) error { if err != nil { l.Error(errors.WithStack(err)) } - return h.updateAgentStatusForChildren(ctx, agent.id, inventorypb.AgentStatus_DONE) + return nil } switch p := req.Payload.(type) { diff --git a/managed/services/agents/mongodb_test.go b/managed/services/agents/mongodb_test.go index 4c8ae1d56c..2f11b0940f 100644 --- a/managed/services/agents/mongodb_test.go +++ b/managed/services/agents/mongodb_test.go @@ -53,7 +53,7 @@ func TestMongodbExporterConfig225(t *testing.T) { "--compatible-mode", "--discovering-mode", "--mongodb.global-conn-pool", - "--web.listen-address=1.2.3.4:{{ .listen_port }}", + "--web.listen-address=0.0.0.0:{{ .listen_port }}", }, Env: []string{ "MONGODB_URI=mongodb://username:s3cur3%20p%40$$w0r4.@1.2.3.4:27017/?connectTimeoutMS=1000&directConnection=true&serverSelectionTimeoutMS=1000", @@ -78,7 +78,7 @@ func TestMongodbExporterConfig225(t *testing.T) { "--discovering-mode", "--mongodb.collstats-colls=col1,col2,col3", "--mongodb.global-conn-pool", - "--web.listen-address=1.2.3.4:{{ .listen_port }}", + "--web.listen-address=0.0.0.0:{{ .listen_port }}", } actual, err := mongodbExporterConfig(node, mongodb, exporter, exposeSecrets, pmmAgentVersion) require.NoError(t, err) @@ -113,7 +113,7 @@ func TestMongodbExporterConfig226(t *testing.T) { "--compatible-mode", "--discovering-mode", "--mongodb.global-conn-pool", - "--web.listen-address=1.2.3.4:{{ .listen_port }}", + "--web.listen-address=0.0.0.0:{{ .listen_port }}", }, Env: []string{ "MONGODB_URI=mongodb://username:s3cur3%20p%40$$w0r4.@1.2.3.4:27017/?connectTimeoutMS=1000&directConnection=true&serverSelectionTimeoutMS=1000", @@ -141,7 +141,7 @@ func TestMongodbExporterConfig226(t *testing.T) { "--mongodb.collstats-colls=col1,col2,col3", "--mongodb.global-conn-pool", "--mongodb.indexstats-colls=col1,col2,col3", - "--web.listen-address=1.2.3.4:{{ .listen_port }}", + "--web.listen-address=0.0.0.0:{{ .listen_port }}", } actual, err := mongodbExporterConfig(node, mongodb, exporter, exposeSecrets, pmmAgentVersion) require.NoError(t, err) @@ -168,7 +168,7 @@ func TestMongodbExporterConfig226(t *testing.T) { "--mongodb.collstats-colls=col1,col2,col3", "--mongodb.global-conn-pool", "--mongodb.indexstats-colls=col1,col2,col3", - "--web.listen-address=1.2.3.4:{{ .listen_port }}", + "--web.listen-address=0.0.0.0:{{ .listen_port }}", } actual, err := mongodbExporterConfig(node, mongodb, exporter, exposeSecrets, pmmAgentVersion) require.NoError(t, err) @@ -196,7 +196,7 @@ func TestMongodbExporterConfig226(t *testing.T) { "--mongodb.collstats-colls=db1.col1.one,db2.col2,db3", "--mongodb.global-conn-pool", "--mongodb.indexstats-colls=db1.col1.one,db2.col2,db3", - "--web.listen-address=1.2.3.4:{{ .listen_port }}", + "--web.listen-address=0.0.0.0:{{ .listen_port }}", } actual, err := mongodbExporterConfig(node, mongodb, exporter, exposeSecrets, pmmAgentVersion) require.NoError(t, err) @@ -223,7 +223,7 @@ func TestMongodbExporterConfig226(t *testing.T) { "--mongodb.collstats-colls=db1.col1.one,db2.col2,db3", "--mongodb.global-conn-pool", "--mongodb.indexstats-colls=db1.col1.one,db2.col2,db3", - "--web.listen-address=1.2.3.4:{{ .listen_port }}", + "--web.listen-address=0.0.0.0:{{ .listen_port }}", } actual, err := mongodbExporterConfig(node, mongodb, exporter, exposeSecrets, pmmAgentVersion) require.NoError(t, err) @@ -258,7 +258,7 @@ func TestMongodbExporterConfig(t *testing.T) { "--collect.topmetrics", "--no-collect.connpoolstats", "--no-collect.indexusage", - "--web.listen-address=1.2.3.4:{{ .listen_port }}", + "--web.listen-address=0.0.0.0:{{ .listen_port }}", }, Env: []string{ "MONGODB_URI=mongodb://username:s3cur3%20p%40$$w0r4.@1.2.3.4:27017/?connectTimeoutMS=1000&directConnection=true&serverSelectionTimeoutMS=1000", @@ -343,7 +343,7 @@ func TestMongodbExporterConfig(t *testing.T) { "--collect.database", "--no-collect.connpoolstats", "--no-collect.indexusage", - "--web.listen-address=1.2.3.4:{{ .listen_port }}", + "--web.listen-address=0.0.0.0:{{ .listen_port }}", }, } require.NoError(t, err) @@ -376,7 +376,7 @@ func TestNewMongodbExporterConfig(t *testing.T) { Args: []string{ "--compatible-mode", "--mongodb.global-conn-pool", - "--web.listen-address=1.2.3.4:{{ .listen_port }}", + "--web.listen-address=0.0.0.0:{{ .listen_port }}", }, Env: []string{ "MONGODB_URI=mongodb://username:s3cur3%20p%40$$w0r4.@1.2.3.4:27017/?connectTimeoutMS=1000&directConnection=true&serverSelectionTimeoutMS=1000", @@ -430,7 +430,7 @@ func TestMongodbExporterConfig228_WebConfigAuth(t *testing.T) { "--compatible-mode", "--discovering-mode", "--mongodb.global-conn-pool", - "--web.listen-address=1.2.3.4:{{ .listen_port }}", + "--web.listen-address=0.0.0.0:{{ .listen_port }}", "--web.config={{ .TextFiles.webConfigPlaceholder }}", } diff --git a/managed/services/agents/mysql_test.go b/managed/services/agents/mysql_test.go index 8a152a1328..b14d5a523f 100644 --- a/managed/services/agents/mysql_test.go +++ b/managed/services/agents/mysql_test.go @@ -88,7 +88,7 @@ func TestMySQLdExporterConfig(t *testing.T) { "--exporter.global-conn-pool", "--exporter.max-idle-conns=3", "--exporter.max-open-conns=3", - "--web.listen-address=1.2.3.4:{{ .listen_port }}", + "--web.listen-address=0.0.0.0:{{ .listen_port }}", }, Env: []string{ "DATA_SOURCE_NAME=username:s3cur3 p@$$w0r4.@tcp(1.2.3.4:3306)/?timeout=1s", @@ -193,7 +193,7 @@ func TestMySQLdExporterConfigTablestatsGroupDisabled(t *testing.T) { "--mysql.ssl-ca-file={{ .TextFiles.tlsCa }}", "--mysql.ssl-cert-file={{ .TextFiles.tlsCert }}", "--mysql.ssl-key-file={{ .TextFiles.tlsKey }}", - "--web.listen-address=1.2.3.4:{{ .listen_port }}", + "--web.listen-address=0.0.0.0:{{ .listen_port }}", }, Env: []string{ "DATA_SOURCE_NAME=username:s3cur3 p@$$w0r4.@tcp(1.2.3.4:3306)/?timeout=1s&tls=custom", @@ -292,7 +292,7 @@ func TestMySQLdExporterConfigDisabledCollectors(t *testing.T) { "--exporter.global-conn-pool", "--exporter.max-idle-conns=3", "--exporter.max-open-conns=3", - "--web.listen-address=1.2.3.4:{{ .listen_port }}", + "--web.listen-address=0.0.0.0:{{ .listen_port }}", }, Env: []string{ "DATA_SOURCE_NAME=username:s3cur3 p@$$w0r4.@tcp(1.2.3.4:3306)/?timeout=1s", diff --git a/managed/services/agents/node_test.go b/managed/services/agents/node_test.go index d82350e0ec..9d0889b631 100644 --- a/managed/services/agents/node_test.go +++ b/managed/services/agents/node_test.go @@ -164,7 +164,7 @@ func TestNodeExporterConfig(t *testing.T) { "--no-collector.xfs", "--no-collector.zfs", "--web.disable-exporter-metrics", - "--web.listen-address=1.2.3.4:{{ .listen_port }}", + "--web.listen-address=0.0.0.0:{{ .listen_port }}", }, Env: []string{ "HTTP_AUTH=pmm:agent-id", @@ -247,7 +247,7 @@ func TestNodeExporterConfig(t *testing.T) { "--no-collector.xfs", "--no-collector.zfs", "--web.disable-exporter-metrics", - "--web.listen-address=:{{ .listen_port }}", + "--web.listen-address=0.0.0.0:{{ .listen_port }}", }, Env: []string{ "HTTP_AUTH=pmm:agent-id", @@ -282,7 +282,7 @@ func TestNodeExporterConfig(t *testing.T) { "--collector.textfile.directory.lr=" + pathsBase(agentVersion, "{{", "}}") + "/collectors/textfile-collector/low-resolution", "--collector.textfile.directory.mr=" + pathsBase(agentVersion, "{{", "}}") + "/collectors/textfile-collector/medium-resolution", "--web.disable-exporter-metrics", - "--web.listen-address=:{{ .listen_port }}", + "--web.listen-address=0.0.0.0:{{ .listen_port }}", }, Env: []string{ "HTTP_AUTH=pmm:agent-id", diff --git a/managed/services/agents/postgresql_test.go b/managed/services/agents/postgresql_test.go index 442f808458..d2206ccd8a 100644 --- a/managed/services/agents/postgresql_test.go +++ b/managed/services/agents/postgresql_test.go @@ -66,7 +66,7 @@ func (s *PostgresExporterConfigTestSuite) SetupTest() { "--collect.custom_query.lr.directory=" + pathsBase(s.pmmAgentVersion, "{{", "}}") + "/collectors/custom-queries/postgresql/low-resolution", "--collect.custom_query.mr", "--collect.custom_query.mr.directory=" + pathsBase(s.pmmAgentVersion, "{{", "}}") + "/collectors/custom-queries/postgresql/medium-resolution", - "--web.listen-address=1.2.3.4:{{ .listen_port }}", + "--web.listen-address=0.0.0.0:{{ .listen_port }}", }, Env: []string{ "DATA_SOURCE_NAME=postgres://username:s3cur3%20p%40$$w0r4.@1.2.3.4:5432/postgres?connect_timeout=1&sslmode=disable", @@ -167,7 +167,7 @@ func (s *PostgresExporterConfigTestSuite) TestDisabledCollectors() { "--collect.custom_query.lr.directory=" + pathsBase(s.pmmAgentVersion, "{{", "}}") + "/collectors/custom-queries/postgresql/low-resolution", "--collect.custom_query.mr", "--collect.custom_query.mr.directory=" + pathsBase(s.pmmAgentVersion, "{{", "}}") + "/collectors/custom-queries/postgresql/medium-resolution", - "--web.listen-address=1.2.3.4:{{ .listen_port }}", + "--web.listen-address=0.0.0.0:{{ .listen_port }}", }, } requireNoDuplicateFlags(s.T(), actual.Args) @@ -205,7 +205,7 @@ func TestAutoDiscovery(t *testing.T) { "--collect.custom_query.lr.directory=" + pathsBase(pmmAgentVersion, "{{", "}}") + "/collectors/custom-queries/postgresql/low-resolution", "--collect.custom_query.mr", "--collect.custom_query.mr.directory=" + pathsBase(pmmAgentVersion, "{{", "}}") + "/collectors/custom-queries/postgresql/medium-resolution", - "--web.listen-address=1.2.3.4:{{ .listen_port }}", + "--web.listen-address=0.0.0.0:{{ .listen_port }}", }, Env: []string{ "DATA_SOURCE_NAME=postgres://username:s3cur3%20p%40$$w0r4.@1.2.3.4:5432/postgres?connect_timeout=1&sslmode=disable", @@ -324,7 +324,7 @@ func (s *PostgresExporterConfigTestSuite) TestAzureTimeout() { "--collect.custom_query.mr", "--collect.custom_query.mr.directory=" + pathsBase(s.pmmAgentVersion, "{{", "}}") + "/collectors/custom-queries/postgresql/medium-resolution", "--exclude-databases=template0,template1,postgres,cloudsqladmin,pmm-managed-dev,azure_maintenance,rdsadmin", - "--web.listen-address=1.2.3.4:{{ .listen_port }}", + "--web.listen-address=0.0.0.0:{{ .listen_port }}", }, Env: []string{ "DATA_SOURCE_NAME=postgres://username:s3cur3%20p%40$$w0r4.@1.2.3.4:5432/postgres?connect_timeout=5&sslmode=disable", @@ -370,7 +370,7 @@ func (s *PostgresExporterConfigTestSuite) TestPrometheusWebConfig() { "--collect.custom_query.mr", "--collect.custom_query.mr.directory=" + pathsBase(s.pmmAgentVersion, "{{", "}}") + "/collectors/custom-queries/postgresql/medium-resolution", "--exclude-databases=template0,template1,postgres,cloudsqladmin,pmm-managed-dev,azure_maintenance,rdsadmin", - "--web.listen-address=1.2.3.4:{{ .listen_port }}", + "--web.listen-address=0.0.0.0:{{ .listen_port }}", "--web.config={{ .TextFiles.webConfigPlaceholder }}", }, Env: []string{ @@ -419,7 +419,7 @@ func (s *PostgresExporterConfigTestSuite) TestSSLSni() { "--collect.custom_query.mr", "--collect.custom_query.mr.directory=" + pathsBase(s.pmmAgentVersion, "{{", "}}") + "/collectors/custom-queries/postgresql/medium-resolution", "--exclude-databases=template0,template1,postgres,cloudsqladmin,pmm-managed-dev,azure_maintenance,rdsadmin", - "--web.listen-address=1.2.3.4:{{ .listen_port }}", + "--web.listen-address=0.0.0.0:{{ .listen_port }}", "--web.config={{ .TextFiles.webConfigPlaceholder }}", }, Env: []string{ diff --git a/managed/services/agents/proxysql_test.go b/managed/services/agents/proxysql_test.go index 5c979dfac5..7e608169ba 100644 --- a/managed/services/agents/proxysql_test.go +++ b/managed/services/agents/proxysql_test.go @@ -55,7 +55,7 @@ func TestProxySQLExporterConfig(t *testing.T) { "-collect.mysql_connection_pool", "-collect.mysql_status", "-collect.stats_memory_metrics", - "-web.listen-address=1.2.3.4:{{ .listen_port }}", + "-web.listen-address=0.0.0.0:{{ .listen_port }}", }, Env: []string{ "DATA_SOURCE_NAME=username:s3cur3 p@$$w0r4.@tcp(1.2.3.4:3306)/?timeout=1s", @@ -89,7 +89,7 @@ func TestProxySQLExporterConfig(t *testing.T) { Args: []string{ "-collect.mysql_connection_pool", "-collect.mysql_status", - "-web.listen-address=1.2.3.4:{{ .listen_port }}", + "-web.listen-address=0.0.0.0:{{ .listen_port }}", }, } require.Equal(t, expected.Args, actual.Args) @@ -120,7 +120,7 @@ func TestProxySQLExporterConfig(t *testing.T) { "-collect.mysql_status", "-collect.stats_command_counter", "-collect.stats_memory_metrics", - "-web.listen-address=1.2.3.4:{{ .listen_port }}", + "-web.listen-address=0.0.0.0:{{ .listen_port }}", }, Env: []string{ "DATA_SOURCE_NAME=username:s3cur3 p@$$w0r4.@tcp(1.2.3.4:3306)/?timeout=1s", @@ -161,7 +161,7 @@ func TestProxySQLExporterConfig(t *testing.T) { "-collect.runtime_mysql_servers", "-collect.stats_command_counter", "-collect.stats_memory_metrics", - "-web.listen-address=1.2.3.4:{{ .listen_port }}", + "-web.listen-address=0.0.0.0:{{ .listen_port }}", }, Env: []string{ "DATA_SOURCE_NAME=username:s3cur3 p@$$w0r4.@tcp(1.2.3.4:3306)/?timeout=1s", diff --git a/managed/services/agents/registry.go b/managed/services/agents/registry.go index 9f381c8ed8..6db039248f 100644 --- a/managed/services/agents/registry.go +++ b/managed/services/agents/registry.go @@ -68,7 +68,7 @@ type pmmAgentInfo struct { channel *channel.Channel id string stateChangeChan chan struct{} - kick chan struct{} + kickChan chan struct{} } // Registry keeps track of all connected pmm-agents. @@ -199,10 +199,10 @@ func (r *Registry) register(stream agentpb.Agent_ConnectServer) (*pmmAgentInfo, defer r.rw.Unlock() agent := &pmmAgentInfo{ - channel: channel.New(stream), + channel: channel.New(ctx, stream), id: agentMD.ID, stateChangeChan: make(chan struct{}, 1), - kick: make(chan struct{}), + kickChan: make(chan struct{}), } r.agents[agentMD.ID] = agent return agent, nil @@ -371,10 +371,10 @@ func (r *Registry) Kick(ctx context.Context, pmmAgentID string) { l.Debugf("pmm-agent with ID %q will be kicked in a moment.", pmmAgentID) // see Run method - close(agent.kick) + close(agent.kickChan) // Do not close agent.stateChangeChan to avoid breaking RequestStateUpdate; - // closing agent.kick is enough to exit runStateChangeHandler goroutine. + // closing agent.kickChan is enough to exit runStateChangeHandler goroutine. } func (r *Registry) get(pmmAgentID string) (*pmmAgentInfo, error) { @@ -417,6 +417,12 @@ func (r *Registry) Collect(ch chan<- prom.Metric) { r.mClockDrift.Collect(ch) } +func (r *Registry) KickAll(ctx context.Context) { + for _, agentInfo := range r.agents { + r.Kick(ctx, agentInfo.id) + } +} + // check interfaces. var ( _ prom.Collector = (*Registry)(nil) diff --git a/managed/services/agents/state.go b/managed/services/agents/state.go index 49ad75ecbb..d7ad55ea4c 100644 --- a/managed/services/agents/state.go +++ b/managed/services/agents/state.go @@ -113,7 +113,7 @@ func (u *StateUpdater) runStateChangeHandler(ctx context.Context, agent *pmmAgen case <-ctx.Done(): return - case <-agent.kick: + case <-agent.kickChan: return case <-agent.stateChangeChan: @@ -226,7 +226,7 @@ func (u *StateUpdater) sendSetStateRequest(ctx context.Context, agent *pmmAgentI if err != nil { return err } - node, _ := models.FindNodeByID(u.db.Querier, pointer.GetString(row.NodeID)) + node, _ := models.FindNodeByID(u.db.Querier, pointer.GetString(pmmAgent.RunsOnNodeID)) switch row.AgentType { //nolint:exhaustive case models.MySQLdExporterType: agentProcesses[row.AgentID] = mysqldExporterConfig(node, service, row, redactMode, pmmAgentVersion) diff --git a/managed/services/backup/backup_service.go b/managed/services/backup/backup_service.go index 2eaa58ad40..f94549ed26 100644 --- a/managed/services/backup/backup_service.go +++ b/managed/services/backup/backup_service.go @@ -226,7 +226,7 @@ func (s *Service) PerformBackup(ctx context.Context, params PerformBackupParams) err = status.Errorf(codes.Unknown, "Unknown service: %s", svc.ServiceType) } if err != nil { - var target *models.AgentNotSupportedError + var target models.AgentNotSupportedError if errors.As(err, &target) { _, dbErr := models.UpdateArtifact(s.db.Querier, artifact.ID, models.UpdateArtifactParams{ Status: models.ErrorBackupStatus.Pointer(), diff --git a/managed/services/backup/compatibility_service.go b/managed/services/backup/compatibility_service.go index c37cf10cef..ffb0dbded7 100644 --- a/managed/services/backup/compatibility_service.go +++ b/managed/services/backup/compatibility_service.go @@ -161,7 +161,7 @@ func (s *CompatibilityService) CheckSoftwareCompatibilityForService(ctx context. if serviceModel.ServiceType == models.MongoDBServiceType { if err := models.PMMAgentSupported(s.db.Querier, agentModel.AgentID, "get mongodb backup software versions", pmmAgentMinVersionForMongoBackupSoftwareCheck); err != nil { - var agentNotSupportedError *models.AgentNotSupportedError + var agentNotSupportedError models.AgentNotSupportedError if errors.As(err, &agentNotSupportedError) { s.l.Warnf("Got versioner error message: %s.", err.Error()) return "", nil diff --git a/managed/services/dump/dump.go b/managed/services/dump/dump.go new file mode 100644 index 0000000000..4f028eb452 --- /dev/null +++ b/managed/services/dump/dump.go @@ -0,0 +1,299 @@ +// Copyright (C) 2023 Percona LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +// Package dump wraps pmm-dump integration. +package dump + +import ( + "bufio" + "context" + "fmt" + "io" + "os" + "os/exec" + "path/filepath" + "sync" + "sync/atomic" + "time" + + "github.com/pkg/errors" + "github.com/sirupsen/logrus" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + "gopkg.in/reform.v1" + + "github.com/percona/pmm/managed/models" +) + +var ErrDumpAlreadyRunning = status.Error(codes.FailedPrecondition, "pmm-dump already running.") + +const ( + pmmDumpBin = "pmm-dump" + dumpsDir = "/srv/dump" +) + +type Service struct { + l *logrus.Entry + + db *reform.DB + + running atomic.Bool + + rw sync.RWMutex + cancel context.CancelFunc +} + +func New(db *reform.DB) *Service { + return &Service{ + l: logrus.WithField("component", "management/backup/backup"), + db: db, + } +} + +type Params struct { + APIKey string + Cookie string + User string + Password string + ServiceNames []string + StartTime *time.Time + EndTime *time.Time + ExportQAN bool + IgnoreLoad bool +} + +func (s *Service) StartDump(params *Params) (string, error) { + // Check if some pmm-dump already running. + if !s.running.CompareAndSwap(false, true) { + return "", ErrDumpAlreadyRunning + } + + dump, err := models.CreateDump(s.db.Querier, models.CreateDumpParams{ + ServiceNames: params.ServiceNames, + StartTime: params.StartTime, + EndTime: params.EndTime, + ExportQAN: params.ExportQAN, + IgnoreLoad: params.IgnoreLoad, + }) + if err != nil { + s.running.Store(false) + return "", errors.Wrap(err, "failed to create dump") + } + + l := s.l.WithField("dump_id", dump.ID) + + ctx, cancel := context.WithCancel(context.Background()) + + s.rw.Lock() + s.cancel = cancel + s.rw.Unlock() + + pmmDumpCmd := exec.CommandContext(ctx, //nolint:gosec + pmmDumpBin, + "export", + "--pmm-url=http://127.0.0.1", + fmt.Sprintf("--dump-path=%s", getDumpFilePath(dump.ID))) + + if params.APIKey != "" { + pmmDumpCmd.Args = append(pmmDumpCmd.Args, fmt.Sprintf(`--pmm-token=%s`, params.APIKey)) + } + + if params.Cookie != "" { + pmmDumpCmd.Args = append(pmmDumpCmd.Args, fmt.Sprintf(`--pmm-cookie=%s`, params.Cookie)) + } + + if params.User != "" { + pmmDumpCmd.Args = append(pmmDumpCmd.Args, fmt.Sprintf(`--pmm-user=%s`, params.User)) + pmmDumpCmd.Args = append(pmmDumpCmd.Args, fmt.Sprintf(`--pmm-pass=%s`, params.Password)) + } + + for _, serviceName := range params.ServiceNames { + pmmDumpCmd.Args = append(pmmDumpCmd.Args, fmt.Sprintf("--instance=%s", serviceName)) + } + + if params.StartTime != nil { + pmmDumpCmd.Args = append(pmmDumpCmd.Args, fmt.Sprintf("--start-ts=%s", params.StartTime.Format(time.RFC3339))) + } + + if params.EndTime != nil { + pmmDumpCmd.Args = append(pmmDumpCmd.Args, fmt.Sprintf("--end-ts=%s", params.EndTime.Format(time.RFC3339))) + } + + if params.ExportQAN { + pmmDumpCmd.Args = append(pmmDumpCmd.Args, "--dump-qan") + } + + if params.IgnoreLoad { + pmmDumpCmd.Args = append(pmmDumpCmd.Args, "--ignore-load") + } + + pReader, pWriter := io.Pipe() + pmmDumpCmd.Stdout = pWriter + pmmDumpCmd.Stderr = pWriter + + go func() { + defer pReader.Close() //nolint:errcheck + + err := s.persistLogs(dump.ID, pReader) + if err != nil && !errors.Is(err, context.Canceled) { + l.Errorf("Dump logs persisting failed: %v", err) + } + + l.Info("Dump logs saved.") + }() + + go func() { + // Switch running flag back to false + defer s.running.Store(false) + defer s.cancel() + defer pWriter.Close() //nolint:errcheck + + err := pmmDumpCmd.Run() + if err != nil { + l.Errorf("Failed to execute pmm-dump: %v", err) + + s.setDumpStatus(dump.ID, models.DumpStatusError) + return + } + + s.setDumpStatus(dump.ID, models.DumpStatusSuccess) + l.WithField("dump_id", dump.ID).Info("Dump done.") + }() + + return dump.ID, nil +} + +func (s *Service) DeleteDump(dumpID string) error { + dump, err := models.FindDumpByID(s.db.Querier, dumpID) + if err != nil { + return errors.Wrap(err, "failed to find dump") + } + + filePath := getDumpFilePath(dump.ID) + err = validateFilePath(filePath) + if err != nil && !errors.Is(err, os.ErrNotExist) { + return errors.WithStack(err) + } + + err = os.Remove(filePath) + if err != nil && !errors.Is(err, os.ErrNotExist) { + return errors.Wrap(err, "failed to remove pmm-dump files") + } + + if err = models.DeleteDump(s.db.Querier, dumpID); err != nil { + return errors.Wrap(err, "failed to delete dump") + } + + return nil +} + +func (s *Service) GetFilePathsForDumps(dumpIDs []string) (map[string]string, error) { + dumps, err := models.FindDumpsByIDs(s.db.Querier, dumpIDs) + if err != nil { + return nil, err + } + + res := make(map[string]string, len(dumps)) + for _, d := range dumps { + if d.Status != models.DumpStatusSuccess { + s.l.Warnf("Dump with id %s is in %s state. Skiping it.", d.ID, d.Status) + continue + } + filePath := getDumpFilePath(d.ID) + if err = validateFilePath(filePath); err != nil { + return nil, errors.WithStack(err) + } + + res[d.ID] = filePath + } + + return res, nil +} + +func (s *Service) setDumpStatus(dumpID string, status models.DumpStatus) { + if err := s.db.InTransaction(func(t *reform.TX) error { + return models.UpdateDumpStatus(t.Querier, dumpID, status) + }); err != nil { + s.l.Warnf("Failed to update dupm status: %+v", err) + } +} + +func (s *Service) persistLogs(dumpID string, r io.Reader) error { + scanner := bufio.NewScanner(r) + var err error + var chunkN uint32 + + for scanner.Scan() { + nErr := s.saveLogChunk(dumpID, atomic.AddUint32(&chunkN, 1)-1, scanner.Text(), false) + if nErr != nil { + s.l.Warnf("failed to read pmm-dump logs: %v", err) + return errors.WithStack(nErr) + } + } + + if err = scanner.Err(); err != nil { + s.l.Warnf("Failed to read pmm-dump logs: %+v", err) + nErr := s.saveLogChunk(dumpID, atomic.AddUint32(&chunkN, 1)-1, err.Error(), false) + if nErr != nil { + return errors.WithStack(nErr) + } + } + + nErr := s.saveLogChunk(dumpID, atomic.AddUint32(&chunkN, 1)-1, "", true) + if nErr != nil { + return errors.WithStack(nErr) + } + + return nil +} + +func (s *Service) saveLogChunk(dumpID string, chunkN uint32, text string, last bool) error { + if _, err := models.CreateDumpLog(s.db.Querier, models.CreateDumpLogParams{ + DumpID: dumpID, + ChunkID: atomic.AddUint32(&chunkN, 1) - 1, + Data: text, + LastChunk: last, + }); err != nil { + return errors.Wrap(err, "failed to save pmm-dump log chunk") + } + + return nil +} + +func (s *Service) StopDump() { + s.rw.RLock() + defer s.rw.RUnlock() + + s.cancel() +} + +func getDumpFilePath(id string) string { + return fmt.Sprintf("%s/%s.tar.gz", dumpsDir, id) +} + +func validateFilePath(path string) error { + c := filepath.Clean(path) + r, err := filepath.EvalSymlinks(c) + if err != nil { + return errors.Wrap(err, "unsafe or invalid dump filepath") + } + + if path != r { + return errors.Errorf("actual file path doesn't match expected, that may be caused by symlinks "+ + "of path traversal, expected path: %s, actual: %s", path, r) + } + + return nil +} diff --git a/managed/services/grafana/auth_server.go b/managed/services/grafana/auth_server.go index 2a599805dc..0eb6842244 100644 --- a/managed/services/grafana/auth_server.go +++ b/managed/services/grafana/auth_server.go @@ -73,8 +73,9 @@ var rules = map[string]role{ "/v1/user": viewer, // must be available without authentication for health checking - "/v1/readyz": none, - "/ping": none, // PMM 1.x variant + "/v1/readyz": none, + "/v1/leaderHealthCheck": none, + "/ping": none, // PMM 1.x variant // must not be available without authentication as it can leak data "/v1/version": viewer, diff --git a/managed/services/ha/highavailability.go b/managed/services/ha/highavailability.go new file mode 100644 index 0000000000..cec144b4d8 --- /dev/null +++ b/managed/services/ha/highavailability.go @@ -0,0 +1,318 @@ +// Copyright (C) 2023 Percona LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +// Package ha contains everything related to high availability. +package ha + +import ( + "context" + "fmt" + "io" + "net" + "strconv" + "sync" + "time" + + "github.com/hashicorp/memberlist" + "github.com/hashicorp/raft" + "github.com/sirupsen/logrus" + + "github.com/percona/pmm/managed/models" +) + +type Service struct { + params *models.HAParams + bootstrapCluster bool + + services *services + + receivedMessages chan []byte + nodeCh chan memberlist.NodeEvent + leaderCh chan raft.Observation + + l *logrus.Entry + wg *sync.WaitGroup + + rw sync.RWMutex + raftNode *raft.Raft + memberlist *memberlist.Memberlist +} + +func (s *Service) Apply(logEntry *raft.Log) interface{} { + s.l.Printf("raft: got a message: %s", string(logEntry.Data)) + s.receivedMessages <- logEntry.Data + return nil +} + +func (s *Service) Snapshot() (raft.FSMSnapshot, error) { //nolint:ireturn + return nil, nil +} + +func (s *Service) Restore(_ io.ReadCloser) error { + return nil +} + +func New(params *models.HAParams) *Service { + return &Service{ + params: params, + bootstrapCluster: params.Bootstrap, + services: newServices(), + nodeCh: make(chan memberlist.NodeEvent, 5), + leaderCh: make(chan raft.Observation), + receivedMessages: make(chan []byte), + l: logrus.WithField("component", "ha"), + wg: &sync.WaitGroup{}, + } +} + +func (s *Service) Run(ctx context.Context) error { + s.wg.Add(1) + go func() { + defer s.wg.Done() + for { + select { + case <-s.services.Refresh(): + if s.IsLeader() { + s.services.StartAllServices(ctx) + } + case <-ctx.Done(): + s.services.StopRunningServices() + return + } + } + }() + + if !s.params.Enabled { + return nil + } + + s.l.Infoln("Starting...") + defer s.l.Infoln("Done.") + + // Create the Raft configuration + raftConfig := raft.DefaultConfig() + raftConfig.LocalID = raft.ServerID(s.params.NodeID) + raftConfig.LogLevel = "DEBUG" + + // Create a new Raft transport + raa, err := net.ResolveTCPAddr("", net.JoinHostPort(s.params.AdvertiseAddress, strconv.Itoa(s.params.RaftPort))) + if err != nil { + return err + } + raftTrans, err := raft.NewTCPTransport(net.JoinHostPort("0.0.0.0", strconv.Itoa(s.params.RaftPort)), raa, 3, 10*time.Second, nil) + if err != nil { + return err + } + + // Create a new Raft node + s.rw.Lock() + s.raftNode, err = raft.NewRaft(raftConfig, s, raft.NewInmemStore(), raft.NewInmemStore(), raft.NewInmemSnapshotStore(), raftTrans) + s.rw.Unlock() + if err != nil { + return err + } + defer func() { + if s.IsLeader() { + s.raftNode.LeadershipTransfer() + } + err := s.raftNode.Shutdown().Error() + if err != nil { + s.l.Errorf("error during the shutdown of raft node: %q", err) + } + }() + + // Create the memberlist configuration + memberlistConfig := memberlist.DefaultWANConfig() + memberlistConfig.Name = s.params.NodeID + memberlistConfig.BindAddr = "0.0.0.0" + memberlistConfig.BindPort = s.params.GossipPort + memberlistConfig.AdvertiseAddr = raa.IP.String() + memberlistConfig.AdvertisePort = s.params.GossipPort + memberlistConfig.Events = &memberlist.ChannelEventDelegate{Ch: s.nodeCh} + + // Create the memberlist + s.memberlist, err = memberlist.Create(memberlistConfig) + if err != nil { + return fmt.Errorf("failed to create memberlist: %w", err) + } + defer func() { + err := s.memberlist.Leave(5 * time.Second) + if err != nil { + s.l.Errorf("couldn't leave memberlist cluster: %q", err) + } + err = s.memberlist.Shutdown() + if err != nil { + s.l.Errorf("couldn't shutdown memberlist listeners: %q", err) + } + }() + + if s.bootstrapCluster { + // Start the Raft node + cfg := raft.Configuration{ + Servers: []raft.Server{ + { + Suffrage: raft.Voter, + ID: raft.ServerID(s.params.NodeID), + Address: raft.ServerAddress(raa.String()), + }, + }, + } + if err := s.raftNode.BootstrapCluster(cfg).Error(); err != nil { + return fmt.Errorf("failed to bootstrap Raft cluster: %w", err) + } + } + if len(s.params.Nodes) != 0 { + _, err := s.memberlist.Join(s.params.Nodes) + if err != nil { + return fmt.Errorf("failed to join memberlist cluster: %w", err) + } + } + s.wg.Add(1) + go func() { + defer s.wg.Done() + s.runLeaderObserver(ctx) + }() + + s.wg.Add(1) + go func() { + defer s.wg.Done() + s.runRaftNodesSynchronizer(ctx) + }() + + <-ctx.Done() + + s.services.Wait() + s.wg.Wait() + + return nil +} + +func (s *Service) runRaftNodesSynchronizer(ctx context.Context) { + t := time.NewTicker(5 * time.Second) + + for { + select { + case event := <-s.nodeCh: + if !s.IsLeader() { + continue + } + node := event.Node + switch event.Event { + case memberlist.NodeJoin: + s.addMemberlistNodeToRaft(node) + case memberlist.NodeLeave: + s.removeMemberlistNodeFromRaft(node) + case memberlist.NodeUpdate: + continue + } + case <-t.C: + if !s.IsLeader() { + continue + } + servers := s.raftNode.GetConfiguration().Configuration().Servers + raftServers := make(map[string]struct{}) + for _, server := range servers { + raftServers[string(server.ID)] = struct{}{} + } + members := s.memberlist.Members() + s.l.Infof("memberlist members: %v", members) + for _, node := range members { + if _, ok := raftServers[node.Name]; !ok { + s.addMemberlistNodeToRaft(node) + } + } + case <-ctx.Done(): + t.Stop() + return + } + } +} + +func (s *Service) removeMemberlistNodeFromRaft(node *memberlist.Node) { + s.rw.RLock() + defer s.rw.RUnlock() + err := s.raftNode.RemoveServer(raft.ServerID(node.Name), 0, 10*time.Second).Error() + if err != nil { + s.l.Errorln(err) + } +} + +func (s *Service) addMemberlistNodeToRaft(node *memberlist.Node) { + s.rw.RLock() + defer s.rw.RUnlock() + err := s.raftNode.AddVoter(raft.ServerID(node.Name), raft.ServerAddress(fmt.Sprintf("%s:%d", node.Addr.String(), s.params.RaftPort)), 0, 10*time.Second).Error() + if err != nil { + s.l.Errorf("couldn't add a server node %s: %q", node.Name, err) + } +} + +func (s *Service) runLeaderObserver(ctx context.Context) { + t := time.NewTicker(5 * time.Second) + for { + s.rw.RLock() + node := s.raftNode + s.rw.RUnlock() + select { + case isLeader := <-node.LeaderCh(): + if isLeader { + s.services.StartAllServices(ctx) + // This node is the leader + s.l.Printf("I am the leader!") + peers := s.memberlist.Members() + for _, peer := range peers { + if peer.Name == s.params.NodeID { + continue + } + s.addMemberlistNodeToRaft(peer) + } + } else { + s.l.Printf("I am not a leader!") + s.services.StopRunningServices() + } + case <-t.C: + address, serverID := s.raftNode.LeaderWithID() + s.l.Infof("Leader is %s on %s", serverID, address) + case <-ctx.Done(): + return + } + } +} + +func (s *Service) AddLeaderService(leaderService LeaderService) { + err := s.services.Add(leaderService) + if err != nil { + s.l.Errorf("couldn't add HA service: +%v", err) + } +} + +func (s *Service) BroadcastMessage(message []byte) { + if s.params.Enabled { + s.rw.RLock() + defer s.rw.RUnlock() + s.raftNode.Apply(message, 3*time.Second) + } else { + s.receivedMessages <- message + } +} + +func (s *Service) IsLeader() bool { + s.rw.RLock() + defer s.rw.RUnlock() + return (s.raftNode != nil && s.raftNode.State() == raft.Leader) || !s.params.Enabled +} + +func (s *Service) Bootstrap() bool { + return s.params.Bootstrap || !s.params.Enabled +} diff --git a/managed/services/ha/leaderservice.go b/managed/services/ha/leaderservice.go new file mode 100644 index 0000000000..9ec5185629 --- /dev/null +++ b/managed/services/ha/leaderservice.go @@ -0,0 +1,87 @@ +// Copyright (C) 2023 Percona LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package ha + +import ( + "context" + "sync" +) + +type LeaderService interface { + Start(ctx context.Context) error + Stop() + ID() string +} + +type StandardService struct { + id string + + startFunc func(context.Context) error + stopFunc func() +} + +func NewStandardService(id string, startFunc func(context.Context) error, stopFunc func()) *StandardService { + return &StandardService{ + id: id, + startFunc: startFunc, + stopFunc: stopFunc, + } +} + +func (s *StandardService) ID() string { + return s.id +} + +func (s *StandardService) Start(ctx context.Context) error { + return s.startFunc(ctx) +} + +func (s *StandardService) Stop() { + s.stopFunc() +} + +type ContextService struct { + id string + + startFunc func(context.Context) error + + m sync.Mutex + cancel context.CancelFunc +} + +func NewContextService(id string, startFunc func(context.Context) error) *ContextService { + return &ContextService{ + id: id, + startFunc: startFunc, + } +} + +func (s *ContextService) ID() string { + return s.id +} + +func (s *ContextService) Start(ctx context.Context) error { + s.m.Lock() + ctx, s.cancel = context.WithCancel(ctx) + s.m.Unlock() + return s.startFunc(ctx) +} + +func (s *ContextService) Stop() { + s.m.Lock() + defer s.m.Unlock() + s.cancel() +} diff --git a/managed/services/ha/services.go b/managed/services/ha/services.go new file mode 100644 index 0000000000..eabc233c8a --- /dev/null +++ b/managed/services/ha/services.go @@ -0,0 +1,107 @@ +// Copyright (C) 2023 Percona LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package ha + +import ( + "context" + "fmt" + "sync" + + "github.com/sirupsen/logrus" +) + +type services struct { + wg sync.WaitGroup + + rw sync.Mutex + all map[string]LeaderService + running map[string]LeaderService + + refresh chan struct{} + + l *logrus.Entry +} + +func newServices() *services { + return &services{ + all: make(map[string]LeaderService), + running: make(map[string]LeaderService), + refresh: make(chan struct{}), + l: logrus.WithField("component", "ha-services"), + } +} + +func (s *services) Add(service LeaderService) error { + s.rw.Lock() + defer s.rw.Unlock() + + id := service.ID() + if _, ok := s.all[id]; ok { + return fmt.Errorf("service with id %s is already exist", id) + } + s.all[id] = service + select { + case s.refresh <- struct{}{}: + default: + } + return nil +} + +func (s *services) StartAllServices(ctx context.Context) { + s.rw.Lock() + defer s.rw.Unlock() + + for id, service := range s.all { + if _, ok := s.running[id]; !ok { + s.wg.Add(1) + s.running[id] = service + ls := service + go func() { + s.l.Infoln("Starting ", ls.ID()) + err := ls.Start(ctx) + if err != nil { + s.l.Errorln(err) + } + }() + } + } +} + +func (s *services) StopRunningServices() { + s.rw.Lock() + defer s.rw.Unlock() + + for id, service := range s.running { + id := id + ls := service + go func() { + defer s.wg.Done() + s.l.Infoln("Stopping ", ls) + ls.Stop() + s.rw.Lock() + defer s.rw.Unlock() + delete(s.running, id) + }() + } +} + +func (s *services) Refresh() chan struct{} { + return s.refresh +} + +func (s *services) Wait() { + s.wg.Wait() +} diff --git a/managed/services/management/backup/backups_service.go b/managed/services/management/backup/backups_service.go index cc91f1beb8..eb5492983e 100644 --- a/managed/services/management/backup/backups_service.go +++ b/managed/services/management/backup/backups_service.go @@ -652,7 +652,7 @@ func convertError(e error) error { return nil } - var unsupportedAgentErr *models.AgentNotSupportedError + var unsupportedAgentErr models.AgentNotSupportedError if errors.As(e, &unsupportedAgentErr) { return status.Error(codes.FailedPrecondition, e.Error()) } diff --git a/managed/services/management/dump/deps.go b/managed/services/management/dump/deps.go new file mode 100644 index 0000000000..b774f32065 --- /dev/null +++ b/managed/services/management/dump/deps.go @@ -0,0 +1,26 @@ +// Copyright (C) 2023 Percona LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package dump + +import "github.com/percona/pmm/managed/services/dump" + +//go:generate ../../../../bin/mockery --name=dumpService --case=snake --inpackage --testonly + +type dumpService interface { + StartDump(params *dump.Params) (string, error) + DeleteDump(dumpID string) error + GetFilePathsForDumps(dumpIDs []string) (map[string]string, error) +} diff --git a/managed/services/management/dump/dump.go b/managed/services/management/dump/dump.go new file mode 100644 index 0000000000..6ea6026c6b --- /dev/null +++ b/managed/services/management/dump/dump.go @@ -0,0 +1,308 @@ +// Copyright (C) 2023 Percona LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +// Package dump exposes PMM Dump API. +package dump + +import ( + "bufio" + "context" + "encoding/base64" + "os" + "path" + "path/filepath" + "strings" + + "github.com/AlekSi/pointer" + "github.com/pkg/errors" + "github.com/pkg/sftp" + "github.com/sirupsen/logrus" + "golang.org/x/crypto/ssh" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/types/known/timestamppb" + "gopkg.in/reform.v1" + + dumpv1beta1 "github.com/percona/pmm/api/managementpb/dump" + "github.com/percona/pmm/managed/models" + "github.com/percona/pmm/managed/services/dump" + "github.com/percona/pmm/managed/services/grafana" +) + +type Service struct { + db *reform.DB + l *logrus.Entry + + dumpService dumpService + grafanaClient *grafana.Client + + dumpv1beta1.UnimplementedDumpsServer +} + +func New(db *reform.DB, grafanaClient *grafana.Client, dumpService dumpService) *Service { + return &Service{ + db: db, + dumpService: dumpService, + grafanaClient: grafanaClient, + l: logrus.WithField("component", "management/dump"), + } +} + +func (s *Service) StartDump(ctx context.Context, req *dumpv1beta1.StartDumpRequest) (*dumpv1beta1.StartDumpResponse, error) { + md, ok := metadata.FromIncomingContext(ctx) + if !ok { + return nil, errors.New("can't get request metadata") + } + + // Here we're trying to extract authentication credentials from incoming request. We need to forward them to pmm-dump tool. + authHeader, cookieHeader := md.Get("grpcgateway-authorization"), md.Get("grpcgateway-cookie") + + // pmm-dump supports user/pass authentication, API token or cookie. + var token, cookie, user, password string + if len(authHeader) != 0 { + // If auth header type is `Basic` try to extract user and password. + if basic, ok := strings.CutPrefix(authHeader[0], "Basic"); ok { + decodedBasic, err := base64.StdEncoding.DecodeString(strings.TrimSpace(basic)) + if err != nil { + return nil, errors.Wrap(err, "failed to decode basic authorization header") + } + + s := strings.Split(string(decodedBasic), ":") + if len(s) < 2 { + return nil, errors.New("failed to parse basic authorization header") + } + user, password = s[0], s[1] + } + + // If auth header type is `Basic` try to extract token. + if bearer, ok := strings.CutPrefix(authHeader[0], "Bearer"); ok { + token = strings.TrimSpace(bearer) + } + } + + // If auth cookie is present try to extract cookie value. + if len(cookieHeader) != 0 { + cookies := strings.Split(cookieHeader[0], ";") + for _, c := range cookies { + if auth, ok := strings.CutPrefix(strings.TrimSpace(c), "grafana_session="); ok { + cookie = auth + } + } + } + + params := &dump.Params{ + APIKey: token, + Cookie: cookie, + User: user, + Password: password, + ServiceNames: req.ServiceNames, + ExportQAN: req.ExportQan, + IgnoreLoad: req.IgnoreLoad, + } + + if req.StartTime != nil { + startTime := req.StartTime.AsTime() + params.StartTime = &startTime + } + + if req.EndTime != nil { + endTime := req.EndTime.AsTime() + params.EndTime = &endTime + } + + if params.StartTime != nil && params.EndTime != nil { + if params.StartTime.After(*params.EndTime) { + return nil, status.Error(codes.InvalidArgument, "Dump start time can't be greater than end time") + } + } + + dumpID, err := s.dumpService.StartDump(params) + if err != nil { + return nil, err + } + + return &dumpv1beta1.StartDumpResponse{DumpId: dumpID}, nil +} + +func (s *Service) ListDumps(_ context.Context, _ *dumpv1beta1.ListDumpsRequest) (*dumpv1beta1.ListDumpsResponse, error) { + dumps, err := models.FindDumps(s.db.Querier, models.DumpFilters{}) + if err != nil { + return nil, err + } + + dumpsResponse := make([]*dumpv1beta1.Dump, 0, len(dumps)) + for _, dump := range dumps { + d, err := convertDump(dump) + if err != nil { + return nil, err + } + + dumpsResponse = append(dumpsResponse, d) + } + + return &dumpv1beta1.ListDumpsResponse{ + Dumps: dumpsResponse, + }, nil +} + +func (s *Service) DeleteDump(_ context.Context, req *dumpv1beta1.DeleteDumpRequest) (*dumpv1beta1.DeleteDumpResponse, error) { + for _, id := range req.DumpIds { + if err := s.dumpService.DeleteDump(id); err != nil { + return nil, err + } + } + + return &dumpv1beta1.DeleteDumpResponse{}, nil +} + +func (s *Service) GetDumpLogs(_ context.Context, req *dumpv1beta1.GetLogsRequest) (*dumpv1beta1.GetLogsResponse, error) { + filter := models.DumpLogsFilter{ + DumpID: req.DumpId, + Offset: int(req.Offset), + } + if req.Limit > 0 { + filter.Limit = pointer.ToInt(int(req.Limit)) + } + + dumpLogs, err := models.FindDumpLogs(s.db.Querier, filter) + if err != nil { + return nil, err + } + + res := &dumpv1beta1.GetLogsResponse{ + Logs: make([]*dumpv1beta1.LogChunk, 0, len(dumpLogs)), + } + for _, log := range dumpLogs { + if log.LastChunk { + res.End = true + break + } + res.Logs = append(res.Logs, &dumpv1beta1.LogChunk{ + ChunkId: log.ChunkID, + Data: log.Data, + }) + } + + return res, nil +} + +func (s *Service) UploadDump(_ context.Context, req *dumpv1beta1.UploadDumpRequest) (*dumpv1beta1.UploadDumpResponse, error) { + filePaths, err := s.dumpService.GetFilePathsForDumps(req.DumpIds) + if err != nil { + return nil, err + } + + if req.SftpParameters == nil { + return nil, status.Error(codes.InvalidArgument, "SFTP parameters are missing.") + } + + var config ssh.Config + config.SetDefaults() + config.KeyExchanges = append(config.KeyExchanges, + "diffie-hellman-group-exchange-sha256", + "diffie-hellman-group-exchange-sha1") + conf := &ssh.ClientConfig{ + User: req.SftpParameters.User, + Auth: []ssh.AuthMethod{ + ssh.Password(req.SftpParameters.Password), + }, + // We can't check host key + HostKeyCallback: ssh.InsecureIgnoreHostKey(), //nolint:gosec + Config: config, + } + + sshClient, err := ssh.Dial("tcp", req.SftpParameters.Address, conf) + if err != nil { + return nil, errors.Wrap(err, "failed to open TCP connection to SFTP server") + } + defer sshClient.Close() //nolint:errcheck + + sftpClient, err := sftp.NewClient(sshClient) + if err != nil { + return nil, errors.Wrap(err, "failed to create SFTP client") + } + defer sftpClient.Close() //nolint:errcheck + + for _, filePath := range filePaths { + if err = s.uploadFile(sftpClient, filePath, req.SftpParameters.Directory); err != nil { + return nil, errors.Wrap(err, "failed to upload file on SFTP server") + } + } + + return &dumpv1beta1.UploadDumpResponse{}, nil +} + +func (s *Service) uploadFile(client *sftp.Client, localFilePath, remoteDir string) error { + fileName := filepath.Base(localFilePath) + remoteFilePath := path.Join(remoteDir, fileName) + + nf, err := client.OpenFile(remoteFilePath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC) + if err != nil { + return errors.Wrap(err, "failed to create file on SFTP server") + } + + f, err := os.Open(localFilePath) //nolint:gosec + if err != nil { + return errors.Wrap(err, "failed to open dump file") + } + defer func() { + if err := f.Close(); err != nil { + s.l.Errorf("Failed to close file: %+v", err) + } + }() + if _, err = bufio.NewReader(f).WriteTo(nf); err != nil { + return errors.Wrap(err, "failed to write dump file on SFTP server") + } + + return nil +} + +func convertDump(dump *models.Dump) (*dumpv1beta1.Dump, error) { + ds, err := convertDumpStatus(dump.Status) + if err != nil { + return nil, errors.Wrap(err, "failed to convert dump ds") + } + + d := &dumpv1beta1.Dump{ + DumpId: dump.ID, + Status: ds, + ServiceNames: dump.ServiceNames, + CreatedAt: timestamppb.New(dump.CreatedAt), + } + + if dump.StartTime != nil { + d.StartTime = timestamppb.New(*dump.StartTime) + } + + if dump.EndTime != nil { + d.EndTime = timestamppb.New(*dump.EndTime) + } + + return d, nil +} + +func convertDumpStatus(status models.DumpStatus) (dumpv1beta1.DumpStatus, error) { + switch status { + case models.DumpStatusSuccess: + return dumpv1beta1.DumpStatus_DUMP_STATUS_SUCCESS, nil + case models.DumpStatusError: + return dumpv1beta1.DumpStatus_DUMP_STATUS_ERROR, nil + case models.DumpStatusInProgress: + return dumpv1beta1.DumpStatus_DUMP_STATUS_IN_PROGRESS, nil + default: + return dumpv1beta1.DumpStatus_DUMP_STATUS_INVALID, errors.Errorf("invalid status '%s'", status) + } +} diff --git a/managed/services/management/dump/mock_dump_service_test.go b/managed/services/management/dump/mock_dump_service_test.go new file mode 100644 index 0000000000..051bfa8db8 --- /dev/null +++ b/managed/services/management/dump/mock_dump_service_test.go @@ -0,0 +1,93 @@ +// Code generated by mockery v2.36.0. DO NOT EDIT. + +package dump + +import ( + mock "github.com/stretchr/testify/mock" + + servicesdump "github.com/percona/pmm/managed/services/dump" +) + +// mockDumpService is an autogenerated mock type for the dumpService type +type mockDumpService struct { + mock.Mock +} + +// DeleteDump provides a mock function with given fields: dumpID +func (_m *mockDumpService) DeleteDump(dumpID string) error { + ret := _m.Called(dumpID) + + var r0 error + if rf, ok := ret.Get(0).(func(string) error); ok { + r0 = rf(dumpID) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// GetFilePathsForDumps provides a mock function with given fields: dumpIDs +func (_m *mockDumpService) GetFilePathsForDumps(dumpIDs []string) (map[string]string, error) { + ret := _m.Called(dumpIDs) + + var r0 map[string]string + var r1 error + if rf, ok := ret.Get(0).(func([]string) (map[string]string, error)); ok { + return rf(dumpIDs) + } + if rf, ok := ret.Get(0).(func([]string) map[string]string); ok { + r0 = rf(dumpIDs) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(map[string]string) + } + } + + if rf, ok := ret.Get(1).(func([]string) error); ok { + r1 = rf(dumpIDs) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// StartDump provides a mock function with given fields: params +func (_m *mockDumpService) StartDump(params *servicesdump.Params) (string, error) { + ret := _m.Called(params) + + var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(*servicesdump.Params) (string, error)); ok { + return rf(params) + } + if rf, ok := ret.Get(0).(func(*servicesdump.Params) string); ok { + r0 = rf(params) + } else { + r0 = ret.Get(0).(string) + } + + if rf, ok := ret.Get(1).(func(*servicesdump.Params) error); ok { + r1 = rf(params) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// newMockDumpService creates a new instance of mockDumpService. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func newMockDumpService(t interface { + mock.TestingT + Cleanup(func()) +}, +) *mockDumpService { + mock := &mockDumpService{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/managed/services/server/deps.go b/managed/services/server/deps.go index c05f171685..4d47530b7b 100644 --- a/managed/services/server/deps.go +++ b/managed/services/server/deps.go @@ -109,3 +109,9 @@ type agentsStateUpdater interface { type templatesService interface { CollectTemplates(ctx context.Context) } + +// haService is a subset of methods of ha.Service used by this package. +// We use it instead of real type for testing and to avoid dependency cycle. +type haService interface { + IsLeader() bool +} diff --git a/managed/services/server/server.go b/managed/services/server/server.go index 8f9558b400..62beecec5c 100644 --- a/managed/services/server/server.go +++ b/managed/services/server/server.go @@ -225,6 +225,16 @@ func (s *Server) Readiness(ctx context.Context, req *serverpb.ReadinessRequest) return &serverpb.ReadinessResponse{}, nil } +// LeaderHealthCheck checks if the instance is the leader in a cluster. +// Returns an error if the instance isn't the leader. +// It's used for HA purpose. +func (s *Server) LeaderHealthCheck(ctx context.Context, req *serverpb.LeaderHealthCheckRequest) (*serverpb.LeaderHealthCheckResponse, error) { + if s.haService.IsLeader() { + return &serverpb.LeaderHealthCheckResponse{}, nil + } + return nil, status.Error(codes.FailedPrecondition, "this PMM Server isn't the leader") +} + func (s *Server) onlyInstalledVersionResponse(ctx context.Context) *serverpb.CheckUpdatesResponse { v := s.supervisord.InstalledPMMVersion(ctx) r := &serverpb.CheckUpdatesResponse{ diff --git a/managed/services/supervisord/devcontainer_test.go b/managed/services/supervisord/devcontainer_test.go index 61d7fb491d..604d31536a 100644 --- a/managed/services/supervisord/devcontainer_test.go +++ b/managed/services/supervisord/devcontainer_test.go @@ -115,7 +115,7 @@ func TestDevContainer(t *testing.T) { vmParams, err := models.NewVictoriaMetricsParams(models.BasePrometheusConfigPath, models.VMBaseURL) require.NoError(t, err) - s := New("/etc/supervisord.d", checker, vmParams, models.PGParams{}, gRPCMessageMaxSize) + s := New("/etc/supervisord.d", checker, &models.Params{VMParams: vmParams, PGParams: &models.PGParams{}, HAParams: &models.HAParams{}}, gRPCMessageMaxSize) require.NotEmpty(t, s.supervisorctlPath) ctx, cancel := context.WithCancel(context.Background()) @@ -168,7 +168,7 @@ func TestDevContainer(t *testing.T) { // logrus.SetLevel(logrus.DebugLevel) checker := NewPMMUpdateChecker(logrus.WithField("test", t.Name())) vmParams := &models.VictoriaMetricsParams{} - s := New("/etc/supervisord.d", checker, vmParams, models.PGParams{}, gRPCMessageMaxSize) + s := New("/etc/supervisord.d", checker, &models.Params{VMParams: vmParams, PGParams: &models.PGParams{}, HAParams: &models.HAParams{}}, gRPCMessageMaxSize) require.NotEmpty(t, s.supervisorctlPath) ctx, cancel := context.WithCancel(context.Background()) diff --git a/managed/services/supervisord/logs.go b/managed/services/supervisord/logs.go index b003f36249..8fcfcb809f 100644 --- a/managed/services/supervisord/logs.go +++ b/managed/services/supervisord/logs.go @@ -61,7 +61,6 @@ type Logs struct { } // NewLogs creates a new Logs service. -// The number of last log lines to read is n. func NewLogs(pmmVersion string, pmmUpdateChecker *PMMUpdateChecker, vmParams victoriaMetricsParams) *Logs { return &Logs{ pmmVersion: pmmVersion, diff --git a/managed/services/supervisord/pmm_config.go b/managed/services/supervisord/pmm_config.go index 5744991b9d..0f9cec3823 100644 --- a/managed/services/supervisord/pmm_config.go +++ b/managed/services/supervisord/pmm_config.go @@ -128,6 +128,7 @@ stdout_logfile_maxbytes = 30MB stdout_logfile_backups = 2 redirect_stderr = true {{- end }} +{{- if not .DisableInternalClickhouse }} [program:clickhouse] priority = 2 @@ -144,6 +145,7 @@ stdout_logfile = /srv/logs/clickhouse-server.log stdout_logfile_maxbytes = 50MB stdout_logfile_backups = 2 redirect_stderr = true +{{- end }} [program:nginx] priority = 4 @@ -183,7 +185,7 @@ priority = 15 command = /usr/sbin/pmm-agent --config-file=/usr/local/percona/pmm/config/pmm-agent.yaml user = pmm autorestart = true -autostart = true +autostart = false startretries = 1000 startsecs = 1 stopsignal = TERM diff --git a/managed/services/supervisord/pmm_config_test.go b/managed/services/supervisord/pmm_config_test.go new file mode 100644 index 0000000000..baaf279b58 --- /dev/null +++ b/managed/services/supervisord/pmm_config_test.go @@ -0,0 +1,57 @@ +// Copyright (C) 2023 Percona LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package supervisord + +import ( + "os" + "path/filepath" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestSavePMMConfig(t *testing.T) { + t.Parallel() + configDir := filepath.Join("..", "..", "testdata", "supervisord.d") + tests := []struct { + description string + params map[string]any + file string + }{ + { + description: "disable internal postgresql db", + params: map[string]any{"DisableInternalDB": true, "DisableSupervisor": false, "DisableInternalClickhouse": false}, + file: "pmm-db_disabled", + }, + { + description: "enable internal postgresql db", + params: map[string]any{"DisableInternalDB": false, "DisableSupervisor": false, "DisableInternalClickhouse": false}, + file: "pmm-db_enabled", + }, + } + for _, test := range tests { + test := test + t.Run(test.description, func(t *testing.T) { + t.Parallel() + expected, err := os.ReadFile(filepath.Join(configDir, test.file+".ini")) //nolint:gosec + require.NoError(t, err) + actual, err := marshalConfig(test.params) + require.NoError(t, err) + assert.Equal(t, string(expected), string(actual)) + }) + } +} diff --git a/managed/services/supervisord/supervisord.go b/managed/services/supervisord/supervisord.go index 79cfede3c5..94f2019c80 100644 --- a/managed/services/supervisord/supervisord.go +++ b/managed/services/supervisord/supervisord.go @@ -68,7 +68,8 @@ type Service struct { supervisordConfigsM sync.Mutex vmParams *models.VictoriaMetricsParams - pgParams models.PGParams + pgParams *models.PGParams + haParams *models.HAParams } type sub struct { @@ -84,7 +85,7 @@ const ( ) // New creates new service. -func New(configDir string, pmmUpdateCheck *PMMUpdateChecker, vmParams *models.VictoriaMetricsParams, pgParams models.PGParams, gRPCMessageMaxSize uint32) *Service { +func New(configDir string, pmmUpdateCheck *PMMUpdateChecker, params *models.Params, gRPCMessageMaxSize uint32) *Service { path, _ := exec.LookPath("supervisorctl") return &Service{ configDir: configDir, @@ -94,8 +95,9 @@ func New(configDir string, pmmUpdateCheck *PMMUpdateChecker, vmParams *models.Vi pmmUpdateCheck: pmmUpdateCheck, subs: make(map[chan *event]sub), lastEvents: make(map[string]eventType), - vmParams: vmParams, - pgParams: pgParams, + vmParams: params.VMParams, + pgParams: params.PGParams, + haParams: params.HAParams, } } @@ -436,6 +438,7 @@ func (s *Service) marshalConfig(tmpl *template.Template, settings *models.Settin } s.addPostgresParams(templateParams) + s.addClusterParams(templateParams) templateParams["PMMServerHost"] = "" if settings.PMMPublicAddress != "" { @@ -508,6 +511,9 @@ func addAlertManagerParams(alertManagerURL string, templateParams map[string]int // addPostgresParams adds pmm-server postgres database params to template config for grafana. func (s *Service) addPostgresParams(templateParams map[string]interface{}) { + if s.pgParams == nil { + return + } templateParams["PostgresAddr"] = s.pgParams.Addr templateParams["PostgresDBName"] = s.pgParams.DBName templateParams["PostgresDBUsername"] = s.pgParams.DBUsername @@ -518,6 +524,21 @@ func (s *Service) addPostgresParams(templateParams map[string]interface{}) { templateParams["PostgresSSLCertPath"] = s.pgParams.SSLCertPath } +func (s *Service) addClusterParams(templateParams map[string]interface{}) { + templateParams["HAEnabled"] = s.haParams.Enabled + if s.haParams.Enabled { + templateParams["GrafanaGossipPort"] = s.haParams.GrafanaGossipPort + templateParams["HAAdvertiseAddress"] = s.haParams.AdvertiseAddress + nodes := make([]string, len(s.haParams.Nodes)) + for i, node := range s.haParams.Nodes { + nodes[i] = fmt.Sprintf("%s:%d", node, s.haParams.GrafanaGossipPort) + } + templateParams["HANodes"] = strings.Join(nodes, ",") + } + //- GF_UNIFIED_ALERTING_HA_ADVERTISE_ADDRESS=172.20.0.5:9095 + //- GF_UNIFIED_ALERTING_HA_PEERS=pmm-server-active:9095,pmm-server-passive:9095 +} + // saveConfigAndReload saves given supervisord program configuration to file and reloads it. // If configuration can't be reloaded for some reason, old file is restored, and configuration is reloaded again. // Returns true if configuration was changed. @@ -581,7 +602,7 @@ func (s *Service) UpdateConfiguration(settings *models.Settings, ssoDetails *mod } for _, tmpl := range templates.Templates() { - if tmpl.Name() == "" { + if tmpl.Name() == "" || (tmpl.Name() == "victoriametrics" && s.vmParams.ExternalVM()) { continue } @@ -606,6 +627,18 @@ func (s *Service) RestartSupervisedService(serviceName string) error { return err } +// StartSupervisedService starts given service. +func (s *Service) StartSupervisedService(serviceName string) error { + _, err := s.supervisorctl("start", serviceName) + return err +} + +// StopSupervisedService stops given service. +func (s *Service) StopSupervisedService(serviceName string) error { + _, err := s.supervisorctl("stop", serviceName) + return err +} + //nolint:lll var templates = template.Must(template.New("").Option("missingkey=error").Parse(` @@ -800,6 +833,11 @@ environment = {{- if .PerconaSSODetails}} GF_AUTH_SIGNOUT_REDIRECT_URL="https://{{ .IssuerDomain }}/login/signout?fromURI=https://{{ .PMMServerAddress }}/graph/login" {{- end}} + {{- if .HAEnabled}} + GF_UNIFIED_ALERTING_HA_LISTEN_ADDRESS="0.0.0.0:{{ .GrafanaGossipPort }}", + GF_UNIFIED_ALERTING_HA_ADVERTISE_ADDRESS="{{ .HAAdvertiseAddress }}:{{ .GrafanaGossipPort }}", + GF_UNIFIED_ALERTING_HA_PEERS="{{ .HANodes }}" + {{- end}} user = grafana directory = /usr/share/grafana autorestart = true diff --git a/managed/services/supervisord/supervisord_test.go b/managed/services/supervisord/supervisord_test.go index 8092666727..a8fb84c825 100644 --- a/managed/services/supervisord/supervisord_test.go +++ b/managed/services/supervisord/supervisord_test.go @@ -37,7 +37,17 @@ func TestConfig(t *testing.T) { configDir := filepath.Join("..", "..", "testdata", "supervisord.d") vmParams, err := models.NewVictoriaMetricsParams(models.BasePrometheusConfigPath, models.VMBaseURL) require.NoError(t, err) - s := New(configDir, pmmUpdateCheck, vmParams, models.PGParams{}, gRPCMessageMaxSize) + pgParams := &models.PGParams{ + Addr: "127.0.0.1:5432", + DBName: "postgres", + DBUsername: "db_username", + DBPassword: "db_password", + SSLMode: "verify", + SSLCAPath: "path-to-CA-cert", + SSLKeyPath: "path-to-key", + SSLCertPath: "path-to-cert", + } + s := New(configDir, pmmUpdateCheck, &models.Params{VMParams: vmParams, PGParams: pgParams, HAParams: &models.HAParams{}}, gRPCMessageMaxSize) settings := &models.Settings{ DataRetention: 30 * 24 * time.Hour, AlertManagerURL: "https://external-user:passw!,ord@external-alertmanager:6443/alerts", @@ -111,35 +121,3 @@ func TestAddAlertManagerParam(t *testing.T) { require.Equal(t, "http://127.0.0.1:9093/alertmanager", params["AlertmanagerURL"]) }) } - -func TestSavePMMConfig(t *testing.T) { - t.Parallel() - configDir := filepath.Join("..", "..", "testdata", "supervisord.d") - tests := []struct { - description string - params map[string]any - file string - }{ - { - description: "disable internal postgresql db", - params: map[string]any{"DisableInternalDB": true, "DisableSupervisor": false}, - file: "pmm-db_disabled", - }, - { - description: "enable internal postgresql db", - params: map[string]any{"DisableInternalDB": false, "DisableSupervisor": false}, - file: "pmm-db_enabled", - }, - } - for _, test := range tests { - test := test - t.Run(test.description, func(t *testing.T) { - t.Parallel() - expected, err := os.ReadFile(filepath.Join(configDir, test.file+".ini")) //nolint:gosec - require.NoError(t, err) - actual, err := marshalConfig(test.params) - require.NoError(t, err) - assert.Equal(t, string(expected), string(actual)) - }) - } -} diff --git a/managed/services/telemetry/config.default.yml b/managed/services/telemetry/config.default.yml index bd2fe3995b..c03e04430f 100644 --- a/managed/services/telemetry/config.default.yml +++ b/managed/services/telemetry/config.default.yml @@ -156,7 +156,7 @@ telemetry: summary: "Runtime for general collector of MongoDB exporter" data: - metric_name: "mongodb_collector_scrape_time_general" - value : 1 + value: 1 - id: MongoDBExporterMetricsDiagnosticDataStats source: VM @@ -164,7 +164,7 @@ telemetry: summary: "Runtime for diagnostic data collector of MongoDB exporter" data: - metric_name: "mongodb_collector_scrape_time_diagnostic_data" - value : 1 + value: 1 - id: MongoDBExporterMetricsCollectionStats source: VM @@ -172,7 +172,7 @@ telemetry: summary: "Runtime for collection statistics collector of MongoDB exporter" data: - metric_name: "mongodb_collector_scrape_time_collstats" - value : 1 + value: 1 - id: MongoDBExporterMetricsDBStats source: VM @@ -180,7 +180,7 @@ telemetry: summary: "Runtime for database statistics collector of MongoDB exporter" data: - metric_name: "mongodb_collector_scrape_time_dbstats" - value : 1 + value: 1 - id: MongoDBExporterMetricsIndexStats source: VM @@ -188,7 +188,7 @@ telemetry: summary: "Runtime for index statistics collector of MongoDB exporter" data: - metric_name: "mongodb_collector_scrape_time_indexstats" - value : 1 + value: 1 - id: MongoDBExporterMetricsTopStats source: VM @@ -196,7 +196,7 @@ telemetry: summary: "Runtime for top metrics collector of MongoDB exporter" data: - metric_name: "mongodb_collector_scrape_time_top" - value : 1 + value: 1 - id: MongoDBExporterMetricsReplicationStatus source: VM @@ -204,7 +204,7 @@ telemetry: summary: "Runtime for replication status collector of MongoDB exporter" data: - metric_name: "mongodb_collector_scrape_time_replset_status" - value : 1 + value: 1 - id: MongoDBEdition source: VM @@ -882,6 +882,38 @@ telemetry: - metric_name: "7" column: "count" + # PMM-Dump information + - id: PMMDumpsPerformed + source: PMMDB_SELECT + query: > + status, + ARRAY_LENGTH(service_names,1) as services_count, + end_time - start_time as timerange, + ignore_load, + export_qan, + count(*) + from dumps + where created_at BETWEEN NOW() - INTERVAL '24 HOURS' AND NOW() + group by status, services_count, timerange, ignore_load, export_qan; + + transform: + type: JSON + metric: pmm_dumps_performed + summary: "How many PMM dumps were created" + data: + - metric_name: "1" + column: "status" + - metric_name: "2" + column: "services_count" + - metric_name: "3" + column: "timerange" + - metric_name: "4" + column: "ignore_load" + - metric_name: "5" + column: "export_qan" + - metric_name: "6" + column: "count" + - id: PXCClusterNodesCount source: VM query: (min by (wsrep_cluster_state_uuid) (mysql_global_status_wsrep_cluster_size * on (service_id) group_left(wsrep_cluster_state_uuid) mysql_galera_status_info)) @@ -903,35 +935,22 @@ telemetry: - metric_name: "postgresql_db_count" value: 1 - # Note: use these for testing and PMM-12462 - # - id: PMMServerFeatureToggles - # source: ENV_VARS - # summary: "Use of feature toggles in PMM Server" - # data: - # - metric_name: "pmm_server_disable_telemetry" - # column: "DISABLE_TELEMETRY" - # - metric_name: "pmm_server_enable_alerting" - # column: "ENABLE_ALERTING" - # - metric_name: "pmm_server_enable_backup_management" - # column: "ENABLE_BACKUP_MANAGEMENT" - # - metric_name: "pmm_server_enable_debug" - # column: "ENABLE_DEBUG" - # - metric_name: "pmm_server_enable_rbac" - # column: "ENABLE_RBAC" - - # - id: PMMServerFeatureTogglesStripValues - # source: ENV_VARS - # summary: "Use of feature toggles in PMM Server" - # transform: - # type: StripValues - # data: - # - metric_name: "pmm_server_disable_telemetry" - # column: "DISABLE_TELEMETRY" - # - metric_name: "pmm_server_enable_alerting" - # column: "ENABLE_ALERTING" - # - metric_name: "pmm_server_enable_backup_management" - # column: "ENABLE_BACKUP_MANAGEMENT" - # - metric_name: "pmm_server_enable_debug" - # column: "ENABLE_DEBUG" - # - metric_name: "pmm_server_enable_rbac" - # column: "ENABLE_RBAC" + - id: PMMServerHAEnabled + source: ENV_VARS + summary: "Use of HA feature" + data: + - metric_name: "pmm_server_ha_enable" + column: "PERCONA_TEST_HA_ENABLE" + + - id: PMMServerHAUseOfDBs + source: ENV_VARS + transform: + type: StripValues + summary: "Use of External DBs" + data: + - metric_name: "pmm_server_ha_clickhouse_address" + column: "PERCONA_TEST_PMM_CLICKHOUSE_ADDR" + - metric_name: "pmm_server_ha_postgres_address" + column: "PERCONA_TEST_POSTGRES_ADDR" + - metric_name: "pmm_server_ha_vm_url" + column: "PMM_VM_URL" diff --git a/managed/testdata/haproxy/haproxy.cfg b/managed/testdata/haproxy/haproxy.cfg new file mode 100644 index 0000000000..57cf72dfb0 --- /dev/null +++ b/managed/testdata/haproxy/haproxy.cfg @@ -0,0 +1,39 @@ +global + log stdout local0 debug + log stdout local1 info + log stdout local2 info + daemon + +defaults + log global + mode http + option httplog + option dontlognull + timeout connect 5000 + timeout client 50000 + timeout server 50000 + +frontend http_front + bind *:80 + default_backend http_back + +frontend https_front + bind *:443 ssl crt /etc/ssl/private/localhost.pem + default_backend https_back + +backend http_back + option httpchk + http-check send meth POST uri /v1/leaderHealthCheck ver HTTP/1.1 hdr Host www + http-check expect status 200 + server pmm-server-active-http pmm-server-active:80 check + server pmm-server-passive-http pmm-server-passive:80 check backup + server pmm-server-passive-2-http pmm-server-passive-2:80 check backup + +backend https_back + option httpchk + http-check send meth POST uri /v1/leaderHealthCheck ver HTTP/1.1 hdr Host www + http-check expect status 200 + server pmm-server-active-https pmm-server-active:443 check ssl verify none backup + server pmm-server-passive-https pmm-server-passive:443 check ssl verify none backup + server pmm-server-passive-2-https pmm-server-passive-2:443 check ssl verify none backup + diff --git a/managed/testdata/haproxy/localhost.crt b/managed/testdata/haproxy/localhost.crt new file mode 100644 index 0000000000..1b601b09c1 --- /dev/null +++ b/managed/testdata/haproxy/localhost.crt @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDPjCCAiYCCQC8Y6/8ayWo6DANBgkqhkiG9w0BAQsFADBhMQswCQYDVQQGEwJU +UjEQMA4GA1UECgwHUGVyY29uYTESMBAGA1UEAwwJbG9jYWxob3N0MSwwKgYJKoZI +hvcNAQkBFh1udXJsYW4ubW9sZG9tdXJvdkBwZXJjb25hLmNvbTAeFw0yMzA3MDYy +MDA2NDNaFw0yNDA3MDUyMDA2NDNaMGExCzAJBgNVBAYTAlRSMRAwDgYDVQQKDAdQ +ZXJjb25hMRIwEAYDVQQDDAlsb2NhbGhvc3QxLDAqBgkqhkiG9w0BCQEWHW51cmxh +bi5tb2xkb211cm92QHBlcmNvbmEuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAmp+Xbi1C79S2l7IawE0dIBaKlx4vO/baQBDi+SXuhUonw8dPTqvD +DZy96/irc7SudvsJdcpcFn9tGfASDez56uZqt/39wsA+uUsym9yV39gcZPRzeoiV +nxDny1dcNJSqlGkcDp7BqXaj2/e6bK5RW3cpUnnRk4M7weDsdblBJLYPAIqTGMmZ +Chf/iKAz6i9E+FRuXi3rhFJKUEGv+5nh7Pjd/9BxmVyjl9f9SWhe+AkimOs+CYrh +lcGAHJ6XKq5KAMB43elZxSXgv6X5eTVhQsqf7X0e8n0OrXKqP+fqrQMPnkOsVvEj +q90mcG1mvvPrMoXN0XN1dfJEhyRB/hwi5QIDAQABMA0GCSqGSIb3DQEBCwUAA4IB +AQB9BKnOT2KiKTdnydorEpuMgzD1RZ9bfX8mGiucjPh5lcjO6L9haUbFN/6PupZP +x1WRKNwYm+R2vP/Q1tlkOwVDfBtycAhyx5NMRyHkmG90ap/hJUThF2D9Q+5A81Ma +tnpg5jbxPEBeMHujGZmDEiBNPHc9oP7HNuPXMzZWxAOjRAg2WtaqjyJi8ExnCP1t +4ELKdjojtSefhxQzZmdHNBKWa0kUJhDGfhvSo0//H9n8Q7VMmtVS94Klu/H+IG88 +EYmEzgkmty2eie+Jiv+S2WGDEUuopAReifGscFI3tYvNBbeU4GbtUCXKoNX8N6hO +1POaPPj84EK2ncLJXffk0XYq +-----END CERTIFICATE----- diff --git a/managed/testdata/haproxy/localhost.csr b/managed/testdata/haproxy/localhost.csr new file mode 100644 index 0000000000..84d654a289 --- /dev/null +++ b/managed/testdata/haproxy/localhost.csr @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICpjCCAY4CAQAwYTELMAkGA1UEBhMCVFIxEDAOBgNVBAoMB1BlcmNvbmExEjAQ +BgNVBAMMCWxvY2FsaG9zdDEsMCoGCSqGSIb3DQEJARYdbnVybGFuLm1vbGRvbXVy +b3ZAcGVyY29uYS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCa +n5duLULv1LaXshrATR0gFoqXHi879tpAEOL5Je6FSifDx09Oq8MNnL3r+KtztK52 ++wl1ylwWf20Z8BIN7Pnq5mq3/f3CwD65SzKb3JXf2Bxk9HN6iJWfEOfLV1w0lKqU +aRwOnsGpdqPb97psrlFbdylSedGTgzvB4Ox1uUEktg8AipMYyZkKF/+IoDPqL0T4 +VG5eLeuEUkpQQa/7meHs+N3/0HGZXKOX1/1JaF74CSKY6z4JiuGVwYAcnpcqrkoA +wHjd6VnFJeC/pfl5NWFCyp/tfR7yfQ6tcqo/5+qtAw+eQ6xW8SOr3SZwbWa+8+sy +hc3Rc3V18kSHJEH+HCLlAgMBAAGgADANBgkqhkiG9w0BAQsFAAOCAQEALWj/APq2 +xfNqyRM4cf8uSpRiIe7OjE9HABFXWowLfFMJ6E337n9TnV/srCNxgdBPZ78pPJLR +EWFRJUtB/cwYqxSauWYg7+x1HtNn2yQnyKX1Fep8LBREs2ykXPQAmiTaUrxja0+W +D880Ck8uy+C8HKF/cBQA3ZCrdkrV9Q6829WG3FNtRdIu72SDZb9opxvufiOxCRgX +6E1CiZL4fTcgUXVcR9MxJfSNj+HgsO3mU5DiyvbsOpXxCfWDy2O0/CmonfhyDL8o +2EF870bTHMJ4sxMOIB9ZFj4TFwoVUnl08G+XEx2mFR1Hb2ooUDUO5LXt80lftJR0 +qBGJW/RYyCRrPA== +-----END CERTIFICATE REQUEST----- diff --git a/managed/testdata/haproxy/localhost.key b/managed/testdata/haproxy/localhost.key new file mode 100644 index 0000000000..81e8700b34 --- /dev/null +++ b/managed/testdata/haproxy/localhost.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAmp+Xbi1C79S2l7IawE0dIBaKlx4vO/baQBDi+SXuhUonw8dP +TqvDDZy96/irc7SudvsJdcpcFn9tGfASDez56uZqt/39wsA+uUsym9yV39gcZPRz +eoiVnxDny1dcNJSqlGkcDp7BqXaj2/e6bK5RW3cpUnnRk4M7weDsdblBJLYPAIqT +GMmZChf/iKAz6i9E+FRuXi3rhFJKUEGv+5nh7Pjd/9BxmVyjl9f9SWhe+AkimOs+ +CYrhlcGAHJ6XKq5KAMB43elZxSXgv6X5eTVhQsqf7X0e8n0OrXKqP+fqrQMPnkOs +VvEjq90mcG1mvvPrMoXN0XN1dfJEhyRB/hwi5QIDAQABAoIBAEk7zT0hstJkrRas +BH+QBntsMbfhU/3SrQwq81WN4aq/tJXFkIpyT6/izRE2df4XVYqE27YuYe9F6yad +ze9KjhPzjhgW9FmJNCwOsamgkFu0v74RCaC/kB4Go8JrXgCJaUFhhyhliNP6nSFR +87oF1gK8LZYinGCBh4wMO/KGC5SW6X9W6xf7f6RJYSPUH7h80XwnDRvsSnldH/3e +QPciQXP8fPUUW9EP9WERjpWTBZ8YqUG5P2w6ZlCrJ7L+/STMbscD3dYTUXxQUsfh +oxjsi9BQKTPFqiLH7gstCfdoufQJkfWMLSxpn8bBiHf5nhehuRRd9hKwz8+S1jdE +Lv0FYAECgYEAy8h9t5QwW3NSD1WclIFcxQhUeHIWHjLB8KJZi9eYJ4oZ7zWa5duV +0DTs3vJfVvxJ8XLbjnaap7ULWDZETbm2m6d5zJBaEGqLYShzlr15vNp0ZzDZghw+ +9hG/TqAB1jj76RYbI9h4TvzSI3+mbq3nl5Sykz1Envuznz2JiKbefIUCgYEAwj5h +fS0wAa5zjR8Lgs1nRFmg37qH6gn6w40yDDYwxDtM2L1l96ONPROvm6RZkM6hkHge +dKzabpHrh7eViQOgbUO+tyxttOdBspdK1ubi7UZTG6xq4zuzqiITP+BnhSw2mzDR +J276DMNalsmzQdI8v+eIMK0yxqOobcgRK979iuECgYBw/NP/onGBcxpPmEc968/1 +Cx5SvebXjYsMkeeWas5ZNfAVOqKMychx7bZcEwSbpTyWW/myLr6nN/F3UndipRLD +kQMuUect7PUkxJn6PUovVOxvfp1Kz8B1DPgGbx81mNjLrs8Te+WQ3grhVdiAy3l6 +CR9OFg1jHOnF5AfKtcLsRQKBgGL800WtX4eb1XsXVRBliLjGTDt3nYfhag95xwV+ +IEAAUFsruekHShTUEWvpx1MKWj97V1nyNKagaj0Ri3z1gi3sliZW19mW+F4Ax7zY +kNCGRBgYN6hxZk/Paavluhudun4/1HaaEYerjmDFjTp/30GUxky4FuYvxMeda1LG +IsNBAoGBAIeBiXXaB8QhlP4vJu6HT9IDZKRRiYTNjiS1o8CQ2U86FfyO7OVQ+19R +DJCYOc10foiwv+HEsEVXAjux79Z2h2dqqxtVoWPNh6yGs0SDKObmPWOEZsFABeF4 +RFTKlWMq0tvbXmnGwciA3Oy9DbsHp5jTo6qbuewVvE5PL7GTnokF +-----END RSA PRIVATE KEY----- diff --git a/managed/testdata/haproxy/localhost.pem b/managed/testdata/haproxy/localhost.pem new file mode 100644 index 0000000000..e401361481 --- /dev/null +++ b/managed/testdata/haproxy/localhost.pem @@ -0,0 +1,47 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAmp+Xbi1C79S2l7IawE0dIBaKlx4vO/baQBDi+SXuhUonw8dP +TqvDDZy96/irc7SudvsJdcpcFn9tGfASDez56uZqt/39wsA+uUsym9yV39gcZPRz +eoiVnxDny1dcNJSqlGkcDp7BqXaj2/e6bK5RW3cpUnnRk4M7weDsdblBJLYPAIqT +GMmZChf/iKAz6i9E+FRuXi3rhFJKUEGv+5nh7Pjd/9BxmVyjl9f9SWhe+AkimOs+ +CYrhlcGAHJ6XKq5KAMB43elZxSXgv6X5eTVhQsqf7X0e8n0OrXKqP+fqrQMPnkOs +VvEjq90mcG1mvvPrMoXN0XN1dfJEhyRB/hwi5QIDAQABAoIBAEk7zT0hstJkrRas +BH+QBntsMbfhU/3SrQwq81WN4aq/tJXFkIpyT6/izRE2df4XVYqE27YuYe9F6yad +ze9KjhPzjhgW9FmJNCwOsamgkFu0v74RCaC/kB4Go8JrXgCJaUFhhyhliNP6nSFR +87oF1gK8LZYinGCBh4wMO/KGC5SW6X9W6xf7f6RJYSPUH7h80XwnDRvsSnldH/3e +QPciQXP8fPUUW9EP9WERjpWTBZ8YqUG5P2w6ZlCrJ7L+/STMbscD3dYTUXxQUsfh +oxjsi9BQKTPFqiLH7gstCfdoufQJkfWMLSxpn8bBiHf5nhehuRRd9hKwz8+S1jdE +Lv0FYAECgYEAy8h9t5QwW3NSD1WclIFcxQhUeHIWHjLB8KJZi9eYJ4oZ7zWa5duV +0DTs3vJfVvxJ8XLbjnaap7ULWDZETbm2m6d5zJBaEGqLYShzlr15vNp0ZzDZghw+ +9hG/TqAB1jj76RYbI9h4TvzSI3+mbq3nl5Sykz1Envuznz2JiKbefIUCgYEAwj5h +fS0wAa5zjR8Lgs1nRFmg37qH6gn6w40yDDYwxDtM2L1l96ONPROvm6RZkM6hkHge +dKzabpHrh7eViQOgbUO+tyxttOdBspdK1ubi7UZTG6xq4zuzqiITP+BnhSw2mzDR +J276DMNalsmzQdI8v+eIMK0yxqOobcgRK979iuECgYBw/NP/onGBcxpPmEc968/1 +Cx5SvebXjYsMkeeWas5ZNfAVOqKMychx7bZcEwSbpTyWW/myLr6nN/F3UndipRLD +kQMuUect7PUkxJn6PUovVOxvfp1Kz8B1DPgGbx81mNjLrs8Te+WQ3grhVdiAy3l6 +CR9OFg1jHOnF5AfKtcLsRQKBgGL800WtX4eb1XsXVRBliLjGTDt3nYfhag95xwV+ +IEAAUFsruekHShTUEWvpx1MKWj97V1nyNKagaj0Ri3z1gi3sliZW19mW+F4Ax7zY +kNCGRBgYN6hxZk/Paavluhudun4/1HaaEYerjmDFjTp/30GUxky4FuYvxMeda1LG +IsNBAoGBAIeBiXXaB8QhlP4vJu6HT9IDZKRRiYTNjiS1o8CQ2U86FfyO7OVQ+19R +DJCYOc10foiwv+HEsEVXAjux79Z2h2dqqxtVoWPNh6yGs0SDKObmPWOEZsFABeF4 +RFTKlWMq0tvbXmnGwciA3Oy9DbsHp5jTo6qbuewVvE5PL7GTnokF +-----END RSA PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIIDPjCCAiYCCQC8Y6/8ayWo6DANBgkqhkiG9w0BAQsFADBhMQswCQYDVQQGEwJU +UjEQMA4GA1UECgwHUGVyY29uYTESMBAGA1UEAwwJbG9jYWxob3N0MSwwKgYJKoZI +hvcNAQkBFh1udXJsYW4ubW9sZG9tdXJvdkBwZXJjb25hLmNvbTAeFw0yMzA3MDYy +MDA2NDNaFw0yNDA3MDUyMDA2NDNaMGExCzAJBgNVBAYTAlRSMRAwDgYDVQQKDAdQ +ZXJjb25hMRIwEAYDVQQDDAlsb2NhbGhvc3QxLDAqBgkqhkiG9w0BCQEWHW51cmxh +bi5tb2xkb211cm92QHBlcmNvbmEuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAmp+Xbi1C79S2l7IawE0dIBaKlx4vO/baQBDi+SXuhUonw8dPTqvD +DZy96/irc7SudvsJdcpcFn9tGfASDez56uZqt/39wsA+uUsym9yV39gcZPRzeoiV +nxDny1dcNJSqlGkcDp7BqXaj2/e6bK5RW3cpUnnRk4M7weDsdblBJLYPAIqTGMmZ +Chf/iKAz6i9E+FRuXi3rhFJKUEGv+5nh7Pjd/9BxmVyjl9f9SWhe+AkimOs+CYrh +lcGAHJ6XKq5KAMB43elZxSXgv6X5eTVhQsqf7X0e8n0OrXKqP+fqrQMPnkOsVvEj +q90mcG1mvvPrMoXN0XN1dfJEhyRB/hwi5QIDAQABMA0GCSqGSIb3DQEBCwUAA4IB +AQB9BKnOT2KiKTdnydorEpuMgzD1RZ9bfX8mGiucjPh5lcjO6L9haUbFN/6PupZP +x1WRKNwYm+R2vP/Q1tlkOwVDfBtycAhyx5NMRyHkmG90ap/hJUThF2D9Q+5A81Ma +tnpg5jbxPEBeMHujGZmDEiBNPHc9oP7HNuPXMzZWxAOjRAg2WtaqjyJi8ExnCP1t +4ELKdjojtSefhxQzZmdHNBKWa0kUJhDGfhvSo0//H9n8Q7VMmtVS94Klu/H+IG88 +EYmEzgkmty2eie+Jiv+S2WGDEUuopAReifGscFI3tYvNBbeU4GbtUCXKoNX8N6hO +1POaPPj84EK2ncLJXffk0XYq +-----END CERTIFICATE----- diff --git a/managed/testdata/pg/Makefile b/managed/testdata/pg/Makefile index f112b5db0c..ebfac42936 100644 --- a/managed/testdata/pg/Makefile +++ b/managed/testdata/pg/Makefile @@ -11,12 +11,12 @@ all: root-ssl server-ssl pmm-managed-ssl grafana-ssl ## Generates all required d root-ssl: ## Generates root-ssl cert. openssl req -new -sha256 -nodes -newkey rsa:2048 \ -config ./certs/root.cnf \ - -keyout /tmp/root.key \ - -out /tmp/root.csr + -keyout ./certs/root.key \ + -out ./certs/root.csr openssl x509 -req -days 3653 -sha256 \ - -in /tmp/root.csr \ + -in ./certs/root.csr \ -extfile /etc/ssl/openssl.cnf -extensions v3_ca \ - -signkey /tmp/root.key \ + -signkey ./certs/root.key \ -out ./certs/root.crt server-ssl: ## Generates server-ssl cert. @@ -26,9 +26,11 @@ server-ssl: ## Generates server-ssl cer -out /tmp/server.csr openssl x509 -req -days 3653 -sha256 \ -extfile ./certs/server.cnf -extensions req_ext \ - -CA ./certs/root.crt -CAkey /tmp/root.key -CAcreateserial \ + -CA ./certs/root.crt -CAkey ./certs/root.key -CAcreateserial \ -in /tmp/server.csr \ -out ./certs/server.crt + chmod 600 certs/server.crt + chmod 600 certs/server.key pmm-managed-ssl: ## Generates pmm-managed-ssl cert. openssl req -new -sha256 -nodes -newkey rsa:2048 \ @@ -39,6 +41,20 @@ pmm-managed-ssl: ## Generates pmm-managed-ssl -CA ./certs/root.crt -CAkey /tmp/root.key -CAcreateserial \ -in /tmp/pmm-managed.csr \ -out ./certs/pmm-managed.crt + chmod 600 certs/pmm-managed.crt + chmod 600 certs/pmm-managed.key + +grafana-ssl: ## Generates grafana-ssl cert. + openssl req -new -sha256 -nodes -newkey rsa:2048 \ + -config ./certs/grafana.cnf \ + -keyout ./certs/grafana.key \ + -out /tmp/grafana.csr + openssl x509 -req -days 3653 -sha256 \ + -CA ./certs/root.crt -CAkey /tmp/root.key -CAcreateserial \ + -in /tmp/grafana.csr \ + -out ./certs/grafana.crt + chmod 600 certs/grafana.crt + chmod 600 certs/grafana.key grafana-ssl: ## Generates grafana-ssl cert. openssl req -new -sha256 -nodes -newkey rsa:2048 \ diff --git a/managed/testdata/pg/conf/pg_hba.conf b/managed/testdata/pg/conf/pg_hba.conf index 81144295c3..c9d25ee111 100644 --- a/managed/testdata/pg/conf/pg_hba.conf +++ b/managed/testdata/pg/conf/pg_hba.conf @@ -1,5 +1,2 @@ local all all trust -hostnossl all pmm-managed all reject -hostssl all pmm-managed all cert -hostnossl all grafana all reject -hostssl all grafana all cert \ No newline at end of file +hostnossl all all trust \ No newline at end of file diff --git a/managed/testdata/supervisord.d/grafana.ini b/managed/testdata/supervisord.d/grafana.ini index c6a0788699..b049c82690 100644 --- a/managed/testdata/supervisord.d/grafana.ini +++ b/managed/testdata/supervisord.d/grafana.ini @@ -7,14 +7,14 @@ command = --homepath=/usr/share/grafana --config=/etc/grafana/grafana.ini environment = - PERCONA_TEST_POSTGRES_ADDR="", - PERCONA_TEST_POSTGRES_DBNAME="", - PERCONA_TEST_POSTGRES_USERNAME="", - PERCONA_TEST_POSTGRES_DBPASSWORD="", - PERCONA_TEST_POSTGRES_SSL_MODE="", - PERCONA_TEST_POSTGRES_SSL_CA_PATH="", - PERCONA_TEST_POSTGRES_SSL_KEY_PATH="", - PERCONA_TEST_POSTGRES_SSL_CERT_PATH="", + PERCONA_TEST_POSTGRES_ADDR="127.0.0.1:5432", + PERCONA_TEST_POSTGRES_DBNAME="postgres", + PERCONA_TEST_POSTGRES_USERNAME="db_username", + PERCONA_TEST_POSTGRES_DBPASSWORD="db_password", + PERCONA_TEST_POSTGRES_SSL_MODE="verify", + PERCONA_TEST_POSTGRES_SSL_CA_PATH="path-to-CA-cert", + PERCONA_TEST_POSTGRES_SSL_KEY_PATH="path-to-key", + PERCONA_TEST_POSTGRES_SSL_CERT_PATH="path-to-cert", PERCONA_TEST_PMM_CLICKHOUSE_DATASOURCE_ADDR="127.0.0.1:8123", PERCONA_TEST_PMM_CLICKHOUSE_HOST="127.0.0.1", PERCONA_TEST_PMM_CLICKHOUSE_PORT="9000", diff --git a/managed/testdata/supervisord.d/pmm-db_disabled.ini b/managed/testdata/supervisord.d/pmm-db_disabled.ini index 181c4794c4..a770f99c47 100644 --- a/managed/testdata/supervisord.d/pmm-db_disabled.ini +++ b/managed/testdata/supervisord.d/pmm-db_disabled.ini @@ -78,7 +78,7 @@ priority = 15 command = /usr/sbin/pmm-agent --config-file=/usr/local/percona/pmm/config/pmm-agent.yaml user = pmm autorestart = true -autostart = true +autostart = false startretries = 1000 startsecs = 1 stopsignal = TERM diff --git a/managed/testdata/supervisord.d/pmm-db_enabled.ini b/managed/testdata/supervisord.d/pmm-db_enabled.ini index b88e9dd0eb..73e1fa27bb 100644 --- a/managed/testdata/supervisord.d/pmm-db_enabled.ini +++ b/managed/testdata/supervisord.d/pmm-db_enabled.ini @@ -102,7 +102,7 @@ priority = 15 command = /usr/sbin/pmm-agent --config-file=/usr/local/percona/pmm/config/pmm-agent.yaml user = pmm autorestart = true -autostart = true +autostart = false startretries = 1000 startsecs = 1 stopsignal = TERM diff --git a/managed/utils/envvars/parser.go b/managed/utils/envvars/parser.go index 9ed915b9fa..b9a669e491 100644 --- a/managed/utils/envvars/parser.go +++ b/managed/utils/envvars/parser.go @@ -65,8 +65,10 @@ func (e InvalidDurationError) Error() string { return string(e) } // - the environment variables prefixed with GF_ passed as related to Grafana. // - the environment variables relating to proxies // - the environment variable set by podman -func ParseEnvVars(envs []string) (envSettings *models.ChangeSettingsParams, errs []error, warns []string) { //nolint:cyclop,nonamedreturns - envSettings = &models.ChangeSettingsParams{} +func ParseEnvVars(envs []string) (*models.ChangeSettingsParams, []error, []string) { //nolint:cyclop,maintidx + envSettings := &models.ChangeSettingsParams{} + var errs []error + var warns []string for _, env := range envs { p := strings.SplitN(env, "=", 2) diff --git a/qan-api2/Makefile b/qan-api2/Makefile index 8190540f7e..534b5828d0 100644 --- a/qan-api2/Makefile +++ b/qan-api2/Makefile @@ -31,11 +31,11 @@ install-race: ## Install qan-api2 binary with race detector go install -v -race ./... test-env-up: ## Start docker containers used for testing - docker run -d --platform=linux/amd64 --name pmm-clickhouse-test -p19000:9000 yandex/clickhouse-server:21.3.20 + docker run -d --platform=linux/amd64 --name pmm-clickhouse-test -p19000:9000 -p18123:8123 clickhouse/clickhouse-server:23.8.2.7 make test-env test-env-up-applem1: ## Start docker containers used for testing on Apple M1 and higher chips. - docker run -d --platform=linux/amd64 --name pmm-clickhouse-test -p19000:9000 clickhouse/clickhouse-server:head-alpine + docker run -d --platform=linux/arm64 --name pmm-clickhouse-test -p19000:9000 -p18123:8123 clickhouse/clickhouse-server:23.8.2.7 make test-env test-env: diff --git a/qan-api2/db.go b/qan-api2/db.go index d121ba6cb6..4e0f9d1646 100644 --- a/qan-api2/db.go +++ b/qan-api2/db.go @@ -123,17 +123,18 @@ func runMigrations(dsn string) error { } // DropOldPartition drops number of days old partitions of pmm.metrics in ClickHouse. -func DropOldPartition(db *sqlx.DB, days uint) { +func DropOldPartition(db *sqlx.DB, dbName string, days uint) { partitions := []string{} const query = ` SELECT DISTINCT partition FROM system.parts - WHERE toUInt32(partition) < toYYYYMMDD(now() - toIntervalDay(?)) ORDER BY partition + WHERE toUInt32(partition) < toYYYYMMDD(now() - toIntervalDay(?)) AND database = ? and visible = 1 ORDER BY partition ` err := db.Select( &partitions, query, - days) + days, + dbName) if err != nil { log.Printf("Select %d days old partitions of system.parts. Result: %v, Error: %v", days, partitions, err) return diff --git a/qan-api2/db_test.go b/qan-api2/db_test.go index fc06a5fd7d..841803965e 100644 --- a/qan-api2/db_test.go +++ b/qan-api2/db_test.go @@ -73,7 +73,7 @@ func cleanup() { func TestDropOldPartition(t *testing.T) { db := setup() - const query = `SELECT DISTINCT partition FROM system.parts WHERE database = 'pmm_test_parts' ORDER BY partition` + const query = `SELECT DISTINCT partition FROM system.parts WHERE database = 'pmm_test_parts' and visible = 1 ORDER BY partition` start := time.Now() // fixtures have two partition 20190101 and 20190102 @@ -85,12 +85,12 @@ func TestDropOldPartition(t *testing.T) { t.Run("no so old partition", func(t *testing.T) { partitions := []string{} days := daysNewestPartition + 1 - DropOldPartition(db, days) + DropOldPartition(db, "pmm_test_parts", days) err := db.Select( &partitions, query) require.NoError(t, err, "Unexpected error in selecting metrics partition") - require.Equal(t, 2, len(partitions), "No one patrition were truncated. Partition %+v, days %d", partitions, days) + require.Equal(t, 2, len(partitions), "No one partition were truncated. Partition %+v, days %d", partitions, days) assert.Equal(t, "20190101", partitions[0], "Newest partition was not truncated") assert.Equal(t, "20190102", partitions[1], "Oldest partition was not truncated") }) @@ -98,12 +98,12 @@ func TestDropOldPartition(t *testing.T) { t.Run("delete one day old partition", func(t *testing.T) { partitions := []string{} days := daysNewestPartition - DropOldPartition(db, days) + DropOldPartition(db, "pmm_test_parts", days) err := db.Select( &partitions, query) require.NoError(t, err, "Unexpected error in selecting metrics partition") - require.Equal(t, 1, len(partitions), "Only one partition left. Partition %+v, days %d", partitions, days) + require.Equal(t, 1, len(partitions), "Only one partition should left. Partition %+v, days %d", partitions, days) assert.Equal(t, "20190102", partitions[0], "Newest partition was not truncated") }) cleanup() diff --git a/qan-api2/main.go b/qan-api2/main.go index 5b151202e4..df5457964d 100644 --- a/qan-api2/main.go +++ b/qan-api2/main.go @@ -355,7 +355,7 @@ func main() { defer wg.Done() for { // Drop old partitions once in 24h. - DropOldPartition(db, *dataRetentionF) + DropOldPartition(db, *clickHouseDatabaseF, *dataRetentionF) select { case <-ctx.Done(): return diff --git a/qan-api2/models/reporter.go b/qan-api2/models/reporter.go index 4a5e463626..5091a00b52 100644 --- a/qan-api2/models/reporter.go +++ b/qan-api2/models/reporter.go @@ -77,7 +77,7 @@ SUM(num_queries) AS num_queries, SUM({{ $col }}) AS {{ $col }}, {{ end }} {{ end }} -rowNumberInAllBlocks() AS total_rows +count(DISTINCT dimension) AS total_rows FROM metrics WHERE period_start >= :period_start_from AND period_start <= :period_start_to {{ if .Search }} diff --git a/qan-api2/services/analytics/profile_test.go b/qan-api2/services/analytics/profile_test.go index 895a7f4dfd..95e22f1f81 100644 --- a/qan-api2/services/analytics/profile_test.go +++ b/qan-api2/services/analytics/profile_test.go @@ -175,13 +175,11 @@ func TestService_GetReport_Mix(t *testing.T) { mm models.Metrics } test := struct { - name string fields fields in *qanpb.ReportRequest want *qanpb.ReportReply wantErr bool }{ - "reverce_order", fields{rm: rm, mm: mm}, &qanpb.ReportRequest{ PeriodStartFrom: ×tamp.Timestamp{Seconds: t1.Unix()}, @@ -205,7 +203,7 @@ func TestService_GetReport_Mix(t *testing.T) { &want, false, } - t.Run(test.name, func(t *testing.T) { + t.Run("reverce_order", func(t *testing.T) { s := &Service{ rm: test.fields.rm, mm: test.fields.mm, @@ -216,7 +214,7 @@ func TestService_GetReport_Mix(t *testing.T) { t.Errorf("Service.GetReport() error = %v, wantErr %v", err, test.wantErr) return } - expectedJSON := getExpectedJSON(t, got, "../../test_data/TestService_GetReport_Mix_"+test.name+".json") + expectedJSON := getExpectedJSON(t, got, "../../test_data/TestService_GetReport_Mix_reverce_order.json") marshaler := jsonpb.Marshaler{Indent: "\t"} gotJSON, err := marshaler.MarshalToString(got) if err != nil { @@ -225,8 +223,7 @@ func TestService_GetReport_Mix(t *testing.T) { assert.JSONEq(t, string(expectedJSON), gotJSON) }) - test.name = "correct_load" - t.Run(test.name, func(t *testing.T) { + t.Run("correct_load", func(t *testing.T) { s := &Service{ rm: test.fields.rm, mm: test.fields.mm, @@ -236,7 +233,7 @@ func TestService_GetReport_Mix(t *testing.T) { t.Errorf("Service.GetReport() error = %v, wantErr %v", err, test.wantErr) return } - expectedJSON := getExpectedJSON(t, got, "../../test_data/TestService_GetReport_Mix_"+test.name+".json") + expectedJSON := getExpectedJSON(t, got, "../../test_data/TestService_GetReport_Mix_correct_load.json") marshaler := jsonpb.Marshaler{Indent: "\t"} gotJSON, err := marshaler.MarshalToString(got) if err != nil { @@ -245,8 +242,7 @@ func TestService_GetReport_Mix(t *testing.T) { assert.JSONEq(t, string(expectedJSON), string(gotJSON)) //nolint:unconvert //keeps converting automatically }) - test.name = "correct_latency" - t.Run(test.name, func(t *testing.T) { + t.Run("correct_latency", func(t *testing.T) { s := &Service{ rm: test.fields.rm, mm: test.fields.mm, @@ -257,7 +253,7 @@ func TestService_GetReport_Mix(t *testing.T) { t.Errorf("Service.GetReport() error = %v, wantErr %v", err, test.wantErr) return } - expectedJSON := getExpectedJSON(t, got, "../../test_data/TestService_GetReport_Mix_"+test.name+".json") + expectedJSON := getExpectedJSON(t, got, "../../test_data/TestService_GetReport_Mix_correct_latency.json") marshaler := jsonpb.Marshaler{Indent: "\t"} gotJSON, err := marshaler.MarshalToString(got) if err != nil { diff --git a/update/.ansible-lint b/update/.ansible-lint index 29c64847a3..0e1628d74b 100644 --- a/update/.ansible-lint +++ b/update/.ansible-lint @@ -11,3 +11,4 @@ warn_list: # don't move to 'skip_list' - it will silence them completely - no-changed-when # Commands should not change things if nothing needs doing - parser-error # AnsibleParserError - ignore-errors # Use failed_when and specify error conditions instead of using ignore_errors + - empty-string-compare # Don't compare to empty string diff --git a/update/ansible/playbook/tasks/roles/clickhouse/tasks/main.yml b/update/ansible/playbook/tasks/roles/clickhouse/tasks/main.yml index d5fa9f845e..aef5604d30 100644 --- a/update/ansible/playbook/tasks/roles/clickhouse/tasks/main.yml +++ b/update/ansible/playbook/tasks/roles/clickhouse/tasks/main.yml @@ -48,22 +48,6 @@ enabled: no ignore_errors: true -# This will implicitly create /srv/clickhouse -- name: Create clickhouse data directory - file: - path: "/srv/clickhouse/flags" - state: directory - owner: root - group: pmm - recurse: true - -- name: Create empty file to convert clickhouse databases from ordinary to atomic - file: - path: "/srv/clickhouse/flags/convert_ordinary_to_atomic" - state: touch - owner: root - group: pmm - - name: Add ClickHouse repository yum_repository: name: clickhouse diff --git a/update/ansible/playbook/tasks/roles/dashboards_upgrade/tasks/main.yml b/update/ansible/playbook/tasks/roles/dashboards_upgrade/tasks/main.yml index c9d4ae9019..6b7b4dbc0c 100644 --- a/update/ansible/playbook/tasks/roles/dashboards_upgrade/tasks/main.yml +++ b/update/ansible/playbook/tasks/roles/dashboards_upgrade/tasks/main.yml @@ -65,6 +65,7 @@ - name: Remove the old clickhouse plugin shell: grafana cli --pluginsDir /srv/grafana/plugins plugins remove vertamedia-clickhouse-datasource || true + when: not ansible_check_mode - name: Restart grafana with new plugins EL7 supervisorctl: @@ -86,9 +87,3 @@ ignore_errors: true # TODO: fix the race condition. # We generate grafana supervisor config in pmm-managed and it may not exist at this stage - -- name: Copy file with image version - copy: - src: /usr/share/percona-dashboards/VERSION - dest: /srv/grafana/PERCONA_DASHBOARDS_VERSION - remote_src: yes diff --git a/update/ansible/playbook/tasks/roles/initialization/tasks/main.yml b/update/ansible/playbook/tasks/roles/initialization/tasks/main.yml index 021b246b2b..5113096993 100644 --- a/update/ansible/playbook/tasks/roles/initialization/tasks/main.yml +++ b/update/ansible/playbook/tasks/roles/initialization/tasks/main.yml @@ -69,6 +69,29 @@ become: true changed_when: True +- name: Update (both) + block: + # This will implicitly create /srv/clickhouse + - name: Create clickhouse data directory + file: + path: "/srv/clickhouse/flags" + state: directory + owner: root + group: pmm + recurse: true + + - name: Create empty file to convert clickhouse databases from ordinary to atomic + file: + path: "/srv/clickhouse/flags/convert_ordinary_to_atomic" + state: touch + owner: root + group: pmm + + - name: Upgrade dashboards + include_role: + name: dashboards_upgrade + when: not pmm_current_version is version(pmm_image_version, '>=') + - name: Create backup directory file: path: /srv/backup @@ -84,20 +107,28 @@ name: postgres when: is_postgres_11.stat.exists -- name: Create grafana database in postgres - postgresql_db: - name: grafana - state: present - -- name: Create grafana user in postgres - postgresql_user: - db: grafana - name: grafana - password: grafana - priv: 'ALL' - expires: infinity - state: present - when: not ansible_check_mode +- name: Create grafana DB + block: + - name: Create grafana database in postgres + postgresql_db: + name: grafana + state: present + + - name: Create grafana user in postgres + postgresql_user: + db: grafana + name: grafana + password: grafana + priv: 'ALL' + expires: infinity + state: present + when: not ansible_check_mode + when: lookup('env','GF_DATABASE_URL') == '' and lookup('env','GF_DATABASE_HOST') == '' + +- name: Upgrade grafana database (Get the latest schema) + command: grafana cli --homepath=/usr/share/grafana admin data-migration encrypt-datasource-passwords + changed_when: True + when: lookup('env','PMM_TEST_HA_BOOTSTRAP') != '' and not pmm_current_version is version(pmm_image_version, '>=') - name: Create working directory for Alertmanager file: path=/srv/alertmanager/data state=directory owner=pmm group=pmm @@ -172,9 +203,12 @@ when: docker_upgrade -- name: Check if we need an update or not - include_role: - name: dashboards_upgrade +- name: Copy file with image version + copy: + src: /usr/share/percona-dashboards/VERSION + dest: /srv/grafana/PERCONA_DASHBOARDS_VERSION + owner: grafana + remote_src: yes when: not pmm_current_version is version(pmm_image_version, '>=') - name: Finalization diff --git a/update/ansible/playbook/tasks/roles/nginx/files/conf.d/pmm.conf b/update/ansible/playbook/tasks/roles/nginx/files/conf.d/pmm.conf index 1450c7c7fe..9a4633467f 100644 --- a/update/ansible/playbook/tasks/roles/nginx/files/conf.d/pmm.conf +++ b/update/ansible/playbook/tasks/roles/nginx/files/conf.d/pmm.conf @@ -239,6 +239,11 @@ proxy_set_header Connection ""; } + # pmm-dump artifacts + location /dump { + alias /srv/dump/; + } + # This localtion stores static content for general pmm-server purposes. # Ex.: local-rss.xml - contains Percona's news when no internet connection. location /pmm-static {