diff --git a/api/inventorypb/json/client/services/change_service_parameters.go b/api/inventorypb/json/client/services/change_service_parameters.go new file mode 100644 index 0000000000..9278a10406 --- /dev/null +++ b/api/inventorypb/json/client/services/change_service_parameters.go @@ -0,0 +1,144 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package services + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + "time" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + cr "github.com/go-openapi/runtime/client" + "github.com/go-openapi/strfmt" +) + +// NewChangeServiceParams creates a new ChangeServiceParams object, +// with the default timeout for this client. +// +// Default values are not hydrated, since defaults are normally applied by the API server side. +// +// To enforce default values in parameter, use SetDefaults or WithDefaults. +func NewChangeServiceParams() *ChangeServiceParams { + return &ChangeServiceParams{ + timeout: cr.DefaultTimeout, + } +} + +// NewChangeServiceParamsWithTimeout creates a new ChangeServiceParams object +// with the ability to set a timeout on a request. +func NewChangeServiceParamsWithTimeout(timeout time.Duration) *ChangeServiceParams { + return &ChangeServiceParams{ + timeout: timeout, + } +} + +// NewChangeServiceParamsWithContext creates a new ChangeServiceParams object +// with the ability to set a context for a request. +func NewChangeServiceParamsWithContext(ctx context.Context) *ChangeServiceParams { + return &ChangeServiceParams{ + Context: ctx, + } +} + +// NewChangeServiceParamsWithHTTPClient creates a new ChangeServiceParams object +// with the ability to set a custom HTTPClient for a request. +func NewChangeServiceParamsWithHTTPClient(client *http.Client) *ChangeServiceParams { + return &ChangeServiceParams{ + HTTPClient: client, + } +} + +/* +ChangeServiceParams contains all the parameters to send to the API endpoint + + for the change service operation. + + Typically these are written to a http.Request. +*/ +type ChangeServiceParams struct { + // Body. + Body ChangeServiceBody + + timeout time.Duration + Context context.Context + HTTPClient *http.Client +} + +// WithDefaults hydrates default values in the change service params (not the query body). +// +// All values with no default are reset to their zero value. +func (o *ChangeServiceParams) WithDefaults() *ChangeServiceParams { + o.SetDefaults() + return o +} + +// SetDefaults hydrates default values in the change service params (not the query body). +// +// All values with no default are reset to their zero value. +func (o *ChangeServiceParams) SetDefaults() { + // no default values defined for this parameter +} + +// WithTimeout adds the timeout to the change service params +func (o *ChangeServiceParams) WithTimeout(timeout time.Duration) *ChangeServiceParams { + o.SetTimeout(timeout) + return o +} + +// SetTimeout adds the timeout to the change service params +func (o *ChangeServiceParams) SetTimeout(timeout time.Duration) { + o.timeout = timeout +} + +// WithContext adds the context to the change service params +func (o *ChangeServiceParams) WithContext(ctx context.Context) *ChangeServiceParams { + o.SetContext(ctx) + return o +} + +// SetContext adds the context to the change service params +func (o *ChangeServiceParams) SetContext(ctx context.Context) { + o.Context = ctx +} + +// WithHTTPClient adds the HTTPClient to the change service params +func (o *ChangeServiceParams) WithHTTPClient(client *http.Client) *ChangeServiceParams { + o.SetHTTPClient(client) + return o +} + +// SetHTTPClient adds the HTTPClient to the change service params +func (o *ChangeServiceParams) SetHTTPClient(client *http.Client) { + o.HTTPClient = client +} + +// WithBody adds the body to the change service params +func (o *ChangeServiceParams) WithBody(body ChangeServiceBody) *ChangeServiceParams { + o.SetBody(body) + return o +} + +// SetBody adds the body to the change service params +func (o *ChangeServiceParams) SetBody(body ChangeServiceBody) { + o.Body = body +} + +// WriteToRequest writes these params to a swagger request +func (o *ChangeServiceParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error { + if err := r.SetTimeout(o.timeout); err != nil { + return err + } + var res []error + if err := r.SetBodyParam(o.Body); err != nil { + return err + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/api/inventorypb/json/client/services/change_service_responses.go b/api/inventorypb/json/client/services/change_service_responses.go new file mode 100644 index 0000000000..c90b7cb47d --- /dev/null +++ b/api/inventorypb/json/client/services/change_service_responses.go @@ -0,0 +1,307 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package services + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "fmt" + "io" + "strconv" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" +) + +// ChangeServiceReader is a Reader for the ChangeService structure. +type ChangeServiceReader struct { + formats strfmt.Registry +} + +// ReadResponse reads a server response into the received o. +func (o *ChangeServiceReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) { + switch response.Code() { + case 200: + result := NewChangeServiceOK() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return result, nil + default: + result := NewChangeServiceDefault(response.Code()) + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + if response.Code()/100 == 2 { + return result, nil + } + return nil, result + } +} + +// NewChangeServiceOK creates a ChangeServiceOK with default headers values +func NewChangeServiceOK() *ChangeServiceOK { + return &ChangeServiceOK{} +} + +/* +ChangeServiceOK describes a response with status code 200, with default header values. + +A successful response. +*/ +type ChangeServiceOK struct { + Payload interface{} +} + +func (o *ChangeServiceOK) Error() string { + return fmt.Sprintf("[POST /v1/inventory/Services/Change][%d] changeServiceOk %+v", 200, o.Payload) +} + +func (o *ChangeServiceOK) GetPayload() interface{} { + return o.Payload +} + +func (o *ChangeServiceOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + // response payload + if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} + +// NewChangeServiceDefault creates a ChangeServiceDefault with default headers values +func NewChangeServiceDefault(code int) *ChangeServiceDefault { + return &ChangeServiceDefault{ + _statusCode: code, + } +} + +/* +ChangeServiceDefault describes a response with status code -1, with default header values. + +An unexpected error response. +*/ +type ChangeServiceDefault struct { + _statusCode int + + Payload *ChangeServiceDefaultBody +} + +// Code gets the status code for the change service default response +func (o *ChangeServiceDefault) Code() int { + return o._statusCode +} + +func (o *ChangeServiceDefault) Error() string { + return fmt.Sprintf("[POST /v1/inventory/Services/Change][%d] ChangeService default %+v", o._statusCode, o.Payload) +} + +func (o *ChangeServiceDefault) GetPayload() *ChangeServiceDefaultBody { + return o.Payload +} + +func (o *ChangeServiceDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + o.Payload = new(ChangeServiceDefaultBody) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} + +/* +ChangeServiceBody change service body +swagger:model ChangeServiceBody +*/ +type ChangeServiceBody struct { + // service id + ServiceID string `json:"service_id,omitempty"` + + // environment + Environment string `json:"environment,omitempty"` + + // cluster + Cluster string `json:"cluster,omitempty"` + + // replication set + ReplicationSet string `json:"replication_set,omitempty"` + + // external group + ExternalGroup string `json:"external_group,omitempty"` +} + +// Validate validates this change service body +func (o *ChangeServiceBody) Validate(formats strfmt.Registry) error { + return nil +} + +// ContextValidate validates this change service body based on context it is used +func (o *ChangeServiceBody) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (o *ChangeServiceBody) MarshalBinary() ([]byte, error) { + if o == nil { + return nil, nil + } + return swag.WriteJSON(o) +} + +// UnmarshalBinary interface implementation +func (o *ChangeServiceBody) UnmarshalBinary(b []byte) error { + var res ChangeServiceBody + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *o = res + return nil +} + +/* +ChangeServiceDefaultBody change service default body +swagger:model ChangeServiceDefaultBody +*/ +type ChangeServiceDefaultBody struct { + // code + Code int32 `json:"code,omitempty"` + + // message + Message string `json:"message,omitempty"` + + // details + Details []*ChangeServiceDefaultBodyDetailsItems0 `json:"details"` +} + +// Validate validates this change service default body +func (o *ChangeServiceDefaultBody) Validate(formats strfmt.Registry) error { + var res []error + + if err := o.validateDetails(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *ChangeServiceDefaultBody) validateDetails(formats strfmt.Registry) error { + if swag.IsZero(o.Details) { // not required + return nil + } + + for i := 0; i < len(o.Details); i++ { + if swag.IsZero(o.Details[i]) { // not required + continue + } + + if o.Details[i] != nil { + if err := o.Details[i].Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("ChangeService default" + "." + "details" + "." + strconv.Itoa(i)) + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("ChangeService default" + "." + "details" + "." + strconv.Itoa(i)) + } + return err + } + } + + } + + return nil +} + +// ContextValidate validate this change service default body based on the context it is used +func (o *ChangeServiceDefaultBody) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + var res []error + + if err := o.contextValidateDetails(ctx, formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *ChangeServiceDefaultBody) contextValidateDetails(ctx context.Context, formats strfmt.Registry) error { + for i := 0; i < len(o.Details); i++ { + if o.Details[i] != nil { + if err := o.Details[i].ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("ChangeService default" + "." + "details" + "." + strconv.Itoa(i)) + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("ChangeService default" + "." + "details" + "." + strconv.Itoa(i)) + } + return err + } + } + } + + return nil +} + +// MarshalBinary interface implementation +func (o *ChangeServiceDefaultBody) MarshalBinary() ([]byte, error) { + if o == nil { + return nil, nil + } + return swag.WriteJSON(o) +} + +// UnmarshalBinary interface implementation +func (o *ChangeServiceDefaultBody) UnmarshalBinary(b []byte) error { + var res ChangeServiceDefaultBody + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *o = res + return nil +} + +/* +ChangeServiceDefaultBodyDetailsItems0 change service default body details items0 +swagger:model ChangeServiceDefaultBodyDetailsItems0 +*/ +type ChangeServiceDefaultBodyDetailsItems0 struct { + // at type + AtType string `json:"@type,omitempty"` +} + +// Validate validates this change service default body details items0 +func (o *ChangeServiceDefaultBodyDetailsItems0) Validate(formats strfmt.Registry) error { + return nil +} + +// ContextValidate validates this change service default body details items0 based on context it is used +func (o *ChangeServiceDefaultBodyDetailsItems0) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (o *ChangeServiceDefaultBodyDetailsItems0) MarshalBinary() ([]byte, error) { + if o == nil { + return nil, nil + } + return swag.WriteJSON(o) +} + +// UnmarshalBinary interface implementation +func (o *ChangeServiceDefaultBodyDetailsItems0) UnmarshalBinary(b []byte) error { + var res ChangeServiceDefaultBodyDetailsItems0 + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *o = res + return nil +} diff --git a/api/inventorypb/json/client/services/services_client.go b/api/inventorypb/json/client/services/services_client.go index 8c33b0d1cd..d168a7c976 100644 --- a/api/inventorypb/json/client/services/services_client.go +++ b/api/inventorypb/json/client/services/services_client.go @@ -42,6 +42,8 @@ type ClientService interface { AddProxySQLService(params *AddProxySQLServiceParams, opts ...ClientOption) (*AddProxySQLServiceOK, error) + ChangeService(params *ChangeServiceParams, opts ...ClientOption) (*ChangeServiceOK, error) + GetService(params *GetServiceParams, opts ...ClientOption) (*GetServiceOK, error) ListActiveServiceTypes(params *ListActiveServiceTypesParams, opts ...ClientOption) (*ListActiveServiceTypesOK, error) @@ -328,6 +330,45 @@ func (a *Client) AddProxySQLService(params *AddProxySQLServiceParams, opts ...Cl return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) } +/* +ChangeService changes service + +Changes service configuration. If a new cluster label is specified, it removes all backup/restore tasks scheduled for the related services. Fails if there are running backup/restore tasks. +*/ +func (a *Client) ChangeService(params *ChangeServiceParams, opts ...ClientOption) (*ChangeServiceOK, error) { + // TODO: Validate the params before sending + if params == nil { + params = NewChangeServiceParams() + } + op := &runtime.ClientOperation{ + ID: "ChangeService", + Method: "POST", + PathPattern: "/v1/inventory/Services/Change", + ProducesMediaTypes: []string{"application/json"}, + ConsumesMediaTypes: []string{"application/json"}, + Schemes: []string{"http", "https"}, + Params: params, + Reader: &ChangeServiceReader{formats: a.formats}, + Context: params.Context, + Client: params.HTTPClient, + } + for _, opt := range opts { + opt(op) + } + + result, err := a.transport.Submit(op) + if err != nil { + return nil, err + } + success, ok := result.(*ChangeServiceOK) + if ok { + return success, nil + } + // unexpected success response + unexpectedSuccess := result.(*ChangeServiceDefault) + return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) +} + /* GetService gets service diff --git a/api/inventorypb/json/inventorypb.json b/api/inventorypb/json/inventorypb.json index 0ff9724ba6..73ab50ba4d 100644 --- a/api/inventorypb/json/inventorypb.json +++ b/api/inventorypb/json/inventorypb.json @@ -11631,6 +11631,87 @@ } } }, + "/v1/inventory/Services/Change": { + "post": { + "description": "Changes service configuration. If a new cluster label is specified, it removes all backup/restore tasks scheduled for the related services. Fails if there are running backup/restore tasks.", + "tags": [ + "Services" + ], + "summary": "Change service", + "operationId": "ChangeService", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "cluster": { + "type": "string", + "x-order": 2 + }, + "environment": { + "type": "string", + "x-order": 1 + }, + "external_group": { + "type": "string", + "x-order": 4 + }, + "replication_set": { + "type": "string", + "x-order": 3 + }, + "service_id": { + "type": "string", + "x-order": 0 + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "type": "object" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32", + "x-order": 0 + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "@type": { + "type": "string", + "x-order": 0 + } + }, + "additionalProperties": false + }, + "x-order": 2 + }, + "message": { + "type": "string", + "x-order": 1 + } + } + } + } + } + } + }, "/v1/inventory/Services/CustomLabels/Add": { "post": { "description": "Adds or replaces (if the key exists) custom labels for a Service.", diff --git a/api/inventorypb/services.pb.go b/api/inventorypb/services.pb.go index f187ecaec2..bf39b9164e 100644 --- a/api/inventorypb/services.pb.go +++ b/api/inventorypb/services.pb.go @@ -2519,6 +2519,123 @@ func (*RemoveCustomLabelsResponse) Descriptor() ([]byte, []int) { return file_inventorypb_services_proto_rawDescGZIP(), []int{29} } +type ChangeServiceRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ServiceId string `protobuf:"bytes,1,opt,name=service_id,json=serviceId,proto3" json:"service_id,omitempty"` + Environment *string `protobuf:"bytes,2,opt,name=environment,proto3,oneof" json:"environment,omitempty"` + Cluster *string `protobuf:"bytes,3,opt,name=cluster,proto3,oneof" json:"cluster,omitempty"` + ReplicationSet *string `protobuf:"bytes,4,opt,name=replication_set,json=replicationSet,proto3,oneof" json:"replication_set,omitempty"` + ExternalGroup *string `protobuf:"bytes,5,opt,name=external_group,json=externalGroup,proto3,oneof" json:"external_group,omitempty"` +} + +func (x *ChangeServiceRequest) Reset() { + *x = ChangeServiceRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_inventorypb_services_proto_msgTypes[30] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ChangeServiceRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ChangeServiceRequest) ProtoMessage() {} + +func (x *ChangeServiceRequest) ProtoReflect() protoreflect.Message { + mi := &file_inventorypb_services_proto_msgTypes[30] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ChangeServiceRequest.ProtoReflect.Descriptor instead. +func (*ChangeServiceRequest) Descriptor() ([]byte, []int) { + return file_inventorypb_services_proto_rawDescGZIP(), []int{30} +} + +func (x *ChangeServiceRequest) GetServiceId() string { + if x != nil { + return x.ServiceId + } + return "" +} + +func (x *ChangeServiceRequest) GetEnvironment() string { + if x != nil && x.Environment != nil { + return *x.Environment + } + return "" +} + +func (x *ChangeServiceRequest) GetCluster() string { + if x != nil && x.Cluster != nil { + return *x.Cluster + } + return "" +} + +func (x *ChangeServiceRequest) GetReplicationSet() string { + if x != nil && x.ReplicationSet != nil { + return *x.ReplicationSet + } + return "" +} + +func (x *ChangeServiceRequest) GetExternalGroup() string { + if x != nil && x.ExternalGroup != nil { + return *x.ExternalGroup + } + return "" +} + +type ChangeServiceResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ChangeServiceResponse) Reset() { + *x = ChangeServiceResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_inventorypb_services_proto_msgTypes[31] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ChangeServiceResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ChangeServiceResponse) ProtoMessage() {} + +func (x *ChangeServiceResponse) ProtoReflect() protoreflect.Message { + mi := &file_inventorypb_services_proto_msgTypes[31] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ChangeServiceResponse.ProtoReflect.Descriptor instead. +func (*ChangeServiceResponse) Descriptor() ([]byte, []int) { + return file_inventorypb_services_proto_rawDescGZIP(), []int{31} +} + var File_inventorypb_services_proto protoreflect.FileDescriptor var file_inventorypb_services_proto_rawDesc = []byte{ @@ -2972,167 +3089,208 @@ var file_inventorypb_services_proto_rawDesc = []byte{ 0x28, 0x09, 0x52, 0x0f, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x4b, 0x65, 0x79, 0x73, 0x22, 0x1c, 0x0a, 0x1a, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x2a, 0xa8, 0x01, 0x0a, 0x0b, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, - 0x65, 0x12, 0x18, 0x0a, 0x14, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, - 0x45, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x4d, - 0x59, 0x53, 0x51, 0x4c, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x10, 0x01, 0x12, 0x13, - 0x0a, 0x0f, 0x4d, 0x4f, 0x4e, 0x47, 0x4f, 0x44, 0x42, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, - 0x45, 0x10, 0x02, 0x12, 0x16, 0x0a, 0x12, 0x50, 0x4f, 0x53, 0x54, 0x47, 0x52, 0x45, 0x53, 0x51, - 0x4c, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x10, 0x03, 0x12, 0x14, 0x0a, 0x10, 0x50, - 0x52, 0x4f, 0x58, 0x59, 0x53, 0x51, 0x4c, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x10, - 0x04, 0x12, 0x13, 0x0a, 0x0f, 0x48, 0x41, 0x50, 0x52, 0x4f, 0x58, 0x59, 0x5f, 0x53, 0x45, 0x52, - 0x56, 0x49, 0x43, 0x45, 0x10, 0x06, 0x12, 0x14, 0x0a, 0x10, 0x45, 0x58, 0x54, 0x45, 0x52, 0x4e, - 0x41, 0x4c, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x10, 0x05, 0x32, 0xd7, 0x12, 0x0a, - 0x08, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0xb7, 0x01, 0x0a, 0x0c, 0x4c, 0x69, - 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x1e, 0x2e, 0x69, 0x6e, 0x76, - 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x69, 0x6e, 0x76, - 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x66, 0x92, 0x41, 0x3d, - 0x12, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x1a, - 0x2c, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x61, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, - 0x6f, 0x66, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x66, 0x69, 0x6c, 0x74, - 0x65, 0x72, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x20, 0x3a, 0x01, 0x2a, 0x22, 0x1b, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x76, 0x65, - 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x4c, - 0x69, 0x73, 0x74, 0x12, 0xe1, 0x01, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x74, 0x69, - 0x76, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x28, - 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, - 0x63, 0x74, 0x69, 0x76, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x6e, - 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x72, 0x92, 0x41, 0x44, 0x12, 0x19, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x41, - 0x63, 0x74, 0x69, 0x76, 0x65, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x20, 0x54, 0x79, - 0x70, 0x65, 0x73, 0x1a, 0x27, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x61, 0x20, 0x6c, - 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x20, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x25, 0x3a, 0x01, 0x2a, 0x22, 0x20, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x76, 0x65, 0x6e, - 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x4c, 0x69, - 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0xa1, 0x01, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x1c, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, - 0x72, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, - 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x56, 0x92, 0x41, 0x2e, 0x12, 0x0b, 0x47, 0x65, 0x74, 0x20, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x1a, 0x1f, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x61, - 0x20, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x20, - 0x62, 0x79, 0x20, 0x49, 0x44, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, 0x3a, 0x01, 0x2a, 0x22, - 0x1a, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x47, 0x65, 0x74, 0x12, 0xaf, 0x01, 0x0a, 0x0f, - 0x41, 0x64, 0x64, 0x4d, 0x79, 0x53, 0x51, 0x4c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, - 0x21, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x41, 0x64, 0x64, 0x4d, - 0x79, 0x53, 0x51, 0x4c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x41, - 0x64, 0x64, 0x4d, 0x79, 0x53, 0x51, 0x4c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x55, 0x92, 0x41, 0x28, 0x12, 0x11, 0x41, 0x64, 0x64, - 0x20, 0x4d, 0x79, 0x53, 0x51, 0x4c, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x1a, 0x13, - 0x41, 0x64, 0x64, 0x73, 0x20, 0x4d, 0x79, 0x53, 0x51, 0x4c, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x3a, 0x01, 0x2a, 0x22, 0x1f, 0x2f, 0x76, + 0x65, 0x22, 0xa1, 0x02, 0x0a, 0x14, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x26, 0x0a, 0x0a, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, + 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x09, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x49, 0x64, 0x12, 0x25, 0x0a, 0x0b, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, + 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x65, 0x6e, 0x76, 0x69, 0x72, + 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x88, 0x01, 0x01, 0x12, 0x1d, 0x0a, 0x07, 0x63, 0x6c, 0x75, + 0x73, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x07, 0x63, 0x6c, + 0x75, 0x73, 0x74, 0x65, 0x72, 0x88, 0x01, 0x01, 0x12, 0x2c, 0x0a, 0x0f, 0x72, 0x65, 0x70, 0x6c, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x65, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x48, 0x02, 0x52, 0x0e, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x53, 0x65, 0x74, 0x88, 0x01, 0x01, 0x12, 0x2a, 0x0a, 0x0e, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, + 0x61, 0x6c, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x03, + 0x52, 0x0d, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x88, + 0x01, 0x01, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, + 0x6e, 0x74, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x42, 0x12, + 0x0a, 0x10, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, + 0x65, 0x74, 0x42, 0x11, 0x0a, 0x0f, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, + 0x67, 0x72, 0x6f, 0x75, 0x70, 0x22, 0x17, 0x0a, 0x15, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2a, 0xa8, + 0x01, 0x0a, 0x0b, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x18, + 0x0a, 0x14, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x49, + 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x4d, 0x59, 0x53, 0x51, + 0x4c, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x4d, + 0x4f, 0x4e, 0x47, 0x4f, 0x44, 0x42, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x10, 0x02, + 0x12, 0x16, 0x0a, 0x12, 0x50, 0x4f, 0x53, 0x54, 0x47, 0x52, 0x45, 0x53, 0x51, 0x4c, 0x5f, 0x53, + 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x10, 0x03, 0x12, 0x14, 0x0a, 0x10, 0x50, 0x52, 0x4f, 0x58, + 0x59, 0x53, 0x51, 0x4c, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x10, 0x04, 0x12, 0x13, + 0x0a, 0x0f, 0x48, 0x41, 0x50, 0x52, 0x4f, 0x58, 0x59, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, + 0x45, 0x10, 0x06, 0x12, 0x14, 0x0a, 0x10, 0x45, 0x58, 0x54, 0x45, 0x52, 0x4e, 0x41, 0x4c, 0x5f, + 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x10, 0x05, 0x32, 0xaa, 0x15, 0x0a, 0x08, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0xb7, 0x01, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x1e, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, + 0x6f, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, + 0x6f, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x66, 0x92, 0x41, 0x3d, 0x12, 0x0d, 0x4c, + 0x69, 0x73, 0x74, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x1a, 0x2c, 0x52, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x61, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, + 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, + 0x3a, 0x01, 0x2a, 0x22, 0x1b, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, + 0x72, 0x79, 0x2f, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x4c, 0x69, 0x73, 0x74, + 0x12, 0xe1, 0x01, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x28, 0x2e, 0x69, 0x6e, + 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x74, 0x69, + 0x76, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, + 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x72, 0x92, 0x41, 0x44, 0x12, 0x19, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x41, 0x63, 0x74, 0x69, + 0x76, 0x65, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x20, 0x54, 0x79, 0x70, 0x65, 0x73, + 0x1a, 0x27, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x61, 0x20, 0x6c, 0x69, 0x73, 0x74, + 0x20, 0x6f, 0x66, 0x20, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x25, 0x3a, + 0x01, 0x2a, 0x22, 0x20, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, + 0x79, 0x2f, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x4c, 0x69, 0x73, 0x74, 0x54, + 0x79, 0x70, 0x65, 0x73, 0x12, 0xa1, 0x01, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x12, 0x1c, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, + 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x1d, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x47, 0x65, + 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x56, 0x92, 0x41, 0x2e, 0x12, 0x0b, 0x47, 0x65, 0x74, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x1a, 0x1f, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x61, 0x20, 0x73, 0x69, + 0x6e, 0x67, 0x6c, 0x65, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x20, 0x62, 0x79, 0x20, + 0x49, 0x44, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, 0x3a, 0x01, 0x2a, 0x22, 0x1a, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x73, 0x2f, 0x41, 0x64, 0x64, 0x4d, 0x79, 0x53, 0x51, 0x4c, 0x12, 0xbb, 0x01, - 0x0a, 0x11, 0x41, 0x64, 0x64, 0x4d, 0x6f, 0x6e, 0x67, 0x6f, 0x44, 0x42, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x12, 0x23, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, - 0x41, 0x64, 0x64, 0x4d, 0x6f, 0x6e, 0x67, 0x6f, 0x44, 0x42, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x6e, - 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x41, 0x64, 0x64, 0x4d, 0x6f, 0x6e, 0x67, 0x6f, 0x44, 0x42, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x5b, - 0x92, 0x41, 0x2c, 0x12, 0x13, 0x41, 0x64, 0x64, 0x20, 0x4d, 0x6f, 0x6e, 0x67, 0x6f, 0x44, 0x42, - 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x1a, 0x15, 0x41, 0x64, 0x64, 0x73, 0x20, 0x4d, - 0x6f, 0x6e, 0x67, 0x6f, 0x44, 0x42, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x26, 0x3a, 0x01, 0x2a, 0x22, 0x21, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, - 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, - 0x2f, 0x41, 0x64, 0x64, 0x4d, 0x6f, 0x6e, 0x67, 0x6f, 0x44, 0x42, 0x12, 0xcd, 0x01, 0x0a, 0x14, - 0x41, 0x64, 0x64, 0x50, 0x6f, 0x73, 0x74, 0x67, 0x72, 0x65, 0x53, 0x51, 0x4c, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x12, 0x26, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, - 0x2e, 0x41, 0x64, 0x64, 0x50, 0x6f, 0x73, 0x74, 0x67, 0x72, 0x65, 0x53, 0x51, 0x4c, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x69, - 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x41, 0x64, 0x64, 0x50, 0x6f, 0x73, 0x74, - 0x67, 0x72, 0x65, 0x53, 0x51, 0x4c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x64, 0x92, 0x41, 0x32, 0x12, 0x16, 0x41, 0x64, 0x64, 0x20, - 0x50, 0x6f, 0x73, 0x74, 0x67, 0x72, 0x65, 0x53, 0x51, 0x4c, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x1a, 0x18, 0x41, 0x64, 0x64, 0x73, 0x20, 0x50, 0x6f, 0x73, 0x74, 0x67, 0x72, 0x65, - 0x53, 0x51, 0x4c, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x29, 0x3a, 0x01, 0x2a, 0x22, 0x24, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x76, 0x65, 0x6e, + 0x69, 0x63, 0x65, 0x73, 0x2f, 0x47, 0x65, 0x74, 0x12, 0xaf, 0x01, 0x0a, 0x0f, 0x41, 0x64, 0x64, + 0x4d, 0x79, 0x53, 0x51, 0x4c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x21, 0x2e, 0x69, + 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x41, 0x64, 0x64, 0x4d, 0x79, 0x53, 0x51, + 0x4c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x22, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x41, 0x64, 0x64, 0x4d, + 0x79, 0x53, 0x51, 0x4c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x55, 0x92, 0x41, 0x28, 0x12, 0x11, 0x41, 0x64, 0x64, 0x20, 0x4d, 0x79, + 0x53, 0x51, 0x4c, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x1a, 0x13, 0x41, 0x64, 0x64, + 0x73, 0x20, 0x4d, 0x79, 0x53, 0x51, 0x4c, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x3a, 0x01, 0x2a, 0x22, 0x1f, 0x2f, 0x76, 0x31, 0x2f, 0x69, + 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x73, 0x2f, 0x41, 0x64, 0x64, 0x4d, 0x79, 0x53, 0x51, 0x4c, 0x12, 0xbb, 0x01, 0x0a, 0x11, 0x41, + 0x64, 0x64, 0x4d, 0x6f, 0x6e, 0x67, 0x6f, 0x44, 0x42, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x12, 0x23, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x41, 0x64, 0x64, + 0x4d, 0x6f, 0x6e, 0x67, 0x6f, 0x44, 0x42, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, + 0x79, 0x2e, 0x41, 0x64, 0x64, 0x4d, 0x6f, 0x6e, 0x67, 0x6f, 0x44, 0x42, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x5b, 0x92, 0x41, 0x2c, + 0x12, 0x13, 0x41, 0x64, 0x64, 0x20, 0x4d, 0x6f, 0x6e, 0x67, 0x6f, 0x44, 0x42, 0x20, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x1a, 0x15, 0x41, 0x64, 0x64, 0x73, 0x20, 0x4d, 0x6f, 0x6e, 0x67, + 0x6f, 0x44, 0x42, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x26, 0x3a, 0x01, 0x2a, 0x22, 0x21, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x41, 0x64, - 0x64, 0x50, 0x6f, 0x73, 0x74, 0x67, 0x72, 0x65, 0x53, 0x51, 0x4c, 0x12, 0xc1, 0x01, 0x0a, 0x12, - 0x41, 0x64, 0x64, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x53, 0x51, 0x4c, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x12, 0x24, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x41, - 0x64, 0x64, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x53, 0x51, 0x4c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x6e, - 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x41, 0x64, 0x64, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x53, 0x51, 0x4c, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x5e, 0x92, 0x41, 0x2e, 0x12, 0x14, 0x41, 0x64, 0x64, 0x20, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x53, - 0x51, 0x4c, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x1a, 0x16, 0x41, 0x64, 0x64, 0x73, - 0x20, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x53, 0x51, 0x4c, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x27, 0x3a, 0x01, 0x2a, 0x22, 0x22, 0x2f, 0x76, 0x31, - 0x2f, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x73, 0x2f, 0x41, 0x64, 0x64, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x53, 0x51, 0x4c, 0x12, - 0xc2, 0x01, 0x0a, 0x11, 0x41, 0x64, 0x64, 0x48, 0x41, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x23, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, - 0x79, 0x2e, 0x41, 0x64, 0x64, 0x48, 0x41, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x69, 0x6e, 0x76, - 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x41, 0x64, 0x64, 0x48, 0x41, 0x50, 0x72, 0x6f, 0x78, - 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x62, 0x92, 0x41, 0x2c, 0x12, 0x13, 0x41, 0x64, 0x64, 0x20, 0x48, 0x41, 0x50, 0x72, 0x6f, - 0x78, 0x79, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x1a, 0x15, 0x41, 0x64, 0x64, 0x73, - 0x20, 0x48, 0x41, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2d, 0x3a, 0x01, 0x2a, 0x22, 0x28, 0x2f, 0x76, 0x31, 0x2f, - 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x73, 0x2f, 0x41, 0x64, 0x64, 0x48, 0x41, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x12, 0xc8, 0x01, 0x0a, 0x12, 0x41, 0x64, 0x64, 0x45, 0x78, 0x74, 0x65, - 0x72, 0x6e, 0x61, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x24, 0x2e, 0x69, 0x6e, - 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x41, 0x64, 0x64, 0x45, 0x78, 0x74, 0x65, 0x72, - 0x6e, 0x61, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x25, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x41, 0x64, - 0x64, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x65, 0x92, 0x41, 0x2e, 0x12, 0x14, 0x41, - 0x64, 0x64, 0x20, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x1a, 0x16, 0x41, 0x64, 0x64, 0x73, 0x20, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, - 0x61, 0x6c, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x2e, 0x3a, 0x01, 0x2a, 0x22, 0x29, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, - 0x6f, 0x72, 0x79, 0x2f, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x41, 0x64, 0x64, - 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, - 0xa1, 0x01, 0x0a, 0x0d, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x12, 0x1f, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x52, 0x65, - 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x52, - 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4d, 0x92, 0x41, 0x22, 0x12, 0x0e, 0x52, 0x65, 0x6d, 0x6f, 0x76, - 0x65, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x1a, 0x10, 0x52, 0x65, 0x6d, 0x6f, 0x76, - 0x65, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x22, 0x3a, 0x01, 0x2a, 0x22, 0x1d, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, - 0x6f, 0x72, 0x79, 0x2f, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x52, 0x65, 0x6d, - 0x6f, 0x76, 0x65, 0x12, 0xee, 0x01, 0x0a, 0x0f, 0x41, 0x64, 0x64, 0x43, 0x75, 0x73, 0x74, 0x6f, - 0x6d, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x21, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, + 0x64, 0x4d, 0x6f, 0x6e, 0x67, 0x6f, 0x44, 0x42, 0x12, 0xcd, 0x01, 0x0a, 0x14, 0x41, 0x64, 0x64, + 0x50, 0x6f, 0x73, 0x74, 0x67, 0x72, 0x65, 0x53, 0x51, 0x4c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x12, 0x26, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x41, 0x64, + 0x64, 0x50, 0x6f, 0x73, 0x74, 0x67, 0x72, 0x65, 0x53, 0x51, 0x4c, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x69, 0x6e, 0x76, 0x65, + 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x41, 0x64, 0x64, 0x50, 0x6f, 0x73, 0x74, 0x67, 0x72, 0x65, + 0x53, 0x51, 0x4c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x64, 0x92, 0x41, 0x32, 0x12, 0x16, 0x41, 0x64, 0x64, 0x20, 0x50, 0x6f, 0x73, + 0x74, 0x67, 0x72, 0x65, 0x53, 0x51, 0x4c, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x1a, + 0x18, 0x41, 0x64, 0x64, 0x73, 0x20, 0x50, 0x6f, 0x73, 0x74, 0x67, 0x72, 0x65, 0x53, 0x51, 0x4c, + 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x3a, + 0x01, 0x2a, 0x22, 0x24, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, + 0x79, 0x2f, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x41, 0x64, 0x64, 0x50, 0x6f, + 0x73, 0x74, 0x67, 0x72, 0x65, 0x53, 0x51, 0x4c, 0x12, 0xc1, 0x01, 0x0a, 0x12, 0x41, 0x64, 0x64, + 0x50, 0x72, 0x6f, 0x78, 0x79, 0x53, 0x51, 0x4c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, + 0x24, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x41, 0x64, 0x64, 0x50, + 0x72, 0x6f, 0x78, 0x79, 0x53, 0x51, 0x4c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, + 0x79, 0x2e, 0x41, 0x64, 0x64, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x53, 0x51, 0x4c, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x5e, 0x92, 0x41, + 0x2e, 0x12, 0x14, 0x41, 0x64, 0x64, 0x20, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x53, 0x51, 0x4c, 0x20, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x1a, 0x16, 0x41, 0x64, 0x64, 0x73, 0x20, 0x50, 0x72, + 0x6f, 0x78, 0x79, 0x53, 0x51, 0x4c, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x27, 0x3a, 0x01, 0x2a, 0x22, 0x22, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, + 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, + 0x2f, 0x41, 0x64, 0x64, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x53, 0x51, 0x4c, 0x12, 0xc2, 0x01, 0x0a, + 0x11, 0x41, 0x64, 0x64, 0x48, 0x41, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x12, 0x23, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x41, + 0x64, 0x64, 0x48, 0x41, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, + 0x6f, 0x72, 0x79, 0x2e, 0x41, 0x64, 0x64, 0x48, 0x41, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x62, 0x92, + 0x41, 0x2c, 0x12, 0x13, 0x41, 0x64, 0x64, 0x20, 0x48, 0x41, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x20, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x1a, 0x15, 0x41, 0x64, 0x64, 0x73, 0x20, 0x48, 0x41, + 0x50, 0x72, 0x6f, 0x78, 0x79, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x2d, 0x3a, 0x01, 0x2a, 0x22, 0x28, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x76, + 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, + 0x41, 0x64, 0x64, 0x48, 0x41, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x12, 0xc8, 0x01, 0x0a, 0x12, 0x41, 0x64, 0x64, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x6c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x24, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x6e, + 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x41, 0x64, 0x64, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, + 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x41, 0x64, 0x64, 0x45, 0x78, + 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x65, 0x92, 0x41, 0x2e, 0x12, 0x14, 0x41, 0x64, 0x64, 0x20, + 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x1a, 0x16, 0x41, 0x64, 0x64, 0x73, 0x20, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2e, 0x3a, 0x01, + 0x2a, 0x22, 0x29, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, + 0x2f, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x41, 0x64, 0x64, 0x45, 0x78, 0x74, + 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0xa1, 0x01, 0x0a, + 0x0d, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x1f, + 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, + 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x20, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x52, 0x65, 0x6d, 0x6f, + 0x76, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x4d, 0x92, 0x41, 0x22, 0x12, 0x0e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x20, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x1a, 0x10, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x73, 0x20, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x22, 0x3a, 0x01, + 0x2a, 0x22, 0x1d, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, + 0x2f, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, + 0x12, 0xee, 0x01, 0x0a, 0x0f, 0x41, 0x64, 0x64, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x4c, 0x61, + 0x62, 0x65, 0x6c, 0x73, 0x12, 0x21, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, + 0x2e, 0x41, 0x64, 0x64, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x41, 0x64, 0x64, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x4c, 0x61, 0x62, - 0x65, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x69, 0x6e, 0x76, - 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x41, 0x64, 0x64, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, - 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x93, - 0x01, 0x92, 0x41, 0x5e, 0x12, 0x19, 0x41, 0x64, 0x64, 0x2f, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, - 0x65, 0x20, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x20, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x1a, - 0x41, 0x41, 0x64, 0x64, 0x73, 0x20, 0x6f, 0x72, 0x20, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, - 0x73, 0x20, 0x28, 0x69, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6b, 0x65, 0x79, 0x20, 0x65, 0x78, - 0x69, 0x73, 0x74, 0x73, 0x29, 0x20, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x20, 0x6c, 0x61, 0x62, - 0x65, 0x6c, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2c, 0x3a, 0x01, 0x2a, 0x22, 0x27, 0x2f, 0x76, 0x31, - 0x2f, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x73, 0x2f, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, - 0x2f, 0x41, 0x64, 0x64, 0x12, 0xdf, 0x01, 0x0a, 0x12, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, - 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x24, 0x2e, 0x69, 0x6e, - 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x75, - 0x73, 0x74, 0x6f, 0x6d, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x25, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x52, 0x65, - 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x7c, 0x92, 0x41, 0x44, 0x12, 0x14, 0x52, - 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x20, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x20, 0x6c, 0x61, 0x62, - 0x65, 0x6c, 0x73, 0x1a, 0x2c, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x73, 0x20, 0x63, 0x75, 0x73, - 0x74, 0x6f, 0x6d, 0x20, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, - 0x61, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x20, 0x62, 0x79, 0x20, 0x6b, 0x65, 0x79, - 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2f, 0x3a, 0x01, 0x2a, 0x22, 0x2a, 0x2f, 0x76, 0x31, 0x2f, - 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x73, 0x2f, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x2f, - 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x42, 0x8a, 0x01, 0x0a, 0x0d, 0x63, 0x6f, 0x6d, 0x2e, 0x69, + 0x65, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x93, 0x01, 0x92, 0x41, + 0x5e, 0x12, 0x19, 0x41, 0x64, 0x64, 0x2f, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x20, 0x63, + 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x20, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x1a, 0x41, 0x41, 0x64, + 0x64, 0x73, 0x20, 0x6f, 0x72, 0x20, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x73, 0x20, 0x28, + 0x69, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6b, 0x65, 0x79, 0x20, 0x65, 0x78, 0x69, 0x73, 0x74, + 0x73, 0x29, 0x20, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x20, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, + 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x2c, 0x3a, 0x01, 0x2a, 0x22, 0x27, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, + 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, + 0x2f, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x2f, 0x41, 0x64, + 0x64, 0x12, 0xdf, 0x01, 0x0a, 0x12, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x75, 0x73, 0x74, + 0x6f, 0x6d, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x24, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x6e, + 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x75, 0x73, 0x74, 0x6f, + 0x6d, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, + 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, + 0x65, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x7c, 0x92, 0x41, 0x44, 0x12, 0x14, 0x52, 0x65, 0x6d, 0x6f, + 0x76, 0x65, 0x20, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x20, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, + 0x1a, 0x2c, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x73, 0x20, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, + 0x20, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x61, 0x20, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x20, 0x62, 0x79, 0x20, 0x6b, 0x65, 0x79, 0x2e, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x2f, 0x3a, 0x01, 0x2a, 0x22, 0x2a, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x76, + 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, + 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x2f, 0x52, 0x65, 0x6d, + 0x6f, 0x76, 0x65, 0x12, 0xd0, 0x02, 0x0a, 0x0d, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x1f, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, + 0x79, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, + 0x72, 0x79, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xfb, 0x01, 0x92, 0x41, 0xcf, 0x01, 0x12, + 0x0e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x1a, + 0xbc, 0x01, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x20, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, + 0x20, 0x49, 0x66, 0x20, 0x61, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, + 0x72, 0x20, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x20, 0x69, 0x73, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, + 0x66, 0x69, 0x65, 0x64, 0x2c, 0x20, 0x69, 0x74, 0x20, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x73, + 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2f, 0x72, 0x65, 0x73, 0x74, + 0x6f, 0x72, 0x65, 0x20, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x20, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, + 0x6c, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x6c, 0x61, + 0x74, 0x65, 0x64, 0x20, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x20, 0x46, 0x61, + 0x69, 0x6c, 0x73, 0x20, 0x69, 0x66, 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, 0x20, 0x61, 0x72, 0x65, + 0x20, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x2f, + 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x20, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x2e, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x22, 0x3a, 0x01, 0x2a, 0x22, 0x1d, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x76, + 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, + 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x42, 0x8a, 0x01, 0x0a, 0x0d, 0x63, 0x6f, 0x6d, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x0d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x26, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x61, 0x2f, 0x70, 0x6d, @@ -3158,7 +3316,7 @@ func file_inventorypb_services_proto_rawDescGZIP() []byte { var ( file_inventorypb_services_proto_enumTypes = make([]protoimpl.EnumInfo, 1) - file_inventorypb_services_proto_msgTypes = make([]protoimpl.MessageInfo, 43) + file_inventorypb_services_proto_msgTypes = make([]protoimpl.MessageInfo, 45) file_inventorypb_services_proto_goTypes = []interface{}{ (ServiceType)(0), // 0: inventory.ServiceType (*MySQLService)(nil), // 1: inventory.MySQLService @@ -3191,29 +3349,31 @@ var ( (*AddCustomLabelsResponse)(nil), // 28: inventory.AddCustomLabelsResponse (*RemoveCustomLabelsRequest)(nil), // 29: inventory.RemoveCustomLabelsRequest (*RemoveCustomLabelsResponse)(nil), // 30: inventory.RemoveCustomLabelsResponse - nil, // 31: inventory.MySQLService.CustomLabelsEntry - nil, // 32: inventory.MongoDBService.CustomLabelsEntry - nil, // 33: inventory.PostgreSQLService.CustomLabelsEntry - nil, // 34: inventory.ProxySQLService.CustomLabelsEntry - nil, // 35: inventory.HAProxyService.CustomLabelsEntry - nil, // 36: inventory.ExternalService.CustomLabelsEntry - nil, // 37: inventory.AddMySQLServiceRequest.CustomLabelsEntry - nil, // 38: inventory.AddMongoDBServiceRequest.CustomLabelsEntry - nil, // 39: inventory.AddPostgreSQLServiceRequest.CustomLabelsEntry - nil, // 40: inventory.AddProxySQLServiceRequest.CustomLabelsEntry - nil, // 41: inventory.AddHAProxyServiceRequest.CustomLabelsEntry - nil, // 42: inventory.AddExternalServiceRequest.CustomLabelsEntry - nil, // 43: inventory.AddCustomLabelsRequest.CustomLabelsEntry + (*ChangeServiceRequest)(nil), // 31: inventory.ChangeServiceRequest + (*ChangeServiceResponse)(nil), // 32: inventory.ChangeServiceResponse + nil, // 33: inventory.MySQLService.CustomLabelsEntry + nil, // 34: inventory.MongoDBService.CustomLabelsEntry + nil, // 35: inventory.PostgreSQLService.CustomLabelsEntry + nil, // 36: inventory.ProxySQLService.CustomLabelsEntry + nil, // 37: inventory.HAProxyService.CustomLabelsEntry + nil, // 38: inventory.ExternalService.CustomLabelsEntry + nil, // 39: inventory.AddMySQLServiceRequest.CustomLabelsEntry + nil, // 40: inventory.AddMongoDBServiceRequest.CustomLabelsEntry + nil, // 41: inventory.AddPostgreSQLServiceRequest.CustomLabelsEntry + nil, // 42: inventory.AddProxySQLServiceRequest.CustomLabelsEntry + nil, // 43: inventory.AddHAProxyServiceRequest.CustomLabelsEntry + nil, // 44: inventory.AddExternalServiceRequest.CustomLabelsEntry + nil, // 45: inventory.AddCustomLabelsRequest.CustomLabelsEntry } ) var file_inventorypb_services_proto_depIdxs = []int32{ - 31, // 0: inventory.MySQLService.custom_labels:type_name -> inventory.MySQLService.CustomLabelsEntry - 32, // 1: inventory.MongoDBService.custom_labels:type_name -> inventory.MongoDBService.CustomLabelsEntry - 33, // 2: inventory.PostgreSQLService.custom_labels:type_name -> inventory.PostgreSQLService.CustomLabelsEntry - 34, // 3: inventory.ProxySQLService.custom_labels:type_name -> inventory.ProxySQLService.CustomLabelsEntry - 35, // 4: inventory.HAProxyService.custom_labels:type_name -> inventory.HAProxyService.CustomLabelsEntry - 36, // 5: inventory.ExternalService.custom_labels:type_name -> inventory.ExternalService.CustomLabelsEntry + 33, // 0: inventory.MySQLService.custom_labels:type_name -> inventory.MySQLService.CustomLabelsEntry + 34, // 1: inventory.MongoDBService.custom_labels:type_name -> inventory.MongoDBService.CustomLabelsEntry + 35, // 2: inventory.PostgreSQLService.custom_labels:type_name -> inventory.PostgreSQLService.CustomLabelsEntry + 36, // 3: inventory.ProxySQLService.custom_labels:type_name -> inventory.ProxySQLService.CustomLabelsEntry + 37, // 4: inventory.HAProxyService.custom_labels:type_name -> inventory.HAProxyService.CustomLabelsEntry + 38, // 5: inventory.ExternalService.custom_labels:type_name -> inventory.ExternalService.CustomLabelsEntry 0, // 6: inventory.ListServicesRequest.service_type:type_name -> inventory.ServiceType 1, // 7: inventory.ListServicesResponse.mysql:type_name -> inventory.MySQLService 2, // 8: inventory.ListServicesResponse.mongodb:type_name -> inventory.MongoDBService @@ -3228,19 +3388,19 @@ var file_inventorypb_services_proto_depIdxs = []int32{ 4, // 17: inventory.GetServiceResponse.proxysql:type_name -> inventory.ProxySQLService 5, // 18: inventory.GetServiceResponse.haproxy:type_name -> inventory.HAProxyService 6, // 19: inventory.GetServiceResponse.external:type_name -> inventory.ExternalService - 37, // 20: inventory.AddMySQLServiceRequest.custom_labels:type_name -> inventory.AddMySQLServiceRequest.CustomLabelsEntry + 39, // 20: inventory.AddMySQLServiceRequest.custom_labels:type_name -> inventory.AddMySQLServiceRequest.CustomLabelsEntry 1, // 21: inventory.AddMySQLServiceResponse.mysql:type_name -> inventory.MySQLService - 38, // 22: inventory.AddMongoDBServiceRequest.custom_labels:type_name -> inventory.AddMongoDBServiceRequest.CustomLabelsEntry + 40, // 22: inventory.AddMongoDBServiceRequest.custom_labels:type_name -> inventory.AddMongoDBServiceRequest.CustomLabelsEntry 2, // 23: inventory.AddMongoDBServiceResponse.mongodb:type_name -> inventory.MongoDBService - 39, // 24: inventory.AddPostgreSQLServiceRequest.custom_labels:type_name -> inventory.AddPostgreSQLServiceRequest.CustomLabelsEntry + 41, // 24: inventory.AddPostgreSQLServiceRequest.custom_labels:type_name -> inventory.AddPostgreSQLServiceRequest.CustomLabelsEntry 3, // 25: inventory.AddPostgreSQLServiceResponse.postgresql:type_name -> inventory.PostgreSQLService - 40, // 26: inventory.AddProxySQLServiceRequest.custom_labels:type_name -> inventory.AddProxySQLServiceRequest.CustomLabelsEntry + 42, // 26: inventory.AddProxySQLServiceRequest.custom_labels:type_name -> inventory.AddProxySQLServiceRequest.CustomLabelsEntry 4, // 27: inventory.AddProxySQLServiceResponse.proxysql:type_name -> inventory.ProxySQLService - 41, // 28: inventory.AddHAProxyServiceRequest.custom_labels:type_name -> inventory.AddHAProxyServiceRequest.CustomLabelsEntry + 43, // 28: inventory.AddHAProxyServiceRequest.custom_labels:type_name -> inventory.AddHAProxyServiceRequest.CustomLabelsEntry 5, // 29: inventory.AddHAProxyServiceResponse.haproxy:type_name -> inventory.HAProxyService - 42, // 30: inventory.AddExternalServiceRequest.custom_labels:type_name -> inventory.AddExternalServiceRequest.CustomLabelsEntry + 44, // 30: inventory.AddExternalServiceRequest.custom_labels:type_name -> inventory.AddExternalServiceRequest.CustomLabelsEntry 6, // 31: inventory.AddExternalServiceResponse.external:type_name -> inventory.ExternalService - 43, // 32: inventory.AddCustomLabelsRequest.custom_labels:type_name -> inventory.AddCustomLabelsRequest.CustomLabelsEntry + 45, // 32: inventory.AddCustomLabelsRequest.custom_labels:type_name -> inventory.AddCustomLabelsRequest.CustomLabelsEntry 7, // 33: inventory.Services.ListServices:input_type -> inventory.ListServicesRequest 9, // 34: inventory.Services.ListActiveServiceTypes:input_type -> inventory.ListActiveServiceTypesRequest 11, // 35: inventory.Services.GetService:input_type -> inventory.GetServiceRequest @@ -3253,20 +3413,22 @@ var file_inventorypb_services_proto_depIdxs = []int32{ 25, // 42: inventory.Services.RemoveService:input_type -> inventory.RemoveServiceRequest 27, // 43: inventory.Services.AddCustomLabels:input_type -> inventory.AddCustomLabelsRequest 29, // 44: inventory.Services.RemoveCustomLabels:input_type -> inventory.RemoveCustomLabelsRequest - 8, // 45: inventory.Services.ListServices:output_type -> inventory.ListServicesResponse - 10, // 46: inventory.Services.ListActiveServiceTypes:output_type -> inventory.ListActiveServiceTypesResponse - 12, // 47: inventory.Services.GetService:output_type -> inventory.GetServiceResponse - 14, // 48: inventory.Services.AddMySQLService:output_type -> inventory.AddMySQLServiceResponse - 16, // 49: inventory.Services.AddMongoDBService:output_type -> inventory.AddMongoDBServiceResponse - 18, // 50: inventory.Services.AddPostgreSQLService:output_type -> inventory.AddPostgreSQLServiceResponse - 20, // 51: inventory.Services.AddProxySQLService:output_type -> inventory.AddProxySQLServiceResponse - 22, // 52: inventory.Services.AddHAProxyService:output_type -> inventory.AddHAProxyServiceResponse - 24, // 53: inventory.Services.AddExternalService:output_type -> inventory.AddExternalServiceResponse - 26, // 54: inventory.Services.RemoveService:output_type -> inventory.RemoveServiceResponse - 28, // 55: inventory.Services.AddCustomLabels:output_type -> inventory.AddCustomLabelsResponse - 30, // 56: inventory.Services.RemoveCustomLabels:output_type -> inventory.RemoveCustomLabelsResponse - 45, // [45:57] is the sub-list for method output_type - 33, // [33:45] is the sub-list for method input_type + 31, // 45: inventory.Services.ChangeService:input_type -> inventory.ChangeServiceRequest + 8, // 46: inventory.Services.ListServices:output_type -> inventory.ListServicesResponse + 10, // 47: inventory.Services.ListActiveServiceTypes:output_type -> inventory.ListActiveServiceTypesResponse + 12, // 48: inventory.Services.GetService:output_type -> inventory.GetServiceResponse + 14, // 49: inventory.Services.AddMySQLService:output_type -> inventory.AddMySQLServiceResponse + 16, // 50: inventory.Services.AddMongoDBService:output_type -> inventory.AddMongoDBServiceResponse + 18, // 51: inventory.Services.AddPostgreSQLService:output_type -> inventory.AddPostgreSQLServiceResponse + 20, // 52: inventory.Services.AddProxySQLService:output_type -> inventory.AddProxySQLServiceResponse + 22, // 53: inventory.Services.AddHAProxyService:output_type -> inventory.AddHAProxyServiceResponse + 24, // 54: inventory.Services.AddExternalService:output_type -> inventory.AddExternalServiceResponse + 26, // 55: inventory.Services.RemoveService:output_type -> inventory.RemoveServiceResponse + 28, // 56: inventory.Services.AddCustomLabels:output_type -> inventory.AddCustomLabelsResponse + 30, // 57: inventory.Services.RemoveCustomLabels:output_type -> inventory.RemoveCustomLabelsResponse + 32, // 58: inventory.Services.ChangeService:output_type -> inventory.ChangeServiceResponse + 46, // [46:59] is the sub-list for method output_type + 33, // [33:46] is the sub-list for method input_type 33, // [33:33] is the sub-list for extension type_name 33, // [33:33] is the sub-list for extension extendee 0, // [0:33] is the sub-list for field type_name @@ -3638,6 +3800,30 @@ func file_inventorypb_services_proto_init() { return nil } } + file_inventorypb_services_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ChangeServiceRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_inventorypb_services_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ChangeServiceResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } file_inventorypb_services_proto_msgTypes[11].OneofWrappers = []interface{}{ (*GetServiceResponse_Mysql)(nil), @@ -3647,13 +3833,14 @@ func file_inventorypb_services_proto_init() { (*GetServiceResponse_Haproxy)(nil), (*GetServiceResponse_External)(nil), } + file_inventorypb_services_proto_msgTypes[30].OneofWrappers = []interface{}{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_inventorypb_services_proto_rawDesc, NumEnums: 1, - NumMessages: 43, + NumMessages: 45, NumExtensions: 0, NumServices: 1, }, diff --git a/api/inventorypb/services.pb.gw.go b/api/inventorypb/services.pb.gw.go index 41149720ca..d9964442e0 100644 --- a/api/inventorypb/services.pb.gw.go +++ b/api/inventorypb/services.pb.gw.go @@ -417,6 +417,38 @@ func local_request_Services_RemoveCustomLabels_0(ctx context.Context, marshaler return msg, metadata, err } +func request_Services_ChangeService_0(ctx context.Context, marshaler runtime.Marshaler, client ServicesClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ChangeServiceRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.ChangeService(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err +} + +func local_request_Services_ChangeService_0(ctx context.Context, marshaler runtime.Marshaler, server ServicesServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ChangeServiceRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.ChangeService(ctx, &protoReq) + return msg, metadata, err +} + // RegisterServicesHandlerServer registers the http handlers for service Services to "mux". // UnaryRPC :call ServicesServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. @@ -710,6 +742,30 @@ func RegisterServicesHandlerServer(ctx context.Context, mux *runtime.ServeMux, s forward_Services_RemoveCustomLabels_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) + mux.Handle("POST", pattern_Services_ChangeService_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/inventory.Services/ChangeService", runtime.WithHTTPPathPattern("/v1/inventory/Services/Change")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Services_ChangeService_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_Services_ChangeService_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) + return nil } @@ -1002,6 +1058,27 @@ func RegisterServicesHandlerClient(ctx context.Context, mux *runtime.ServeMux, c forward_Services_RemoveCustomLabels_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) + mux.Handle("POST", pattern_Services_ChangeService_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/inventory.Services/ChangeService", runtime.WithHTTPPathPattern("/v1/inventory/Services/Change")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Services_ChangeService_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_Services_ChangeService_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) + return nil } @@ -1029,6 +1106,8 @@ var ( pattern_Services_AddCustomLabels_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"v1", "inventory", "Services", "CustomLabels", "Add"}, "")) pattern_Services_RemoveCustomLabels_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"v1", "inventory", "Services", "CustomLabels", "Remove"}, "")) + + pattern_Services_ChangeService_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v1", "inventory", "Services", "Change"}, "")) ) var ( @@ -1055,4 +1134,6 @@ var ( forward_Services_AddCustomLabels_0 = runtime.ForwardResponseMessage forward_Services_RemoveCustomLabels_0 = runtime.ForwardResponseMessage + + forward_Services_ChangeService_0 = runtime.ForwardResponseMessage ) diff --git a/api/inventorypb/services.pb.validate.go b/api/inventorypb/services.pb.validate.go index 9b1f0567d7..65c779fbef 100644 --- a/api/inventorypb/services.pb.validate.go +++ b/api/inventorypb/services.pb.validate.go @@ -4088,3 +4088,234 @@ var _ interface { Cause() error ErrorName() string } = RemoveCustomLabelsResponseValidationError{} + +// Validate checks the field values on ChangeServiceRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *ChangeServiceRequest) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on ChangeServiceRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// ChangeServiceRequestMultiError, or nil if none found. +func (m *ChangeServiceRequest) ValidateAll() error { + return m.validate(true) +} + +func (m *ChangeServiceRequest) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if utf8.RuneCountInString(m.GetServiceId()) < 1 { + err := ChangeServiceRequestValidationError{ + field: "ServiceId", + reason: "value length must be at least 1 runes", + } + if !all { + return err + } + errors = append(errors, err) + } + + if m.Environment != nil { + // no validation rules for Environment + } + + if m.Cluster != nil { + // no validation rules for Cluster + } + + if m.ReplicationSet != nil { + // no validation rules for ReplicationSet + } + + if m.ExternalGroup != nil { + // no validation rules for ExternalGroup + } + + if len(errors) > 0 { + return ChangeServiceRequestMultiError(errors) + } + + return nil +} + +// ChangeServiceRequestMultiError is an error wrapping multiple validation +// errors returned by ChangeServiceRequest.ValidateAll() if the designated +// constraints aren't met. +type ChangeServiceRequestMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m ChangeServiceRequestMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m ChangeServiceRequestMultiError) AllErrors() []error { return m } + +// ChangeServiceRequestValidationError is the validation error returned by +// ChangeServiceRequest.Validate if the designated constraints aren't met. +type ChangeServiceRequestValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e ChangeServiceRequestValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e ChangeServiceRequestValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e ChangeServiceRequestValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e ChangeServiceRequestValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e ChangeServiceRequestValidationError) ErrorName() string { + return "ChangeServiceRequestValidationError" +} + +// Error satisfies the builtin error interface +func (e ChangeServiceRequestValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sChangeServiceRequest.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = ChangeServiceRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = ChangeServiceRequestValidationError{} + +// Validate checks the field values on ChangeServiceResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *ChangeServiceResponse) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on ChangeServiceResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// ChangeServiceResponseMultiError, or nil if none found. +func (m *ChangeServiceResponse) ValidateAll() error { + return m.validate(true) +} + +func (m *ChangeServiceResponse) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if len(errors) > 0 { + return ChangeServiceResponseMultiError(errors) + } + + return nil +} + +// ChangeServiceResponseMultiError is an error wrapping multiple validation +// errors returned by ChangeServiceResponse.ValidateAll() if the designated +// constraints aren't met. +type ChangeServiceResponseMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m ChangeServiceResponseMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m ChangeServiceResponseMultiError) AllErrors() []error { return m } + +// ChangeServiceResponseValidationError is the validation error returned by +// ChangeServiceResponse.Validate if the designated constraints aren't met. +type ChangeServiceResponseValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e ChangeServiceResponseValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e ChangeServiceResponseValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e ChangeServiceResponseValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e ChangeServiceResponseValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e ChangeServiceResponseValidationError) ErrorName() string { + return "ChangeServiceResponseValidationError" +} + +// Error satisfies the builtin error interface +func (e ChangeServiceResponseValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sChangeServiceResponse.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = ChangeServiceResponseValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = ChangeServiceResponseValidationError{} diff --git a/api/inventorypb/services.proto b/api/inventorypb/services.proto index 94ddc9f43c..199f6000c6 100644 --- a/api/inventorypb/services.proto +++ b/api/inventorypb/services.proto @@ -404,6 +404,16 @@ message RemoveCustomLabelsRequest { message RemoveCustomLabelsResponse {} +message ChangeServiceRequest { + string service_id = 1 [(validate.rules).string.min_len = 1]; + optional string environment = 2; + optional string cluster = 3; + optional string replication_set = 4; + optional string external_group = 5; +} + +message ChangeServiceResponse {} + // Services service provides public methods for managing Services. service Services { // ListServices returns a list of Services filtered by type. @@ -538,4 +548,15 @@ service Services { description: "Removes custom labels from a Service by key." }; } + // ChangeService allows changing configuration of a service. + rpc ChangeService(ChangeServiceRequest) returns (ChangeServiceResponse) { + option (google.api.http) = { + post: "/v1/inventory/Services/Change" + body: "*" + }; + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + summary: "Change service" + description: "Changes service configuration. If a new cluster label is specified, it removes all backup/restore tasks scheduled for the related services. Fails if there are running backup/restore tasks." + }; + } } diff --git a/api/inventorypb/services_grpc.pb.go b/api/inventorypb/services_grpc.pb.go index c1e42669ca..84f88883fd 100644 --- a/api/inventorypb/services_grpc.pb.go +++ b/api/inventorypb/services_grpc.pb.go @@ -32,6 +32,7 @@ const ( Services_RemoveService_FullMethodName = "/inventory.Services/RemoveService" Services_AddCustomLabels_FullMethodName = "/inventory.Services/AddCustomLabels" Services_RemoveCustomLabels_FullMethodName = "/inventory.Services/RemoveCustomLabels" + Services_ChangeService_FullMethodName = "/inventory.Services/ChangeService" ) // ServicesClient is the client API for Services service. @@ -62,6 +63,8 @@ type ServicesClient interface { AddCustomLabels(ctx context.Context, in *AddCustomLabelsRequest, opts ...grpc.CallOption) (*AddCustomLabelsResponse, error) // RemoveCustomLabels removes custom labels from a Service. RemoveCustomLabels(ctx context.Context, in *RemoveCustomLabelsRequest, opts ...grpc.CallOption) (*RemoveCustomLabelsResponse, error) + // ChangeService allows changing configuration of a service. + ChangeService(ctx context.Context, in *ChangeServiceRequest, opts ...grpc.CallOption) (*ChangeServiceResponse, error) } type servicesClient struct { @@ -180,6 +183,15 @@ func (c *servicesClient) RemoveCustomLabels(ctx context.Context, in *RemoveCusto return out, nil } +func (c *servicesClient) ChangeService(ctx context.Context, in *ChangeServiceRequest, opts ...grpc.CallOption) (*ChangeServiceResponse, error) { + out := new(ChangeServiceResponse) + err := c.cc.Invoke(ctx, Services_ChangeService_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // ServicesServer is the server API for Services service. // All implementations must embed UnimplementedServicesServer // for forward compatibility @@ -208,6 +220,8 @@ type ServicesServer interface { AddCustomLabels(context.Context, *AddCustomLabelsRequest) (*AddCustomLabelsResponse, error) // RemoveCustomLabels removes custom labels from a Service. RemoveCustomLabels(context.Context, *RemoveCustomLabelsRequest) (*RemoveCustomLabelsResponse, error) + // ChangeService allows changing configuration of a service. + ChangeService(context.Context, *ChangeServiceRequest) (*ChangeServiceResponse, error) mustEmbedUnimplementedServicesServer() } @@ -261,6 +275,10 @@ func (UnimplementedServicesServer) AddCustomLabels(context.Context, *AddCustomLa func (UnimplementedServicesServer) RemoveCustomLabels(context.Context, *RemoveCustomLabelsRequest) (*RemoveCustomLabelsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method RemoveCustomLabels not implemented") } + +func (UnimplementedServicesServer) ChangeService(context.Context, *ChangeServiceRequest) (*ChangeServiceResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ChangeService not implemented") +} func (UnimplementedServicesServer) mustEmbedUnimplementedServicesServer() {} // UnsafeServicesServer may be embedded to opt out of forward compatibility for this service. @@ -490,6 +508,24 @@ func _Services_RemoveCustomLabels_Handler(srv interface{}, ctx context.Context, return interceptor(ctx, in, info, handler) } +func _Services_ChangeService_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ChangeServiceRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ServicesServer).ChangeService(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Services_ChangeService_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ServicesServer).ChangeService(ctx, req.(*ChangeServiceRequest)) + } + return interceptor(ctx, in, info, handler) +} + // Services_ServiceDesc is the grpc.ServiceDesc for Services service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -545,6 +581,10 @@ var Services_ServiceDesc = grpc.ServiceDesc{ MethodName: "RemoveCustomLabels", Handler: _Services_RemoveCustomLabels_Handler, }, + { + MethodName: "ChangeService", + Handler: _Services_ChangeService_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "inventorypb/services.proto", diff --git a/api/swagger/swagger-dev.json b/api/swagger/swagger-dev.json index 4e04d3fe73..bd44fe8f09 100644 --- a/api/swagger/swagger-dev.json +++ b/api/swagger/swagger-dev.json @@ -15782,6 +15782,87 @@ } } }, + "/v1/inventory/Services/Change": { + "post": { + "description": "Changes service configuration. If a new cluster label is specified, it removes all backup/restore tasks scheduled for the related services. Fails if there are running backup/restore tasks.", + "tags": [ + "Services" + ], + "summary": "Change service", + "operationId": "ChangeService", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "service_id": { + "type": "string", + "x-order": 0 + }, + "environment": { + "type": "string", + "x-order": 1 + }, + "cluster": { + "type": "string", + "x-order": 2 + }, + "replication_set": { + "type": "string", + "x-order": 3 + }, + "external_group": { + "type": "string", + "x-order": 4 + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "type": "object" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32", + "x-order": 0 + }, + "message": { + "type": "string", + "x-order": 1 + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "@type": { + "type": "string", + "x-order": 0 + } + }, + "additionalProperties": false + }, + "x-order": 2 + } + } + } + } + } + } + }, "/v1/inventory/Services/CustomLabels/Add": { "post": { "description": "Adds or replaces (if the key exists) custom labels for a Service.", diff --git a/api/swagger/swagger.json b/api/swagger/swagger.json index 908e2702de..48d466adff 100644 --- a/api/swagger/swagger.json +++ b/api/swagger/swagger.json @@ -12938,6 +12938,87 @@ } } }, + "/v1/inventory/Services/Change": { + "post": { + "description": "Changes service configuration. If a new cluster label is specified, it removes all backup/restore tasks scheduled for the related services. Fails if there are running backup/restore tasks.", + "tags": [ + "Services" + ], + "summary": "Change service", + "operationId": "ChangeService", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "service_id": { + "type": "string", + "x-order": 0 + }, + "environment": { + "type": "string", + "x-order": 1 + }, + "cluster": { + "type": "string", + "x-order": 2 + }, + "replication_set": { + "type": "string", + "x-order": 3 + }, + "external_group": { + "type": "string", + "x-order": 4 + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "type": "object" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32", + "x-order": 0 + }, + "message": { + "type": "string", + "x-order": 1 + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "@type": { + "type": "string", + "x-order": 0 + } + }, + "additionalProperties": false + }, + "x-order": 2 + } + } + } + } + } + } + }, "/v1/inventory/Services/CustomLabels/Add": { "post": { "description": "Adds or replaces (if the key exists) custom labels for a Service.", diff --git a/managed/cmd/pmm-managed/main.go b/managed/cmd/pmm-managed/main.go index 64faf965b1..bc15c61f60 100644 --- a/managed/cmd/pmm-managed/main.go +++ b/managed/cmd/pmm-managed/main.go @@ -89,6 +89,7 @@ import ( "github.com/percona/pmm/managed/services/management" "github.com/percona/pmm/managed/services/management/alerting" managementbackup "github.com/percona/pmm/managed/services/management/backup" + "github.com/percona/pmm/managed/services/management/common" managementdbaas "github.com/percona/pmm/managed/services/management/dbaas" managementgrpc "github.com/percona/pmm/managed/services/management/grpc" "github.com/percona/pmm/managed/services/management/ia" @@ -260,8 +261,13 @@ func runGRPCServer(ctx context.Context, deps *gRPCServerDeps) { deps.db, deps.agentsRegistry, deps.agentsStateUpdater, deps.vmdb, deps.connectionCheck, deps.agentService) + mgmtBackupsService := managementbackup.NewBackupsService(deps.db, deps.backupService, deps.compatibilityService, deps.schedulerService) + mgmtArtifactsService := managementbackup.NewArtifactsService(deps.db, deps.backupRemovalService, deps.pbmPITRService) + mgmtRestoreHistoryService := managementbackup.NewRestoreHistoryService(deps.db) + mgmtServices := common.MgmtServices{BackupsService: mgmtBackupsService, ArtifactsService: mgmtArtifactsService, RestoreHistoryService: mgmtRestoreHistoryService} + inventorypb.RegisterNodesServer(gRPCServer, inventorygrpc.NewNodesServer(nodesSvc)) - inventorypb.RegisterServicesServer(gRPCServer, inventorygrpc.NewServicesServer(servicesSvc)) + inventorypb.RegisterServicesServer(gRPCServer, inventorygrpc.NewServicesServer(servicesSvc, mgmtServices)) inventorypb.RegisterAgentsServer(gRPCServer, inventorygrpc.NewAgentsServer(agentsSvc)) nodeSvc := management.NewNodeService(deps.db, deps.grafanaClient) @@ -296,10 +302,10 @@ func runGRPCServer(ctx context.Context, deps *gRPCServerDeps) { iav1beta1.RegisterAlertsServer(gRPCServer, deps.alertsService) alertingpb.RegisterAlertingServer(gRPCServer, deps.templatesService) - backuppb.RegisterBackupsServer(gRPCServer, managementbackup.NewBackupsService(deps.db, deps.backupService, deps.compatibilityService, deps.schedulerService)) + backuppb.RegisterBackupsServer(gRPCServer, mgmtBackupsService) backuppb.RegisterLocationsServer(gRPCServer, managementbackup.NewLocationsService(deps.db, deps.minioClient)) - backuppb.RegisterArtifactsServer(gRPCServer, managementbackup.NewArtifactsService(deps.db, deps.backupRemovalService, deps.pbmPITRService)) - backuppb.RegisterRestoreHistoryServer(gRPCServer, managementbackup.NewRestoreHistoryService(deps.db)) + backuppb.RegisterArtifactsServer(gRPCServer, mgmtArtifactsService) + backuppb.RegisterRestoreHistoryServer(gRPCServer, mgmtRestoreHistoryService) k8sServer := managementdbaas.NewKubernetesServer(deps.db, deps.dbaasClient, deps.versionServiceClient, deps.grafanaClient) deps.dbaasInitializer.RegisterKubernetesServer(k8sServer) diff --git a/managed/cmd/pmm-managed/main_test.go b/managed/cmd/pmm-managed/main_test.go index 894f272a4d..2b97955616 100644 --- a/managed/cmd/pmm-managed/main_test.go +++ b/managed/cmd/pmm-managed/main_test.go @@ -41,6 +41,7 @@ func TestPackages(t *testing.T) { func TestImports(t *testing.T) { type constraint struct { blacklistPrefixes []string + whitelistPrefixes []string } constraints := make(map[string]constraint) @@ -76,7 +77,6 @@ func TestImports(t *testing.T) { // those services should be independent too, but has some common code // as converters, errors, ... "github.com/percona/pmm/managed/services/grafana", - "github.com/percona/pmm/managed/services/inventory", "github.com/percona/pmm/managed/services/management", "github.com/percona/pmm/managed/services/server", "github.com/percona/pmm/managed/services/checks", @@ -89,6 +89,20 @@ func TestImports(t *testing.T) { } } + for _, service := range []string{ + // TODO come up with a new code structure that allows cross-service communication without the need to do tricks. + "github.com/percona/pmm/managed/services/inventory", + } { + constraints[service] = constraint{ + blacklistPrefixes: []string{ + "github.com/percona/pmm/managed/services/", + }, + whitelistPrefixes: []string{ + "github.com/percona/pmm/managed/services/management/common", + }, + } + } + // validators should not import gRPC stack, including errors constraints["github.com/percona/pmm/managed/utils/validators"] = constraint{ blacklistPrefixes: []string{ @@ -127,6 +141,18 @@ func TestImports(t *testing.T) { continue } + // check allowlist + var allow bool + for _, a := range c.whitelistPrefixes { + if strings.HasPrefix(i, a) { + allow = true + break + } + } + if allow { + continue + } + // check blacklist if strings.HasPrefix(i, b) { t.Errorf("Package %q should not import package %q (blacklisted by %q).", path, i, b) diff --git a/managed/models/service_helpers.go b/managed/models/service_helpers.go index a2b04f9336..6c9f8b3e4f 100644 --- a/managed/models/service_helpers.go +++ b/managed/models/service_helpers.go @@ -402,6 +402,51 @@ func ValidateServiceType(serviceType ServiceType) error { } } +// ChangeStandardLabelsParams contains parameters for changing standard labels for a service. +type ChangeStandardLabelsParams struct { + ServiceID string + Cluster *string + Environment *string + ReplicationSet *string + ExternalGroup *string +} + +// ChangeStandardLabels changes standard labels for a service. +func ChangeStandardLabels(q *reform.Querier, serviceID string, labels ServiceStandardLabelsParams) error { + s, err := FindServiceByID(q, serviceID) + if err != nil { + return err + } + + columns := []string{} + + if labels.Cluster != nil { + columns = append(columns, "cluster") + s.Cluster = *labels.Cluster + } + + if labels.Environment != nil { + columns = append(columns, "environment") + s.Environment = *labels.Environment + } + + if labels.ReplicationSet != nil { + columns = append(columns, "replication_set") + s.ReplicationSet = *labels.ReplicationSet + } + + if labels.ExternalGroup != nil { + columns = append(columns, "external_group") + s.ExternalGroup = *labels.ExternalGroup + } + + if err = q.UpdateColumns(s, columns...); err != nil { + return err + } + + return nil +} + func initSoftwareVersions(q *reform.Querier, serviceID string, serviceType ServiceType) error { switch serviceType { case MySQLServiceType: diff --git a/managed/models/service_helpers_test.go b/managed/models/service_helpers_test.go index 140497e11a..07e4773a45 100644 --- a/managed/models/service_helpers_test.go +++ b/managed/models/service_helpers_test.go @@ -442,6 +442,36 @@ func TestServiceHelpers(t *testing.T) { assert.ElementsMatch(t, []*models.Service{s1, s2}, services) }) + t.Run("Change standard labels", func(t *testing.T) { + q, teardown := setup(t) + defer teardown(t) + s, err := models.AddNewService(q, models.ExternalServiceType, &models.AddDBMSServiceParams{ + ServiceName: "mongors1", + NodeID: "N1", + Cluster: "cluster0", + ExternalGroup: "ext", + Address: pointer.ToString("127.0.0.1"), + Port: pointer.ToUint16OrNil(27017), + }) + require.NoError(t, err) + + err = models.ChangeStandardLabels(q, s.ServiceID, models.ServiceStandardLabelsParams{ + Cluster: pointer.ToString("cluster"), + Environment: pointer.ToString("env"), + ReplicationSet: pointer.ToString("rs"), + ExternalGroup: pointer.ToString("external"), + }) + require.NoError(t, err) + + ns, err := models.FindServiceByID(q, s.ServiceID) + require.NoError(t, err) + + assert.Equal(t, ns.Cluster, "cluster") + assert.Equal(t, ns.Environment, "env") + assert.Equal(t, ns.ReplicationSet, "rs") + assert.Equal(t, ns.ExternalGroup, "external") + }) + t.Run("Software versions record created when adding a service", func(t *testing.T) { q, teardown := setup(t) defer teardown(t) diff --git a/managed/models/service_model.go b/managed/models/service_model.go index 55e326826b..fe3c3cc145 100644 --- a/managed/models/service_model.go +++ b/managed/models/service_model.go @@ -27,6 +27,13 @@ import ( // pmm-managed's PostgreSQL, qan-api's ClickHouse, and VictoriaMetrics. type ServiceType string +type ServiceStandardLabelsParams struct { + Cluster *string + Environment *string + ReplicationSet *string + ExternalGroup *string +} + // Service types (in the same order as in services.proto). const ( MySQLServiceType ServiceType = "mysql" diff --git a/managed/services/inventory/grpc/services_server.go b/managed/services/inventory/grpc/services_server.go index 72d0798124..7636617249 100644 --- a/managed/services/inventory/grpc/services_server.go +++ b/managed/services/inventory/grpc/services_server.go @@ -20,21 +20,29 @@ import ( "fmt" "github.com/AlekSi/pointer" + "github.com/pkg/errors" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" "github.com/percona/pmm/api/inventorypb" "github.com/percona/pmm/managed/models" "github.com/percona/pmm/managed/services/inventory" + "github.com/percona/pmm/managed/services/management/common" ) type servicesServer struct { - s *inventory.ServicesService + s *inventory.ServicesService + mgmtServices common.MgmtServices inventorypb.UnimplementedServicesServer } // NewServicesServer returns Inventory API handler for managing Services. -func NewServicesServer(s *inventory.ServicesService) inventorypb.ServicesServer { //nolint:ireturn - return &servicesServer{s: s} +func NewServicesServer(s *inventory.ServicesService, mgmtServices common.MgmtServices) inventorypb.ServicesServer { //nolint:ireturn + return &servicesServer{ + s: s, + mgmtServices: mgmtServices, + } } var serviceTypes = map[inventorypb.ServiceType]models.ServiceType{ @@ -278,3 +286,29 @@ func (s *servicesServer) AddCustomLabels(ctx context.Context, req *inventorypb.A func (s *servicesServer) RemoveCustomLabels(ctx context.Context, req *inventorypb.RemoveCustomLabelsRequest) (*inventorypb.RemoveCustomLabelsResponse, error) { return s.s.RemoveCustomLabels(ctx, req) } + +// ChangeService changes service configuration. +func (s *servicesServer) ChangeService(ctx context.Context, req *inventorypb.ChangeServiceRequest) (*inventorypb.ChangeServiceResponse, error) { + err := s.s.ChangeService(ctx, s.mgmtServices, &models.ChangeStandardLabelsParams{ + ServiceID: req.ServiceId, + Cluster: req.Cluster, + Environment: req.Environment, + ReplicationSet: req.ReplicationSet, + ExternalGroup: req.ExternalGroup, + }) + if err != nil { + return nil, toAPIError(err) + } + + return &inventorypb.ChangeServiceResponse{}, nil +} + +// toAPIError converts GO errors into API-level errors. +func toAPIError(err error) error { + switch { + case errors.Is(err, common.ErrClusterLocked): + return status.Error(codes.FailedPrecondition, err.Error()) + default: + return err + } +} diff --git a/managed/services/inventory/services.go b/managed/services/inventory/services.go index a742b24c92..885300bb2f 100644 --- a/managed/services/inventory/services.go +++ b/managed/services/inventory/services.go @@ -24,6 +24,7 @@ import ( "github.com/percona/pmm/api/inventorypb" "github.com/percona/pmm/managed/models" "github.com/percona/pmm/managed/services" + "github.com/percona/pmm/managed/services/management/common" ) // ServicesService works with inventory API Services. @@ -381,18 +382,10 @@ func (ss *ServicesService) AddCustomLabels(ctx context.Context, req *inventorypb return nil, errTx } - // Update scrape configuration - ss.vmdb.RequestConfigurationUpdate() - - agents, err := models.FindPMMAgentsForService(ss.db.Querier, req.ServiceId) - if err != nil { + if err := ss.updateScrapeConfig(ctx, req.ServiceId); err != nil { return nil, err } - for _, a := range agents { - ss.state.RequestStateUpdate(ctx, a.AgentID) - } - return &inventorypb.AddCustomLabelsResponse{}, nil } @@ -432,17 +425,50 @@ func (ss *ServicesService) RemoveCustomLabels(ctx context.Context, req *inventor return nil, errTx } - // Update scrape configuration + if err := ss.updateScrapeConfig(ctx, req.ServiceId); err != nil { + return nil, err + } + + return &inventorypb.RemoveCustomLabelsResponse{}, nil +} + +// ChangeService changes service configuration. +func (ss *ServicesService) ChangeService(ctx context.Context, mgmtServices common.MgmtServices, params *models.ChangeStandardLabelsParams) error { + if err := mgmtServices.RemoveScheduledTasks(ctx, ss.db, params); err != nil { + return err + } + + errTx := ss.db.InTransactionContext(ctx, nil, func(tx *reform.TX) error { + err := models.ChangeStandardLabels(tx.Querier, params.ServiceID, models.ServiceStandardLabelsParams{ + Cluster: params.Cluster, + Environment: params.Environment, + ReplicationSet: params.ReplicationSet, + ExternalGroup: params.ExternalGroup, + }) + return err + }) + if errTx != nil { + return errTx + } + + if err := ss.updateScrapeConfig(ctx, params.ServiceID); err != nil { + return err + } + + return nil +} + +func (ss *ServicesService) updateScrapeConfig(ctx context.Context, serviceID string) error { ss.vmdb.RequestConfigurationUpdate() - agents, err := models.FindPMMAgentsForService(ss.db.Querier, req.ServiceId) + agents, err := models.FindPMMAgentsForService(ss.db.Querier, serviceID) if err != nil { - return nil, err + return err } for _, a := range agents { ss.state.RequestStateUpdate(ctx, a.AgentID) } - return &inventorypb.RemoveCustomLabelsResponse{}, nil + return nil } diff --git a/managed/services/management/common/common.go b/managed/services/management/common/common.go new file mode 100644 index 0000000000..6dae1f8719 --- /dev/null +++ b/managed/services/management/common/common.go @@ -0,0 +1,126 @@ +// Copyright (C) 2017 Percona LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +// Package common contains common and cross-service logics. +package common + +import ( + "context" + + "github.com/pkg/errors" + "gopkg.in/reform.v1" + + backuppb "github.com/percona/pmm/api/managementpb/backup" + "github.com/percona/pmm/managed/models" + managementbackup "github.com/percona/pmm/managed/services/management/backup" +) + +// ErrClusterLocked is returned when there is an unfinished job that doesn't allow to change service cluster name. +var ErrClusterLocked = errors.New("cluster/service is locked") + +type MgmtServices struct { + BackupsService *managementbackup.BackupsService + ArtifactsService *managementbackup.ArtifactsService + RestoreHistoryService *managementbackup.RestoreHistoryService +} + +// RemoveScheduledTasks removes scheduled backup tasks and check there are no running backup/restore tasks in case user changes service cluster label. +func (s *MgmtServices) RemoveScheduledTasks(ctx context.Context, db *reform.DB, params *models.ChangeStandardLabelsParams) error { + if params.Cluster == nil { + return nil + } + + service, err := models.FindServiceByID(db.Querier, params.ServiceID) + if err != nil { + return err + } + + var servicesInCurrentCluster, servicesInNewCluster []*models.Service + + if service.Cluster != "" { + servicesInCurrentCluster, err = models.FindServices(db.Querier, models.ServiceFilters{Cluster: service.Cluster}) + if err != nil { + return err + } + } + + if *params.Cluster != "" { + servicesInNewCluster, err = models.FindServices(db.Querier, models.ServiceFilters{Cluster: *params.Cluster}) + if err != nil { + return err + } + } + + allServices := append(servicesInCurrentCluster, servicesInNewCluster...) //nolint:gocritic + allServices = append(allServices, service) + + sMap := make(map[string]struct{}) + for _, service := range allServices { + sMap[service.ServiceID] = struct{}{} + } + + scheduledTasks, err := s.BackupsService.ListScheduledBackups(ctx, &backuppb.ListScheduledBackupsRequest{}) + if err != nil { + return err + } + + // Remove scheduled tasks. + for _, task := range scheduledTasks.ScheduledBackups { + if _, ok := sMap[task.ServiceId]; ok { + _, err = s.BackupsService.RemoveScheduledBackup(ctx, &backuppb.RemoveScheduledBackupRequest{ScheduledBackupId: task.ScheduledBackupId}) + if err != nil { + return err + } + } + } + + // Check no backup tasks running. + artifacts, err := s.ArtifactsService.ListArtifacts(ctx, &backuppb.ListArtifactsRequest{}) + if err != nil { + return err + } + + statusNotFinal := func(status backuppb.BackupStatus) bool { + switch status { + case + backuppb.BackupStatus_BACKUP_STATUS_IN_PROGRESS, + backuppb.BackupStatus_BACKUP_STATUS_PENDING, + backuppb.BackupStatus_BACKUP_STATUS_PAUSED: + return true + default: + return false + } + } + + for _, artifact := range artifacts.Artifacts { + if _, ok := sMap[artifact.ServiceId]; ok && statusNotFinal(artifact.Status) { + return errors.Wrapf(ErrClusterLocked, "there is an unfinished backup job for service %s or other service in the same cluster", service.ServiceID) + } + } + + // Check no restore tasks running. + restores, err := s.RestoreHistoryService.ListRestoreHistory(ctx, &backuppb.ListRestoreHistoryRequest{}) + if err != nil { + return err + } + + for _, restoreItem := range restores.Items { + if _, ok := sMap[restoreItem.ServiceId]; ok && restoreItem.Status == backuppb.RestoreStatus_RESTORE_STATUS_IN_PROGRESS { + return errors.Wrapf(ErrClusterLocked, "there is an unfinished restore job for service %s or other service in the same cluster", service.ServiceID) + } + } + + return nil +}