From 293f087fb987421348dd9a4173087bb5f08cb850 Mon Sep 17 00:00:00 2001 From: Siyuan Zhang Date: Mon, 25 Sep 2023 13:38:04 -0700 Subject: [PATCH] Add grpc and etcdctl command for livez and readyz. tested with `bin/etcdctl endpoint readyz --cluster` Output: ``` http://127.0.0.1:2379: /readyz is OK,: took = 1.382416ms [+]ping ok [+]serializable_read ok [+]data_corruption ok http://127.0.0.1:32379: /readyz is OK,: took = 1.778917ms [+]ping ok [+]serializable_read ok [+]data_corruption ok http://127.0.0.1:22379: /readyz is OK,: took = 1.775041ms [+]ping ok [+]serializable_read ok [+]data_corruption ok ``` and the output for livez is ``` http://127.0.0.1:32379: /livez is OK,: took = 1.904625ms [+]ping ok [+]serializable_read ok http://127.0.0.1:2379: /livez is OK,: took = 2.125209ms [+]ping ok [+]serializable_read ok http://127.0.0.1:22379: /livez is OK,: took = 2.12025ms [+]ping ok [+]serializable_read ok ``` --- .../apispec/swagger/rpc.swagger.json | 134 ++ api/etcdserverpb/rpc.pb.go | 1561 +++++++++++++---- api/etcdserverpb/rpc.proto | 42 + client/v3/client_test.go | 12 + client/v3/maintenance.go | 32 + client/v3/retry.go | 12 + etcdctl/ctlv3/command/ep_command.go | 116 +- etcdctl/ctlv3/command/printer.go | 8 +- etcdctl/ctlv3/command/printer_json.go | 7 +- etcdctl/ctlv3/command/printer_simple.go | 13 + etcdctl/ctlv3/command/printer_table.go | 3 + scripts/etcd_version_annotations.txt | 7 + .../api/v3lock/v3lockpb/v3lock.pb.go | 7 +- server/etcdserver/api/v3rpc/maintenance.go | 43 +- server/etcdserver/healthz.go | 222 ++- server/etcdserver/healthz_test.go | 6 +- .../adapter/maintenance_client_adapter.go | 12 + server/proxy/grpcproxy/maintenance.go | 12 + 18 files changed, 1821 insertions(+), 428 deletions(-) diff --git a/Documentation/dev-guide/apispec/swagger/rpc.swagger.json b/Documentation/dev-guide/apispec/swagger/rpc.swagger.json index 51b0f1ad928..bd67eb908b4 100644 --- a/Documentation/dev-guide/apispec/swagger/rpc.swagger.json +++ b/Documentation/dev-guide/apispec/swagger/rpc.swagger.json @@ -1363,6 +1363,102 @@ ] } }, + "/v3/maintenance/healthz": { + "post": { + "operationId": "Maintenance_Healthz", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/etcdserverpbHealthResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/etcdserverpbHealthRequest" + } + } + ], + "tags": [ + "Maintenance" + ] + } + }, + "/v3/maintenance/livez": { + "post": { + "operationId": "Maintenance_Livez", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/etcdserverpbHealthResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/etcdserverpbHealthRequest" + } + } + ], + "tags": [ + "Maintenance" + ] + } + }, + "/v3/maintenance/readyz": { + "post": { + "operationId": "Maintenance_Readyz", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/etcdserverpbHealthResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/etcdserverpbHealthRequest" + } + } + ], + "tags": [ + "Maintenance" + ] + } + }, "/v3/maintenance/snapshot": { "post": { "summary": "Snapshot sends a snapshot of the entire backend from a member over a stream to a client.", @@ -1563,6 +1659,17 @@ ], "default": "PUT" }, + "HealthRequestStringArray": { + "type": "object", + "properties": { + "values": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, "RangeRequestSortOrder": { "type": "string", "enum": [ @@ -2209,6 +2316,33 @@ } } }, + "etcdserverpbHealthRequest": { + "type": "object", + "properties": { + "exclude": { + "$ref": "#/definitions/HealthRequestStringArray", + "description": "List of health checks to exclude." + }, + "allowlist": { + "$ref": "#/definitions/HealthRequestStringArray", + "description": "List of health checks to allowlist.\nCannot be used with exclude." + } + } + }, + "etcdserverpbHealthResponse": { + "type": "object", + "properties": { + "header": { + "$ref": "#/definitions/etcdserverpbResponseHeader" + }, + "ok": { + "type": "boolean" + }, + "reason": { + "type": "string" + } + } + }, "etcdserverpbLeaseGrantRequest": { "type": "object", "properties": { diff --git a/api/etcdserverpb/rpc.pb.go b/api/etcdserverpb/rpc.pb.go index 79b92e3bed5..0e10e64d3e7 100644 --- a/api/etcdserverpb/rpc.pb.go +++ b/api/etcdserverpb/rpc.pb.go @@ -268,7 +268,7 @@ func (x DowngradeRequest_DowngradeAction) String() string { } func (DowngradeRequest_DowngradeAction) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{57, 0} + return fileDescriptor_77a6da22d6a3feb1, []int{59, 0} } type ResponseHeader struct { @@ -4073,6 +4073,205 @@ func (m *AlarmResponse) GetAlarms() []*AlarmMember { return nil } +type HealthRequest struct { + // Types that are valid to be assigned to HealthCheckSelector: + // + // *HealthRequest_Exclude + // *HealthRequest_Allowlist + HealthCheckSelector isHealthRequest_HealthCheckSelector `protobuf_oneof:"healthCheckSelector"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *HealthRequest) Reset() { *m = HealthRequest{} } +func (m *HealthRequest) String() string { return proto.CompactTextString(m) } +func (*HealthRequest) ProtoMessage() {} +func (*HealthRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_77a6da22d6a3feb1, []int{57} +} +func (m *HealthRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *HealthRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_HealthRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *HealthRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_HealthRequest.Merge(m, src) +} +func (m *HealthRequest) XXX_Size() int { + return m.Size() +} +func (m *HealthRequest) XXX_DiscardUnknown() { + xxx_messageInfo_HealthRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_HealthRequest proto.InternalMessageInfo + +type isHealthRequest_HealthCheckSelector interface { + isHealthRequest_HealthCheckSelector() + MarshalTo([]byte) (int, error) + Size() int +} + +type HealthRequest_Exclude struct { + Exclude *HealthRequest_StringArray `protobuf:"bytes,1,opt,name=exclude,proto3,oneof" json:"exclude,omitempty"` +} +type HealthRequest_Allowlist struct { + Allowlist *HealthRequest_StringArray `protobuf:"bytes,2,opt,name=allowlist,proto3,oneof" json:"allowlist,omitempty"` +} + +func (*HealthRequest_Exclude) isHealthRequest_HealthCheckSelector() {} +func (*HealthRequest_Allowlist) isHealthRequest_HealthCheckSelector() {} + +func (m *HealthRequest) GetHealthCheckSelector() isHealthRequest_HealthCheckSelector { + if m != nil { + return m.HealthCheckSelector + } + return nil +} + +func (m *HealthRequest) GetExclude() *HealthRequest_StringArray { + if x, ok := m.GetHealthCheckSelector().(*HealthRequest_Exclude); ok { + return x.Exclude + } + return nil +} + +func (m *HealthRequest) GetAllowlist() *HealthRequest_StringArray { + if x, ok := m.GetHealthCheckSelector().(*HealthRequest_Allowlist); ok { + return x.Allowlist + } + return nil +} + +// XXX_OneofWrappers is for the internal use of the proto package. +func (*HealthRequest) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*HealthRequest_Exclude)(nil), + (*HealthRequest_Allowlist)(nil), + } +} + +type HealthRequest_StringArray struct { + Values []string `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *HealthRequest_StringArray) Reset() { *m = HealthRequest_StringArray{} } +func (m *HealthRequest_StringArray) String() string { return proto.CompactTextString(m) } +func (*HealthRequest_StringArray) ProtoMessage() {} +func (*HealthRequest_StringArray) Descriptor() ([]byte, []int) { + return fileDescriptor_77a6da22d6a3feb1, []int{57, 0} +} +func (m *HealthRequest_StringArray) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *HealthRequest_StringArray) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_HealthRequest_StringArray.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *HealthRequest_StringArray) XXX_Merge(src proto.Message) { + xxx_messageInfo_HealthRequest_StringArray.Merge(m, src) +} +func (m *HealthRequest_StringArray) XXX_Size() int { + return m.Size() +} +func (m *HealthRequest_StringArray) XXX_DiscardUnknown() { + xxx_messageInfo_HealthRequest_StringArray.DiscardUnknown(m) +} + +var xxx_messageInfo_HealthRequest_StringArray proto.InternalMessageInfo + +func (m *HealthRequest_StringArray) GetValues() []string { + if m != nil { + return m.Values + } + return nil +} + +type HealthResponse struct { + Header *ResponseHeader `protobuf:"bytes,1,opt,name=header,proto3" json:"header,omitempty"` + Ok bool `protobuf:"varint,2,opt,name=ok,proto3" json:"ok,omitempty"` + Reason string `protobuf:"bytes,3,opt,name=reason,proto3" json:"reason,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *HealthResponse) Reset() { *m = HealthResponse{} } +func (m *HealthResponse) String() string { return proto.CompactTextString(m) } +func (*HealthResponse) ProtoMessage() {} +func (*HealthResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_77a6da22d6a3feb1, []int{58} +} +func (m *HealthResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *HealthResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_HealthResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *HealthResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_HealthResponse.Merge(m, src) +} +func (m *HealthResponse) XXX_Size() int { + return m.Size() +} +func (m *HealthResponse) XXX_DiscardUnknown() { + xxx_messageInfo_HealthResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_HealthResponse proto.InternalMessageInfo + +func (m *HealthResponse) GetHeader() *ResponseHeader { + if m != nil { + return m.Header + } + return nil +} + +func (m *HealthResponse) GetOk() bool { + if m != nil { + return m.Ok + } + return false +} + +func (m *HealthResponse) GetReason() string { + if m != nil { + return m.Reason + } + return "" +} + type DowngradeRequest struct { // action is the kind of downgrade request to issue. The action may // VALIDATE the target version, DOWNGRADE the cluster version, @@ -4089,7 +4288,7 @@ func (m *DowngradeRequest) Reset() { *m = DowngradeRequest{} } func (m *DowngradeRequest) String() string { return proto.CompactTextString(m) } func (*DowngradeRequest) ProtoMessage() {} func (*DowngradeRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{57} + return fileDescriptor_77a6da22d6a3feb1, []int{59} } func (m *DowngradeRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4145,7 +4344,7 @@ func (m *DowngradeResponse) Reset() { *m = DowngradeResponse{} } func (m *DowngradeResponse) String() string { return proto.CompactTextString(m) } func (*DowngradeResponse) ProtoMessage() {} func (*DowngradeResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{58} + return fileDescriptor_77a6da22d6a3feb1, []int{60} } func (m *DowngradeResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4198,7 +4397,7 @@ func (m *StatusRequest) Reset() { *m = StatusRequest{} } func (m *StatusRequest) String() string { return proto.CompactTextString(m) } func (*StatusRequest) ProtoMessage() {} func (*StatusRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{59} + return fileDescriptor_77a6da22d6a3feb1, []int{61} } func (m *StatusRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4258,7 +4457,7 @@ func (m *StatusResponse) Reset() { *m = StatusResponse{} } func (m *StatusResponse) String() string { return proto.CompactTextString(m) } func (*StatusResponse) ProtoMessage() {} func (*StatusResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{60} + return fileDescriptor_77a6da22d6a3feb1, []int{62} } func (m *StatusResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4374,7 +4573,7 @@ func (m *AuthEnableRequest) Reset() { *m = AuthEnableRequest{} } func (m *AuthEnableRequest) String() string { return proto.CompactTextString(m) } func (*AuthEnableRequest) ProtoMessage() {} func (*AuthEnableRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{61} + return fileDescriptor_77a6da22d6a3feb1, []int{63} } func (m *AuthEnableRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4413,7 +4612,7 @@ func (m *AuthDisableRequest) Reset() { *m = AuthDisableRequest{} } func (m *AuthDisableRequest) String() string { return proto.CompactTextString(m) } func (*AuthDisableRequest) ProtoMessage() {} func (*AuthDisableRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{62} + return fileDescriptor_77a6da22d6a3feb1, []int{64} } func (m *AuthDisableRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4452,7 +4651,7 @@ func (m *AuthStatusRequest) Reset() { *m = AuthStatusRequest{} } func (m *AuthStatusRequest) String() string { return proto.CompactTextString(m) } func (*AuthStatusRequest) ProtoMessage() {} func (*AuthStatusRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{63} + return fileDescriptor_77a6da22d6a3feb1, []int{65} } func (m *AuthStatusRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4493,7 +4692,7 @@ func (m *AuthenticateRequest) Reset() { *m = AuthenticateRequest{} } func (m *AuthenticateRequest) String() string { return proto.CompactTextString(m) } func (*AuthenticateRequest) ProtoMessage() {} func (*AuthenticateRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{64} + return fileDescriptor_77a6da22d6a3feb1, []int{66} } func (m *AuthenticateRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4550,7 +4749,7 @@ func (m *AuthUserAddRequest) Reset() { *m = AuthUserAddRequest{} } func (m *AuthUserAddRequest) String() string { return proto.CompactTextString(m) } func (*AuthUserAddRequest) ProtoMessage() {} func (*AuthUserAddRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{65} + return fileDescriptor_77a6da22d6a3feb1, []int{67} } func (m *AuthUserAddRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4618,7 +4817,7 @@ func (m *AuthUserGetRequest) Reset() { *m = AuthUserGetRequest{} } func (m *AuthUserGetRequest) String() string { return proto.CompactTextString(m) } func (*AuthUserGetRequest) ProtoMessage() {} func (*AuthUserGetRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{66} + return fileDescriptor_77a6da22d6a3feb1, []int{68} } func (m *AuthUserGetRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4666,7 +4865,7 @@ func (m *AuthUserDeleteRequest) Reset() { *m = AuthUserDeleteRequest{} } func (m *AuthUserDeleteRequest) String() string { return proto.CompactTextString(m) } func (*AuthUserDeleteRequest) ProtoMessage() {} func (*AuthUserDeleteRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{67} + return fileDescriptor_77a6da22d6a3feb1, []int{69} } func (m *AuthUserDeleteRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4718,7 +4917,7 @@ func (m *AuthUserChangePasswordRequest) Reset() { *m = AuthUserChangePas func (m *AuthUserChangePasswordRequest) String() string { return proto.CompactTextString(m) } func (*AuthUserChangePasswordRequest) ProtoMessage() {} func (*AuthUserChangePasswordRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{68} + return fileDescriptor_77a6da22d6a3feb1, []int{70} } func (m *AuthUserChangePasswordRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4782,7 +4981,7 @@ func (m *AuthUserGrantRoleRequest) Reset() { *m = AuthUserGrantRoleReque func (m *AuthUserGrantRoleRequest) String() string { return proto.CompactTextString(m) } func (*AuthUserGrantRoleRequest) ProtoMessage() {} func (*AuthUserGrantRoleRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{69} + return fileDescriptor_77a6da22d6a3feb1, []int{71} } func (m *AuthUserGrantRoleRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4837,7 +5036,7 @@ func (m *AuthUserRevokeRoleRequest) Reset() { *m = AuthUserRevokeRoleReq func (m *AuthUserRevokeRoleRequest) String() string { return proto.CompactTextString(m) } func (*AuthUserRevokeRoleRequest) ProtoMessage() {} func (*AuthUserRevokeRoleRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{70} + return fileDescriptor_77a6da22d6a3feb1, []int{72} } func (m *AuthUserRevokeRoleRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4892,7 +5091,7 @@ func (m *AuthRoleAddRequest) Reset() { *m = AuthRoleAddRequest{} } func (m *AuthRoleAddRequest) String() string { return proto.CompactTextString(m) } func (*AuthRoleAddRequest) ProtoMessage() {} func (*AuthRoleAddRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{71} + return fileDescriptor_77a6da22d6a3feb1, []int{73} } func (m *AuthRoleAddRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4939,7 +5138,7 @@ func (m *AuthRoleGetRequest) Reset() { *m = AuthRoleGetRequest{} } func (m *AuthRoleGetRequest) String() string { return proto.CompactTextString(m) } func (*AuthRoleGetRequest) ProtoMessage() {} func (*AuthRoleGetRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{72} + return fileDescriptor_77a6da22d6a3feb1, []int{74} } func (m *AuthRoleGetRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4985,7 +5184,7 @@ func (m *AuthUserListRequest) Reset() { *m = AuthUserListRequest{} } func (m *AuthUserListRequest) String() string { return proto.CompactTextString(m) } func (*AuthUserListRequest) ProtoMessage() {} func (*AuthUserListRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{73} + return fileDescriptor_77a6da22d6a3feb1, []int{75} } func (m *AuthUserListRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5024,7 +5223,7 @@ func (m *AuthRoleListRequest) Reset() { *m = AuthRoleListRequest{} } func (m *AuthRoleListRequest) String() string { return proto.CompactTextString(m) } func (*AuthRoleListRequest) ProtoMessage() {} func (*AuthRoleListRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{74} + return fileDescriptor_77a6da22d6a3feb1, []int{76} } func (m *AuthRoleListRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5064,7 +5263,7 @@ func (m *AuthRoleDeleteRequest) Reset() { *m = AuthRoleDeleteRequest{} } func (m *AuthRoleDeleteRequest) String() string { return proto.CompactTextString(m) } func (*AuthRoleDeleteRequest) ProtoMessage() {} func (*AuthRoleDeleteRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{75} + return fileDescriptor_77a6da22d6a3feb1, []int{77} } func (m *AuthRoleDeleteRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5114,7 +5313,7 @@ func (m *AuthRoleGrantPermissionRequest) Reset() { *m = AuthRoleGrantPer func (m *AuthRoleGrantPermissionRequest) String() string { return proto.CompactTextString(m) } func (*AuthRoleGrantPermissionRequest) ProtoMessage() {} func (*AuthRoleGrantPermissionRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{76} + return fileDescriptor_77a6da22d6a3feb1, []int{78} } func (m *AuthRoleGrantPermissionRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5170,7 +5369,7 @@ func (m *AuthRoleRevokePermissionRequest) Reset() { *m = AuthRoleRevokeP func (m *AuthRoleRevokePermissionRequest) String() string { return proto.CompactTextString(m) } func (*AuthRoleRevokePermissionRequest) ProtoMessage() {} func (*AuthRoleRevokePermissionRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{77} + return fileDescriptor_77a6da22d6a3feb1, []int{79} } func (m *AuthRoleRevokePermissionRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5231,7 +5430,7 @@ func (m *AuthEnableResponse) Reset() { *m = AuthEnableResponse{} } func (m *AuthEnableResponse) String() string { return proto.CompactTextString(m) } func (*AuthEnableResponse) ProtoMessage() {} func (*AuthEnableResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{78} + return fileDescriptor_77a6da22d6a3feb1, []int{80} } func (m *AuthEnableResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5278,7 +5477,7 @@ func (m *AuthDisableResponse) Reset() { *m = AuthDisableResponse{} } func (m *AuthDisableResponse) String() string { return proto.CompactTextString(m) } func (*AuthDisableResponse) ProtoMessage() {} func (*AuthDisableResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{79} + return fileDescriptor_77a6da22d6a3feb1, []int{81} } func (m *AuthDisableResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5328,7 +5527,7 @@ func (m *AuthStatusResponse) Reset() { *m = AuthStatusResponse{} } func (m *AuthStatusResponse) String() string { return proto.CompactTextString(m) } func (*AuthStatusResponse) ProtoMessage() {} func (*AuthStatusResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{80} + return fileDescriptor_77a6da22d6a3feb1, []int{82} } func (m *AuthStatusResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5391,7 +5590,7 @@ func (m *AuthenticateResponse) Reset() { *m = AuthenticateResponse{} } func (m *AuthenticateResponse) String() string { return proto.CompactTextString(m) } func (*AuthenticateResponse) ProtoMessage() {} func (*AuthenticateResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{81} + return fileDescriptor_77a6da22d6a3feb1, []int{83} } func (m *AuthenticateResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5445,7 +5644,7 @@ func (m *AuthUserAddResponse) Reset() { *m = AuthUserAddResponse{} } func (m *AuthUserAddResponse) String() string { return proto.CompactTextString(m) } func (*AuthUserAddResponse) ProtoMessage() {} func (*AuthUserAddResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{82} + return fileDescriptor_77a6da22d6a3feb1, []int{84} } func (m *AuthUserAddResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5493,7 +5692,7 @@ func (m *AuthUserGetResponse) Reset() { *m = AuthUserGetResponse{} } func (m *AuthUserGetResponse) String() string { return proto.CompactTextString(m) } func (*AuthUserGetResponse) ProtoMessage() {} func (*AuthUserGetResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{83} + return fileDescriptor_77a6da22d6a3feb1, []int{85} } func (m *AuthUserGetResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5547,7 +5746,7 @@ func (m *AuthUserDeleteResponse) Reset() { *m = AuthUserDeleteResponse{} func (m *AuthUserDeleteResponse) String() string { return proto.CompactTextString(m) } func (*AuthUserDeleteResponse) ProtoMessage() {} func (*AuthUserDeleteResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{84} + return fileDescriptor_77a6da22d6a3feb1, []int{86} } func (m *AuthUserDeleteResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5594,7 +5793,7 @@ func (m *AuthUserChangePasswordResponse) Reset() { *m = AuthUserChangePa func (m *AuthUserChangePasswordResponse) String() string { return proto.CompactTextString(m) } func (*AuthUserChangePasswordResponse) ProtoMessage() {} func (*AuthUserChangePasswordResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{85} + return fileDescriptor_77a6da22d6a3feb1, []int{87} } func (m *AuthUserChangePasswordResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5641,7 +5840,7 @@ func (m *AuthUserGrantRoleResponse) Reset() { *m = AuthUserGrantRoleResp func (m *AuthUserGrantRoleResponse) String() string { return proto.CompactTextString(m) } func (*AuthUserGrantRoleResponse) ProtoMessage() {} func (*AuthUserGrantRoleResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{86} + return fileDescriptor_77a6da22d6a3feb1, []int{88} } func (m *AuthUserGrantRoleResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5688,7 +5887,7 @@ func (m *AuthUserRevokeRoleResponse) Reset() { *m = AuthUserRevokeRoleRe func (m *AuthUserRevokeRoleResponse) String() string { return proto.CompactTextString(m) } func (*AuthUserRevokeRoleResponse) ProtoMessage() {} func (*AuthUserRevokeRoleResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{87} + return fileDescriptor_77a6da22d6a3feb1, []int{89} } func (m *AuthUserRevokeRoleResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5735,7 +5934,7 @@ func (m *AuthRoleAddResponse) Reset() { *m = AuthRoleAddResponse{} } func (m *AuthRoleAddResponse) String() string { return proto.CompactTextString(m) } func (*AuthRoleAddResponse) ProtoMessage() {} func (*AuthRoleAddResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{88} + return fileDescriptor_77a6da22d6a3feb1, []int{90} } func (m *AuthRoleAddResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5783,7 +5982,7 @@ func (m *AuthRoleGetResponse) Reset() { *m = AuthRoleGetResponse{} } func (m *AuthRoleGetResponse) String() string { return proto.CompactTextString(m) } func (*AuthRoleGetResponse) ProtoMessage() {} func (*AuthRoleGetResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{89} + return fileDescriptor_77a6da22d6a3feb1, []int{91} } func (m *AuthRoleGetResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5838,7 +6037,7 @@ func (m *AuthRoleListResponse) Reset() { *m = AuthRoleListResponse{} } func (m *AuthRoleListResponse) String() string { return proto.CompactTextString(m) } func (*AuthRoleListResponse) ProtoMessage() {} func (*AuthRoleListResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{90} + return fileDescriptor_77a6da22d6a3feb1, []int{92} } func (m *AuthRoleListResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5893,7 +6092,7 @@ func (m *AuthUserListResponse) Reset() { *m = AuthUserListResponse{} } func (m *AuthUserListResponse) String() string { return proto.CompactTextString(m) } func (*AuthUserListResponse) ProtoMessage() {} func (*AuthUserListResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{91} + return fileDescriptor_77a6da22d6a3feb1, []int{93} } func (m *AuthUserListResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5947,7 +6146,7 @@ func (m *AuthRoleDeleteResponse) Reset() { *m = AuthRoleDeleteResponse{} func (m *AuthRoleDeleteResponse) String() string { return proto.CompactTextString(m) } func (*AuthRoleDeleteResponse) ProtoMessage() {} func (*AuthRoleDeleteResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{92} + return fileDescriptor_77a6da22d6a3feb1, []int{94} } func (m *AuthRoleDeleteResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5994,7 +6193,7 @@ func (m *AuthRoleGrantPermissionResponse) Reset() { *m = AuthRoleGrantPe func (m *AuthRoleGrantPermissionResponse) String() string { return proto.CompactTextString(m) } func (*AuthRoleGrantPermissionResponse) ProtoMessage() {} func (*AuthRoleGrantPermissionResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{93} + return fileDescriptor_77a6da22d6a3feb1, []int{95} } func (m *AuthRoleGrantPermissionResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6041,7 +6240,7 @@ func (m *AuthRoleRevokePermissionResponse) Reset() { *m = AuthRoleRevoke func (m *AuthRoleRevokePermissionResponse) String() string { return proto.CompactTextString(m) } func (*AuthRoleRevokePermissionResponse) ProtoMessage() {} func (*AuthRoleRevokePermissionResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_77a6da22d6a3feb1, []int{94} + return fileDescriptor_77a6da22d6a3feb1, []int{96} } func (m *AuthRoleRevokePermissionResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6143,6 +6342,9 @@ func init() { proto.RegisterType((*AlarmRequest)(nil), "etcdserverpb.AlarmRequest") proto.RegisterType((*AlarmMember)(nil), "etcdserverpb.AlarmMember") proto.RegisterType((*AlarmResponse)(nil), "etcdserverpb.AlarmResponse") + proto.RegisterType((*HealthRequest)(nil), "etcdserverpb.HealthRequest") + proto.RegisterType((*HealthRequest_StringArray)(nil), "etcdserverpb.HealthRequest.StringArray") + proto.RegisterType((*HealthResponse)(nil), "etcdserverpb.HealthResponse") proto.RegisterType((*DowngradeRequest)(nil), "etcdserverpb.DowngradeRequest") proto.RegisterType((*DowngradeResponse)(nil), "etcdserverpb.DowngradeResponse") proto.RegisterType((*StatusRequest)(nil), "etcdserverpb.StatusRequest") @@ -6186,289 +6388,299 @@ func init() { func init() { proto.RegisterFile("rpc.proto", fileDescriptor_77a6da22d6a3feb1) } var fileDescriptor_77a6da22d6a3feb1 = []byte{ - // 4499 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x7c, 0x5f, 0x6f, 0x1b, 0x49, - 0x72, 0xb8, 0x86, 0x94, 0x44, 0xb1, 0x48, 0x51, 0x54, 0x5b, 0xb6, 0x69, 0xae, 0x2d, 0x6b, 0xc7, - 0xeb, 0x5d, 0xaf, 0x77, 0x2d, 0xda, 0x92, 0x7d, 0xfb, 0xfb, 0x39, 0xd8, 0xcd, 0xd1, 0x12, 0xd7, - 0x56, 0x2c, 0x4b, 0xba, 0x11, 0xed, 0xbd, 0x75, 0x80, 0x53, 0x46, 0x64, 0x9b, 0x9a, 0x13, 0x39, - 0xc3, 0x9b, 0x19, 0xd1, 0xd2, 0xe6, 0xe1, 0x36, 0x97, 0x5c, 0x0e, 0x97, 0x00, 0x07, 0x64, 0x03, - 0x04, 0x87, 0x20, 0x79, 0x09, 0x02, 0x24, 0x0f, 0x97, 0x20, 0x79, 0xc8, 0x43, 0x90, 0x00, 0x79, - 0x48, 0x1e, 0x92, 0x87, 0x00, 0x01, 0xf2, 0x05, 0x92, 0xcd, 0x3d, 0xe5, 0x53, 0x04, 0xfd, 0x6f, - 0xba, 0x67, 0xa6, 0x47, 0xd2, 0x9e, 0xb4, 0xb8, 0x17, 0x6b, 0xba, 0xbb, 0xba, 0xaa, 0xba, 0xaa, - 0xab, 0xaa, 0xbb, 0xaa, 0x4d, 0x28, 0xfa, 0xc3, 0xce, 0xe2, 0xd0, 0xf7, 0x42, 0x0f, 0x95, 0x71, - 0xd8, 0xe9, 0x06, 0xd8, 0x1f, 0x61, 0x7f, 0xb8, 0x5b, 0x9f, 0xeb, 0x79, 0x3d, 0x8f, 0x0e, 0x34, - 0xc8, 0x17, 0x83, 0xa9, 0xd7, 0x08, 0x4c, 0xc3, 0x1e, 0x3a, 0x8d, 0xc1, 0xa8, 0xd3, 0x19, 0xee, - 0x36, 0xf6, 0x47, 0x7c, 0xa4, 0x1e, 0x8d, 0xd8, 0x07, 0xe1, 0xde, 0x70, 0x97, 0xfe, 0xe1, 0x63, - 0x0b, 0xd1, 0xd8, 0x08, 0xfb, 0x81, 0xe3, 0xb9, 0xc3, 0x5d, 0xf1, 0xc5, 0x21, 0xae, 0xf6, 0x3c, - 0xaf, 0xd7, 0xc7, 0x6c, 0xbe, 0xeb, 0x7a, 0xa1, 0x1d, 0x3a, 0x9e, 0x1b, 0xf0, 0x51, 0xf6, 0xa7, - 0x73, 0xa7, 0x87, 0xdd, 0x3b, 0xde, 0x10, 0xbb, 0xf6, 0xd0, 0x19, 0x2d, 0x35, 0xbc, 0x21, 0x85, - 0x49, 0xc3, 0x9b, 0x3f, 0x31, 0xa0, 0x62, 0xe1, 0x60, 0xe8, 0xb9, 0x01, 0x7e, 0x82, 0xed, 0x2e, - 0xf6, 0xd1, 0x35, 0x80, 0x4e, 0xff, 0x20, 0x08, 0xb1, 0xbf, 0xe3, 0x74, 0x6b, 0xc6, 0x82, 0x71, - 0x6b, 0xdc, 0x2a, 0xf2, 0x9e, 0xb5, 0x2e, 0x7a, 0x03, 0x8a, 0x03, 0x3c, 0xd8, 0x65, 0xa3, 0x39, - 0x3a, 0x3a, 0xc5, 0x3a, 0xd6, 0xba, 0xa8, 0x0e, 0x53, 0x3e, 0x1e, 0x39, 0x84, 0xdd, 0x5a, 0x7e, - 0xc1, 0xb8, 0x95, 0xb7, 0xa2, 0x36, 0x99, 0xe8, 0xdb, 0xaf, 0xc2, 0x9d, 0x10, 0xfb, 0x83, 0xda, - 0x38, 0x9b, 0x48, 0x3a, 0xda, 0xd8, 0x1f, 0x3c, 0x2c, 0xfc, 0xe0, 0xef, 0x6a, 0xf9, 0xe5, 0xc5, - 0xbb, 0xe6, 0x3f, 0x4f, 0x40, 0xd9, 0xb2, 0xdd, 0x1e, 0xb6, 0xf0, 0xf7, 0x0e, 0x70, 0x10, 0xa2, - 0x2a, 0xe4, 0xf7, 0xf1, 0x11, 0xe5, 0xa3, 0x6c, 0x91, 0x4f, 0x86, 0xc8, 0xed, 0xe1, 0x1d, 0xec, - 0x32, 0x0e, 0xca, 0x04, 0x91, 0xdb, 0xc3, 0x2d, 0xb7, 0x8b, 0xe6, 0x60, 0xa2, 0xef, 0x0c, 0x9c, - 0x90, 0x93, 0x67, 0x8d, 0x18, 0x5f, 0xe3, 0x09, 0xbe, 0x56, 0x00, 0x02, 0xcf, 0x0f, 0x77, 0x3c, - 0xbf, 0x8b, 0xfd, 0xda, 0xc4, 0x82, 0x71, 0xab, 0xb2, 0xf4, 0xd6, 0xa2, 0xaa, 0xe1, 0x45, 0x95, - 0xa1, 0xc5, 0x6d, 0xcf, 0x0f, 0x37, 0x09, 0xac, 0x55, 0x0c, 0xc4, 0x27, 0xfa, 0x18, 0x4a, 0x14, - 0x49, 0x68, 0xfb, 0x3d, 0x1c, 0xd6, 0x26, 0x29, 0x96, 0x9b, 0x27, 0x60, 0x69, 0x53, 0x60, 0x8b, - 0x92, 0x67, 0xdf, 0xc8, 0x84, 0x72, 0x80, 0x7d, 0xc7, 0xee, 0x3b, 0x9f, 0xd9, 0xbb, 0x7d, 0x5c, - 0x2b, 0x2c, 0x18, 0xb7, 0xa6, 0xac, 0x58, 0x1f, 0x59, 0xff, 0x3e, 0x3e, 0x0a, 0x76, 0x3c, 0xb7, - 0x7f, 0x54, 0x9b, 0xa2, 0x00, 0x53, 0xa4, 0x63, 0xd3, 0xed, 0x1f, 0x51, 0xed, 0x79, 0x07, 0x6e, - 0xc8, 0x46, 0x8b, 0x74, 0xb4, 0x48, 0x7b, 0xe8, 0xf0, 0x3d, 0xa8, 0x0e, 0x1c, 0x77, 0x67, 0xe0, - 0x75, 0x77, 0x22, 0x81, 0x00, 0x11, 0xc8, 0xa3, 0xc2, 0xef, 0x51, 0x0d, 0xdc, 0xb3, 0x2a, 0x03, - 0xc7, 0x7d, 0xe6, 0x75, 0x2d, 0x21, 0x1f, 0x32, 0xc5, 0x3e, 0x8c, 0x4f, 0x29, 0x25, 0xa7, 0xd8, - 0x87, 0xea, 0x94, 0x0f, 0xe0, 0x02, 0xa1, 0xd2, 0xf1, 0xb1, 0x1d, 0x62, 0x39, 0xab, 0x1c, 0x9f, - 0x35, 0x3b, 0x70, 0xdc, 0x15, 0x0a, 0x12, 0x9b, 0x68, 0x1f, 0xa6, 0x26, 0x4e, 0x27, 0x27, 0xda, - 0x87, 0xf1, 0x89, 0xe6, 0x07, 0x50, 0x8c, 0xf4, 0x82, 0xa6, 0x60, 0x7c, 0x63, 0x73, 0xa3, 0x55, - 0x1d, 0x43, 0x00, 0x93, 0xcd, 0xed, 0x95, 0xd6, 0xc6, 0x6a, 0xd5, 0x40, 0x25, 0x28, 0xac, 0xb6, - 0x58, 0x23, 0x57, 0x2f, 0x7c, 0xc1, 0xf7, 0xdb, 0x53, 0x00, 0xa9, 0x0a, 0x54, 0x80, 0xfc, 0xd3, - 0xd6, 0xa7, 0xd5, 0x31, 0x02, 0xfc, 0xa2, 0x65, 0x6d, 0xaf, 0x6d, 0x6e, 0x54, 0x0d, 0x82, 0x65, - 0xc5, 0x6a, 0x35, 0xdb, 0xad, 0x6a, 0x8e, 0x40, 0x3c, 0xdb, 0x5c, 0xad, 0xe6, 0x51, 0x11, 0x26, - 0x5e, 0x34, 0xd7, 0x9f, 0xb7, 0xaa, 0xe3, 0x11, 0x32, 0xb9, 0x8b, 0xff, 0xc4, 0x80, 0x69, 0xae, - 0x6e, 0x66, 0x5b, 0xe8, 0x3e, 0x4c, 0xee, 0x51, 0xfb, 0xa2, 0x3b, 0xb9, 0xb4, 0x74, 0x35, 0xb1, - 0x37, 0x62, 0x36, 0x68, 0x71, 0x58, 0x64, 0x42, 0x7e, 0x7f, 0x14, 0xd4, 0x72, 0x0b, 0xf9, 0x5b, - 0xa5, 0xa5, 0xea, 0x22, 0xf3, 0x24, 0x8b, 0x4f, 0xf1, 0xd1, 0x0b, 0xbb, 0x7f, 0x80, 0x2d, 0x32, - 0x88, 0x10, 0x8c, 0x0f, 0x3c, 0x1f, 0xd3, 0x0d, 0x3f, 0x65, 0xd1, 0x6f, 0x62, 0x05, 0x54, 0xe7, - 0x7c, 0xb3, 0xb3, 0x86, 0x64, 0xef, 0xdf, 0x0d, 0x80, 0xad, 0x83, 0x30, 0xdb, 0xc4, 0xe6, 0x60, - 0x62, 0x44, 0x28, 0x70, 0xf3, 0x62, 0x0d, 0x6a, 0x5b, 0xd8, 0x0e, 0x70, 0x64, 0x5b, 0xa4, 0x81, - 0x16, 0xa0, 0x30, 0xf4, 0xf1, 0x68, 0x67, 0x7f, 0x44, 0xa9, 0x4d, 0x49, 0x3d, 0x4d, 0x92, 0xfe, - 0xa7, 0x23, 0x74, 0x1b, 0xca, 0x4e, 0xcf, 0xf5, 0x7c, 0xbc, 0xc3, 0x90, 0x4e, 0xa8, 0x60, 0x4b, - 0x56, 0x89, 0x0d, 0xd2, 0x25, 0x29, 0xb0, 0x8c, 0xd4, 0xa4, 0x16, 0x76, 0x9d, 0x8c, 0xc9, 0xf5, - 0x7c, 0x6e, 0x40, 0x89, 0xae, 0xe7, 0x4c, 0xc2, 0x5e, 0x92, 0x0b, 0xc9, 0xd1, 0x69, 0x29, 0x81, - 0xa7, 0x96, 0x26, 0x59, 0x70, 0x01, 0xad, 0xe2, 0x3e, 0x0e, 0xf1, 0x59, 0x9c, 0x97, 0x22, 0xca, - 0xbc, 0x56, 0x94, 0x92, 0xde, 0x9f, 0x1b, 0x70, 0x21, 0x46, 0xf0, 0x4c, 0x4b, 0xaf, 0x41, 0xa1, - 0x4b, 0x91, 0x31, 0x9e, 0xf2, 0x96, 0x68, 0xa2, 0xfb, 0x30, 0xc5, 0x59, 0x0a, 0x6a, 0x79, 0xfd, - 0x36, 0x94, 0x5c, 0x16, 0x18, 0x97, 0x81, 0x64, 0xf3, 0x1f, 0x72, 0x50, 0xe4, 0xc2, 0xd8, 0x1c, - 0xa2, 0x26, 0x4c, 0xfb, 0xac, 0xb1, 0x43, 0xd7, 0xcc, 0x79, 0xac, 0x67, 0xfb, 0xc9, 0x27, 0x63, - 0x56, 0x99, 0x4f, 0xa1, 0xdd, 0xe8, 0x57, 0xa0, 0x24, 0x50, 0x0c, 0x0f, 0x42, 0xae, 0xa8, 0x5a, - 0x1c, 0x81, 0xdc, 0xda, 0x4f, 0xc6, 0x2c, 0xe0, 0xe0, 0x5b, 0x07, 0x21, 0x6a, 0xc3, 0x9c, 0x98, - 0xcc, 0xd6, 0xc7, 0xd9, 0xc8, 0x53, 0x2c, 0x0b, 0x71, 0x2c, 0x69, 0x75, 0x3e, 0x19, 0xb3, 0x10, - 0x9f, 0xaf, 0x0c, 0xa2, 0x55, 0xc9, 0x52, 0x78, 0xc8, 0xe2, 0x4b, 0x8a, 0xa5, 0xf6, 0xa1, 0xcb, - 0x91, 0x08, 0x69, 0x2d, 0x2b, 0xbc, 0xb5, 0x0f, 0xdd, 0x48, 0x64, 0x8f, 0x8a, 0x50, 0xe0, 0xdd, - 0xe6, 0xbf, 0xe5, 0x00, 0x84, 0xc6, 0x36, 0x87, 0x68, 0x15, 0x2a, 0x3e, 0x6f, 0xc5, 0xe4, 0xf7, - 0x86, 0x56, 0x7e, 0x5c, 0xd1, 0x63, 0xd6, 0xb4, 0x98, 0xc4, 0xd8, 0xfd, 0x08, 0xca, 0x11, 0x16, - 0x29, 0xc2, 0x2b, 0x1a, 0x11, 0x46, 0x18, 0x4a, 0x62, 0x02, 0x11, 0xe2, 0x27, 0x70, 0x31, 0x9a, - 0xaf, 0x91, 0xe2, 0x9b, 0xc7, 0x48, 0x31, 0x42, 0x78, 0x41, 0x60, 0x50, 0xe5, 0xf8, 0x58, 0x61, - 0x4c, 0x0a, 0xf2, 0x8a, 0x46, 0x90, 0x0c, 0x48, 0x95, 0x64, 0xc4, 0x61, 0x4c, 0x94, 0x40, 0xc2, - 0x3e, 0xeb, 0x37, 0xff, 0x72, 0x1c, 0x0a, 0x2b, 0xde, 0x60, 0x68, 0xfb, 0x64, 0x13, 0x4d, 0xfa, - 0x38, 0x38, 0xe8, 0x87, 0x54, 0x80, 0x95, 0xa5, 0x1b, 0x71, 0x1a, 0x1c, 0x4c, 0xfc, 0xb5, 0x28, - 0xa8, 0xc5, 0xa7, 0x90, 0xc9, 0x3c, 0xca, 0xe7, 0x4e, 0x31, 0x99, 0xc7, 0x78, 0x3e, 0x45, 0x38, - 0x84, 0xbc, 0x74, 0x08, 0x75, 0x28, 0xf0, 0x03, 0x1e, 0x73, 0xd6, 0x4f, 0xc6, 0x2c, 0xd1, 0x81, - 0xde, 0x85, 0x99, 0x64, 0x28, 0x9c, 0xe0, 0x30, 0x95, 0x4e, 0x3c, 0x72, 0xde, 0x80, 0x72, 0x2c, - 0x42, 0x4f, 0x72, 0xb8, 0xd2, 0x40, 0x89, 0xcb, 0x97, 0x84, 0x5b, 0x27, 0xc7, 0x8a, 0xf2, 0x93, - 0x31, 0xe1, 0xd8, 0xaf, 0x0b, 0xc7, 0x3e, 0xa5, 0x06, 0x5a, 0x22, 0x57, 0xee, 0xe3, 0xdf, 0x52, - 0xbd, 0xd6, 0x37, 0xc9, 0xe4, 0x08, 0x48, 0xba, 0x2f, 0xd3, 0x82, 0xe9, 0x98, 0xc8, 0x48, 0x8c, - 0x6c, 0x7d, 0xeb, 0x79, 0x73, 0x9d, 0x05, 0xd4, 0xc7, 0x34, 0x86, 0x5a, 0x55, 0x83, 0x04, 0xe8, - 0xf5, 0xd6, 0xf6, 0x76, 0x35, 0x87, 0x2e, 0x41, 0x71, 0x63, 0xb3, 0xbd, 0xc3, 0xa0, 0xf2, 0xf5, - 0xc2, 0x1f, 0x33, 0x4f, 0x22, 0xe3, 0xf3, 0xa7, 0x11, 0x4e, 0x1e, 0xa2, 0x95, 0xc8, 0x3c, 0xa6, - 0x44, 0x66, 0x43, 0x44, 0xe6, 0x9c, 0x8c, 0xcc, 0x79, 0x84, 0x60, 0x62, 0xbd, 0xd5, 0xdc, 0xa6, - 0x41, 0x9a, 0xa1, 0x5e, 0x4e, 0x47, 0xeb, 0x47, 0x15, 0x28, 0x33, 0xf5, 0xec, 0x1c, 0xb8, 0xe4, - 0x30, 0xf1, 0x33, 0x03, 0x40, 0x1a, 0x2c, 0x6a, 0x40, 0xa1, 0xc3, 0x58, 0xa8, 0x19, 0xd4, 0x03, - 0x5e, 0xd4, 0x6a, 0xdc, 0x12, 0x50, 0xe8, 0x1e, 0x14, 0x82, 0x83, 0x4e, 0x07, 0x07, 0x22, 0x72, - 0x5f, 0x4e, 0x3a, 0x61, 0xee, 0x10, 0x2d, 0x01, 0x47, 0xa6, 0xbc, 0xb2, 0x9d, 0xfe, 0x01, 0x8d, - 0xe3, 0xc7, 0x4f, 0xe1, 0x70, 0xd2, 0xc7, 0xfe, 0x99, 0x01, 0x25, 0xc5, 0x2c, 0x7e, 0xc1, 0x10, - 0x70, 0x15, 0x8a, 0x94, 0x19, 0xdc, 0xe5, 0x41, 0x60, 0xca, 0x92, 0x1d, 0xe8, 0x1b, 0x50, 0x14, - 0x96, 0x24, 0xe2, 0x40, 0x4d, 0x8f, 0x76, 0x73, 0x68, 0x49, 0x50, 0xc9, 0x64, 0x1b, 0x66, 0xa9, - 0x9c, 0x3a, 0xe4, 0xf6, 0x21, 0x24, 0xab, 0x1e, 0xcb, 0x8d, 0xc4, 0xb1, 0xbc, 0x0e, 0x53, 0xc3, - 0xbd, 0xa3, 0xc0, 0xe9, 0xd8, 0x7d, 0xce, 0x4e, 0xd4, 0x96, 0x58, 0xb7, 0x01, 0xa9, 0x58, 0xcf, - 0x22, 0x00, 0x89, 0xf4, 0x12, 0x94, 0x9e, 0xd8, 0xc1, 0x1e, 0x67, 0x52, 0xf6, 0xdf, 0x87, 0x69, - 0xd2, 0xff, 0xf4, 0xc5, 0x29, 0xd8, 0x17, 0xb3, 0x96, 0xcd, 0x7f, 0x34, 0xa0, 0x22, 0xa6, 0x9d, - 0x49, 0x41, 0x08, 0xc6, 0xf7, 0xec, 0x60, 0x8f, 0x0a, 0x63, 0xda, 0xa2, 0xdf, 0xe8, 0x5d, 0xa8, - 0x76, 0xd8, 0xfa, 0x77, 0x12, 0xf7, 0xae, 0x19, 0xde, 0x1f, 0xd9, 0xfe, 0xfb, 0x30, 0x4d, 0xa6, - 0xec, 0xc4, 0xef, 0x41, 0xc2, 0x8c, 0xbf, 0x61, 0x95, 0xf7, 0xe8, 0x9a, 0x93, 0xec, 0xdb, 0x50, - 0x66, 0xc2, 0x38, 0x6f, 0xde, 0xa5, 0x5c, 0xeb, 0x30, 0xb3, 0xed, 0xda, 0xc3, 0x60, 0xcf, 0x0b, - 0x13, 0x32, 0x5f, 0x36, 0xff, 0xd6, 0x80, 0xaa, 0x1c, 0x3c, 0x13, 0x0f, 0xef, 0xc0, 0x8c, 0x8f, - 0x07, 0xb6, 0xe3, 0x3a, 0x6e, 0x6f, 0x67, 0xf7, 0x28, 0xc4, 0x01, 0xbf, 0xbe, 0x56, 0xa2, 0xee, - 0x47, 0xa4, 0x97, 0x30, 0xbb, 0xdb, 0xf7, 0x76, 0xb9, 0x93, 0xa6, 0xdf, 0xe8, 0xcd, 0xb8, 0x97, - 0x2e, 0x4a, 0xb9, 0x89, 0x7e, 0xc9, 0xf3, 0x4f, 0x73, 0x50, 0xfe, 0xc4, 0x0e, 0x3b, 0x62, 0x07, - 0xa1, 0x35, 0xa8, 0x44, 0x6e, 0x9c, 0xf6, 0x70, 0xbe, 0x13, 0x07, 0x0e, 0x3a, 0x47, 0xdc, 0x6b, - 0xc4, 0x81, 0x63, 0xba, 0xa3, 0x76, 0x50, 0x54, 0xb6, 0xdb, 0xc1, 0xfd, 0x08, 0x55, 0x2e, 0x1b, - 0x15, 0x05, 0x54, 0x51, 0xa9, 0x1d, 0xe8, 0xdb, 0x50, 0x1d, 0xfa, 0x5e, 0xcf, 0xc7, 0x41, 0x10, - 0x21, 0x63, 0x21, 0xdc, 0xd4, 0x20, 0xdb, 0xe2, 0xa0, 0x89, 0x53, 0xcc, 0xfd, 0x27, 0x63, 0xd6, - 0xcc, 0x30, 0x3e, 0x26, 0x1d, 0xeb, 0x8c, 0x3c, 0xef, 0x31, 0xcf, 0xfa, 0xa3, 0x3c, 0xa0, 0xf4, - 0x32, 0xbf, 0xea, 0x31, 0xf9, 0x26, 0x54, 0x82, 0xd0, 0xf6, 0x53, 0x7b, 0x7e, 0x9a, 0xf6, 0x46, - 0x3b, 0xfe, 0x1d, 0x88, 0x38, 0xdb, 0x71, 0xbd, 0xd0, 0x79, 0x75, 0xc4, 0x2e, 0x28, 0x56, 0x45, - 0x74, 0x6f, 0xd0, 0x5e, 0xb4, 0x01, 0x85, 0x57, 0x4e, 0x3f, 0xc4, 0x7e, 0x50, 0x9b, 0x58, 0xc8, - 0xdf, 0xaa, 0x2c, 0xbd, 0x77, 0x92, 0x62, 0x16, 0x3f, 0xa6, 0xf0, 0xed, 0xa3, 0xa1, 0x7a, 0xfa, - 0xe5, 0x48, 0xd4, 0x63, 0xfc, 0xa4, 0xfe, 0x46, 0x64, 0xc2, 0xd4, 0x6b, 0x82, 0x74, 0xc7, 0xe9, - 0xd2, 0x58, 0x1c, 0xd9, 0xe1, 0x7d, 0xab, 0x40, 0x07, 0xd6, 0xba, 0xe8, 0x06, 0x4c, 0xbd, 0xf2, - 0xed, 0xde, 0x00, 0xbb, 0x21, 0xbb, 0xe5, 0x4b, 0x98, 0x68, 0xc0, 0x5c, 0x04, 0x90, 0xac, 0x90, - 0xc8, 0xb7, 0xb1, 0xb9, 0xf5, 0xbc, 0x5d, 0x1d, 0x43, 0x65, 0x98, 0xda, 0xd8, 0x5c, 0x6d, 0xad, - 0xb7, 0x48, 0x6c, 0x14, 0x31, 0xef, 0x9e, 0x34, 0xba, 0xa6, 0x50, 0x44, 0x6c, 0x4f, 0xa8, 0x7c, - 0x19, 0xf1, 0x4b, 0xb7, 0xe0, 0x4b, 0xa0, 0xb8, 0x67, 0x5e, 0x87, 0x39, 0xdd, 0xd6, 0x10, 0x00, - 0xf7, 0xcd, 0x7f, 0xc9, 0xc1, 0x34, 0x37, 0x84, 0x33, 0x59, 0xee, 0x15, 0x85, 0x2b, 0x7e, 0x3d, - 0x11, 0x42, 0xaa, 0x41, 0x81, 0x19, 0x48, 0x97, 0xdf, 0x7f, 0x45, 0x93, 0x38, 0x67, 0xb6, 0xdf, - 0x71, 0x97, 0xab, 0x3d, 0x6a, 0x6b, 0xdd, 0xe6, 0x44, 0xa6, 0xdb, 0x8c, 0x0c, 0xce, 0x0e, 0xf8, - 0xc1, 0xaa, 0x28, 0x55, 0x51, 0x16, 0x46, 0x45, 0x06, 0x63, 0x3a, 0x2b, 0x64, 0xe8, 0x0c, 0xdd, - 0x84, 0x49, 0x3c, 0xc2, 0x6e, 0x18, 0xd4, 0x4a, 0x34, 0x90, 0x4e, 0x8b, 0x0b, 0x55, 0x8b, 0xf4, - 0x5a, 0x7c, 0x50, 0xaa, 0xea, 0x23, 0x98, 0xa5, 0xf7, 0xdd, 0xc7, 0xbe, 0xed, 0xaa, 0x77, 0xf6, - 0x76, 0x7b, 0x9d, 0x87, 0x1d, 0xf2, 0x89, 0x2a, 0x90, 0x5b, 0x5b, 0xe5, 0xf2, 0xc9, 0xad, 0xad, - 0xca, 0xf9, 0xbf, 0x6f, 0x00, 0x52, 0x11, 0x9c, 0x49, 0x17, 0x09, 0x2a, 0x82, 0x8f, 0xbc, 0xe4, - 0x63, 0x0e, 0x26, 0xb0, 0xef, 0x7b, 0x3e, 0x73, 0x94, 0x16, 0x6b, 0x48, 0x6e, 0xee, 0x70, 0x66, - 0x2c, 0x3c, 0xf2, 0xf6, 0x23, 0x0f, 0xc0, 0xd0, 0x1a, 0x69, 0xe6, 0xdb, 0x70, 0x21, 0x06, 0x7e, - 0x3e, 0x21, 0x7e, 0x13, 0x66, 0x28, 0xd6, 0x95, 0x3d, 0xdc, 0xd9, 0x1f, 0x7a, 0x8e, 0x9b, 0xe2, - 0x00, 0xdd, 0x20, 0xbe, 0x4b, 0x84, 0x0b, 0xb2, 0x44, 0xb6, 0xe6, 0x72, 0xd4, 0xd9, 0x6e, 0xaf, - 0xcb, 0xad, 0xbe, 0x0b, 0x97, 0x12, 0x08, 0xc5, 0xca, 0x7e, 0x15, 0x4a, 0x9d, 0xa8, 0x33, 0xe0, - 0x27, 0xc8, 0x6b, 0x71, 0x76, 0x93, 0x53, 0xd5, 0x19, 0x92, 0xc6, 0xb7, 0xe1, 0x72, 0x8a, 0xc6, - 0x79, 0x88, 0xe3, 0xbe, 0x79, 0x17, 0x2e, 0x52, 0xcc, 0x4f, 0x31, 0x1e, 0x36, 0xfb, 0xce, 0xe8, - 0x64, 0xb5, 0x1c, 0xf1, 0xf5, 0x2a, 0x33, 0xbe, 0xde, 0x6d, 0x25, 0x49, 0xb7, 0x38, 0xe9, 0xb6, - 0x33, 0xc0, 0x6d, 0x6f, 0x3d, 0x9b, 0x5b, 0x12, 0xc8, 0xf7, 0xf1, 0x51, 0xc0, 0x8f, 0x8f, 0xf4, - 0x5b, 0x7a, 0xaf, 0xbf, 0x36, 0xb8, 0x38, 0x55, 0x3c, 0x5f, 0xb3, 0x69, 0xcc, 0x03, 0xf4, 0x88, - 0x0d, 0xe2, 0x2e, 0x19, 0x60, 0xb9, 0x39, 0xa5, 0x27, 0x62, 0x98, 0x44, 0xa1, 0x72, 0x92, 0xe1, - 0x6b, 0xdc, 0x70, 0xe8, 0x3f, 0x41, 0xea, 0xa4, 0xf4, 0x36, 0x94, 0xe8, 0xc8, 0x76, 0x68, 0x87, - 0x07, 0x41, 0x96, 0xe6, 0x96, 0xcd, 0x1f, 0x19, 0xdc, 0xa2, 0x04, 0x9e, 0x33, 0xad, 0xf9, 0x1e, - 0x4c, 0xd2, 0x1b, 0xa2, 0xb8, 0xe9, 0x5c, 0xd1, 0x6c, 0x6c, 0xc6, 0x91, 0xc5, 0x01, 0x95, 0x73, - 0x92, 0x01, 0x93, 0xcf, 0x68, 0xe5, 0x40, 0xe1, 0x76, 0x5c, 0x68, 0xce, 0xb5, 0x07, 0x2c, 0xfd, - 0x58, 0xb4, 0xe8, 0x37, 0xbd, 0x10, 0x60, 0xec, 0x3f, 0xb7, 0xd6, 0xd9, 0x0d, 0xa4, 0x68, 0x45, - 0x6d, 0x22, 0xd8, 0x4e, 0xdf, 0xc1, 0x6e, 0x48, 0x47, 0xc7, 0xe9, 0xa8, 0xd2, 0x83, 0x6e, 0x42, - 0xd1, 0x09, 0xd6, 0xb1, 0xed, 0xbb, 0x3c, 0xc5, 0xaf, 0x38, 0x66, 0x39, 0x22, 0xf7, 0xd8, 0x77, - 0xa0, 0xca, 0x38, 0x6b, 0x76, 0xbb, 0xca, 0x69, 0x3f, 0xa2, 0x6f, 0x24, 0xe8, 0xc7, 0xf0, 0xe7, - 0x4e, 0xc6, 0xff, 0x37, 0x06, 0xcc, 0x2a, 0x04, 0xce, 0xa4, 0x82, 0xf7, 0x61, 0x92, 0xd5, 0x5f, - 0xf8, 0x51, 0x70, 0x2e, 0x3e, 0x8b, 0x91, 0xb1, 0x38, 0x0c, 0x5a, 0x84, 0x02, 0xfb, 0x12, 0xd7, - 0x38, 0x3d, 0xb8, 0x00, 0x92, 0x2c, 0x2f, 0xc2, 0x05, 0x3e, 0x86, 0x07, 0x9e, 0xce, 0xe6, 0xc6, - 0xe3, 0x1e, 0xe2, 0x87, 0x06, 0xcc, 0xc5, 0x27, 0x9c, 0x69, 0x95, 0x0a, 0xdf, 0xb9, 0xaf, 0xc4, - 0xf7, 0xaf, 0x09, 0xbe, 0x9f, 0x0f, 0xbb, 0xca, 0x91, 0x33, 0xb9, 0xe3, 0x54, 0xed, 0xe6, 0xe2, - 0xda, 0x95, 0xb8, 0x7e, 0x12, 0xad, 0x49, 0x20, 0x3b, 0xd3, 0x9a, 0x3e, 0x38, 0xd5, 0x9a, 0x94, - 0x23, 0x58, 0x6a, 0x71, 0x6b, 0x62, 0x1b, 0xad, 0x3b, 0x41, 0x14, 0x71, 0xde, 0x83, 0x72, 0xdf, - 0x71, 0xb1, 0xed, 0xf3, 0x1a, 0x92, 0xa1, 0xee, 0xc7, 0x07, 0x56, 0x6c, 0x50, 0xa2, 0xfa, 0x6d, - 0x03, 0x90, 0x8a, 0xeb, 0x97, 0xa3, 0xad, 0x86, 0x10, 0xf0, 0x96, 0xef, 0x0d, 0xbc, 0xf0, 0xa4, - 0x6d, 0x76, 0xdf, 0xfc, 0x5d, 0x03, 0x2e, 0x26, 0x66, 0xfc, 0x32, 0x38, 0xbf, 0x6f, 0x5e, 0x85, - 0xd9, 0x55, 0x2c, 0xce, 0x78, 0xa9, 0xdc, 0xc1, 0x36, 0x20, 0x75, 0xf4, 0x7c, 0x4e, 0x31, 0xff, - 0x0f, 0x66, 0x9f, 0x79, 0x23, 0xe2, 0xc8, 0xc9, 0xb0, 0x74, 0x53, 0x2c, 0x99, 0x15, 0xc9, 0x2b, - 0x6a, 0x4b, 0xd7, 0xbb, 0x0d, 0x48, 0x9d, 0x79, 0x1e, 0xec, 0x2c, 0x9b, 0xff, 0x6d, 0x40, 0xb9, - 0xd9, 0xb7, 0xfd, 0x81, 0x60, 0xe5, 0x23, 0x98, 0x64, 0x99, 0x19, 0x9e, 0x66, 0x7d, 0x3b, 0x8e, - 0x4f, 0x85, 0x65, 0x8d, 0x26, 0xcb, 0xe3, 0xf0, 0x59, 0x64, 0x29, 0xbc, 0xb2, 0xbc, 0x9a, 0xa8, - 0x34, 0xaf, 0xa2, 0x3b, 0x30, 0x61, 0x93, 0x29, 0x34, 0xbc, 0x56, 0x92, 0xe9, 0x32, 0x8a, 0x8d, - 0x5c, 0x89, 0x2c, 0x06, 0x65, 0x7e, 0x08, 0x25, 0x85, 0x02, 0x2a, 0x40, 0xfe, 0x71, 0x8b, 0x5f, - 0x93, 0x9a, 0x2b, 0xed, 0xb5, 0x17, 0x2c, 0x85, 0x58, 0x01, 0x58, 0x6d, 0x45, 0xed, 0x9c, 0xa6, - 0xb0, 0x67, 0x73, 0x3c, 0x3c, 0x6e, 0xa9, 0x1c, 0x1a, 0x59, 0x1c, 0xe6, 0x4e, 0xc3, 0xa1, 0x24, - 0xf1, 0x5b, 0x06, 0x4c, 0x73, 0xd1, 0x9c, 0x35, 0x34, 0x53, 0xcc, 0x19, 0xa1, 0x59, 0x59, 0x86, - 0xc5, 0x01, 0x25, 0x0f, 0xff, 0x64, 0x40, 0x75, 0xd5, 0x7b, 0xed, 0xf6, 0x7c, 0xbb, 0x1b, 0xd9, - 0xe0, 0xc7, 0x09, 0x75, 0x2e, 0x26, 0x32, 0xfd, 0x09, 0x78, 0xd9, 0x91, 0x50, 0x6b, 0x4d, 0xe6, - 0x52, 0x58, 0x7c, 0x17, 0x4d, 0xf3, 0x9b, 0x30, 0x93, 0x98, 0x44, 0x14, 0xf4, 0xa2, 0xb9, 0xbe, - 0xb6, 0x4a, 0x14, 0x42, 0xf3, 0xbd, 0xad, 0x8d, 0xe6, 0xa3, 0xf5, 0x16, 0xaf, 0xca, 0x36, 0x37, - 0x56, 0x5a, 0xeb, 0x52, 0x51, 0x0f, 0xc4, 0x0a, 0x1e, 0x98, 0x7d, 0x98, 0x55, 0x18, 0x3a, 0x6b, - 0x71, 0x4c, 0xcf, 0xaf, 0xa4, 0x56, 0x83, 0x69, 0x7e, 0xca, 0x49, 0x1a, 0xfe, 0xcf, 0xf2, 0x50, - 0x11, 0x43, 0x5f, 0x0f, 0x17, 0xe8, 0x12, 0x4c, 0x76, 0x77, 0xb7, 0x9d, 0xcf, 0x44, 0x5d, 0x96, - 0xb7, 0x48, 0x7f, 0x9f, 0xd1, 0x61, 0xaf, 0x2d, 0x78, 0x0b, 0x5d, 0x65, 0x0f, 0x31, 0xd6, 0xdc, - 0x2e, 0x3e, 0xa4, 0x87, 0xa1, 0x71, 0x4b, 0x76, 0xd0, 0xa4, 0x26, 0x7f, 0x95, 0x41, 0xef, 0xba, - 0xca, 0x2b, 0x0d, 0xb4, 0x0c, 0x55, 0xf2, 0xdd, 0x1c, 0x0e, 0xfb, 0x0e, 0xee, 0x32, 0x04, 0xe4, - 0x9a, 0x3b, 0x2e, 0x4f, 0x3b, 0x29, 0x00, 0x74, 0x1d, 0x26, 0xe9, 0x15, 0x30, 0xa8, 0x4d, 0x91, - 0xb8, 0x2a, 0x41, 0x79, 0x37, 0x7a, 0x17, 0x4a, 0x8c, 0xe3, 0x35, 0xf7, 0x79, 0x80, 0xe9, 0x9b, - 0x05, 0x25, 0x1f, 0xa2, 0x8e, 0xc5, 0xcf, 0x59, 0x90, 0x75, 0xce, 0x42, 0x0d, 0xa8, 0x04, 0xa1, - 0xe7, 0xdb, 0x3d, 0xfc, 0x82, 0x8b, 0xac, 0x14, 0x4f, 0xda, 0x25, 0x86, 0xa5, 0xba, 0xae, 0xc2, - 0x6c, 0xf3, 0x20, 0xdc, 0x6b, 0xb9, 0x24, 0x38, 0xa6, 0x94, 0x79, 0x0d, 0x10, 0x19, 0x5d, 0x75, - 0x02, 0xed, 0x30, 0x9f, 0xac, 0xdd, 0x09, 0x0f, 0xcc, 0x0d, 0xb8, 0x40, 0x46, 0xb1, 0x1b, 0x3a, - 0x1d, 0xe5, 0x20, 0x22, 0x8e, 0xba, 0x46, 0xe2, 0xa8, 0x6b, 0x07, 0xc1, 0x6b, 0xcf, 0xef, 0x72, - 0x65, 0x47, 0x6d, 0x49, 0xed, 0xef, 0x0d, 0xc6, 0xcd, 0xf3, 0x20, 0x76, 0x4c, 0xfd, 0x8a, 0xf8, - 0xd0, 0xff, 0x87, 0x02, 0x7f, 0x1e, 0xc4, 0xb3, 0x7f, 0x97, 0x16, 0xd9, 0xb3, 0xa4, 0x45, 0x8e, - 0x78, 0x93, 0x8d, 0x2a, 0x19, 0x2a, 0x0e, 0x4f, 0xc4, 0xbc, 0x67, 0x07, 0x7b, 0xb8, 0xbb, 0x25, - 0x90, 0xc7, 0x72, 0xa3, 0x0f, 0xac, 0xc4, 0xb0, 0xe4, 0xfd, 0x9e, 0x64, 0xfd, 0x31, 0x0e, 0x8f, - 0x61, 0x5d, 0xcd, 0xbe, 0x5f, 0x14, 0x53, 0x78, 0xd1, 0xf0, 0x34, 0xb3, 0x7e, 0x6c, 0xc0, 0x35, - 0x31, 0x6d, 0x65, 0xcf, 0x76, 0x7b, 0x58, 0x30, 0xf3, 0x8b, 0xca, 0x2b, 0xbd, 0xe8, 0xfc, 0x29, - 0x17, 0xfd, 0x14, 0x6a, 0xd1, 0xa2, 0x69, 0x26, 0xc6, 0xeb, 0xab, 0x8b, 0x38, 0x08, 0xb8, 0x47, - 0x28, 0x5a, 0xf4, 0x9b, 0xf4, 0xf9, 0x5e, 0x3f, 0xba, 0x04, 0x91, 0x6f, 0x89, 0x6c, 0x1d, 0xae, - 0x08, 0x64, 0x3c, 0x35, 0x12, 0xc7, 0x96, 0x5a, 0xd3, 0xb1, 0xd8, 0xb8, 0x3e, 0x08, 0x8e, 0xe3, - 0xb7, 0x92, 0x76, 0x4a, 0x5c, 0x85, 0x94, 0x8a, 0xa1, 0xa3, 0x32, 0xcf, 0x2c, 0x80, 0xf0, 0xac, - 0x9c, 0x57, 0x53, 0xe3, 0x04, 0xa5, 0x76, 0x9c, 0x6f, 0x01, 0x32, 0x9e, 0xda, 0x02, 0xd9, 0x54, - 0x31, 0xcc, 0x47, 0x8c, 0x12, 0xb1, 0x6f, 0x61, 0x7f, 0xe0, 0x04, 0x81, 0x52, 0x86, 0xd2, 0x89, - 0xeb, 0x6d, 0x18, 0x1f, 0x62, 0x1e, 0xbc, 0x4b, 0x4b, 0x48, 0xd8, 0x84, 0x32, 0x99, 0x8e, 0x4b, - 0x32, 0x03, 0xb8, 0x2e, 0xc8, 0x30, 0x85, 0x68, 0xe9, 0x24, 0xd9, 0x14, 0xa9, 0xef, 0x5c, 0x46, - 0xea, 0x3b, 0x1f, 0x4f, 0x7d, 0xc7, 0x0e, 0x94, 0xaa, 0xa3, 0x3a, 0x9f, 0x03, 0x65, 0x9b, 0x29, - 0x20, 0xf2, 0x6f, 0xe7, 0x83, 0xf5, 0x0f, 0xb8, 0xa3, 0x3a, 0xaf, 0x30, 0x88, 0xe9, 0x9a, 0x45, - 0x91, 0x52, 0x34, 0x91, 0x09, 0x65, 0xa2, 0x24, 0x4b, 0xad, 0x09, 0x8c, 0x5b, 0xb1, 0x3e, 0xe9, - 0x8c, 0xf7, 0x61, 0x2e, 0xee, 0x8c, 0xcf, 0xc4, 0xd4, 0x1c, 0x4c, 0x84, 0xde, 0x3e, 0x16, 0x91, - 0x99, 0x35, 0x52, 0x62, 0x8d, 0x1c, 0xf5, 0xf9, 0x88, 0xf5, 0xbb, 0x12, 0x2b, 0x35, 0xc0, 0xb3, - 0xae, 0x80, 0x6c, 0x47, 0x71, 0xf7, 0x65, 0x0d, 0x49, 0xeb, 0x13, 0xb8, 0x94, 0x74, 0xbe, 0xe7, - 0xb3, 0x88, 0x1d, 0x66, 0x9c, 0x3a, 0xf7, 0x7c, 0x3e, 0x04, 0x5e, 0x4a, 0x3f, 0xa9, 0x38, 0xdd, - 0xf3, 0xc1, 0xfd, 0xeb, 0x50, 0xd7, 0xf9, 0xe0, 0x73, 0xb5, 0xc5, 0xc8, 0x25, 0x9f, 0x0f, 0xd6, - 0x1f, 0x1a, 0x12, 0xad, 0xba, 0x6b, 0x3e, 0xfc, 0x2a, 0x68, 0x45, 0xac, 0xbb, 0x1b, 0x6d, 0x9f, - 0x46, 0xe4, 0x2d, 0xf3, 0x7a, 0x6f, 0x29, 0xa7, 0x50, 0x40, 0x61, 0x7f, 0xd2, 0xd5, 0x7f, 0x9d, - 0xbb, 0x97, 0x13, 0x93, 0x71, 0xe7, 0xac, 0xc4, 0x48, 0x78, 0x8e, 0x88, 0xd1, 0x46, 0xca, 0x54, - 0xd4, 0x20, 0x75, 0x3e, 0xaa, 0xfb, 0x0d, 0x19, 0x60, 0x52, 0x71, 0xec, 0x7c, 0x28, 0xd8, 0xb0, - 0x90, 0x1d, 0xc2, 0xce, 0x85, 0xc4, 0xed, 0x26, 0x14, 0xa3, 0x9b, 0xaf, 0xf2, 0x4e, 0xb7, 0x04, - 0x85, 0x8d, 0xcd, 0xed, 0xad, 0xe6, 0x0a, 0xb9, 0xd8, 0xcd, 0x41, 0x61, 0x65, 0xd3, 0xb2, 0x9e, - 0x6f, 0xb5, 0xc9, 0xcd, 0x2e, 0xf9, 0x6c, 0x67, 0xe9, 0xe7, 0x79, 0xc8, 0x3d, 0x7d, 0x81, 0x3e, - 0x85, 0x09, 0xf6, 0x6c, 0xec, 0x98, 0xd7, 0x83, 0xf5, 0xe3, 0x5e, 0xc6, 0x99, 0x97, 0x7f, 0xf0, - 0x9f, 0x3f, 0xff, 0xc3, 0xdc, 0xac, 0x59, 0x6e, 0x8c, 0x96, 0x1b, 0xfb, 0xa3, 0x06, 0x0d, 0xb2, - 0x0f, 0x8d, 0xdb, 0xe8, 0x5b, 0x90, 0xdf, 0x3a, 0x08, 0x51, 0xe6, 0xab, 0xc2, 0x7a, 0xf6, 0x63, - 0x39, 0xf3, 0x22, 0x45, 0x3a, 0x63, 0x02, 0x47, 0x3a, 0x3c, 0x08, 0x09, 0xca, 0xef, 0x41, 0x49, - 0x7d, 0xea, 0x76, 0xe2, 0x53, 0xc3, 0xfa, 0xc9, 0xcf, 0xe8, 0xcc, 0x6b, 0x94, 0xd4, 0x65, 0x13, - 0x71, 0x52, 0xec, 0x31, 0x9e, 0xba, 0x8a, 0xf6, 0xa1, 0x8b, 0x32, 0x1f, 0x22, 0xd6, 0xb3, 0x5f, - 0xd6, 0xa5, 0x56, 0x11, 0x1e, 0xba, 0x04, 0xe5, 0x77, 0xf9, 0x13, 0xba, 0x4e, 0x88, 0xae, 0x6b, - 0xde, 0x40, 0xa9, 0x6f, 0x7b, 0xea, 0x0b, 0xd9, 0x00, 0x9c, 0xc8, 0x55, 0x4a, 0xe4, 0x92, 0x39, - 0xcb, 0x89, 0x74, 0x22, 0x90, 0x87, 0xc6, 0xed, 0xa5, 0x0e, 0x4c, 0xd0, 0xda, 0x31, 0x7a, 0x29, - 0x3e, 0xea, 0x9a, 0xaa, 0x7c, 0x86, 0xa2, 0x63, 0x55, 0x67, 0x73, 0x8e, 0x12, 0xaa, 0x98, 0x45, - 0x42, 0x88, 0x56, 0x8e, 0x1f, 0x1a, 0xb7, 0x6f, 0x19, 0x77, 0x8d, 0xa5, 0xbf, 0x9a, 0x80, 0x09, - 0x5a, 0xa3, 0x40, 0xfb, 0x00, 0xb2, 0x46, 0x9a, 0x5c, 0x5d, 0xaa, 0xfc, 0x9a, 0x5c, 0x5d, 0xba, - 0xbc, 0x6a, 0xd6, 0x29, 0xd1, 0x39, 0x73, 0x86, 0x10, 0xa5, 0xa5, 0x8f, 0x06, 0xad, 0xf4, 0x10, - 0x39, 0xfe, 0xd8, 0xe0, 0xc5, 0x1a, 0x66, 0x66, 0x48, 0x87, 0x2d, 0x56, 0x1f, 0x4d, 0x6e, 0x07, - 0x4d, 0x49, 0xd4, 0x7c, 0x40, 0x09, 0x36, 0xcc, 0xaa, 0x24, 0xe8, 0x53, 0x88, 0x87, 0xc6, 0xed, - 0x97, 0x35, 0xf3, 0x02, 0x97, 0x72, 0x62, 0x04, 0x7d, 0x1f, 0x2a, 0xf1, 0x4a, 0x1e, 0xba, 0xa1, - 0xa1, 0x95, 0xac, 0x0c, 0xd6, 0xdf, 0x3a, 0x1e, 0x88, 0xf3, 0x34, 0x4f, 0x79, 0xe2, 0xc4, 0x19, - 0xe5, 0x7d, 0x8c, 0x87, 0x36, 0x01, 0xe2, 0x3a, 0x40, 0x7f, 0x6a, 0xf0, 0x62, 0xac, 0x2c, 0xc4, - 0x21, 0x1d, 0xf6, 0x54, 0xbd, 0xaf, 0x7e, 0xf3, 0x04, 0x28, 0xce, 0xc4, 0x87, 0x94, 0x89, 0x0f, - 0xcc, 0x39, 0xc9, 0x44, 0xe8, 0x0c, 0x70, 0xe8, 0x71, 0x2e, 0x5e, 0x5e, 0x35, 0x2f, 0xc7, 0x84, - 0x13, 0x1b, 0x95, 0xca, 0x62, 0x05, 0x33, 0xad, 0xb2, 0x62, 0x35, 0x39, 0xad, 0xb2, 0xe2, 0xd5, - 0x36, 0x9d, 0xb2, 0x78, 0x79, 0x4c, 0xa3, 0xac, 0x68, 0x64, 0xe9, 0x7f, 0xc7, 0xa1, 0xb0, 0xc2, - 0xfe, 0x2b, 0x0e, 0xf2, 0xa0, 0x18, 0x95, 0x90, 0xd0, 0xbc, 0x2e, 0x4b, 0x2d, 0xaf, 0x72, 0xf5, - 0xeb, 0x99, 0xe3, 0x9c, 0xa1, 0x37, 0x29, 0x43, 0x6f, 0x98, 0x97, 0x08, 0x65, 0xfe, 0xbf, 0x7d, - 0x1a, 0x2c, 0x97, 0xd9, 0xb0, 0xbb, 0x5d, 0x22, 0x88, 0xdf, 0x84, 0xb2, 0x5a, 0xd0, 0x41, 0x6f, - 0x6a, 0x33, 0xe3, 0x6a, 0x75, 0xa8, 0x6e, 0x1e, 0x07, 0xc2, 0x29, 0xbf, 0x45, 0x29, 0xcf, 0x9b, - 0x57, 0x34, 0x94, 0x7d, 0x0a, 0x1a, 0x23, 0xce, 0x2a, 0x2f, 0x7a, 0xe2, 0xb1, 0x12, 0x8f, 0x9e, - 0x78, 0xbc, 0x70, 0x73, 0x2c, 0xf1, 0x03, 0x0a, 0x4a, 0x88, 0x07, 0x00, 0xb2, 0x34, 0x82, 0xb4, - 0xb2, 0x54, 0x2e, 0xac, 0x49, 0xe7, 0x90, 0xae, 0xaa, 0x98, 0x26, 0x25, 0xcb, 0xf7, 0x5d, 0x82, - 0x6c, 0xdf, 0x09, 0x42, 0x66, 0x98, 0xd3, 0xb1, 0xc2, 0x06, 0xd2, 0xae, 0x27, 0x5e, 0x27, 0xa9, - 0xdf, 0x38, 0x16, 0x86, 0x53, 0xbf, 0x49, 0xa9, 0x5f, 0x37, 0xeb, 0x1a, 0xea, 0x43, 0x06, 0x4b, - 0x36, 0xdb, 0xe7, 0x05, 0x28, 0x3d, 0xb3, 0x1d, 0x37, 0xc4, 0xae, 0xed, 0x76, 0x30, 0xda, 0x85, - 0x09, 0x1a, 0xbb, 0x93, 0x8e, 0x58, 0xcd, 0xe3, 0x27, 0x1d, 0x71, 0x2c, 0x91, 0x6d, 0x2e, 0x50, - 0xc2, 0x75, 0xf3, 0x22, 0x21, 0x3c, 0x90, 0xa8, 0x1b, 0x2c, 0x05, 0x6e, 0xdc, 0x46, 0xaf, 0x60, - 0x92, 0x17, 0xb0, 0x13, 0x88, 0x62, 0x49, 0xb5, 0xfa, 0x55, 0xfd, 0xa0, 0x6e, 0x2f, 0xab, 0x64, - 0x02, 0x0a, 0x47, 0xe8, 0x8c, 0x00, 0x64, 0x3d, 0x26, 0xa9, 0xd1, 0x54, 0x1d, 0xa7, 0xbe, 0x90, - 0x0d, 0xa0, 0x93, 0xa9, 0x4a, 0xb3, 0x1b, 0xc1, 0x12, 0xba, 0xdf, 0x81, 0xf1, 0x27, 0x76, 0xb0, - 0x87, 0x12, 0xb1, 0x57, 0x79, 0x6f, 0x5a, 0xaf, 0xeb, 0x86, 0x38, 0x95, 0xeb, 0x94, 0xca, 0x15, - 0xe6, 0xca, 0x54, 0x2a, 0xf4, 0x45, 0x25, 0x93, 0x1f, 0x7b, 0x6c, 0x9a, 0x94, 0x5f, 0xec, 0xe5, - 0x6a, 0x52, 0x7e, 0xf1, 0xf7, 0xa9, 0xd9, 0xf2, 0x23, 0x54, 0xf6, 0x47, 0x84, 0xce, 0x10, 0xa6, - 0xc4, 0xb3, 0x4c, 0x94, 0x78, 0xcc, 0x92, 0x78, 0xcb, 0x59, 0x9f, 0xcf, 0x1a, 0xe6, 0xd4, 0x6e, - 0x50, 0x6a, 0xd7, 0xcc, 0x5a, 0x4a, 0x5b, 0x1c, 0xf2, 0xa1, 0x71, 0xfb, 0xae, 0x81, 0xbe, 0x0f, - 0x20, 0x4b, 0x56, 0x29, 0x1b, 0x4c, 0x96, 0xc1, 0x52, 0x36, 0x98, 0xaa, 0x76, 0x99, 0x8b, 0x94, - 0xee, 0x2d, 0xf3, 0x46, 0x92, 0x6e, 0xe8, 0xdb, 0x6e, 0xf0, 0x0a, 0xfb, 0x77, 0x58, 0xbe, 0x3c, - 0xd8, 0x73, 0x86, 0x64, 0xc9, 0x3e, 0x14, 0xa3, 0x8a, 0x42, 0xd2, 0xdf, 0x26, 0x6b, 0x1f, 0x49, - 0x7f, 0x9b, 0x2a, 0x45, 0xc4, 0x1d, 0x4f, 0x6c, 0xbf, 0x08, 0x50, 0x62, 0x82, 0x7f, 0x51, 0x85, - 0x71, 0x72, 0x24, 0x27, 0xc7, 0x13, 0x99, 0xee, 0x49, 0xae, 0x3e, 0x95, 0xb1, 0x4e, 0xae, 0x3e, - 0x9d, 0x29, 0x8a, 0x1f, 0x4f, 0xc8, 0x75, 0xad, 0xc1, 0xf2, 0x28, 0x64, 0xa5, 0x1e, 0x94, 0x94, - 0x34, 0x10, 0xd2, 0x20, 0x8b, 0x67, 0xc0, 0x93, 0x01, 0x4f, 0x93, 0x43, 0x32, 0xdf, 0xa0, 0xf4, - 0x2e, 0xb2, 0x80, 0x47, 0xe9, 0x75, 0x19, 0x04, 0x21, 0xc8, 0x57, 0xc7, 0x2d, 0x5f, 0xb3, 0xba, - 0xb8, 0xf5, 0x2f, 0x64, 0x03, 0x64, 0xae, 0x4e, 0x9a, 0xfe, 0x6b, 0x28, 0xab, 0xa9, 0x1f, 0xa4, - 0x61, 0x3e, 0x91, 0xa3, 0x4f, 0x46, 0x12, 0x5d, 0xe6, 0x28, 0xee, 0xdb, 0x28, 0x49, 0x5b, 0x01, - 0x23, 0x84, 0xfb, 0x50, 0xe0, 0x29, 0x20, 0x9d, 0x48, 0xe3, 0x69, 0x7c, 0x9d, 0x48, 0x13, 0xf9, - 0xa3, 0xf8, 0xf9, 0x99, 0x52, 0x24, 0x57, 0x51, 0x11, 0xad, 0x39, 0xb5, 0xc7, 0x38, 0xcc, 0xa2, - 0x26, 0xd3, 0xb6, 0x59, 0xd4, 0x94, 0x0c, 0x41, 0x16, 0xb5, 0x1e, 0x0e, 0xb9, 0x3f, 0x10, 0xd7, - 0x6b, 0x94, 0x81, 0x4c, 0x8d, 0x90, 0xe6, 0x71, 0x20, 0xba, 0xeb, 0x8d, 0x24, 0x28, 0xc2, 0xe3, - 0x21, 0x80, 0x4c, 0x47, 0x25, 0xcf, 0xac, 0xda, 0x4a, 0x41, 0xf2, 0xcc, 0xaa, 0xcf, 0x68, 0xc5, - 0x7d, 0xac, 0xa4, 0xcb, 0x6e, 0x57, 0x84, 0xf2, 0x17, 0x06, 0xa0, 0x74, 0xc2, 0x0a, 0xbd, 0xa7, - 0xc7, 0xae, 0xad, 0x3a, 0xd4, 0xdf, 0x3f, 0x1d, 0xb0, 0xce, 0x21, 0x4b, 0x96, 0x3a, 0x14, 0x7a, - 0xf8, 0x9a, 0x30, 0xf5, 0xb9, 0x01, 0xd3, 0xb1, 0x24, 0x17, 0x7a, 0x3b, 0x43, 0xa7, 0x89, 0xd2, - 0x43, 0xfd, 0x9d, 0x13, 0xe1, 0x74, 0x87, 0x79, 0x65, 0x07, 0x88, 0x5b, 0xcd, 0xef, 0x18, 0x50, - 0x89, 0xe7, 0xc2, 0x50, 0x06, 0xee, 0x54, 0xc5, 0xa2, 0x7e, 0xeb, 0x64, 0xc0, 0xe3, 0xd5, 0x23, - 0x2f, 0x34, 0x7d, 0x28, 0xf0, 0xa4, 0x99, 0x6e, 0xe3, 0xc7, 0x4b, 0x1c, 0xba, 0x8d, 0x9f, 0xc8, - 0xb8, 0x69, 0x36, 0xbe, 0xef, 0xf5, 0xb1, 0x62, 0x66, 0x3c, 0x97, 0x96, 0x45, 0xed, 0x78, 0x33, - 0x4b, 0x24, 0xe2, 0xb2, 0xa8, 0x49, 0x33, 0x13, 0x29, 0x33, 0x94, 0x81, 0xec, 0x04, 0x33, 0x4b, - 0x66, 0xdc, 0x34, 0x66, 0x46, 0x09, 0x2a, 0x66, 0x26, 0x53, 0x59, 0x3a, 0x33, 0x4b, 0x55, 0x63, - 0x74, 0x66, 0x96, 0xce, 0x86, 0x69, 0xf4, 0x48, 0xe9, 0xc6, 0xcc, 0xec, 0x82, 0x26, 0xd9, 0x85, - 0xde, 0xcf, 0x10, 0xa2, 0xb6, 0xb6, 0x53, 0xbf, 0x73, 0x4a, 0xe8, 0xcc, 0x3d, 0xce, 0xc4, 0x2f, - 0xf6, 0xf8, 0x1f, 0x19, 0x30, 0xa7, 0xcb, 0x8f, 0xa1, 0x0c, 0x3a, 0x19, 0xa5, 0xa0, 0xfa, 0xe2, - 0x69, 0xc1, 0x8f, 0x97, 0x56, 0xb4, 0xeb, 0x1f, 0xf5, 0xbe, 0x68, 0x36, 0x5e, 0x5e, 0x87, 0x6b, - 0x30, 0xd9, 0x1c, 0x3a, 0x4f, 0xf1, 0x11, 0xba, 0x30, 0x95, 0xab, 0x4f, 0x13, 0xbc, 0x9e, 0xef, - 0x7c, 0x46, 0x7f, 0xf3, 0x61, 0x21, 0xb7, 0x5b, 0x06, 0x88, 0x00, 0xc6, 0xfe, 0xf5, 0xcb, 0x79, - 0xe3, 0x3f, 0xbe, 0x9c, 0x37, 0xfe, 0xeb, 0xcb, 0x79, 0xe3, 0xa7, 0xff, 0x33, 0x3f, 0xf6, 0xf2, - 0x46, 0xcf, 0xa3, 0x6c, 0x2d, 0x3a, 0x5e, 0x43, 0xfe, 0x0e, 0xc5, 0x72, 0x43, 0x65, 0x75, 0x77, - 0x92, 0xfe, 0x70, 0xc4, 0xf2, 0xff, 0x05, 0x00, 0x00, 0xff, 0xff, 0x52, 0x62, 0x44, 0x5a, 0x0f, - 0x43, 0x00, 0x00, + // 4665 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x5c, 0x5f, 0x6f, 0x1b, 0x49, + 0x72, 0xd7, 0x90, 0xa2, 0x28, 0x16, 0x29, 0x8a, 0x6a, 0xc9, 0x5e, 0x9a, 0xb6, 0x65, 0xed, 0x78, + 0xbd, 0xeb, 0xf3, 0xae, 0x45, 0x5b, 0xb2, 0x6f, 0x13, 0x07, 0xbb, 0x39, 0x5a, 0xe2, 0x5a, 0x8a, + 0x65, 0x49, 0x37, 0xa2, 0xbd, 0xb7, 0x0e, 0x70, 0xca, 0x88, 0x6c, 0x53, 0x73, 0x22, 0x67, 0x78, + 0x33, 0x43, 0x5a, 0x72, 0x1e, 0xee, 0x72, 0xc9, 0xe5, 0x70, 0x09, 0x70, 0x40, 0x36, 0x40, 0x70, + 0x08, 0x92, 0x97, 0x20, 0x40, 0xf2, 0x70, 0x09, 0x92, 0x87, 0x00, 0x09, 0x12, 0x20, 0x0f, 0xc9, + 0x43, 0xf2, 0x10, 0x20, 0x40, 0xbe, 0x40, 0xb2, 0xd9, 0xa7, 0x7c, 0x8a, 0xa0, 0xff, 0x4d, 0xf7, + 0xfc, 0x93, 0xec, 0xa3, 0x16, 0xf7, 0xb2, 0xe6, 0x74, 0x57, 0xd7, 0xaf, 0xba, 0xba, 0xab, 0xaa, + 0xbb, 0xaa, 0x57, 0x50, 0x70, 0x07, 0xed, 0xe5, 0x81, 0xeb, 0xf8, 0x0e, 0x2a, 0x61, 0xbf, 0xdd, + 0xf1, 0xb0, 0x3b, 0xc2, 0xee, 0xe0, 0xa0, 0xb6, 0xd0, 0x75, 0xba, 0x0e, 0xed, 0xa8, 0x93, 0x5f, + 0x8c, 0xa6, 0x56, 0x25, 0x34, 0x75, 0x73, 0x60, 0xd5, 0xfb, 0xa3, 0x76, 0x7b, 0x70, 0x50, 0x3f, + 0x1a, 0xf1, 0x9e, 0x5a, 0xd0, 0x63, 0x0e, 0xfd, 0xc3, 0xc1, 0x01, 0xfd, 0x87, 0xf7, 0x2d, 0x05, + 0x7d, 0x23, 0xec, 0x7a, 0x96, 0x63, 0x0f, 0x0e, 0xc4, 0x2f, 0x4e, 0x71, 0xa5, 0xeb, 0x38, 0xdd, + 0x1e, 0x66, 0xe3, 0x6d, 0xdb, 0xf1, 0x4d, 0xdf, 0x72, 0x6c, 0x8f, 0xf7, 0xb2, 0x7f, 0xda, 0xb7, + 0xbb, 0xd8, 0xbe, 0xed, 0x0c, 0xb0, 0x6d, 0x0e, 0xac, 0xd1, 0x4a, 0xdd, 0x19, 0x50, 0x9a, 0x38, + 0xbd, 0xfe, 0x13, 0x0d, 0xca, 0x06, 0xf6, 0x06, 0x8e, 0xed, 0xe1, 0x0d, 0x6c, 0x76, 0xb0, 0x8b, + 0xae, 0x02, 0xb4, 0x7b, 0x43, 0xcf, 0xc7, 0xee, 0xbe, 0xd5, 0xa9, 0x6a, 0x4b, 0xda, 0xcd, 0x49, + 0xa3, 0xc0, 0x5b, 0x36, 0x3b, 0xe8, 0x32, 0x14, 0xfa, 0xb8, 0x7f, 0xc0, 0x7a, 0x33, 0xb4, 0x77, + 0x9a, 0x35, 0x6c, 0x76, 0x50, 0x0d, 0xa6, 0x5d, 0x3c, 0xb2, 0x88, 0xb8, 0xd5, 0xec, 0x92, 0x76, + 0x33, 0x6b, 0x04, 0xdf, 0x64, 0xa0, 0x6b, 0xbe, 0xf0, 0xf7, 0x7d, 0xec, 0xf6, 0xab, 0x93, 0x6c, + 0x20, 0x69, 0x68, 0x61, 0xb7, 0xff, 0x20, 0xff, 0x83, 0xbf, 0xab, 0x66, 0x57, 0x97, 0xef, 0xe8, + 0xff, 0x92, 0x83, 0x92, 0x61, 0xda, 0x5d, 0x6c, 0xe0, 0xef, 0x0e, 0xb1, 0xe7, 0xa3, 0x0a, 0x64, + 0x8f, 0xf0, 0x09, 0x95, 0xa3, 0x64, 0x90, 0x9f, 0x8c, 0x91, 0xdd, 0xc5, 0xfb, 0xd8, 0x66, 0x12, + 0x94, 0x08, 0x23, 0xbb, 0x8b, 0x9b, 0x76, 0x07, 0x2d, 0x40, 0xae, 0x67, 0xf5, 0x2d, 0x9f, 0xc3, + 0xb3, 0x8f, 0x90, 0x5c, 0x93, 0x11, 0xb9, 0xd6, 0x00, 0x3c, 0xc7, 0xf5, 0xf7, 0x1d, 0xb7, 0x83, + 0xdd, 0x6a, 0x6e, 0x49, 0xbb, 0x59, 0x5e, 0x79, 0x67, 0x59, 0x5d, 0xe1, 0x65, 0x55, 0xa0, 0xe5, + 0x3d, 0xc7, 0xf5, 0x77, 0x08, 0xad, 0x51, 0xf0, 0xc4, 0x4f, 0xf4, 0x09, 0x14, 0x29, 0x13, 0xdf, + 0x74, 0xbb, 0xd8, 0xaf, 0x4e, 0x51, 0x2e, 0x37, 0xce, 0xe0, 0xd2, 0xa2, 0xc4, 0x06, 0x85, 0x67, + 0xbf, 0x91, 0x0e, 0x25, 0x0f, 0xbb, 0x96, 0xd9, 0xb3, 0x5e, 0x99, 0x07, 0x3d, 0x5c, 0xcd, 0x2f, + 0x69, 0x37, 0xa7, 0x8d, 0x50, 0x1b, 0x99, 0xff, 0x11, 0x3e, 0xf1, 0xf6, 0x1d, 0xbb, 0x77, 0x52, + 0x9d, 0xa6, 0x04, 0xd3, 0xa4, 0x61, 0xc7, 0xee, 0x9d, 0xd0, 0xd5, 0x73, 0x86, 0xb6, 0xcf, 0x7a, + 0x0b, 0xb4, 0xb7, 0x40, 0x5b, 0x68, 0xf7, 0x5d, 0xa8, 0xf4, 0x2d, 0x7b, 0xbf, 0xef, 0x74, 0xf6, + 0x03, 0x85, 0x00, 0x51, 0xc8, 0xc3, 0xfc, 0xef, 0xd1, 0x15, 0xb8, 0x6b, 0x94, 0xfb, 0x96, 0xfd, + 0xc4, 0xe9, 0x18, 0x42, 0x3f, 0x64, 0x88, 0x79, 0x1c, 0x1e, 0x52, 0x8c, 0x0e, 0x31, 0x8f, 0xd5, + 0x21, 0x1f, 0xc2, 0x3c, 0x41, 0x69, 0xbb, 0xd8, 0xf4, 0xb1, 0x1c, 0x55, 0x0a, 0x8f, 0x9a, 0xeb, + 0x5b, 0xf6, 0x1a, 0x25, 0x09, 0x0d, 0x34, 0x8f, 0x63, 0x03, 0x67, 0xa2, 0x03, 0xcd, 0xe3, 0xf0, + 0x40, 0xfd, 0x43, 0x28, 0x04, 0xeb, 0x82, 0xa6, 0x61, 0x72, 0x7b, 0x67, 0xbb, 0x59, 0x99, 0x40, + 0x00, 0x53, 0x8d, 0xbd, 0xb5, 0xe6, 0xf6, 0x7a, 0x45, 0x43, 0x45, 0xc8, 0xaf, 0x37, 0xd9, 0x47, + 0xa6, 0x96, 0xff, 0x9c, 0xef, 0xb7, 0xc7, 0x00, 0x72, 0x29, 0x50, 0x1e, 0xb2, 0x8f, 0x9b, 0x9f, + 0x55, 0x26, 0x08, 0xf1, 0xb3, 0xa6, 0xb1, 0xb7, 0xb9, 0xb3, 0x5d, 0xd1, 0x08, 0x97, 0x35, 0xa3, + 0xd9, 0x68, 0x35, 0x2b, 0x19, 0x42, 0xf1, 0x64, 0x67, 0xbd, 0x92, 0x45, 0x05, 0xc8, 0x3d, 0x6b, + 0x6c, 0x3d, 0x6d, 0x56, 0x26, 0x03, 0x66, 0x72, 0x17, 0xff, 0x89, 0x06, 0x33, 0x7c, 0xb9, 0x99, + 0x6d, 0xa1, 0x7b, 0x30, 0x75, 0x48, 0xed, 0x8b, 0xee, 0xe4, 0xe2, 0xca, 0x95, 0xc8, 0xde, 0x08, + 0xd9, 0xa0, 0xc1, 0x69, 0x91, 0x0e, 0xd9, 0xa3, 0x91, 0x57, 0xcd, 0x2c, 0x65, 0x6f, 0x16, 0x57, + 0x2a, 0xcb, 0xcc, 0x93, 0x2c, 0x3f, 0xc6, 0x27, 0xcf, 0xcc, 0xde, 0x10, 0x1b, 0xa4, 0x13, 0x21, + 0x98, 0xec, 0x3b, 0x2e, 0xa6, 0x1b, 0x7e, 0xda, 0xa0, 0xbf, 0x89, 0x15, 0xd0, 0x35, 0xe7, 0x9b, + 0x9d, 0x7d, 0x48, 0xf1, 0xfe, 0x43, 0x03, 0xd8, 0x1d, 0xfa, 0xe9, 0x26, 0xb6, 0x00, 0xb9, 0x11, + 0x41, 0xe0, 0xe6, 0xc5, 0x3e, 0xa8, 0x6d, 0x61, 0xd3, 0xc3, 0x81, 0x6d, 0x91, 0x0f, 0xb4, 0x04, + 0xf9, 0x81, 0x8b, 0x47, 0xfb, 0x47, 0x23, 0x8a, 0x36, 0x2d, 0xd7, 0x69, 0x8a, 0xb4, 0x3f, 0x1e, + 0xa1, 0x5b, 0x50, 0xb2, 0xba, 0xb6, 0xe3, 0xe2, 0x7d, 0xc6, 0x34, 0xa7, 0x92, 0xad, 0x18, 0x45, + 0xd6, 0x49, 0xa7, 0xa4, 0xd0, 0x32, 0xa8, 0xa9, 0x44, 0xda, 0x2d, 0xd2, 0x27, 0xe7, 0xf3, 0x7d, + 0x0d, 0x8a, 0x74, 0x3e, 0x63, 0x29, 0x7b, 0x45, 0x4e, 0x24, 0x43, 0x87, 0xc5, 0x14, 0x1e, 0x9b, + 0x9a, 0x14, 0xc1, 0x06, 0xb4, 0x8e, 0x7b, 0xd8, 0xc7, 0xe3, 0x38, 0x2f, 0x45, 0x95, 0xd9, 0x44, + 0x55, 0x4a, 0xbc, 0x3f, 0xd7, 0x60, 0x3e, 0x04, 0x38, 0xd6, 0xd4, 0xab, 0x90, 0xef, 0x50, 0x66, + 0x4c, 0xa6, 0xac, 0x21, 0x3e, 0xd1, 0x3d, 0x98, 0xe6, 0x22, 0x79, 0xd5, 0x6c, 0xf2, 0x36, 0x94, + 0x52, 0xe6, 0x99, 0x94, 0x9e, 0x14, 0xf3, 0x1f, 0x33, 0x50, 0xe0, 0xca, 0xd8, 0x19, 0xa0, 0x06, + 0xcc, 0xb8, 0xec, 0x63, 0x9f, 0xce, 0x99, 0xcb, 0x58, 0x4b, 0xf7, 0x93, 0x1b, 0x13, 0x46, 0x89, + 0x0f, 0xa1, 0xcd, 0xe8, 0x57, 0xa0, 0x28, 0x58, 0x0c, 0x86, 0x3e, 0x5f, 0xa8, 0x6a, 0x98, 0x81, + 0xdc, 0xda, 0x1b, 0x13, 0x06, 0x70, 0xf2, 0xdd, 0xa1, 0x8f, 0x5a, 0xb0, 0x20, 0x06, 0xb3, 0xf9, + 0x71, 0x31, 0xb2, 0x94, 0xcb, 0x52, 0x98, 0x4b, 0x7c, 0x39, 0x37, 0x26, 0x0c, 0xc4, 0xc7, 0x2b, + 0x9d, 0x68, 0x5d, 0x8a, 0xe4, 0x1f, 0xb3, 0xf8, 0x12, 0x13, 0xa9, 0x75, 0x6c, 0x73, 0x26, 0x42, + 0x5b, 0xab, 0x8a, 0x6c, 0xad, 0x63, 0x3b, 0x50, 0xd9, 0xc3, 0x02, 0xe4, 0x79, 0xb3, 0xfe, 0xef, + 0x19, 0x00, 0xb1, 0x62, 0x3b, 0x03, 0xb4, 0x0e, 0x65, 0x97, 0x7f, 0x85, 0xf4, 0x77, 0x39, 0x51, + 0x7f, 0x7c, 0xa1, 0x27, 0x8c, 0x19, 0x31, 0x88, 0x89, 0xfb, 0x31, 0x94, 0x02, 0x2e, 0x52, 0x85, + 0x97, 0x12, 0x54, 0x18, 0x70, 0x28, 0x8a, 0x01, 0x44, 0x89, 0x9f, 0xc2, 0x85, 0x60, 0x7c, 0x82, + 0x16, 0xdf, 0x3e, 0x45, 0x8b, 0x01, 0xc3, 0x79, 0xc1, 0x41, 0xd5, 0xe3, 0x23, 0x45, 0x30, 0xa9, + 0xc8, 0x4b, 0x09, 0x8a, 0x64, 0x44, 0xaa, 0x26, 0x03, 0x09, 0x43, 0xaa, 0x04, 0x12, 0xf6, 0x59, + 0xbb, 0xfe, 0x97, 0x93, 0x90, 0x5f, 0x73, 0xfa, 0x03, 0xd3, 0x25, 0x9b, 0x68, 0xca, 0xc5, 0xde, + 0xb0, 0xe7, 0x53, 0x05, 0x96, 0x57, 0xae, 0x87, 0x31, 0x38, 0x99, 0xf8, 0xd7, 0xa0, 0xa4, 0x06, + 0x1f, 0x42, 0x06, 0xf3, 0x28, 0x9f, 0x79, 0x8d, 0xc1, 0x3c, 0xc6, 0xf3, 0x21, 0xc2, 0x21, 0x64, + 0xa5, 0x43, 0xa8, 0x41, 0x9e, 0x1f, 0xf0, 0x98, 0xb3, 0xde, 0x98, 0x30, 0x44, 0x03, 0xfa, 0x1a, + 0xcc, 0x46, 0x43, 0x61, 0x8e, 0xd3, 0x94, 0xdb, 0xe1, 0xc8, 0x79, 0x1d, 0x4a, 0xa1, 0x08, 0x3d, + 0xc5, 0xe9, 0x8a, 0x7d, 0x25, 0x2e, 0x5f, 0x14, 0x6e, 0x9d, 0x1c, 0x2b, 0x4a, 0x1b, 0x13, 0xc2, + 0xb1, 0x5f, 0x13, 0x8e, 0x7d, 0x5a, 0x0d, 0xb4, 0x44, 0xaf, 0xdc, 0xc7, 0xbf, 0xa3, 0x7a, 0xad, + 0x6f, 0x90, 0xc1, 0x01, 0x91, 0x74, 0x5f, 0xba, 0x01, 0x33, 0x21, 0x95, 0x91, 0x18, 0xd9, 0xfc, + 0xe6, 0xd3, 0xc6, 0x16, 0x0b, 0xa8, 0x8f, 0x68, 0x0c, 0x35, 0x2a, 0x1a, 0x09, 0xd0, 0x5b, 0xcd, + 0xbd, 0xbd, 0x4a, 0x06, 0x5d, 0x84, 0xc2, 0xf6, 0x4e, 0x6b, 0x9f, 0x51, 0x65, 0x6b, 0xf9, 0x3f, + 0x66, 0x9e, 0x44, 0xc6, 0xe7, 0xcf, 0x02, 0x9e, 0x3c, 0x44, 0x2b, 0x91, 0x79, 0x42, 0x89, 0xcc, + 0x9a, 0x88, 0xcc, 0x19, 0x19, 0x99, 0xb3, 0x08, 0x41, 0x6e, 0xab, 0xd9, 0xd8, 0xa3, 0x41, 0x9a, + 0xb1, 0x5e, 0x8d, 0x47, 0xeb, 0x87, 0x65, 0x28, 0xb1, 0xe5, 0xd9, 0x1f, 0xda, 0xe4, 0x30, 0xf1, + 0x33, 0x0d, 0x40, 0x1a, 0x2c, 0xaa, 0x43, 0xbe, 0xcd, 0x44, 0xa8, 0x6a, 0xd4, 0x03, 0x5e, 0x48, + 0x5c, 0x71, 0x43, 0x50, 0xa1, 0xbb, 0x90, 0xf7, 0x86, 0xed, 0x36, 0xf6, 0x44, 0xe4, 0x7e, 0x2b, + 0xea, 0x84, 0xb9, 0x43, 0x34, 0x04, 0x1d, 0x19, 0xf2, 0xc2, 0xb4, 0x7a, 0x43, 0x1a, 0xc7, 0x4f, + 0x1f, 0xc2, 0xe9, 0xa4, 0x8f, 0xfd, 0x33, 0x0d, 0x8a, 0x8a, 0x59, 0xfc, 0x9c, 0x21, 0xe0, 0x0a, + 0x14, 0xa8, 0x30, 0xb8, 0xc3, 0x83, 0xc0, 0xb4, 0x21, 0x1b, 0xd0, 0xd7, 0xa1, 0x20, 0x2c, 0x49, + 0xc4, 0x81, 0x6a, 0x32, 0xdb, 0x9d, 0x81, 0x21, 0x49, 0xa5, 0x90, 0x2d, 0x98, 0xa3, 0x7a, 0x6a, + 0x93, 0xdb, 0x87, 0xd0, 0xac, 0x7a, 0x2c, 0xd7, 0x22, 0xc7, 0xf2, 0x1a, 0x4c, 0x0f, 0x0e, 0x4f, + 0x3c, 0xab, 0x6d, 0xf6, 0xb8, 0x38, 0xc1, 0xb7, 0xe4, 0xba, 0x07, 0x48, 0xe5, 0x3a, 0x8e, 0x02, + 0x24, 0xd3, 0x8b, 0x50, 0xdc, 0x30, 0xbd, 0x43, 0x2e, 0xa4, 0x6c, 0xbf, 0x07, 0x33, 0xa4, 0xfd, + 0xf1, 0xb3, 0xd7, 0x10, 0x5f, 0x8c, 0x5a, 0xd5, 0xff, 0x49, 0x83, 0xb2, 0x18, 0x36, 0xd6, 0x02, + 0x21, 0x98, 0x3c, 0x34, 0xbd, 0x43, 0xaa, 0x8c, 0x19, 0x83, 0xfe, 0x46, 0x5f, 0x83, 0x4a, 0x9b, + 0xcd, 0x7f, 0x3f, 0x72, 0xef, 0x9a, 0xe5, 0xed, 0x81, 0xed, 0x7f, 0x00, 0x33, 0x64, 0xc8, 0x7e, + 0xf8, 0x1e, 0x24, 0xcc, 0xf8, 0xeb, 0x46, 0xe9, 0x90, 0xce, 0x39, 0x2a, 0xbe, 0x09, 0x25, 0xa6, + 0x8c, 0xf3, 0x96, 0x5d, 0xea, 0xb5, 0x06, 0xb3, 0x7b, 0xb6, 0x39, 0xf0, 0x0e, 0x1d, 0x3f, 0xa2, + 0xf3, 0x55, 0xfd, 0x6f, 0x35, 0xa8, 0xc8, 0xce, 0xb1, 0x64, 0x78, 0x0f, 0x66, 0x5d, 0xdc, 0x37, + 0x2d, 0xdb, 0xb2, 0xbb, 0xfb, 0x07, 0x27, 0x3e, 0xf6, 0xf8, 0xf5, 0xb5, 0x1c, 0x34, 0x3f, 0x24, + 0xad, 0x44, 0xd8, 0x83, 0x9e, 0x73, 0xc0, 0x9d, 0x34, 0xfd, 0x8d, 0xde, 0x0e, 0x7b, 0xe9, 0x82, + 0xd4, 0x9b, 0x68, 0x97, 0x32, 0xff, 0x34, 0x03, 0xa5, 0x4f, 0x4d, 0xbf, 0x2d, 0x76, 0x10, 0xda, + 0x84, 0x72, 0xe0, 0xc6, 0x69, 0x0b, 0x97, 0x3b, 0x72, 0xe0, 0xa0, 0x63, 0xc4, 0xbd, 0x46, 0x1c, + 0x38, 0x66, 0xda, 0x6a, 0x03, 0x65, 0x65, 0xda, 0x6d, 0xdc, 0x0b, 0x58, 0x65, 0xd2, 0x59, 0x51, + 0x42, 0x95, 0x95, 0xda, 0x80, 0xbe, 0x05, 0x95, 0x81, 0xeb, 0x74, 0x5d, 0xec, 0x79, 0x01, 0x33, + 0x16, 0xc2, 0xf5, 0x04, 0x66, 0xbb, 0x9c, 0x34, 0x72, 0x8a, 0xb9, 0xb7, 0x31, 0x61, 0xcc, 0x0e, + 0xc2, 0x7d, 0xd2, 0xb1, 0xce, 0xca, 0xf3, 0x1e, 0xf3, 0xac, 0x3f, 0xca, 0x02, 0x8a, 0x4f, 0xf3, + 0x4d, 0x8f, 0xc9, 0x37, 0xa0, 0xec, 0xf9, 0xa6, 0x1b, 0xdb, 0xf3, 0x33, 0xb4, 0x35, 0xd8, 0xf1, + 0xef, 0x41, 0x20, 0xd9, 0xbe, 0xed, 0xf8, 0xd6, 0x8b, 0x13, 0x76, 0x41, 0x31, 0xca, 0xa2, 0x79, + 0x9b, 0xb6, 0xa2, 0x6d, 0xc8, 0xbf, 0xb0, 0x7a, 0x3e, 0x76, 0xbd, 0x6a, 0x6e, 0x29, 0x7b, 0xb3, + 0xbc, 0xf2, 0xfe, 0x59, 0x0b, 0xb3, 0xfc, 0x09, 0xa5, 0x6f, 0x9d, 0x0c, 0xd4, 0xd3, 0x2f, 0x67, + 0xa2, 0x1e, 0xe3, 0xa7, 0x92, 0x6f, 0x44, 0x3a, 0x4c, 0xbf, 0x24, 0x4c, 0xf7, 0xad, 0x0e, 0x8d, + 0xc5, 0x81, 0x1d, 0xde, 0x33, 0xf2, 0xb4, 0x63, 0xb3, 0x83, 0xae, 0xc3, 0xf4, 0x0b, 0xd7, 0xec, + 0xf6, 0xb1, 0xed, 0xb3, 0x5b, 0xbe, 0xa4, 0x09, 0x3a, 0xf4, 0x65, 0x00, 0x29, 0x0a, 0x89, 0x7c, + 0xdb, 0x3b, 0xbb, 0x4f, 0x5b, 0x95, 0x09, 0x54, 0x82, 0xe9, 0xed, 0x9d, 0xf5, 0xe6, 0x56, 0x93, + 0xc4, 0x46, 0x11, 0xf3, 0xee, 0x4a, 0xa3, 0x6b, 0x88, 0x85, 0x08, 0xed, 0x09, 0x55, 0x2e, 0x2d, + 0x7c, 0xe9, 0x16, 0x72, 0x09, 0x16, 0x77, 0xf5, 0x6b, 0xb0, 0x90, 0xb4, 0x35, 0x04, 0xc1, 0x3d, + 0xfd, 0x5f, 0x33, 0x30, 0xc3, 0x0d, 0x61, 0x2c, 0xcb, 0xbd, 0xa4, 0x48, 0xc5, 0xaf, 0x27, 0x42, + 0x49, 0x55, 0xc8, 0x33, 0x03, 0xe9, 0xf0, 0xfb, 0xaf, 0xf8, 0x24, 0xce, 0x99, 0xed, 0x77, 0xdc, + 0xe1, 0xcb, 0x1e, 0x7c, 0x27, 0xba, 0xcd, 0x5c, 0xaa, 0xdb, 0x0c, 0x0c, 0xce, 0xf4, 0xf8, 0xc1, + 0xaa, 0x20, 0x97, 0xa2, 0x24, 0x8c, 0x8a, 0x74, 0x86, 0xd6, 0x2c, 0x9f, 0xb2, 0x66, 0xe8, 0x06, + 0x4c, 0xe1, 0x11, 0xb6, 0x7d, 0xaf, 0x5a, 0xa4, 0x81, 0x74, 0x46, 0x5c, 0xa8, 0x9a, 0xa4, 0xd5, + 0xe0, 0x9d, 0x72, 0xa9, 0x3e, 0x86, 0x39, 0x7a, 0xdf, 0x7d, 0xe4, 0x9a, 0xb6, 0x7a, 0x67, 0x6f, + 0xb5, 0xb6, 0x78, 0xd8, 0x21, 0x3f, 0x51, 0x19, 0x32, 0x9b, 0xeb, 0x5c, 0x3f, 0x99, 0xcd, 0x75, + 0x39, 0xfe, 0xf7, 0x35, 0x40, 0x2a, 0x83, 0xb1, 0xd6, 0x22, 0x82, 0x22, 0xe4, 0xc8, 0x4a, 0x39, + 0x16, 0x20, 0x87, 0x5d, 0xd7, 0x71, 0x99, 0xa3, 0x34, 0xd8, 0x87, 0x94, 0xe6, 0x36, 0x17, 0xc6, + 0xc0, 0x23, 0xe7, 0x28, 0xf0, 0x00, 0x8c, 0xad, 0x16, 0x17, 0xbe, 0x05, 0xf3, 0x21, 0xf2, 0xf3, + 0x09, 0xf1, 0x3b, 0x30, 0x4b, 0xb9, 0xae, 0x1d, 0xe2, 0xf6, 0xd1, 0xc0, 0xb1, 0xec, 0x98, 0x04, + 0xe8, 0x3a, 0xf1, 0x5d, 0x22, 0x5c, 0x90, 0x29, 0xb2, 0x39, 0x97, 0x82, 0xc6, 0x56, 0x6b, 0x4b, + 0x6e, 0xf5, 0x03, 0xb8, 0x18, 0x61, 0x28, 0x66, 0xf6, 0xab, 0x50, 0x6c, 0x07, 0x8d, 0x1e, 0x3f, + 0x41, 0x5e, 0x0d, 0x8b, 0x1b, 0x1d, 0xaa, 0x8e, 0x90, 0x18, 0xdf, 0x82, 0xb7, 0x62, 0x18, 0xe7, + 0xa1, 0x8e, 0x7b, 0xfa, 0x1d, 0xb8, 0x40, 0x39, 0x3f, 0xc6, 0x78, 0xd0, 0xe8, 0x59, 0xa3, 0xb3, + 0x97, 0xe5, 0x84, 0xcf, 0x57, 0x19, 0xf1, 0xd5, 0x6e, 0x2b, 0x09, 0xdd, 0xe4, 0xd0, 0x2d, 0xab, + 0x8f, 0x5b, 0xce, 0x56, 0xba, 0xb4, 0x24, 0x90, 0x1f, 0xe1, 0x13, 0x8f, 0x1f, 0x1f, 0xe9, 0x6f, + 0xe9, 0xbd, 0xfe, 0x5a, 0xe3, 0xea, 0x54, 0xf9, 0x7c, 0xc5, 0xa6, 0xb1, 0x08, 0xd0, 0x25, 0x36, + 0x88, 0x3b, 0xa4, 0x83, 0xe5, 0xe6, 0x94, 0x96, 0x40, 0x60, 0x12, 0x85, 0x4a, 0x51, 0x81, 0xaf, + 0x72, 0xc3, 0xa1, 0xff, 0xf1, 0x62, 0x27, 0xa5, 0x77, 0xa1, 0x48, 0x7b, 0xf6, 0x7c, 0xd3, 0x1f, + 0x7a, 0x69, 0x2b, 0xb7, 0xaa, 0xff, 0x48, 0xe3, 0x16, 0x25, 0xf8, 0x8c, 0x35, 0xe7, 0xbb, 0x30, + 0x45, 0x6f, 0x88, 0xe2, 0xa6, 0x73, 0x29, 0x61, 0x63, 0x33, 0x89, 0x0c, 0x4e, 0xa8, 0x9c, 0x93, + 0x34, 0x98, 0x7a, 0x42, 0x2b, 0x07, 0x8a, 0xb4, 0x93, 0x62, 0xe5, 0x6c, 0xb3, 0xcf, 0xd2, 0x8f, + 0x05, 0x83, 0xfe, 0xa6, 0x17, 0x02, 0x8c, 0xdd, 0xa7, 0xc6, 0x16, 0xbb, 0x81, 0x14, 0x8c, 0xe0, + 0x9b, 0x28, 0xb6, 0xdd, 0xb3, 0xb0, 0xed, 0xd3, 0xde, 0x49, 0xda, 0xab, 0xb4, 0xa0, 0x1b, 0x50, + 0xb0, 0xbc, 0x2d, 0x6c, 0xba, 0x36, 0x4f, 0xf1, 0x2b, 0x8e, 0x59, 0xf6, 0xc8, 0x3d, 0xf6, 0x6d, + 0xa8, 0x30, 0xc9, 0x1a, 0x9d, 0x8e, 0x72, 0xda, 0x0f, 0xf0, 0xb5, 0x08, 0x7e, 0x88, 0x7f, 0xe6, + 0x6c, 0xfe, 0x7f, 0xa3, 0xc1, 0x9c, 0x02, 0x30, 0xd6, 0x12, 0x7c, 0x00, 0x53, 0xac, 0xfe, 0xc2, + 0x8f, 0x82, 0x0b, 0xe1, 0x51, 0x0c, 0xc6, 0xe0, 0x34, 0x68, 0x19, 0xf2, 0xec, 0x97, 0xb8, 0xc6, + 0x25, 0x93, 0x0b, 0x22, 0x29, 0xf2, 0x32, 0xcc, 0xf3, 0x3e, 0xdc, 0x77, 0x92, 0x6c, 0x6e, 0x32, + 0xec, 0x21, 0x7e, 0xa8, 0xc1, 0x42, 0x78, 0xc0, 0x58, 0xb3, 0x54, 0xe4, 0xce, 0xbc, 0x91, 0xdc, + 0xbf, 0x26, 0xe4, 0x7e, 0x3a, 0xe8, 0x28, 0x47, 0xce, 0xe8, 0x8e, 0x53, 0x57, 0x37, 0x13, 0x5e, + 0x5d, 0xc9, 0xeb, 0x27, 0xc1, 0x9c, 0x04, 0xb3, 0xb1, 0xe6, 0xf4, 0xe1, 0x6b, 0xcd, 0x49, 0x39, + 0x82, 0xc5, 0x26, 0xb7, 0x29, 0xb6, 0xd1, 0x96, 0xe5, 0x05, 0x11, 0xe7, 0x7d, 0x28, 0xf5, 0x2c, + 0x1b, 0x9b, 0x2e, 0xaf, 0x21, 0x69, 0xea, 0x7e, 0xbc, 0x6f, 0x84, 0x3a, 0x25, 0xab, 0xdf, 0xd6, + 0x00, 0xa9, 0xbc, 0x7e, 0x31, 0xab, 0x55, 0x17, 0x0a, 0xde, 0x75, 0x9d, 0xbe, 0xe3, 0x9f, 0xb5, + 0xcd, 0xee, 0xe9, 0xbf, 0xab, 0xc1, 0x85, 0xc8, 0x88, 0x5f, 0x84, 0xe4, 0xf7, 0xf4, 0x2b, 0x30, + 0xb7, 0x8e, 0xc5, 0x19, 0x2f, 0x96, 0x3b, 0xd8, 0x03, 0xa4, 0xf6, 0x9e, 0xcf, 0x29, 0xe6, 0x97, + 0x60, 0xee, 0x89, 0x33, 0x22, 0x8e, 0x9c, 0x74, 0x4b, 0x37, 0xc5, 0x92, 0x59, 0x81, 0xbe, 0x82, + 0x6f, 0xe9, 0x7a, 0xf7, 0x00, 0xa9, 0x23, 0xcf, 0x43, 0x9c, 0x55, 0xfd, 0x7f, 0x34, 0x28, 0x35, + 0x7a, 0xa6, 0xdb, 0x17, 0xa2, 0x7c, 0x0c, 0x53, 0x2c, 0x33, 0xc3, 0xd3, 0xac, 0xef, 0x86, 0xf9, + 0xa9, 0xb4, 0xec, 0xa3, 0xc1, 0xf2, 0x38, 0x7c, 0x14, 0x99, 0x0a, 0xaf, 0x2c, 0xaf, 0x47, 0x2a, + 0xcd, 0xeb, 0xe8, 0x36, 0xe4, 0x4c, 0x32, 0x84, 0x86, 0xd7, 0x72, 0x34, 0x5d, 0x46, 0xb9, 0x91, + 0x2b, 0x91, 0xc1, 0xa8, 0xf4, 0x8f, 0xa0, 0xa8, 0x20, 0xa0, 0x3c, 0x64, 0x1f, 0x35, 0xf9, 0x35, + 0xa9, 0xb1, 0xd6, 0xda, 0x7c, 0xc6, 0x52, 0x88, 0x65, 0x80, 0xf5, 0x66, 0xf0, 0x9d, 0x49, 0x28, + 0xec, 0x99, 0x9c, 0x0f, 0x8f, 0x5b, 0xaa, 0x84, 0x5a, 0x9a, 0x84, 0x99, 0xd7, 0x91, 0x50, 0x42, + 0xfc, 0x96, 0x06, 0x33, 0x5c, 0x35, 0xe3, 0x86, 0x66, 0xca, 0x39, 0x25, 0x34, 0x2b, 0xd3, 0x30, + 0x38, 0xa1, 0x94, 0xe1, 0x4b, 0x0d, 0x66, 0x36, 0xb0, 0xd9, 0xf3, 0x83, 0x1c, 0xc6, 0x1a, 0xe4, + 0xf1, 0x71, 0xbb, 0x37, 0xec, 0x88, 0xa2, 0xc3, 0x7b, 0x61, 0x76, 0x21, 0xea, 0xe5, 0x3d, 0xdf, + 0xb5, 0xec, 0x6e, 0xc3, 0x75, 0xcd, 0x93, 0x8d, 0x09, 0x43, 0x8c, 0x44, 0x8f, 0xa0, 0x60, 0xf6, + 0x7a, 0xce, 0xcb, 0x9e, 0x15, 0x24, 0x2e, 0xde, 0x80, 0x8d, 0x1c, 0x5b, 0xbb, 0x01, 0x45, 0xa5, + 0x0f, 0x5d, 0x84, 0x29, 0x9a, 0xc8, 0x16, 0x81, 0x99, 0x7f, 0xc9, 0x44, 0xc4, 0x05, 0x98, 0x3f, + 0xa4, 0x9c, 0xe9, 0xd9, 0x79, 0x0f, 0xf7, 0x70, 0xdb, 0x77, 0x5c, 0xfd, 0x25, 0x94, 0x05, 0xe0, + 0xb8, 0x27, 0x3f, 0xe7, 0x88, 0x1f, 0x33, 0x33, 0xce, 0x11, 0x91, 0x87, 0xdf, 0x16, 0xb3, 0xf4, + 0x00, 0xc3, 0xbf, 0xa4, 0x7e, 0xff, 0x59, 0x83, 0xca, 0xba, 0xf3, 0xd2, 0xee, 0xba, 0x66, 0x27, + 0xf0, 0x71, 0x9f, 0x44, 0xcc, 0x65, 0x39, 0x52, 0x49, 0x89, 0xd0, 0xcb, 0x86, 0x88, 0xd9, 0x54, + 0x65, 0xae, 0x8a, 0x9d, 0x9f, 0xc4, 0xa7, 0xfe, 0x0d, 0x98, 0x8d, 0x0c, 0x22, 0x06, 0xf0, 0xac, + 0xb1, 0xb5, 0xb9, 0x4e, 0x36, 0x3c, 0xcd, 0xa7, 0x37, 0xb7, 0x1b, 0x0f, 0xb7, 0x9a, 0xbc, 0xea, + 0xdd, 0xd8, 0x5e, 0x6b, 0x6e, 0x49, 0x43, 0xb8, 0x2f, 0x66, 0x70, 0x5f, 0xef, 0xc1, 0x9c, 0x22, + 0xd0, 0xb8, 0xc5, 0xc7, 0x64, 0x79, 0x25, 0x5a, 0x15, 0x66, 0xf8, 0x29, 0x32, 0xea, 0x58, 0x7f, + 0x96, 0x85, 0xb2, 0xe8, 0xfa, 0x6a, 0xa4, 0x20, 0xab, 0xd9, 0x39, 0xd8, 0xb3, 0x5e, 0x89, 0xba, + 0x37, 0xff, 0x22, 0xed, 0x3d, 0x86, 0xc3, 0x5e, 0xb3, 0xf0, 0x2f, 0x74, 0x85, 0x3d, 0x74, 0xd9, + 0xb4, 0x3b, 0xf8, 0x98, 0x1e, 0x36, 0x27, 0x0d, 0xd9, 0x40, 0x93, 0xc6, 0xfc, 0xd5, 0x0b, 0xcd, + 0x25, 0x28, 0xaf, 0x60, 0xd0, 0x2a, 0x54, 0xc8, 0xef, 0xc6, 0x60, 0xd0, 0xb3, 0x70, 0x87, 0x31, + 0xc8, 0x13, 0x1a, 0x79, 0x9a, 0x8c, 0x11, 0xa0, 0x6b, 0x30, 0x45, 0xaf, 0xd8, 0x5e, 0x75, 0x9a, + 0x6c, 0x7e, 0x49, 0xca, 0x9b, 0xd1, 0xd7, 0xa0, 0xc8, 0x24, 0xde, 0xb4, 0x9f, 0x7a, 0x98, 0xbe, + 0x09, 0x51, 0xf2, 0x4d, 0x6a, 0x5f, 0xf8, 0x1c, 0x0b, 0x69, 0xe7, 0x58, 0x54, 0x87, 0xb2, 0xe7, + 0x3b, 0xae, 0xd9, 0xc5, 0xcf, 0xb8, 0xca, 0x8a, 0xe1, 0xa4, 0x68, 0xa4, 0x5b, 0x2e, 0xd7, 0x15, + 0x98, 0x6b, 0x0c, 0xfd, 0xc3, 0xa6, 0x4d, 0x0e, 0x1f, 0xb1, 0xc5, 0xbc, 0x0a, 0x88, 0xf4, 0xae, + 0x5b, 0x5e, 0x62, 0x37, 0x1f, 0x9c, 0xb8, 0x13, 0xee, 0xeb, 0xdb, 0x30, 0x4f, 0x7a, 0xb1, 0xed, + 0x5b, 0x6d, 0xe5, 0xa0, 0x27, 0xae, 0x12, 0x5a, 0xe4, 0x2a, 0x61, 0x7a, 0xde, 0x4b, 0xc7, 0xed, + 0xf0, 0xc5, 0x0e, 0xbe, 0x25, 0xda, 0x3f, 0x68, 0x4c, 0x9a, 0xa7, 0x5e, 0xe8, 0x1a, 0xf0, 0x86, + 0xfc, 0xd0, 0x2f, 0x43, 0x9e, 0x3f, 0xbf, 0xe2, 0xd9, 0xd5, 0x8b, 0xcb, 0xec, 0xd9, 0xd7, 0x32, + 0x67, 0xbc, 0xc3, 0x7a, 0x95, 0x0c, 0x20, 0xa7, 0x27, 0x6a, 0x3e, 0x34, 0xbd, 0x43, 0xdc, 0xd9, + 0x15, 0xcc, 0x43, 0xb9, 0xe7, 0xfb, 0x46, 0xa4, 0x5b, 0xca, 0x7e, 0x57, 0x8a, 0xfe, 0x08, 0xfb, + 0xa7, 0x88, 0xae, 0x56, 0x37, 0x2e, 0x88, 0x21, 0xbc, 0x28, 0xfb, 0x3a, 0xa3, 0x7e, 0xac, 0xc1, + 0x55, 0x31, 0x6c, 0xed, 0xd0, 0xb4, 0xbb, 0x58, 0x08, 0xf3, 0xf3, 0xea, 0x2b, 0x3e, 0xe9, 0xec, + 0x6b, 0x4e, 0xfa, 0x31, 0x54, 0x83, 0x49, 0xd3, 0x4c, 0x97, 0xd3, 0x53, 0x27, 0x31, 0xf4, 0xb8, + 0x47, 0x28, 0x18, 0xf4, 0x37, 0x69, 0x73, 0x9d, 0x5e, 0x70, 0xc9, 0x24, 0xbf, 0x25, 0xb3, 0x2d, + 0xb8, 0x24, 0x98, 0xf1, 0xd4, 0x53, 0x98, 0x5b, 0x6c, 0x4e, 0xa7, 0x72, 0xe3, 0xeb, 0x41, 0x78, + 0x9c, 0xbe, 0x95, 0x12, 0x87, 0x84, 0x97, 0x90, 0xa2, 0x68, 0x49, 0x28, 0x8b, 0xcc, 0x02, 0x88, + 0xcc, 0xca, 0x7d, 0x20, 0xd6, 0x4f, 0x58, 0x26, 0xf6, 0xf3, 0x2d, 0x40, 0xfa, 0x63, 0x5b, 0x20, + 0x1d, 0x15, 0xc3, 0x62, 0x20, 0x28, 0x51, 0xfb, 0x2e, 0x76, 0xfb, 0x96, 0xe7, 0x29, 0x65, 0xbe, + 0x24, 0x75, 0xbd, 0x0b, 0x93, 0x03, 0xcc, 0x0f, 0x47, 0xc5, 0x15, 0x24, 0x6c, 0x42, 0x19, 0x4c, + 0xfb, 0x25, 0x4c, 0x1f, 0xae, 0x09, 0x18, 0xb6, 0x20, 0x89, 0x38, 0x51, 0x31, 0x45, 0x69, 0x21, + 0x93, 0x52, 0x5a, 0xc8, 0x86, 0x4b, 0x0b, 0xa1, 0x03, 0xbb, 0xea, 0xa8, 0xce, 0xe7, 0xc0, 0xde, + 0x62, 0x0b, 0x10, 0xf8, 0xb7, 0xf3, 0xe1, 0xfa, 0x07, 0xdc, 0x51, 0x9d, 0x57, 0x18, 0xc4, 0x74, + 0xce, 0xa2, 0x08, 0x2c, 0x3e, 0x91, 0x0e, 0x25, 0xb2, 0x48, 0x86, 0x5a, 0x73, 0x99, 0x34, 0x42, + 0x6d, 0xd2, 0x19, 0x1f, 0xc1, 0x42, 0xd8, 0x19, 0x8f, 0x25, 0xd4, 0x02, 0xe4, 0x7c, 0xe7, 0x08, + 0x8b, 0xc8, 0xcc, 0x3e, 0x62, 0x6a, 0x0d, 0x1c, 0xf5, 0xf9, 0xa8, 0xf5, 0x3b, 0x92, 0x2b, 0x35, + 0xc0, 0x71, 0x67, 0x40, 0xb6, 0xa3, 0xc8, 0x2d, 0xb0, 0x0f, 0x89, 0xf5, 0x29, 0x5c, 0x8c, 0x3a, + 0xdf, 0xf3, 0x99, 0xc4, 0x3e, 0x33, 0xce, 0x24, 0xf7, 0x7c, 0x3e, 0x00, 0xcf, 0xa5, 0x9f, 0x54, + 0x9c, 0xee, 0xf9, 0xf0, 0xfe, 0x75, 0xa8, 0x25, 0xf9, 0xe0, 0x73, 0xb5, 0xc5, 0xc0, 0x25, 0x9f, + 0x0f, 0xd7, 0x1f, 0x6a, 0x92, 0xad, 0xba, 0x6b, 0x3e, 0x7a, 0x13, 0xb6, 0x22, 0xd6, 0xdd, 0x09, + 0xb6, 0x4f, 0x3d, 0xf0, 0x96, 0xd9, 0x64, 0x6f, 0x29, 0x87, 0x50, 0x42, 0x61, 0x7f, 0xd2, 0xd5, + 0x7f, 0x95, 0xbb, 0x97, 0x83, 0xc9, 0xb8, 0x33, 0x2e, 0x18, 0x09, 0xcf, 0x01, 0x18, 0xfd, 0x88, + 0x99, 0x8a, 0x1a, 0xa4, 0xce, 0x67, 0xe9, 0x7e, 0x43, 0x06, 0x98, 0x58, 0x1c, 0x3b, 0x1f, 0x04, + 0x13, 0x96, 0xd2, 0x43, 0xd8, 0xb9, 0x40, 0xdc, 0x6a, 0x40, 0x21, 0xc8, 0x2c, 0x28, 0xef, 0xa0, + 0x8b, 0x90, 0xdf, 0xde, 0xd9, 0xdb, 0x6d, 0xac, 0x91, 0x8b, 0xdd, 0x02, 0xe4, 0xd7, 0x76, 0x0c, + 0xe3, 0xe9, 0x6e, 0x8b, 0xdc, 0xec, 0xa2, 0xcf, 0xa2, 0x56, 0xbe, 0xcc, 0x42, 0xe6, 0xf1, 0x33, + 0xf4, 0x19, 0xe4, 0xd8, 0xb3, 0xbc, 0x53, 0x5e, 0x67, 0xd6, 0x4e, 0x7b, 0x79, 0xa8, 0xbf, 0xf5, + 0x83, 0xff, 0xfa, 0xf2, 0x0f, 0x33, 0x73, 0x7a, 0xa9, 0x3e, 0x5a, 0xad, 0x1f, 0x8d, 0xea, 0x34, + 0xc8, 0x3e, 0xd0, 0x6e, 0xa1, 0x6f, 0x42, 0x76, 0x77, 0xe8, 0xa3, 0xd4, 0x57, 0x9b, 0xb5, 0xf4, + 0xc7, 0x88, 0xfa, 0x05, 0xca, 0x74, 0x56, 0x07, 0xce, 0x74, 0x30, 0xf4, 0x09, 0xcb, 0xef, 0x42, + 0x51, 0x7d, 0x4a, 0x78, 0xe6, 0x53, 0xce, 0xda, 0xd9, 0xcf, 0x14, 0xf5, 0xab, 0x14, 0xea, 0x2d, + 0x1d, 0x71, 0x28, 0xf6, 0xd8, 0x51, 0x9d, 0x45, 0xeb, 0xd8, 0x46, 0xa9, 0x0f, 0x3d, 0x6b, 0xe9, + 0x2f, 0x17, 0x63, 0xb3, 0xf0, 0x8f, 0x6d, 0xc2, 0xf2, 0x3b, 0xfc, 0x89, 0x62, 0xdb, 0x47, 0xd7, + 0x12, 0xde, 0x98, 0xa9, 0x6f, 0xa7, 0x6a, 0x4b, 0xe9, 0x04, 0x1c, 0xe4, 0x0a, 0x05, 0xb9, 0xa8, + 0xcf, 0x71, 0x90, 0x76, 0x40, 0xf2, 0x40, 0xbb, 0xb5, 0xd2, 0x86, 0x1c, 0xad, 0xcd, 0xa3, 0xe7, + 0xe2, 0x47, 0x2d, 0xe1, 0xd5, 0x43, 0xca, 0x42, 0x87, 0xaa, 0xfa, 0xfa, 0x02, 0x05, 0x2a, 0xeb, + 0x05, 0x02, 0x44, 0x2b, 0xf3, 0x0f, 0xb4, 0x5b, 0x37, 0xb5, 0x3b, 0xda, 0xca, 0x5f, 0xe5, 0x20, + 0x47, 0x6b, 0x40, 0xe8, 0x08, 0x40, 0xd6, 0xa0, 0xa3, 0xb3, 0x8b, 0x95, 0xb7, 0xa3, 0xb3, 0x8b, + 0x97, 0xaf, 0xf5, 0x1a, 0x05, 0x5d, 0xd0, 0x67, 0x09, 0x28, 0x2d, 0x2d, 0xd5, 0x69, 0x25, 0x8d, + 0xe8, 0xf1, 0xc7, 0x1a, 0x2f, 0x86, 0x31, 0x33, 0x43, 0x49, 0xdc, 0x42, 0xf5, 0xe7, 0xe8, 0x76, + 0x48, 0x28, 0x39, 0xeb, 0xf7, 0x29, 0x60, 0x5d, 0xaf, 0x48, 0x40, 0x97, 0x52, 0x3c, 0xd0, 0x6e, + 0x3d, 0xaf, 0xea, 0xf3, 0x5c, 0xcb, 0x91, 0x1e, 0xf4, 0x3d, 0x28, 0x87, 0x2b, 0xa5, 0xe8, 0x7a, + 0x02, 0x56, 0xb4, 0xf2, 0x5a, 0x7b, 0xe7, 0x74, 0x22, 0x2e, 0xd3, 0x22, 0x95, 0x89, 0x83, 0x33, + 0xe4, 0x23, 0x8c, 0x07, 0x26, 0x21, 0xe2, 0x6b, 0x80, 0xfe, 0x54, 0xe3, 0xc5, 0x6e, 0x59, 0xe8, + 0x44, 0x49, 0xdc, 0x63, 0xf5, 0xd4, 0xda, 0x8d, 0x33, 0xa8, 0xb8, 0x10, 0x1f, 0x51, 0x21, 0x3e, + 0xd4, 0x17, 0xa4, 0x10, 0xbe, 0xd5, 0xc7, 0xbe, 0xc3, 0xa5, 0x78, 0x7e, 0x45, 0x7f, 0x2b, 0xa4, + 0x9c, 0x50, 0xaf, 0x5c, 0x2c, 0x56, 0x90, 0x4c, 0x5c, 0xac, 0x50, 0xcd, 0x33, 0x71, 0xb1, 0xc2, + 0xd5, 0xcc, 0xa4, 0xc5, 0xe2, 0xe5, 0xc7, 0x84, 0xc5, 0x0a, 0x7a, 0x56, 0xfe, 0x6f, 0x12, 0xf2, + 0x6b, 0xec, 0x7f, 0x75, 0x42, 0x0e, 0x14, 0x82, 0x12, 0x1d, 0x5a, 0x4c, 0xaa, 0x02, 0xc8, 0xab, + 0x5c, 0xed, 0x5a, 0x6a, 0x3f, 0x17, 0xe8, 0x6d, 0x2a, 0xd0, 0x65, 0xfd, 0x22, 0x41, 0xe6, 0xff, + 0x37, 0x55, 0x9d, 0xe5, 0x8a, 0xeb, 0x66, 0xa7, 0x43, 0x14, 0xf1, 0x9b, 0x50, 0x52, 0x0b, 0x66, + 0xe8, 0xed, 0xc4, 0xca, 0x83, 0x5a, 0x7d, 0xab, 0xe9, 0xa7, 0x91, 0x70, 0xe4, 0x77, 0x28, 0xf2, + 0xa2, 0x7e, 0x29, 0x01, 0xd9, 0xa5, 0xa4, 0x21, 0x70, 0x56, 0xd9, 0x4a, 0x06, 0x0f, 0x95, 0xd0, + 0x92, 0xc1, 0xc3, 0x85, 0xb1, 0x53, 0xc1, 0x87, 0x94, 0x94, 0x80, 0x7b, 0x00, 0xb2, 0xf4, 0x84, + 0x12, 0x75, 0xa9, 0x5c, 0x58, 0xa3, 0xce, 0x21, 0x5e, 0xb5, 0xd2, 0x75, 0x0a, 0xcb, 0xf7, 0x5d, + 0x04, 0xb6, 0x67, 0x79, 0x3e, 0x33, 0xcc, 0x99, 0x50, 0xe1, 0x08, 0x25, 0xce, 0x27, 0x5c, 0x87, + 0xaa, 0x5d, 0x3f, 0x95, 0x86, 0xa3, 0xdf, 0xa0, 0xe8, 0xd7, 0xf4, 0x5a, 0x02, 0xfa, 0x80, 0xd1, + 0x92, 0xcd, 0xf6, 0xf7, 0x05, 0x28, 0x3e, 0x31, 0x2d, 0xdb, 0xc7, 0xb6, 0x69, 0xb7, 0x31, 0x3a, + 0x80, 0x1c, 0x8d, 0xdd, 0x51, 0x47, 0xac, 0xd6, 0x49, 0xa2, 0x8e, 0x38, 0x54, 0x28, 0xd0, 0x97, + 0x28, 0x70, 0x4d, 0xbf, 0x40, 0x80, 0xfb, 0x92, 0x75, 0x9d, 0x95, 0x18, 0xb4, 0x5b, 0xa8, 0x03, + 0x39, 0x62, 0xbb, 0xaf, 0xd0, 0xe5, 0x53, 0xf2, 0xee, 0xb5, 0x2b, 0xc9, 0x9d, 0x67, 0xa1, 0x10, + 0x8b, 0x7e, 0x45, 0x50, 0x5e, 0xc0, 0x94, 0x81, 0xcd, 0xce, 0xc9, 0x58, 0x30, 0x21, 0x8b, 0x51, + 0x61, 0x5c, 0xca, 0x9a, 0xe0, 0x1c, 0x42, 0x9e, 0x0d, 0x1a, 0x0b, 0x28, 0xb4, 0x59, 0x54, 0x20, + 0x56, 0x32, 0x10, 0x33, 0xe2, 0x0f, 0x2b, 0x22, 0x40, 0xa1, 0x64, 0x64, 0x14, 0x28, 0x7c, 0x23, + 0x4f, 0x9f, 0x91, 0x47, 0xe9, 0x08, 0xce, 0x08, 0x40, 0xd6, 0x09, 0xa3, 0x96, 0x10, 0xab, 0x2f, + 0xd6, 0x96, 0xd2, 0x09, 0x92, 0xf6, 0xa2, 0x8a, 0xd9, 0x09, 0x68, 0x09, 0xee, 0xb7, 0x61, 0x72, + 0xc3, 0xf4, 0x0e, 0x51, 0xe4, 0xcc, 0xa2, 0xbc, 0x83, 0xae, 0xd5, 0x92, 0xba, 0x38, 0xca, 0x35, + 0x8a, 0x72, 0x89, 0x85, 0x80, 0x90, 0x0a, 0x4d, 0xef, 0x90, 0xeb, 0x8f, 0x3d, 0x82, 0x8e, 0x2d, + 0x94, 0xfa, 0xa2, 0x3a, 0xb6, 0x50, 0xa1, 0x77, 0xd3, 0xe9, 0xfa, 0x23, 0x28, 0x47, 0x23, 0x82, + 0x33, 0x80, 0x69, 0xf1, 0x5c, 0x18, 0x45, 0x1e, 0x59, 0x45, 0xde, 0x18, 0xd7, 0x16, 0xd3, 0xba, + 0x39, 0xda, 0x75, 0x8a, 0x76, 0x55, 0xaf, 0xc6, 0x56, 0x8b, 0x53, 0x3e, 0xd0, 0x6e, 0xdd, 0xd1, + 0xd0, 0xf7, 0x00, 0x64, 0x29, 0x35, 0xe6, 0xbb, 0xa2, 0xe5, 0xd9, 0x98, 0xef, 0x8a, 0x55, 0x61, + 0xf5, 0x65, 0x8a, 0x7b, 0x53, 0xbf, 0x1e, 0xc5, 0xf5, 0x5d, 0xd3, 0xf6, 0x5e, 0x60, 0xf7, 0x36, + 0xab, 0x33, 0x78, 0x87, 0xd6, 0x80, 0x4c, 0xd9, 0x85, 0x42, 0x50, 0x89, 0x89, 0xc6, 0xa9, 0x68, + 0xcd, 0x28, 0x1a, 0xa7, 0x62, 0x25, 0x9c, 0xb0, 0xc3, 0x0e, 0xed, 0x17, 0x41, 0x4a, 0x5c, 0xd7, + 0x5f, 0x54, 0x60, 0x92, 0x5c, 0x65, 0xc8, 0xb1, 0x4e, 0xa6, 0xc9, 0xa2, 0xb3, 0x8f, 0x65, 0xfa, + 0xa3, 0xb3, 0x8f, 0x67, 0xd8, 0xc2, 0xc7, 0x3a, 0x72, 0xcd, 0xad, 0xb3, 0xfc, 0x13, 0x99, 0xa9, + 0x03, 0x45, 0x25, 0x7d, 0x86, 0x12, 0x98, 0x85, 0x2b, 0x07, 0xd1, 0x83, 0x42, 0x42, 0xee, 0x4d, + 0xbf, 0x4c, 0xf1, 0x2e, 0xb0, 0x83, 0x02, 0xc5, 0xeb, 0x30, 0x0a, 0x02, 0xc8, 0x67, 0xc7, 0x2d, + 0x3f, 0x61, 0x76, 0x61, 0xeb, 0x5f, 0x4a, 0x27, 0x48, 0x9d, 0x9d, 0x34, 0xfd, 0x97, 0x50, 0x52, + 0x53, 0x66, 0x28, 0x41, 0xf8, 0x48, 0x6d, 0x23, 0x1a, 0x81, 0x93, 0x32, 0x6e, 0x61, 0x6f, 0x4d, + 0x21, 0x4d, 0x85, 0x8c, 0x00, 0xf7, 0x20, 0xcf, 0x53, 0x67, 0x49, 0x2a, 0x0d, 0x97, 0x3f, 0x92, + 0x54, 0x1a, 0xc9, 0xbb, 0x85, 0xef, 0x1d, 0x14, 0x91, 0x5c, 0xe1, 0xc5, 0x29, 0x87, 0xa3, 0x3d, + 0xc2, 0x7e, 0x1a, 0x9a, 0x4c, 0x77, 0xa7, 0xa1, 0x29, 0x99, 0x95, 0x34, 0xb4, 0x2e, 0xf6, 0xb9, + 0x3f, 0x10, 0x69, 0x09, 0x94, 0xc2, 0x4c, 0x3d, 0x59, 0xe8, 0xa7, 0x91, 0x24, 0x5d, 0x0b, 0x25, + 0xa0, 0x38, 0x56, 0x1c, 0x03, 0xc8, 0x34, 0x5e, 0xf4, 0xac, 0x9f, 0x58, 0x61, 0x89, 0x9e, 0xf5, + 0x93, 0x33, 0x81, 0x61, 0x1f, 0x2b, 0x71, 0xd9, 0xad, 0x94, 0x20, 0x7f, 0xae, 0x01, 0x8a, 0x27, + 0xfa, 0xd0, 0xfb, 0xc9, 0xdc, 0x13, 0xab, 0x35, 0xb5, 0x0f, 0x5e, 0x8f, 0x38, 0xc9, 0x21, 0x4b, + 0x91, 0xda, 0x94, 0x7a, 0xf0, 0x92, 0x08, 0xf5, 0x7d, 0x0d, 0x66, 0x42, 0xc9, 0x41, 0xf4, 0x6e, + 0xca, 0x9a, 0x46, 0x4a, 0x36, 0xb5, 0xf7, 0xce, 0xa4, 0x4b, 0xba, 0x04, 0x29, 0x3b, 0x40, 0xdc, + 0x06, 0x7f, 0x47, 0x83, 0x72, 0x38, 0x87, 0x88, 0x52, 0x78, 0xc7, 0x2a, 0x3d, 0xb5, 0x9b, 0x67, + 0x13, 0x9e, 0xbe, 0x3c, 0xf2, 0x22, 0xd8, 0x83, 0x3c, 0x4f, 0x36, 0x26, 0x6d, 0xfc, 0x70, 0x69, + 0x28, 0x69, 0xe3, 0x47, 0x32, 0x95, 0x09, 0x1b, 0xdf, 0x75, 0x7a, 0x58, 0x31, 0x33, 0x9e, 0x83, + 0x4c, 0x43, 0x3b, 0xdd, 0xcc, 0x22, 0x09, 0xcc, 0x34, 0x34, 0x69, 0x66, 0x22, 0xd5, 0x88, 0x52, + 0x98, 0x9d, 0x61, 0x66, 0xd1, 0x4c, 0x65, 0x82, 0x99, 0x51, 0x40, 0xc5, 0xcc, 0x64, 0x0a, 0x30, + 0xc9, 0xcc, 0x62, 0x55, 0xac, 0x24, 0x33, 0x8b, 0x67, 0x11, 0x13, 0xd6, 0x91, 0xe2, 0x86, 0xcc, + 0x6c, 0x3e, 0x21, 0x49, 0x88, 0x3e, 0x48, 0x51, 0x62, 0x62, 0x4d, 0xac, 0x76, 0xfb, 0x35, 0xa9, + 0x53, 0xf7, 0x38, 0x53, 0xbf, 0xd8, 0xe3, 0x7f, 0xa4, 0xc1, 0x42, 0x52, 0x5e, 0x11, 0xa5, 0xe0, + 0xa4, 0x94, 0xd0, 0x6a, 0xcb, 0xaf, 0x4b, 0x7e, 0xba, 0xb6, 0x82, 0x5d, 0xff, 0xb0, 0xfb, 0x79, + 0xa3, 0xfe, 0xfc, 0x1a, 0x5c, 0x85, 0xa9, 0xc6, 0xc0, 0x7a, 0x8c, 0x4f, 0xd0, 0xfc, 0x74, 0xa6, + 0x36, 0x43, 0xf8, 0x3a, 0xae, 0xf5, 0x8a, 0xfe, 0x2d, 0x92, 0xa5, 0xcc, 0x41, 0x09, 0x20, 0x20, + 0x98, 0xf8, 0xb7, 0x2f, 0x16, 0xb5, 0xff, 0xfc, 0x62, 0x51, 0xfb, 0xef, 0x2f, 0x16, 0xb5, 0x9f, + 0xfe, 0xef, 0xe2, 0xc4, 0xf3, 0xeb, 0x5d, 0x87, 0x8a, 0xb5, 0x6c, 0x39, 0x75, 0xf9, 0xf7, 0x51, + 0x56, 0xeb, 0xaa, 0xa8, 0x07, 0x53, 0xf4, 0x0f, 0x9a, 0xac, 0xfe, 0x7f, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xde, 0xd8, 0xa8, 0xc5, 0xa7, 0x45, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -7334,6 +7546,9 @@ var _Cluster_serviceDesc = grpc.ServiceDesc{ type MaintenanceClient interface { // Alarm activates, deactivates, and queries alarms regarding cluster health. Alarm(ctx context.Context, in *AlarmRequest, opts ...grpc.CallOption) (*AlarmResponse, error) + Livez(ctx context.Context, in *HealthRequest, opts ...grpc.CallOption) (*HealthResponse, error) + Readyz(ctx context.Context, in *HealthRequest, opts ...grpc.CallOption) (*HealthResponse, error) + Healthz(ctx context.Context, in *HealthRequest, opts ...grpc.CallOption) (*HealthResponse, error) // Status gets the status of the member. Status(ctx context.Context, in *StatusRequest, opts ...grpc.CallOption) (*StatusResponse, error) // Defragment defragments a member's backend database to recover storage space. @@ -7375,6 +7590,33 @@ func (c *maintenanceClient) Alarm(ctx context.Context, in *AlarmRequest, opts .. return out, nil } +func (c *maintenanceClient) Livez(ctx context.Context, in *HealthRequest, opts ...grpc.CallOption) (*HealthResponse, error) { + out := new(HealthResponse) + err := c.cc.Invoke(ctx, "/etcdserverpb.Maintenance/Livez", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *maintenanceClient) Readyz(ctx context.Context, in *HealthRequest, opts ...grpc.CallOption) (*HealthResponse, error) { + out := new(HealthResponse) + err := c.cc.Invoke(ctx, "/etcdserverpb.Maintenance/Readyz", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *maintenanceClient) Healthz(ctx context.Context, in *HealthRequest, opts ...grpc.CallOption) (*HealthResponse, error) { + out := new(HealthResponse) + err := c.cc.Invoke(ctx, "/etcdserverpb.Maintenance/Healthz", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *maintenanceClient) Status(ctx context.Context, in *StatusRequest, opts ...grpc.CallOption) (*StatusResponse, error) { out := new(StatusResponse) err := c.cc.Invoke(ctx, "/etcdserverpb.Maintenance/Status", in, out, opts...) @@ -7465,6 +7707,9 @@ func (c *maintenanceClient) Downgrade(ctx context.Context, in *DowngradeRequest, type MaintenanceServer interface { // Alarm activates, deactivates, and queries alarms regarding cluster health. Alarm(context.Context, *AlarmRequest) (*AlarmResponse, error) + Livez(context.Context, *HealthRequest) (*HealthResponse, error) + Readyz(context.Context, *HealthRequest) (*HealthResponse, error) + Healthz(context.Context, *HealthRequest) (*HealthResponse, error) // Status gets the status of the member. Status(context.Context, *StatusRequest) (*StatusResponse, error) // Defragment defragments a member's backend database to recover storage space. @@ -7496,6 +7741,15 @@ type UnimplementedMaintenanceServer struct { func (*UnimplementedMaintenanceServer) Alarm(ctx context.Context, req *AlarmRequest) (*AlarmResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Alarm not implemented") } +func (*UnimplementedMaintenanceServer) Livez(ctx context.Context, req *HealthRequest) (*HealthResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Livez not implemented") +} +func (*UnimplementedMaintenanceServer) Readyz(ctx context.Context, req *HealthRequest) (*HealthResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Readyz not implemented") +} +func (*UnimplementedMaintenanceServer) Healthz(ctx context.Context, req *HealthRequest) (*HealthResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Healthz not implemented") +} func (*UnimplementedMaintenanceServer) Status(ctx context.Context, req *StatusRequest) (*StatusResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Status not implemented") } @@ -7540,6 +7794,60 @@ func _Maintenance_Alarm_Handler(srv interface{}, ctx context.Context, dec func(i return interceptor(ctx, in, info, handler) } +func _Maintenance_Livez_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(HealthRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MaintenanceServer).Livez(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/etcdserverpb.Maintenance/Livez", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MaintenanceServer).Livez(ctx, req.(*HealthRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Maintenance_Readyz_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(HealthRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MaintenanceServer).Readyz(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/etcdserverpb.Maintenance/Readyz", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MaintenanceServer).Readyz(ctx, req.(*HealthRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Maintenance_Healthz_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(HealthRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MaintenanceServer).Healthz(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/etcdserverpb.Maintenance/Healthz", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MaintenanceServer).Healthz(ctx, req.(*HealthRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _Maintenance_Status_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(StatusRequest) if err := dec(in); err != nil { @@ -7678,8 +7986,20 @@ var _Maintenance_serviceDesc = grpc.ServiceDesc{ Handler: _Maintenance_Alarm_Handler, }, { - MethodName: "Status", - Handler: _Maintenance_Status_Handler, + MethodName: "Livez", + Handler: _Maintenance_Livez_Handler, + }, + { + MethodName: "Readyz", + Handler: _Maintenance_Readyz_Handler, + }, + { + MethodName: "Healthz", + Handler: _Maintenance_Healthz_Handler, + }, + { + MethodName: "Status", + Handler: _Maintenance_Status_Handler, }, { MethodName: "Defragment", @@ -11414,6 +11734,176 @@ func (m *AlarmResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *HealthRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *HealthRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *HealthRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.HealthCheckSelector != nil { + { + size := m.HealthCheckSelector.Size() + i -= size + if _, err := m.HealthCheckSelector.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + } + } + return len(dAtA) - i, nil +} + +func (m *HealthRequest_Exclude) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *HealthRequest_Exclude) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.Exclude != nil { + { + size, err := m.Exclude.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintRpc(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} +func (m *HealthRequest_Allowlist) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *HealthRequest_Allowlist) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.Allowlist != nil { + { + size, err := m.Allowlist.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintRpc(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + return len(dAtA) - i, nil +} +func (m *HealthRequest_StringArray) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *HealthRequest_StringArray) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *HealthRequest_StringArray) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.Values) > 0 { + for iNdEx := len(m.Values) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Values[iNdEx]) + copy(dAtA[i:], m.Values[iNdEx]) + i = encodeVarintRpc(dAtA, i, uint64(len(m.Values[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *HealthResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *HealthResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *HealthResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.Reason) > 0 { + i -= len(m.Reason) + copy(dAtA[i:], m.Reason) + i = encodeVarintRpc(dAtA, i, uint64(len(m.Reason))) + i-- + dAtA[i] = 0x1a + } + if m.Ok { + i-- + if m.Ok { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x10 + } + if m.Header != nil { + { + size, err := m.Header.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintRpc(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *DowngradeRequest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -14380,6 +14870,86 @@ func (m *AlarmResponse) Size() (n int) { return n } +func (m *HealthRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.HealthCheckSelector != nil { + n += m.HealthCheckSelector.Size() + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *HealthRequest_Exclude) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Exclude != nil { + l = m.Exclude.Size() + n += 1 + l + sovRpc(uint64(l)) + } + return n +} +func (m *HealthRequest_Allowlist) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Allowlist != nil { + l = m.Allowlist.Size() + n += 1 + l + sovRpc(uint64(l)) + } + return n +} +func (m *HealthRequest_StringArray) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Values) > 0 { + for _, s := range m.Values { + l = len(s) + n += 1 + l + sovRpc(uint64(l)) + } + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *HealthResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Header != nil { + l = m.Header.Size() + n += 1 + l + sovRpc(uint64(l)) + } + if m.Ok { + n += 2 + } + l = len(m.Reason) + if l > 0 { + n += 1 + l + sovRpc(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + func (m *DowngradeRequest) Size() (n int) { if m == nil { return 0 @@ -22062,6 +22632,349 @@ func (m *AlarmResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *HealthRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: HealthRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: HealthRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Exclude", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthRpc + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &HealthRequest_StringArray{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.HealthCheckSelector = &HealthRequest_Exclude{v} + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Allowlist", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthRpc + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &HealthRequest_StringArray{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.HealthCheckSelector = &HealthRequest_Allowlist{v} + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRpc(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthRpc + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *HealthRequest_StringArray) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: StringArray: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: StringArray: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Values", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthRpc + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Values = append(m.Values, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRpc(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthRpc + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *HealthResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: HealthResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: HealthResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Header", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthRpc + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Header == nil { + m.Header = &ResponseHeader{} + } + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Ok", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Ok = bool(v != 0) + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Reason", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthRpc + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Reason = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRpc(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthRpc + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *DowngradeRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/api/etcdserverpb/rpc.proto b/api/etcdserverpb/rpc.proto index 68cbd4f020d..ce1687467c4 100644 --- a/api/etcdserverpb/rpc.proto +++ b/api/etcdserverpb/rpc.proto @@ -207,6 +207,26 @@ service Maintenance { }; } + + rpc Livez(HealthRequest) returns (HealthResponse) { + option (google.api.http) = { + post: "/v3/maintenance/livez" + body: "*" + }; + } + rpc Readyz(HealthRequest) returns (HealthResponse) { + option (google.api.http) = { + post: "/v3/maintenance/readyz" + body: "*" + }; + } + rpc Healthz(HealthRequest) returns (HealthResponse) { + option (google.api.http) = { + post: "/v3/maintenance/healthz" + body: "*" + }; + } + // Status gets the status of the member. rpc Status(StatusRequest) returns (StatusResponse) { option (google.api.http) = { @@ -1130,6 +1150,28 @@ message AlarmResponse { repeated AlarmMember alarms = 2; } +message HealthRequest { + message StringArray { + repeated string values = 1; + } + option (versionpb.etcd_version_msg) = "3.0"; + oneof healthCheckSelector { + // List of health checks to exclude. + StringArray exclude = 1; + // List of health checks to allowlist. + // Cannot be used with exclude. + StringArray allowlist = 2; + } +} + +message HealthResponse { + option (versionpb.etcd_version_msg) = "3.0"; + + ResponseHeader header = 1; + bool ok = 2; + string reason = 3; +} + message DowngradeRequest { option (versionpb.etcd_version_msg) = "3.5"; diff --git a/client/v3/client_test.go b/client/v3/client_test.go index 350b1960a10..3a5e27ac15d 100644 --- a/client/v3/client_test.go +++ b/client/v3/client_test.go @@ -432,6 +432,18 @@ func (mm mockMaintenance) AlarmDisarm(ctx context.Context, m *AlarmMember) (*Ala return nil, nil } +func (mm mockMaintenance) Livez(ctx context.Context) (*HealthResponse, error) { + return nil, nil +} + +func (mm mockMaintenance) Readyz(ctx context.Context) (*HealthResponse, error) { + return nil, nil +} + +func (mm mockMaintenance) Healthz(ctx context.Context) (*HealthResponse, error) { + return nil, nil +} + func (mm mockMaintenance) Defragment(ctx context.Context, endpoint string) (*DefragmentResponse, error) { return nil, nil } diff --git a/client/v3/maintenance.go b/client/v3/maintenance.go index d8cd137179f..b261ff887c4 100644 --- a/client/v3/maintenance.go +++ b/client/v3/maintenance.go @@ -30,6 +30,7 @@ type ( DefragmentResponse pb.DefragmentResponse AlarmResponse pb.AlarmResponse AlarmMember pb.AlarmMember + HealthResponse pb.HealthResponse StatusResponse pb.StatusResponse HashKVResponse pb.HashKVResponse MoveLeaderResponse pb.MoveLeaderResponse @@ -51,6 +52,10 @@ type Maintenance interface { // AlarmDisarm disarms a given alarm. AlarmDisarm(ctx context.Context, m *AlarmMember) (*AlarmResponse, error) + Livez(ctx context.Context) (*HealthResponse, error) + Readyz(ctx context.Context) (*HealthResponse, error) + Healthz(ctx context.Context) (*HealthResponse, error) + // Defragment releases wasted space from internal fragmentation on a given etcd member. // Defragment is only needed when deleting a large number of keys and want to reclaim // the resources. @@ -158,6 +163,33 @@ func (m *maintenance) AlarmList(ctx context.Context) (*AlarmResponse, error) { return nil, toErr(ctx, err) } +func (m *maintenance) Livez(ctx context.Context) (*HealthResponse, error) { + req := &pb.HealthRequest{} + resp, err := m.remote.Livez(ctx, req, m.callOpts...) + if err == nil { + return (*HealthResponse)(resp), nil + } + return nil, toErr(ctx, err) +} + +func (m *maintenance) Readyz(ctx context.Context) (*HealthResponse, error) { + req := &pb.HealthRequest{} + resp, err := m.remote.Readyz(ctx, req, m.callOpts...) + if err == nil { + return (*HealthResponse)(resp), nil + } + return nil, toErr(ctx, err) +} + +func (m *maintenance) Healthz(ctx context.Context) (*HealthResponse, error) { + req := &pb.HealthRequest{} + resp, err := m.remote.Healthz(ctx, req, m.callOpts...) + if err == nil { + return (*HealthResponse)(resp), nil + } + return nil, toErr(ctx, err) +} + func (m *maintenance) AlarmDisarm(ctx context.Context, am *AlarmMember) (*AlarmResponse, error) { req := &pb.AlarmRequest{ Action: pb.AlarmRequest_DEACTIVATE, diff --git a/client/v3/retry.go b/client/v3/retry.go index e56e061340d..49379395d52 100644 --- a/client/v3/retry.go +++ b/client/v3/retry.go @@ -198,6 +198,18 @@ func (rmc *retryMaintenanceClient) Alarm(ctx context.Context, in *pb.AlarmReques return rmc.mc.Alarm(ctx, in, append(opts, withRetryPolicy(repeatable))...) } +func (rmc *retryMaintenanceClient) Livez(ctx context.Context, in *pb.HealthRequest, opts ...grpc.CallOption) (resp *pb.HealthResponse, err error) { + return rmc.mc.Livez(ctx, in, append(opts, withRetryPolicy(repeatable))...) +} + +func (rmc *retryMaintenanceClient) Readyz(ctx context.Context, in *pb.HealthRequest, opts ...grpc.CallOption) (resp *pb.HealthResponse, err error) { + return rmc.mc.Readyz(ctx, in, append(opts, withRetryPolicy(repeatable))...) +} + +func (rmc *retryMaintenanceClient) Healthz(ctx context.Context, in *pb.HealthRequest, opts ...grpc.CallOption) (resp *pb.HealthResponse, err error) { + return rmc.mc.Healthz(ctx, in, append(opts, withRetryPolicy(repeatable))...) +} + func (rmc *retryMaintenanceClient) Status(ctx context.Context, in *pb.StatusRequest, opts ...grpc.CallOption) (resp *pb.StatusResponse, err error) { return rmc.mc.Status(ctx, in, append(opts, withRetryPolicy(repeatable))...) } diff --git a/etcdctl/ctlv3/command/ep_command.go b/etcdctl/ctlv3/command/ep_command.go index 2fb017c1fd0..279d755a212 100644 --- a/etcdctl/ctlv3/command/ep_command.go +++ b/etcdctl/ctlv3/command/ep_command.go @@ -45,6 +45,8 @@ func NewEndpointCommand() *cobra.Command { ec.AddCommand(newEpHealthCommand()) ec.AddCommand(newEpStatusCommand()) ec.AddCommand(newEpHashKVCommand()) + ec.AddCommand(newEpLivezCommand()) + ec.AddCommand(newEpReadyzCommand()) return ec } @@ -59,6 +61,26 @@ func newEpHealthCommand() *cobra.Command { return cmd } +func newEpLivezCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "livez", + Short: "Checks the livez of endpoints specified in `--endpoints` flag", + Run: epHealthCheckCommandFunc(true), + } + + return cmd +} + +func newEpReadyzCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "readyz", + Short: "Checks the readyz of endpoints specified in `--endpoints` flag", + Run: epHealthCheckCommandFunc(false), + } + + return cmd +} + func newEpStatusCommand() *cobra.Command { return &cobra.Command{ Use: "status", @@ -81,10 +103,11 @@ func newEpHashKVCommand() *cobra.Command { } type epHealth struct { - Ep string `json:"endpoint"` - Health bool `json:"health"` - Took string `json:"took"` - Error string `json:"error,omitempty"` + Ep string `json:"endpoint"` + Health bool `json:"health"` + Took string `json:"took"` + Error string `json:"error,omitempty"` + DebugString string `json:"debugString,omitempty"` } // epHealthCommandFunc executes the "endpoint-health" command. @@ -185,6 +208,91 @@ func epHealthCommandFunc(cmd *cobra.Command, args []string) { } } +// epHealthCheckCommandFunc executes the "endpoint-check" command. +func epHealthCheckCommandFunc(isLivez bool) func(*cobra.Command, []string) { + return func(cmd *cobra.Command, args []string) { + lg, err := logutil.CreateDefaultZapLogger(zap.InfoLevel) + if err != nil { + cobrautl.ExitWithError(cobrautl.ExitError, err) + } + flags.SetPflagsFromEnv(lg, "ETCDCTL", cmd.InheritedFlags()) + initDisplayFromCmd(cmd) + + sec := secureCfgFromCmd(cmd) + dt := dialTimeoutFromCmd(cmd) + ka := keepAliveTimeFromCmd(cmd) + kat := keepAliveTimeoutFromCmd(cmd) + auth := authCfgFromCmd(cmd) + var cfgs []*clientv3.Config + for _, ep := range endpointsFromCluster(cmd) { + cfg, err := clientv3.NewClientConfig(&clientv3.ConfigSpec{ + Endpoints: []string{ep}, + DialTimeout: dt, + KeepAliveTime: ka, + KeepAliveTimeout: kat, + Secure: sec, + Auth: auth, + }, lg) + if err != nil { + cobrautl.ExitWithError(cobrautl.ExitBadArgs, err) + } + cfgs = append(cfgs, cfg) + } + + var wg sync.WaitGroup + hch := make(chan epHealth, len(cfgs)) + for _, cfg := range cfgs { + wg.Add(1) + go func(cfg *clientv3.Config) { + defer wg.Done() + ep := cfg.Endpoints[0] + cfg.Logger = lg.Named("client") + cli, err := clientv3.New(*cfg) + if err != nil { + hch <- epHealth{Ep: ep, Health: false, Error: err.Error()} + return + } + st := time.Now() + ctx, cancel := commandCtx(cmd) + var resp *clientv3.HealthResponse + if isLivez { + resp, err = cli.Livez(ctx) + } else { + resp, err = cli.Readyz(ctx) + } + var eh epHealth + if err != nil { + eh = epHealth{Ep: ep, Error: err.Error(), Took: time.Since(st).String()} + } else { + eh = epHealth{Ep: ep, Health: resp.Ok, Took: time.Since(st).String(), DebugString: resp.Reason} + } + cancel() + hch <- eh + }(cfg) + } + + wg.Wait() + close(hch) + + errs := false + var healthList []epHealth + for h := range hch { + healthList = append(healthList, h) + if !h.Health { + errs = true + } + } + path := "/readyz" + if isLivez { + path = "/livez" + } + display.EndpointHealthCheck(healthList, path, true) + if errs { + cobrautl.ExitWithError(cobrautl.ExitError, fmt.Errorf("unhealthy cluster")) + } + } +} + type epStatus struct { Ep string `json:"Endpoint"` Resp *clientv3.StatusResponse `json:"Status"` diff --git a/etcdctl/ctlv3/command/printer.go b/etcdctl/ctlv3/command/printer.go index a7b9fb6a76e..e4e0359e87d 100644 --- a/etcdctl/ctlv3/command/printer.go +++ b/etcdctl/ctlv3/command/printer.go @@ -46,6 +46,7 @@ type printer interface { MemberList(v3.MemberListResponse) EndpointHealth([]epHealth) + EndpointHealthCheck(hs []epHealth, path string, verbose bool) EndpointStatus([]epStatus) EndpointHashKV([]epHashKV) MoveLeader(leader, target uint64, r v3.MoveLeaderResponse) @@ -165,9 +166,10 @@ func newPrinterUnsupported(n string) printer { return &printerUnsupported{printerRPC{nil, f}} } -func (p *printerUnsupported) EndpointHealth([]epHealth) { p.p(nil) } -func (p *printerUnsupported) EndpointStatus([]epStatus) { p.p(nil) } -func (p *printerUnsupported) EndpointHashKV([]epHashKV) { p.p(nil) } +func (p *printerUnsupported) EndpointHealth([]epHealth) { p.p(nil) } +func (p *printerUnsupported) EndpointHealthCheck(hs []epHealth, path string, verbose bool) { p.p(nil) } +func (p *printerUnsupported) EndpointStatus([]epStatus) { p.p(nil) } +func (p *printerUnsupported) EndpointHashKV([]epHashKV) { p.p(nil) } func (p *printerUnsupported) MoveLeader(leader, target uint64, r v3.MoveLeaderResponse) { p.p(nil) } func (p *printerUnsupported) DowngradeValidate(r v3.DowngradeResponse) { p.p(nil) } diff --git a/etcdctl/ctlv3/command/printer_json.go b/etcdctl/ctlv3/command/printer_json.go index 93d8c842f06..d5b791d1d96 100644 --- a/etcdctl/ctlv3/command/printer_json.go +++ b/etcdctl/ctlv3/command/printer_json.go @@ -36,9 +36,10 @@ func newJSONPrinter(isHex bool) printer { } } -func (p *jsonPrinter) EndpointHealth(r []epHealth) { printJSON(r) } -func (p *jsonPrinter) EndpointStatus(r []epStatus) { printJSON(r) } -func (p *jsonPrinter) EndpointHashKV(r []epHashKV) { printJSON(r) } +func (p *jsonPrinter) EndpointHealth(r []epHealth) { printJSON(r) } +func (p *jsonPrinter) EndpointHealthCheck(r []epHealth, path string, verbose bool) { printJSON(r) } +func (p *jsonPrinter) EndpointStatus(r []epStatus) { printJSON(r) } +func (p *jsonPrinter) EndpointHashKV(r []epHashKV) { printJSON(r) } func (p *jsonPrinter) MemberList(r clientv3.MemberListResponse) { if p.isHex { diff --git a/etcdctl/ctlv3/command/printer_simple.go b/etcdctl/ctlv3/command/printer_simple.go index 80f3bc9b92a..6d379374588 100644 --- a/etcdctl/ctlv3/command/printer_simple.go +++ b/etcdctl/ctlv3/command/printer_simple.go @@ -162,6 +162,19 @@ func (s *simplePrinter) EndpointHealth(hs []epHealth) { } } +func (s *simplePrinter) EndpointHealthCheck(hs []epHealth, path string, verbose bool) { + for _, h := range hs { + if h.Health { + fmt.Printf("%s: %s is OK,: took = %v\n", h.Ep, path, h.Took) + } else { + fmt.Printf("%s: %s is OK,: took = %v, Error = %v\n", h.Ep, path, h.Took, h.Error) + } + if verbose { + fmt.Printf("%s\n", h.DebugString) + } + } +} + func (s *simplePrinter) EndpointStatus(statusList []epStatus) { _, rows := makeEndpointStatusTable(statusList) for _, row := range rows { diff --git a/etcdctl/ctlv3/command/printer_table.go b/etcdctl/ctlv3/command/printer_table.go index b617744649f..42e733d5886 100644 --- a/etcdctl/ctlv3/command/printer_table.go +++ b/etcdctl/ctlv3/command/printer_table.go @@ -34,6 +34,9 @@ func (tp *tablePrinter) MemberList(r v3.MemberListResponse) { table.SetAlignment(tablewriter.ALIGN_RIGHT) table.Render() } +func (tp *tablePrinter) EndpointHealthCheck(r []epHealth, path string, verbose bool) { + tp.EndpointHealth(r) +} func (tp *tablePrinter) EndpointHealth(r []epHealth) { hdr, rows := makeEndpointHealthTable(r) table := tablewriter.NewWriter(os.Stdout) diff --git a/scripts/etcd_version_annotations.txt b/scripts/etcd_version_annotations.txt index 3e5d23f94d8..c3b6ff9bad2 100644 --- a/scripts/etcd_version_annotations.txt +++ b/scripts/etcd_version_annotations.txt @@ -172,6 +172,13 @@ etcdserverpb.HashRequest: "3.0" etcdserverpb.HashResponse: "3.0" etcdserverpb.HashResponse.hash: "" etcdserverpb.HashResponse.header: "" +etcdserverpb.HealthRequest: "3.0" +etcdserverpb.HealthRequest.allowlist: "" +etcdserverpb.HealthRequest.exclude: "" +etcdserverpb.HealthResponse: "3.0" +etcdserverpb.HealthResponse.header: "" +etcdserverpb.HealthResponse.ok: "" +etcdserverpb.HealthResponse.reason: "" etcdserverpb.InternalAuthenticateRequest: "3.0" etcdserverpb.InternalAuthenticateRequest.name: "" etcdserverpb.InternalAuthenticateRequest.password: "" diff --git a/server/etcdserver/api/v3lock/v3lockpb/v3lock.pb.go b/server/etcdserver/api/v3lock/v3lockpb/v3lock.pb.go index 39c04abe179..bbfdd963aa1 100644 --- a/server/etcdserver/api/v3lock/v3lockpb/v3lock.pb.go +++ b/server/etcdserver/api/v3lock/v3lockpb/v3lock.pb.go @@ -6,10 +6,6 @@ package v3lockpb import ( context "context" fmt "fmt" - io "io" - math "math" - math_bits "math/bits" - _ "github.com/gogo/protobuf/gogoproto" proto "github.com/golang/protobuf/proto" etcdserverpb "go.etcd.io/etcd/api/v3/etcdserverpb" @@ -17,6 +13,9 @@ import ( grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" + io "io" + math "math" + math_bits "math/bits" ) // Reference imports to suppress errors if they are not otherwise used. diff --git a/server/etcdserver/api/v3rpc/maintenance.go b/server/etcdserver/api/v3rpc/maintenance.go index 56309505760..20a1b9bb695 100644 --- a/server/etcdserver/api/v3rpc/maintenance.go +++ b/server/etcdserver/api/v3rpc/maintenance.go @@ -51,6 +51,10 @@ type Alarmer interface { Alarm(ctx context.Context, ar *pb.AlarmRequest) (*pb.AlarmResponse, error) } +type HealthServer interface { + CheckServerHealth(ctx context.Context, req *pb.HealthRequest, path string) (*pb.HealthResponse, error) +} + type Downgrader interface { Downgrade(ctx context.Context, dr *pb.DowngradeRequest) (*pb.DowngradeResponse, error) } @@ -74,10 +78,11 @@ type maintenanceServer struct { cs ClusterStatusGetter d Downgrader vs serverversion.Server + hs HealthServer } func NewMaintenanceServer(s *etcdserver.EtcdServer) pb.MaintenanceServer { - srv := &maintenanceServer{lg: s.Cfg.Logger, rg: s, hasher: s.KV().HashStorage(), bg: s, a: s, lt: s, hdr: newHeader(s), cs: s, d: s, vs: etcdserver.NewServerVersionAdapter(s)} + srv := &maintenanceServer{lg: s.Cfg.Logger, rg: s, hasher: s.KV().HashStorage(), bg: s, a: s, lt: s, hdr: newHeader(s), cs: s, d: s, vs: etcdserver.NewServerVersionAdapter(s), hs: s} if srv.lg == nil { srv.lg = zap.NewNop() } @@ -224,6 +229,42 @@ func (ms *maintenanceServer) Alarm(ctx context.Context, ar *pb.AlarmRequest) (*p return resp, nil } +func (ms *maintenanceServer) Livez(ctx context.Context, req *pb.HealthRequest) (*pb.HealthResponse, error) { + resp, err := ms.hs.CheckServerHealth(ctx, req, etcdserver.PathLivez) + if err != nil { + return nil, togRPCError(err) + } + if resp.Header == nil { + resp.Header = &pb.ResponseHeader{} + } + ms.hdr.fill(resp.Header) + return resp, nil +} + +func (ms *maintenanceServer) Readyz(ctx context.Context, req *pb.HealthRequest) (*pb.HealthResponse, error) { + resp, err := ms.hs.CheckServerHealth(ctx, req, etcdserver.PathReadyz) + if err != nil { + return nil, togRPCError(err) + } + if resp.Header == nil { + resp.Header = &pb.ResponseHeader{} + } + ms.hdr.fill(resp.Header) + return resp, nil +} + +func (ms *maintenanceServer) Healthz(ctx context.Context, req *pb.HealthRequest) (*pb.HealthResponse, error) { + resp, err := ms.hs.CheckServerHealth(ctx, req, etcdserver.PathHealthz) + if err != nil { + return nil, togRPCError(err) + } + if resp.Header == nil { + resp.Header = &pb.ResponseHeader{} + } + ms.hdr.fill(resp.Header) + return resp, nil +} + func (ms *maintenanceServer) Status(ctx context.Context, ar *pb.StatusRequest) (*pb.StatusResponse, error) { hdr := &pb.ResponseHeader{} ms.hdr.fill(hdr) diff --git a/server/etcdserver/healthz.go b/server/etcdserver/healthz.go index 5e9c223a9b9..bb3d3891f18 100644 --- a/server/etcdserver/healthz.go +++ b/server/etcdserver/healthz.go @@ -23,9 +23,16 @@ import ( "sync" "time" + "go.uber.org/zap" + "go.etcd.io/etcd/api/v3/etcdserverpb" "go.etcd.io/etcd/server/v3/auth" - "go.uber.org/zap" +) + +const ( + PathLivez = "/livez" + PathReadyz = "/readyz" + PathHealthz = "/healthz" ) type EtcdServerHealth interface { @@ -36,7 +43,11 @@ type EtcdServerHealth interface { // HealthChecker is a named healthz checker. type HealthChecker interface { Name() string - Check(req *http.Request) error + Check() error +} + +type healthLogger interface { + Infof(template string, args ...interface{}) } func (s *EtcdServer) InstallLivezReadyz(lg *zap.Logger, mux mux) { @@ -49,6 +60,36 @@ func (s *EtcdServer) AddHealthCheck(check HealthChecker, isLivez bool, isReadyz return s.healthHandler.addHealthCheck(check, isLivez, isReadyz) } +func (s *EtcdServer) CheckServerHealth(ctx context.Context, req *etcdserverpb.HealthRequest, path string) (*etcdserverpb.HealthResponse, error) { + resp := &etcdserverpb.HealthResponse{} + var healthCheckList []string + switch path { + case PathLivez: + healthCheckList = s.healthHandler.livezChecks + case PathReadyz: + healthCheckList = s.healthHandler.readyzChecks + default: + healthCheckList = s.healthHandler.healthzChecks + } + var excludeList, allowList []string + switch req.HealthCheckSelector.(type) { + case *etcdserverpb.HealthRequest_Exclude: + excludeList = req.GetExclude().Values + case *etcdserverpb.HealthRequest_Allowlist: + allowList = req.GetAllowlist().Values + } + + failedChecks, individualCheckOutput, err := checkHealth(s.Logger().Sugar(), path, excludeList, allowList, s.healthHandler.getHealthChecksByNames(healthCheckList)...) + if err != nil { + return resp, err + } + if len(failedChecks) == 0 { + resp.Ok = true + } + resp.Reason = individualCheckOutput.String() + return resp, nil +} + type HealthHandler struct { server EtcdServerHealth // lock for health check related functions. @@ -81,19 +122,6 @@ func NewHealthHandler(s EtcdServerHealth) (handler *HealthHandler, err error) { return handler, nil } -type stringSet map[string]struct{} - -func (s stringSet) List() []string { - keys := make([]string, len(s)) - - i := 0 - for k := range s { - keys[i] = k - i++ - } - return keys -} - // PingHealthz returns true automatically when checked var PingHealthz HealthChecker = ping{} @@ -104,15 +132,14 @@ func (ping) Name() string { return "ping" } -// PingHealthz is a health check that returns true. -func (ping) Check(_ *http.Request) error { +func (ping) Check() error { return nil } // healthzCheck implements HealthChecker on an arbitrary name and check function. type healthzCheck struct { name string - check func(r *http.Request) error + check func() error } var _ HealthChecker = &healthzCheck{} @@ -121,12 +148,12 @@ func (c *healthzCheck) Name() string { return c.name } -func (c *healthzCheck) Check(r *http.Request) error { - return c.check(r) +func (c *healthzCheck) Check() error { + return c.check() } // NamedCheck returns a healthz checker for the given name and function. -func NamedCheck(name string, check func(r *http.Request) error) HealthChecker { +func NamedCheck(name string, check func() error) HealthChecker { return &healthzCheck{name, check} } @@ -145,7 +172,7 @@ func checkAlarm(srv EtcdServerHealth, at etcdserverpb.AlarmType) error { func (h *HealthHandler) addDefaultHealthChecks() error { // Checks that should be included both in livez and readyz. h.addHealthCheck(PingHealthz, true, true) - serializableReadCheck := NamedCheck("serializable_read", func(r *http.Request) error { + serializableReadCheck := NamedCheck("serializable_read", func() error { ctx, cancel := context.WithTimeout(context.Background(), time.Second) _, err := h.server.Range(ctx, &etcdserverpb.RangeRequest{KeysOnly: true, Limit: 1, Serializable: true}) cancel() @@ -157,7 +184,7 @@ func (h *HealthHandler) addDefaultHealthChecks() error { h.addHealthCheck(serializableReadCheck, true, true) // Checks that should be included only in livez. // Checks that should be included only in readyz. - corruptionAlarmCheck := NamedCheck("data_corruption", func(r *http.Request) error { + corruptionAlarmCheck := NamedCheck("data_corruption", func() error { return checkAlarm(h.server, etcdserverpb.AlarmType_CORRUPT) }) h.addHealthCheck(corruptionAlarmCheck, false, true) @@ -212,7 +239,7 @@ func (h *HealthHandler) installHealthz(lg *zap.Logger, mux mux) { h.healthMux.Lock() defer h.healthMux.Unlock() h.healthzChecksInstalled = true - InstallPathHandler(lg, mux, "/healthz", h.getHealthChecksByNames(h.healthzChecks)...) + InstallPathHandler(lg, mux, PathHealthz, h.getHealthChecksByNames(h.healthzChecks)...) } // installReadyz creates the readyz endpoint for this server. @@ -220,7 +247,7 @@ func (h *HealthHandler) installReadyz(lg *zap.Logger, mux mux) { h.healthMux.Lock() defer h.healthMux.Unlock() h.readyzChecksInstalled = true - InstallPathHandler(lg, mux, "/readyz", h.getHealthChecksByNames(h.readyzChecks)...) + InstallPathHandler(lg, mux, PathReadyz, h.getHealthChecksByNames(h.readyzChecks)...) } // installLivez creates the livez endpoint for this server. @@ -228,7 +255,7 @@ func (h *HealthHandler) installLivez(lg *zap.Logger, mux mux) { h.healthMux.Lock() defer h.healthMux.Unlock() h.livezChecksInstalled = true - InstallPathHandler(lg, mux, "/livez", h.getHealthChecksByNames(h.livezChecks)...) + InstallPathHandler(lg, mux, PathLivez, h.getHealthChecksByNames(h.livezChecks)...) } // InstallPathHandler registers handlers for health checking on @@ -257,77 +284,100 @@ type mux interface { Handle(pattern string, handler http.Handler) } -// getChecksForQuery extracts the health check names from the query param -func getChecksForQuery(r *http.Request, query string) stringSet { - checksSet := make(map[string]struct{}, 2) - checks, found := r.URL.Query()[query] - if found { - for _, chk := range checks { - if len(chk) == 0 { +type stringSet map[string]struct{} + +func (s stringSet) List() []string { + keys := make([]string, len(s)) + + i := 0 + for k := range s { + keys[i] = k + i++ + } + return keys +} + +func listToStringSet(list []string) stringSet { + set := make(map[string]struct{}) + for _, s := range list { + if len(s) == 0 { + continue + } + set[s] = struct{}{} + } + return set +} + +func checkHealth(lg healthLogger, name string, excludeList []string, allowList []string, checks ...HealthChecker) (failedChecks []string, individualCheckOutput bytes.Buffer, requestErr error) { + requestErr = nil + if len(excludeList) > 0 && len(allowList) > 0 { + requestErr = fmt.Errorf("do not expect both allowlist: %v and exclude list: %v to be both specified in health check.", allowList, excludeList) + return + } + excluded := listToStringSet(excludeList) + included := listToStringSet(allowList) + // failedVerboseLogOutput is for output to the log. It indicates detailed failed output information for the log. + var failedVerboseLogOutput bytes.Buffer + for _, check := range checks { + if len(included) > 0 { + if _, found := included[check.Name()]; !found { + fmt.Fprintf(&individualCheckOutput, "[+]%s not included: ok\n", check.Name()) continue } - checksSet[chk] = struct{}{} + delete(included, check.Name()) + } else { + // no-op the check if we've specified we want to exclude the check + if _, found := excluded[check.Name()]; found { + delete(excluded, check.Name()) + fmt.Fprintf(&individualCheckOutput, "[+]%s excluded: ok\n", check.Name()) + continue + } + } + if err := check.Check(); err != nil { + // don't include the error since this endpoint is public. If someone wants more detail + // they should have explicit permission to the detailed checks. + fmt.Fprintf(&individualCheckOutput, "[-]%s failed: reason withheld\n", check.Name()) + // but we do want detailed information for our log + fmt.Fprintf(&failedVerboseLogOutput, "[-]%s failed: %v\n", check.Name(), err) + failedChecks = append(failedChecks, check.Name()) + } else { + fmt.Fprintf(&individualCheckOutput, "[+]%s ok\n", check.Name()) } } - return checksSet + if len(excluded) > 0 { + fmt.Fprintf(&individualCheckOutput, "warn: some health checks cannot be excluded: no matches for %s\n", formatQuoted(excluded.List()...)) + lg.Infof("cannot exclude some health checks, no health checks are installed matching %s", + formatQuoted(excluded.List()...)) + } + if len(included) > 0 { + fmt.Fprintf(&individualCheckOutput, "warn: some health checks cannot be included: no matches for %s\n", formatQuoted(included.List()...)) + lg.Infof("cannot include some health checks, no health checks are installed matching %s", + formatQuoted(included.List()...)) + } + // always be verbose on failure + if len(failedChecks) > 0 { + lg.Infof("%s check failed: %s\n%v", strings.Join(failedChecks, ","), name, failedVerboseLogOutput.String()) + return + } + lg.Infof("%s check passed\n", name) + return } // handleRootHealth returns an http.HandlerFunc that serves the provided checks. func handleRootHealth(lg *zap.Logger, name string, checks ...HealthChecker) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - // extracts the health check names to be excluded from the query param - excluded := getChecksForQuery(r, "exclude") - // extracts the health check names to be included from the query param - included := getChecksForQuery(r, "allowlist") - if len(excluded) > 0 && len(included) > 0 { - lg.Sugar().Infof("do not expect both allowlist and exclude to be specified in the query %v", r.URL.RawQuery) - http.Error(w, fmt.Sprintf("do not expect both allowlist and exclude to be specified in the query %v", r.URL.RawQuery), http.StatusBadRequest) + // extracts the health check names to be excludeList from the query param + excludeList, _ := r.URL.Query()["exclude"] + // extracts the health check names to be allowList from the query param + allowList, _ := r.URL.Query()["allowlist"] + + failedChecks, individualCheckOutput, err := checkHealth(lg.Sugar(), name, excludeList, allowList, checks...) + if err != nil { + http.Error(w, fmt.Sprintf("%v", err), http.StatusBadRequest) return } - isAllowList := len(included) > 0 - // failedVerboseLogOutput is for output to the log. It indicates detailed failed output information for the log. - var failedVerboseLogOutput bytes.Buffer - var failedChecks []string - var individualCheckOutput bytes.Buffer - for _, check := range checks { - if isAllowList { - if _, found := included[check.Name()]; !found { - fmt.Fprintf(&individualCheckOutput, "[+]%s not included: ok\n", check.Name()) - continue - } - delete(included, check.Name()) - } else { - // no-op the check if we've specified we want to exclude the check - if _, found := excluded[check.Name()]; found { - delete(excluded, check.Name()) - fmt.Fprintf(&individualCheckOutput, "[+]%s excluded: ok\n", check.Name()) - continue - } - } - if err := check.Check(r); err != nil { - // don't include the error since this endpoint is public. If someone wants more detail - // they should have explicit permission to the detailed checks. - fmt.Fprintf(&individualCheckOutput, "[-]%s failed: reason withheld\n", check.Name()) - // but we do want detailed information for our log - fmt.Fprintf(&failedVerboseLogOutput, "[-]%s failed: %v\n", check.Name(), err) - failedChecks = append(failedChecks, check.Name()) - } else { - fmt.Fprintf(&individualCheckOutput, "[+]%s ok\n", check.Name()) - } - } - if len(excluded) > 0 { - fmt.Fprintf(&individualCheckOutput, "warn: some health checks cannot be excluded: no matches for %s\n", formatQuoted(excluded.List()...)) - lg.Sugar().Infof("cannot exclude some health checks, no health checks are installed matching %s", - formatQuoted(excluded.List()...)) - } - if len(included) > 0 { - fmt.Fprintf(&individualCheckOutput, "warn: some health checks cannot be included: no matches for %s\n", formatQuoted(included.List()...)) - lg.Sugar().Infof("cannot include some health checks, no health checks are installed matching %s", - formatQuoted(included.List()...)) - } // always be verbose on failure if len(failedChecks) > 0 { - lg.Sugar().Infof("%s check failed: %s\n%v", strings.Join(failedChecks, ","), name, failedVerboseLogOutput.String()) http.Error(w, fmt.Sprintf("%s%s check failed", individualCheckOutput.String(), name), http.StatusInternalServerError) return } @@ -345,9 +395,9 @@ func handleRootHealth(lg *zap.Logger, name string, checks ...HealthChecker) http } // adaptCheckToHandler returns an http.HandlerFunc that serves the provided checks. -func adaptCheckToHandler(c func(r *http.Request) error) http.HandlerFunc { +func adaptCheckToHandler(c func() error) http.HandlerFunc { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - err := c(r) + err := c() if err != nil { http.Error(w, fmt.Sprintf("internal server error: %v", err), http.StatusInternalServerError) } else { diff --git a/server/etcdserver/healthz_test.go b/server/etcdserver/healthz_test.go index 7388f60d64a..0ca0cfd7448 100644 --- a/server/etcdserver/healthz_test.go +++ b/server/etcdserver/healthz_test.go @@ -55,7 +55,7 @@ type healthzTestCase struct { apiError error } -// Test the basic logic flow in the handler. +// TestHealthHandler tests the basic logic flow in the handler. func TestHealthHandler(t *testing.T) { mux := http.NewServeMux() handler := &HealthHandler{ @@ -67,8 +67,8 @@ func TestHealthHandler(t *testing.T) { } logger := zaptest.NewLogger(t) // Some helper functions - failedFunc := func(r *http.Request) error { return fmt.Errorf("Failed") } - succeededFunc := func(r *http.Request) error { return nil } + failedFunc := func() error { return fmt.Errorf("Failed") } + succeededFunc := func() error { return nil } ableToAddCheck := func(expectSuccess bool, chk HealthChecker, isLivez bool, isReadyz bool) { err := handler.addHealthCheck(chk, isLivez, isReadyz) if expectSuccess && err != nil { diff --git a/server/proxy/grpcproxy/adapter/maintenance_client_adapter.go b/server/proxy/grpcproxy/adapter/maintenance_client_adapter.go index d3bb805a1f6..d1c47c603b5 100644 --- a/server/proxy/grpcproxy/adapter/maintenance_client_adapter.go +++ b/server/proxy/grpcproxy/adapter/maintenance_client_adapter.go @@ -32,6 +32,18 @@ func (s *mts2mtc) Alarm(ctx context.Context, r *pb.AlarmRequest, opts ...grpc.Ca return s.mts.Alarm(ctx, r) } +func (s *mts2mtc) Livez(ctx context.Context, r *pb.HealthRequest, opts ...grpc.CallOption) (*pb.HealthResponse, error) { + return s.mts.Livez(ctx, r) +} + +func (s *mts2mtc) Readyz(ctx context.Context, r *pb.HealthRequest, opts ...grpc.CallOption) (*pb.HealthResponse, error) { + return s.mts.Readyz(ctx, r) +} + +func (s *mts2mtc) Healthz(ctx context.Context, r *pb.HealthRequest, opts ...grpc.CallOption) (*pb.HealthResponse, error) { + return s.mts.Healthz(ctx, r) +} + func (s *mts2mtc) Status(ctx context.Context, r *pb.StatusRequest, opts ...grpc.CallOption) (*pb.StatusResponse, error) { return s.mts.Status(ctx, r) } diff --git a/server/proxy/grpcproxy/maintenance.go b/server/proxy/grpcproxy/maintenance.go index 50ecf67ffa0..99be12b42da 100644 --- a/server/proxy/grpcproxy/maintenance.go +++ b/server/proxy/grpcproxy/maintenance.go @@ -74,6 +74,18 @@ func (mp *maintenanceProxy) Alarm(ctx context.Context, r *pb.AlarmRequest) (*pb. return mp.maintenanceClient.Alarm(ctx, r) } +func (mp *maintenanceProxy) Livez(ctx context.Context, r *pb.HealthRequest) (*pb.HealthResponse, error) { + return mp.maintenanceClient.Livez(ctx, r) +} + +func (mp *maintenanceProxy) Readyz(ctx context.Context, r *pb.HealthRequest) (*pb.HealthResponse, error) { + return mp.maintenanceClient.Readyz(ctx, r) +} + +func (mp *maintenanceProxy) Healthz(ctx context.Context, r *pb.HealthRequest) (*pb.HealthResponse, error) { + return mp.maintenanceClient.Healthz(ctx, r) +} + func (mp *maintenanceProxy) Status(ctx context.Context, r *pb.StatusRequest) (*pb.StatusResponse, error) { return mp.maintenanceClient.Status(ctx, r) }