diff --git a/api-tests/server/auth_test.go b/api-tests/server/auth_test.go index 0430f11d1e..a51d60b3dd 100644 --- a/api-tests/server/auth_test.go +++ b/api-tests/server/auth_test.go @@ -24,7 +24,6 @@ import ( "net/http/httputil" "net/url" "strconv" - "strings" "testing" "time" @@ -98,96 +97,6 @@ func TestAuth(t *testing.T) { }) } -func TestSetup(t *testing.T) { - t.Parallel() - // make a BaseURL without authentication - baseURL, err := url.Parse(pmmapitests.BaseURL.String()) - require.NoError(t, err) - baseURL.User = nil - - // make client that does not follow redirects - client := &http.Client{ - CheckRedirect: func(req *http.Request, via []*http.Request) error { - return http.ErrUseLastResponse - }, - } - - t.Run("WebPage", func(t *testing.T) { - t.Parallel() - - uri := baseURL.ResolveReference(&url.URL{ - Path: "/setup", - }) - t.Logf("URI: %s", uri) - req, err := http.NewRequestWithContext(pmmapitests.Context, http.MethodGet, uri.String(), nil) - require.NoError(t, err) - req.Header.Set("X-Test-Must-Setup", "1") - - resp, b := doRequest(t, client, req) //nolint:bodyclose - - assert.Equal(t, 200, resp.StatusCode, "response:\n%s", b) - assert.True(t, strings.HasPrefix(string(b), ``), string(b)) - }) - - t.Run("Redirect", func(t *testing.T) { - t.Parallel() - paths := map[string]int{ - "graph": 303, - "graph/": 303, - "prometheus": 303, - "prometheus/": 303, - "swagger": 200, - "swagger/": 301, - - "v1/server/readyz": 200, - "v1/server/AWSInstance": 400, // It must accept a parameter - "v1/server/version": 401, // Grafana authentication required - } - for path, code := range paths { - path, code := path, code - t.Run(fmt.Sprintf("%s=%d", path, code), func(t *testing.T) { - t.Parallel() - - uri := baseURL.ResolveReference(&url.URL{ - Path: path, - }) - t.Logf("URI: %s", uri) - req, err := http.NewRequestWithContext(pmmapitests.Context, http.MethodGet, uri.String(), nil) - require.NoError(t, err) - req.Header.Set("X-Test-Must-Setup", "1") - - resp, b := doRequest(t, client, req) //nolint:bodyclose - - assert.Equal(t, code, resp.StatusCode, "response:\n%s", b) - if code == 303 { - assert.Equal(t, "/setup", resp.Header.Get("Location")) - } - }) - } - }) - - t.Run("API", func(t *testing.T) { - t.Parallel() - - q := make(url.Values) - q.Set("instance_id", "123") - uri := baseURL.ResolveReference(&url.URL{ - Path: "v1/server/AWSInstance", - RawQuery: q.Encode(), - }) - t.Logf("URI: %s", uri) - require.NoError(t, err) - req, err := http.NewRequestWithContext(pmmapitests.Context, http.MethodGet, uri.String(), nil) - require.NoError(t, err) - req.Header.Set("X-Test-Must-Setup", "1") - - resp, b := doRequest(t, client, req) //nolint:bodyclose - - assert.Equal(t, 200, resp.StatusCode, "response:\n%s", b) - assert.Equal(t, "{}", string(b), "response:\n%s", b) - }) -} - func TestSwagger(t *testing.T) { t.Parallel() for _, path := range []string{ diff --git a/api/server/v1/json/client/server_service/aws_instance_check_parameters.go b/api/server/v1/json/client/server_service/aws_instance_check_parameters.go deleted file mode 100644 index 87f36dd758..0000000000 --- a/api/server/v1/json/client/server_service/aws_instance_check_parameters.go +++ /dev/null @@ -1,160 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - -package server_service - -// 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" -) - -// NewAWSInstanceCheckParams creates a new AWSInstanceCheckParams 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 NewAWSInstanceCheckParams() *AWSInstanceCheckParams { - return &AWSInstanceCheckParams{ - timeout: cr.DefaultTimeout, - } -} - -// NewAWSInstanceCheckParamsWithTimeout creates a new AWSInstanceCheckParams object -// with the ability to set a timeout on a request. -func NewAWSInstanceCheckParamsWithTimeout(timeout time.Duration) *AWSInstanceCheckParams { - return &AWSInstanceCheckParams{ - timeout: timeout, - } -} - -// NewAWSInstanceCheckParamsWithContext creates a new AWSInstanceCheckParams object -// with the ability to set a context for a request. -func NewAWSInstanceCheckParamsWithContext(ctx context.Context) *AWSInstanceCheckParams { - return &AWSInstanceCheckParams{ - Context: ctx, - } -} - -// NewAWSInstanceCheckParamsWithHTTPClient creates a new AWSInstanceCheckParams object -// with the ability to set a custom HTTPClient for a request. -func NewAWSInstanceCheckParamsWithHTTPClient(client *http.Client) *AWSInstanceCheckParams { - return &AWSInstanceCheckParams{ - HTTPClient: client, - } -} - -/* -AWSInstanceCheckParams contains all the parameters to send to the API endpoint - - for the AWS instance check operation. - - Typically these are written to a http.Request. -*/ -type AWSInstanceCheckParams struct { - /* InstanceID. - - AWS EC2 instance ID (i-1234567890abcdef0). - */ - InstanceID *string - - timeout time.Duration - Context context.Context - HTTPClient *http.Client -} - -// WithDefaults hydrates default values in the AWS instance check params (not the query body). -// -// All values with no default are reset to their zero value. -func (o *AWSInstanceCheckParams) WithDefaults() *AWSInstanceCheckParams { - o.SetDefaults() - return o -} - -// SetDefaults hydrates default values in the AWS instance check params (not the query body). -// -// All values with no default are reset to their zero value. -func (o *AWSInstanceCheckParams) SetDefaults() { - // no default values defined for this parameter -} - -// WithTimeout adds the timeout to the AWS instance check params -func (o *AWSInstanceCheckParams) WithTimeout(timeout time.Duration) *AWSInstanceCheckParams { - o.SetTimeout(timeout) - return o -} - -// SetTimeout adds the timeout to the AWS instance check params -func (o *AWSInstanceCheckParams) SetTimeout(timeout time.Duration) { - o.timeout = timeout -} - -// WithContext adds the context to the AWS instance check params -func (o *AWSInstanceCheckParams) WithContext(ctx context.Context) *AWSInstanceCheckParams { - o.SetContext(ctx) - return o -} - -// SetContext adds the context to the AWS instance check params -func (o *AWSInstanceCheckParams) SetContext(ctx context.Context) { - o.Context = ctx -} - -// WithHTTPClient adds the HTTPClient to the AWS instance check params -func (o *AWSInstanceCheckParams) WithHTTPClient(client *http.Client) *AWSInstanceCheckParams { - o.SetHTTPClient(client) - return o -} - -// SetHTTPClient adds the HTTPClient to the AWS instance check params -func (o *AWSInstanceCheckParams) SetHTTPClient(client *http.Client) { - o.HTTPClient = client -} - -// WithInstanceID adds the instanceID to the AWS instance check params -func (o *AWSInstanceCheckParams) WithInstanceID(instanceID *string) *AWSInstanceCheckParams { - o.SetInstanceID(instanceID) - return o -} - -// SetInstanceID adds the instanceId to the AWS instance check params -func (o *AWSInstanceCheckParams) SetInstanceID(instanceID *string) { - o.InstanceID = instanceID -} - -// WriteToRequest writes these params to a swagger request -func (o *AWSInstanceCheckParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error { - if err := r.SetTimeout(o.timeout); err != nil { - return err - } - var res []error - - if o.InstanceID != nil { - - // query param instance_id - var qrInstanceID string - - if o.InstanceID != nil { - qrInstanceID = *o.InstanceID - } - qInstanceID := qrInstanceID - if qInstanceID != "" { - if err := r.SetQueryParam("instance_id", qInstanceID); err != nil { - return err - } - } - } - - if len(res) > 0 { - return errors.CompositeValidationError(res...) - } - return nil -} diff --git a/api/server/v1/json/client/server_service/aws_instance_check_responses.go b/api/server/v1/json/client/server_service/aws_instance_check_responses.go deleted file mode 100644 index ed42e91f41..0000000000 --- a/api/server/v1/json/client/server_service/aws_instance_check_responses.go +++ /dev/null @@ -1,369 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - -package server_service - -// 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" -) - -// AWSInstanceCheckReader is a Reader for the AWSInstanceCheck structure. -type AWSInstanceCheckReader struct { - formats strfmt.Registry -} - -// ReadResponse reads a server response into the received o. -func (o *AWSInstanceCheckReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) { - switch response.Code() { - case 200: - result := NewAWSInstanceCheckOK() - if err := result.readResponse(response, consumer, o.formats); err != nil { - return nil, err - } - return result, nil - default: - result := NewAWSInstanceCheckDefault(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 - } -} - -// NewAWSInstanceCheckOK creates a AWSInstanceCheckOK with default headers values -func NewAWSInstanceCheckOK() *AWSInstanceCheckOK { - return &AWSInstanceCheckOK{} -} - -/* -AWSInstanceCheckOK describes a response with status code 200, with default header values. - -A successful response. -*/ -type AWSInstanceCheckOK struct { - Payload interface{} -} - -func (o *AWSInstanceCheckOK) Error() string { - return fmt.Sprintf("[GET /v1/server/AWSInstance][%d] awsInstanceCheckOk %+v", 200, o.Payload) -} - -func (o *AWSInstanceCheckOK) GetPayload() interface{} { - return o.Payload -} - -func (o *AWSInstanceCheckOK) 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 -} - -// NewAWSInstanceCheckDefault creates a AWSInstanceCheckDefault with default headers values -func NewAWSInstanceCheckDefault(code int) *AWSInstanceCheckDefault { - return &AWSInstanceCheckDefault{ - _statusCode: code, - } -} - -/* -AWSInstanceCheckDefault describes a response with status code -1, with default header values. - -An unexpected error response. -*/ -type AWSInstanceCheckDefault struct { - _statusCode int - - Payload *AWSInstanceCheckDefaultBody -} - -// Code gets the status code for the AWS instance check default response -func (o *AWSInstanceCheckDefault) Code() int { - return o._statusCode -} - -func (o *AWSInstanceCheckDefault) Error() string { - return fmt.Sprintf("[GET /v1/server/AWSInstance][%d] AWSInstanceCheck default %+v", o._statusCode, o.Payload) -} - -func (o *AWSInstanceCheckDefault) GetPayload() *AWSInstanceCheckDefaultBody { - return o.Payload -} - -func (o *AWSInstanceCheckDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { - o.Payload = new(AWSInstanceCheckDefaultBody) - - // response payload - if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { - return err - } - - return nil -} - -/* -AWSInstanceCheckDefaultBody AWS instance check default body -swagger:model AWSInstanceCheckDefaultBody -*/ -type AWSInstanceCheckDefaultBody struct { - // code - Code int32 `json:"code,omitempty"` - - // message - Message string `json:"message,omitempty"` - - // details - Details []*AWSInstanceCheckDefaultBodyDetailsItems0 `json:"details"` -} - -// Validate validates this AWS instance check default body -func (o *AWSInstanceCheckDefaultBody) 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 *AWSInstanceCheckDefaultBody) 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("AWSInstanceCheck default" + "." + "details" + "." + strconv.Itoa(i)) - } else if ce, ok := err.(*errors.CompositeError); ok { - return ce.ValidateName("AWSInstanceCheck default" + "." + "details" + "." + strconv.Itoa(i)) - } - return err - } - } - - } - - return nil -} - -// ContextValidate validate this AWS instance check default body based on the context it is used -func (o *AWSInstanceCheckDefaultBody) 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 *AWSInstanceCheckDefaultBody) 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("AWSInstanceCheck default" + "." + "details" + "." + strconv.Itoa(i)) - } else if ce, ok := err.(*errors.CompositeError); ok { - return ce.ValidateName("AWSInstanceCheck default" + "." + "details" + "." + strconv.Itoa(i)) - } - return err - } - } - } - - return nil -} - -// MarshalBinary interface implementation -func (o *AWSInstanceCheckDefaultBody) MarshalBinary() ([]byte, error) { - if o == nil { - return nil, nil - } - return swag.WriteJSON(o) -} - -// UnmarshalBinary interface implementation -func (o *AWSInstanceCheckDefaultBody) UnmarshalBinary(b []byte) error { - var res AWSInstanceCheckDefaultBody - if err := swag.ReadJSON(b, &res); err != nil { - return err - } - *o = res - return nil -} - -/* -AWSInstanceCheckDefaultBodyDetailsItems0 `Any` contains an arbitrary serialized protocol buffer message along with a -// URL that describes the type of the serialized message. -// -// Protobuf library provides support to pack/unpack Any values in the form -// of utility functions or additional generated methods of the Any type. -// -// Example 1: Pack and unpack a message in C++. -// -// Foo foo = ...; -// Any any; -// any.PackFrom(foo); -// ... -// if (any.UnpackTo(&foo)) { -// ... -// } -// -// Example 2: Pack and unpack a message in Java. -// -// Foo foo = ...; -// Any any = Any.pack(foo); -// ... -// if (any.is(Foo.class)) { -// foo = any.unpack(Foo.class); -// } -// // or ... -// if (any.isSameTypeAs(Foo.getDefaultInstance())) { -// foo = any.unpack(Foo.getDefaultInstance()); -// } -// -// Example 3: Pack and unpack a message in Python. -// -// foo = Foo(...) -// any = Any() -// any.Pack(foo) -// ... -// if any.Is(Foo.DESCRIPTOR): -// any.Unpack(foo) -// ... -// -// Example 4: Pack and unpack a message in Go -// -// foo := &pb.Foo{...} -// any, err := anypb.New(foo) -// if err != nil { -// ... -// } -// ... -// foo := &pb.Foo{} -// if err := any.UnmarshalTo(foo); err != nil { -// ... -// } -// -// The pack methods provided by protobuf library will by default use -// 'type.googleapis.com/full.type.name' as the type URL and the unpack -// methods only use the fully qualified type name after the last '/' -// in the type URL, for example "foo.bar.com/x/y.z" will yield type -// name "y.z". -// -// JSON -// ==== -// The JSON representation of an `Any` value uses the regular -// representation of the deserialized, embedded message, with an -// additional field `@type` which contains the type URL. Example: -// -// package google.profile; -// message Person { -// string first_name = 1; -// string last_name = 2; -// } -// -// { -// "@type": "type.googleapis.com/google.profile.Person", -// "firstName": , -// "lastName": -// } -// -// If the embedded message type is well-known and has a custom JSON -// representation, that representation will be embedded adding a field -// `value` which holds the custom JSON in addition to the `@type` -// field. Example (for message [google.protobuf.Duration][]): -// -// { -// "@type": "type.googleapis.com/google.protobuf.Duration", -// "value": "1.212s" -// } -swagger:model AWSInstanceCheckDefaultBodyDetailsItems0 -*/ -type AWSInstanceCheckDefaultBodyDetailsItems0 struct { - // A URL/resource name that uniquely identifies the type of the serialized - // protocol buffer message. This string must contain at least - // one "/" character. The last segment of the URL's path must represent - // the fully qualified name of the type (as in - // `path/google.protobuf.Duration`). The name should be in a canonical form - // (e.g., leading "." is not accepted). - // - // In practice, teams usually precompile into the binary all types that they - // expect it to use in the context of Any. However, for URLs which use the - // scheme `http`, `https`, or no scheme, one can optionally set up a type - // server that maps type URLs to message definitions as follows: - // - // * If no scheme is provided, `https` is assumed. - // * An HTTP GET on the URL must yield a [google.protobuf.Type][] - // value in binary format, or produce an error. - // * Applications are allowed to cache lookup results based on the - // URL, or have them precompiled into a binary to avoid any - // lookup. Therefore, binary compatibility needs to be preserved - // on changes to types. (Use versioned type names to manage - // breaking changes.) - // - // Note: this functionality is not currently available in the official - // protobuf release, and it is not used for type URLs beginning with - // type.googleapis.com. As of May 2023, there are no widely used type server - // implementations and no plans to implement one. - // - // Schemes other than `http`, `https` (or the empty scheme) might be - // used with implementation specific semantics. - AtType string `json:"@type,omitempty"` -} - -// Validate validates this AWS instance check default body details items0 -func (o *AWSInstanceCheckDefaultBodyDetailsItems0) Validate(formats strfmt.Registry) error { - return nil -} - -// ContextValidate validates this AWS instance check default body details items0 based on context it is used -func (o *AWSInstanceCheckDefaultBodyDetailsItems0) ContextValidate(ctx context.Context, formats strfmt.Registry) error { - return nil -} - -// MarshalBinary interface implementation -func (o *AWSInstanceCheckDefaultBodyDetailsItems0) MarshalBinary() ([]byte, error) { - if o == nil { - return nil, nil - } - return swag.WriteJSON(o) -} - -// UnmarshalBinary interface implementation -func (o *AWSInstanceCheckDefaultBodyDetailsItems0) UnmarshalBinary(b []byte) error { - var res AWSInstanceCheckDefaultBodyDetailsItems0 - if err := swag.ReadJSON(b, &res); err != nil { - return err - } - *o = res - return nil -} diff --git a/api/server/v1/json/client/server_service/server_service_client.go b/api/server/v1/json/client/server_service/server_service_client.go index 11343140a9..4d1cd044ff 100644 --- a/api/server/v1/json/client/server_service/server_service_client.go +++ b/api/server/v1/json/client/server_service/server_service_client.go @@ -30,8 +30,6 @@ type ClientOption func(*runtime.ClientOperation) // ClientService is the interface for Client methods type ClientService interface { - AWSInstanceCheck(params *AWSInstanceCheckParams, opts ...ClientOption) (*AWSInstanceCheckOK, error) - ChangeSettings(params *ChangeSettingsParams, opts ...ClientOption) (*ChangeSettingsOK, error) CheckUpdates(params *CheckUpdatesParams, opts ...ClientOption) (*CheckUpdatesOK, error) @@ -53,45 +51,6 @@ type ClientService interface { SetTransport(transport runtime.ClientTransport) } -/* -AWSInstanceCheck AWSs instance check - -Checks AWS EC2 instance ID. -*/ -func (a *Client) AWSInstanceCheck(params *AWSInstanceCheckParams, opts ...ClientOption) (*AWSInstanceCheckOK, error) { - // TODO: Validate the params before sending - if params == nil { - params = NewAWSInstanceCheckParams() - } - op := &runtime.ClientOperation{ - ID: "AWSInstanceCheck", - Method: "GET", - PathPattern: "/v1/server/AWSInstance", - ProducesMediaTypes: []string{"application/json"}, - ConsumesMediaTypes: []string{"application/json"}, - Schemes: []string{"http", "https"}, - Params: params, - Reader: &AWSInstanceCheckReader{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.(*AWSInstanceCheckOK) - if ok { - return success, nil - } - // unexpected success response - unexpectedSuccess := result.(*AWSInstanceCheckDefault) - return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) -} - /* ChangeSettings changes settings diff --git a/api/server/v1/json/v1.json b/api/server/v1/json/v1.json index 7831e9a4fa..a47880959b 100644 --- a/api/server/v1/json/v1.json +++ b/api/server/v1/json/v1.json @@ -15,65 +15,6 @@ "version": "v1" }, "paths": { - "/v1/server/AWSInstance": { - "get": { - "description": "Checks AWS EC2 instance ID.", - "tags": [ - "ServerService" - ], - "summary": "AWS instance check", - "operationId": "AWSInstanceCheck", - "parameters": [ - { - "type": "string", - "description": "AWS EC2 instance ID (i-1234567890abcdef0).", - "name": "instance_id", - "in": "query" - } - ], - "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": { - "description": "`Any` contains an arbitrary serialized protocol buffer message along with a\nURL that describes the type of the serialized message.\n\nProtobuf library provides support to pack/unpack Any values in the form\nof utility functions or additional generated methods of the Any type.\n\nExample 1: Pack and unpack a message in C++.\n\n Foo foo = ...;\n Any any;\n any.PackFrom(foo);\n ...\n if (any.UnpackTo(\u0026foo)) {\n ...\n }\n\nExample 2: Pack and unpack a message in Java.\n\n Foo foo = ...;\n Any any = Any.pack(foo);\n ...\n if (any.is(Foo.class)) {\n foo = any.unpack(Foo.class);\n }\n // or ...\n if (any.isSameTypeAs(Foo.getDefaultInstance())) {\n foo = any.unpack(Foo.getDefaultInstance());\n }\n\n Example 3: Pack and unpack a message in Python.\n\n foo = Foo(...)\n any = Any()\n any.Pack(foo)\n ...\n if any.Is(Foo.DESCRIPTOR):\n any.Unpack(foo)\n ...\n\n Example 4: Pack and unpack a message in Go\n\n foo := \u0026pb.Foo{...}\n any, err := anypb.New(foo)\n if err != nil {\n ...\n }\n ...\n foo := \u0026pb.Foo{}\n if err := any.UnmarshalTo(foo); err != nil {\n ...\n }\n\nThe pack methods provided by protobuf library will by default use\n'type.googleapis.com/full.type.name' as the type URL and the unpack\nmethods only use the fully qualified type name after the last '/'\nin the type URL, for example \"foo.bar.com/x/y.z\" will yield type\nname \"y.z\".\n\nJSON\n====\nThe JSON representation of an `Any` value uses the regular\nrepresentation of the deserialized, embedded message, with an\nadditional field `@type` which contains the type URL. Example:\n\n package google.profile;\n message Person {\n string first_name = 1;\n string last_name = 2;\n }\n\n {\n \"@type\": \"type.googleapis.com/google.profile.Person\",\n \"firstName\": \u003cstring\u003e,\n \"lastName\": \u003cstring\u003e\n }\n\nIf the embedded message type is well-known and has a custom JSON\nrepresentation, that representation will be embedded adding a field\n`value` which holds the custom JSON in addition to the `@type`\nfield. Example (for message [google.protobuf.Duration][]):\n\n {\n \"@type\": \"type.googleapis.com/google.protobuf.Duration\",\n \"value\": \"1.212s\"\n }", - "type": "object", - "properties": { - "@type": { - "description": "A URL/resource name that uniquely identifies the type of the serialized\nprotocol buffer message. This string must contain at least\none \"/\" character. The last segment of the URL's path must represent\nthe fully qualified name of the type (as in\n`path/google.protobuf.Duration`). The name should be in a canonical form\n(e.g., leading \".\" is not accepted).\n\nIn practice, teams usually precompile into the binary all types that they\nexpect it to use in the context of Any. However, for URLs which use the\nscheme `http`, `https`, or no scheme, one can optionally set up a type\nserver that maps type URLs to message definitions as follows:\n\n* If no scheme is provided, `https` is assumed.\n* An HTTP GET on the URL must yield a [google.protobuf.Type][]\n value in binary format, or produce an error.\n* Applications are allowed to cache lookup results based on the\n URL, or have them precompiled into a binary to avoid any\n lookup. Therefore, binary compatibility needs to be preserved\n on changes to types. (Use versioned type names to manage\n breaking changes.)\n\nNote: this functionality is not currently available in the official\nprotobuf release, and it is not used for type URLs beginning with\ntype.googleapis.com. As of May 2023, there are no widely used type server\nimplementations and no plans to implement one.\n\nSchemes other than `http`, `https` (or the empty scheme) might be\nused with implementation specific semantics.", - "type": "string", - "x-order": 0 - } - }, - "additionalProperties": false - }, - "x-order": 2 - }, - "message": { - "type": "string", - "x-order": 1 - } - } - } - } - } - } - }, "/v1/server/leaderHealthCheck": { "get": { "description": "Checks if the instance is the leader in a cluster. Returns an error if the instance isn't the leader.", diff --git a/api/server/v1/server.pb.go b/api/server/v1/server.pb.go index ff671a9f28..fd1eccccee 100644 --- a/api/server/v1/server.pb.go +++ b/api/server/v1/server.pb.go @@ -1469,92 +1469,6 @@ func (x *ChangeSettingsResponse) GetSettings() *Settings { return nil } -type AWSInstanceCheckRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // AWS EC2 instance ID (i-1234567890abcdef0). - InstanceId string `protobuf:"bytes,1,opt,name=instance_id,json=instanceId,proto3" json:"instance_id,omitempty"` -} - -func (x *AWSInstanceCheckRequest) Reset() { - *x = AWSInstanceCheckRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_server_v1_server_proto_msgTypes[21] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *AWSInstanceCheckRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AWSInstanceCheckRequest) ProtoMessage() {} - -func (x *AWSInstanceCheckRequest) ProtoReflect() protoreflect.Message { - mi := &file_server_v1_server_proto_msgTypes[21] - 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 AWSInstanceCheckRequest.ProtoReflect.Descriptor instead. -func (*AWSInstanceCheckRequest) Descriptor() ([]byte, []int) { - return file_server_v1_server_proto_rawDescGZIP(), []int{21} -} - -func (x *AWSInstanceCheckRequest) GetInstanceId() string { - if x != nil { - return x.InstanceId - } - return "" -} - -type AWSInstanceCheckResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *AWSInstanceCheckResponse) Reset() { - *x = AWSInstanceCheckResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_server_v1_server_proto_msgTypes[22] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *AWSInstanceCheckResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AWSInstanceCheckResponse) ProtoMessage() {} - -func (x *AWSInstanceCheckResponse) ProtoReflect() protoreflect.Message { - mi := &file_server_v1_server_proto_msgTypes[22] - 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 AWSInstanceCheckResponse.ProtoReflect.Descriptor instead. -func (*AWSInstanceCheckResponse) Descriptor() ([]byte, []int) { - return file_server_v1_server_proto_rawDescGZIP(), []int{22} -} - var File_server_v1_server_proto protoreflect.FileDescriptor var file_server_v1_server_proto_rawDesc = []byte{ @@ -1804,144 +1718,127 @@ var file_server_v1_server_proto_rawDesc = []byte{ 0x12, 0x2f, 0x0a, 0x08, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x08, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, - 0x73, 0x22, 0x43, 0x0a, 0x17, 0x41, 0x57, 0x53, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, - 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, 0x0a, 0x0b, - 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, - 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x22, 0x1a, 0x0a, 0x18, 0x41, 0x57, 0x53, 0x49, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x2a, 0xce, 0x01, 0x0a, 0x12, 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x23, 0x0a, 0x1f, 0x44, 0x49, 0x53, - 0x54, 0x52, 0x49, 0x42, 0x55, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, - 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1e, - 0x0a, 0x1a, 0x44, 0x49, 0x53, 0x54, 0x52, 0x49, 0x42, 0x55, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4d, - 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x44, 0x4f, 0x43, 0x4b, 0x45, 0x52, 0x10, 0x01, 0x12, 0x1b, - 0x0a, 0x17, 0x44, 0x49, 0x53, 0x54, 0x52, 0x49, 0x42, 0x55, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4d, - 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x4f, 0x56, 0x46, 0x10, 0x02, 0x12, 0x1b, 0x0a, 0x17, 0x44, - 0x49, 0x53, 0x54, 0x52, 0x49, 0x42, 0x55, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4d, 0x45, 0x54, 0x48, - 0x4f, 0x44, 0x5f, 0x41, 0x4d, 0x49, 0x10, 0x03, 0x12, 0x1d, 0x0a, 0x19, 0x44, 0x49, 0x53, 0x54, + 0x73, 0x2a, 0xce, 0x01, 0x0a, 0x12, 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, + 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x23, 0x0a, 0x1f, 0x44, 0x49, 0x53, 0x54, 0x52, 0x49, 0x42, 0x55, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, - 0x41, 0x5a, 0x55, 0x52, 0x45, 0x10, 0x04, 0x12, 0x1a, 0x0a, 0x16, 0x44, 0x49, 0x53, 0x54, 0x52, - 0x49, 0x42, 0x55, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x44, - 0x4f, 0x10, 0x05, 0x32, 0xc3, 0x0d, 0x0a, 0x0d, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x86, 0x01, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x12, 0x19, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x44, 0x92, 0x41, 0x27, 0x12, 0x07, 0x56, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x1a, 0x1c, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, - 0x50, 0x4d, 0x4d, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x73, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x14, 0x12, 0x12, 0x2f, 0x76, 0x31, 0x2f, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0xab, - 0x02, 0x0a, 0x09, 0x52, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x12, 0x1b, 0x2e, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x65, - 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xe2, 0x01, 0x92, 0x41, 0xc5, 0x01, 0x12, 0x16, - 0x43, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x72, 0x65, 0x61, - 0x64, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x1a, 0xaa, 0x01, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, - 0x20, 0x61, 0x6e, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x53, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x73, - 0x20, 0x62, 0x65, 0x69, 0x6e, 0x67, 0x20, 0x72, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, - 0x20, 0x61, 0x72, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x72, 0x65, 0x61, 0x64, 0x79, 0x20, 0x79, - 0x65, 0x74, 0x2e, 0x20, 0x55, 0x73, 0x65, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x41, 0x50, 0x49, - 0x20, 0x66, 0x6f, 0x72, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, - 0x65, 0x20, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x20, 0x6f, 0x66, 0x20, 0x44, 0x6f, 0x63, 0x6b, - 0x65, 0x72, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x20, 0x61, 0x6e, - 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x70, 0x72, 0x6f, 0x62, 0x69, 0x6e, 0x67, 0x20, 0x4b, 0x75, - 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x20, 0x72, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x65, - 0x73, 0x73, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x12, 0x11, 0x2f, 0x76, 0x31, 0x2f, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x72, 0x65, 0x61, 0x64, 0x79, 0x7a, 0x12, 0x81, 0x02, 0x0a, - 0x11, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, - 0x63, 0x6b, 0x12, 0x23, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, - 0x65, 0x61, 0x64, 0x65, 0x72, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, - 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xa0, 0x01, - 0x92, 0x41, 0x79, 0x12, 0x10, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x4c, 0x65, 0x61, 0x64, 0x65, - 0x72, 0x73, 0x68, 0x69, 0x70, 0x1a, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x20, 0x69, 0x66, - 0x20, 0x74, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x69, 0x73, - 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x20, 0x61, - 0x20, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x20, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, - 0x73, 0x20, 0x61, 0x6e, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x69, 0x66, 0x20, 0x74, 0x68, - 0x65, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x69, 0x73, 0x6e, 0x27, 0x74, - 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x1e, 0x12, 0x1c, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x6c, - 0x65, 0x61, 0x64, 0x65, 0x72, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, - 0x12, 0xa7, 0x01, 0x0a, 0x0c, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x73, 0x12, 0x1e, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, - 0x65, 0x63, 0x6b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x1f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, - 0x65, 0x63, 0x6b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x56, 0x92, 0x41, 0x39, 0x12, 0x0d, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x75, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x1a, 0x28, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x20, 0x66, - 0x6f, 0x72, 0x20, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x50, 0x4d, 0x4d, - 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x2e, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x14, 0x12, 0x12, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x2f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x12, 0x9d, 0x01, 0x0a, 0x0b, 0x53, - 0x74, 0x61, 0x72, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x1d, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x73, 0x65, 0x72, 0x76, + 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1e, 0x0a, + 0x1a, 0x44, 0x49, 0x53, 0x54, 0x52, 0x49, 0x42, 0x55, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4d, 0x45, + 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x44, 0x4f, 0x43, 0x4b, 0x45, 0x52, 0x10, 0x01, 0x12, 0x1b, 0x0a, + 0x17, 0x44, 0x49, 0x53, 0x54, 0x52, 0x49, 0x42, 0x55, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4d, 0x45, + 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x4f, 0x56, 0x46, 0x10, 0x02, 0x12, 0x1b, 0x0a, 0x17, 0x44, 0x49, + 0x53, 0x54, 0x52, 0x49, 0x42, 0x55, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, + 0x44, 0x5f, 0x41, 0x4d, 0x49, 0x10, 0x03, 0x12, 0x1d, 0x0a, 0x19, 0x44, 0x49, 0x53, 0x54, 0x52, + 0x49, 0x42, 0x55, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x41, + 0x5a, 0x55, 0x52, 0x45, 0x10, 0x04, 0x12, 0x1a, 0x0a, 0x16, 0x44, 0x49, 0x53, 0x54, 0x52, 0x49, + 0x42, 0x55, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x44, 0x4f, + 0x10, 0x05, 0x32, 0x91, 0x0c, 0x0a, 0x0d, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x12, 0x86, 0x01, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x12, 0x19, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x44, 0x92, 0x41, 0x27, 0x12, 0x07, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x1a, 0x1c, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x50, + 0x4d, 0x4d, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x73, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x14, 0x12, 0x12, 0x2f, 0x76, 0x31, 0x2f, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0xab, 0x02, + 0x0a, 0x09, 0x52, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x12, 0x1b, 0x2e, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x65, 0x73, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xe2, 0x01, 0x92, 0x41, 0xc5, 0x01, 0x12, 0x16, 0x43, + 0x68, 0x65, 0x63, 0x6b, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x72, 0x65, 0x61, 0x64, + 0x69, 0x6e, 0x65, 0x73, 0x73, 0x1a, 0xaa, 0x01, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, + 0x61, 0x6e, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x53, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x73, 0x20, + 0x62, 0x65, 0x69, 0x6e, 0x67, 0x20, 0x72, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x20, + 0x61, 0x72, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x72, 0x65, 0x61, 0x64, 0x79, 0x20, 0x79, 0x65, + 0x74, 0x2e, 0x20, 0x55, 0x73, 0x65, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x41, 0x50, 0x49, 0x20, + 0x66, 0x6f, 0x72, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x20, 0x6f, 0x66, 0x20, 0x44, 0x6f, 0x63, 0x6b, 0x65, + 0x72, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x20, 0x61, 0x6e, 0x64, + 0x20, 0x66, 0x6f, 0x72, 0x20, 0x70, 0x72, 0x6f, 0x62, 0x69, 0x6e, 0x67, 0x20, 0x4b, 0x75, 0x62, + 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x20, 0x72, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x65, 0x73, + 0x73, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x12, 0x11, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x2f, 0x72, 0x65, 0x61, 0x64, 0x79, 0x7a, 0x12, 0x81, 0x02, 0x0a, 0x11, + 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, + 0x6b, 0x12, 0x23, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x65, + 0x61, 0x64, 0x65, 0x72, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, + 0x76, 0x31, 0x2e, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, + 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xa0, 0x01, 0x92, + 0x41, 0x79, 0x12, 0x10, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, + 0x73, 0x68, 0x69, 0x70, 0x1a, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x20, 0x69, 0x66, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x69, 0x73, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x6c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x20, + 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x20, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, + 0x20, 0x61, 0x6e, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x69, 0x66, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x69, 0x73, 0x6e, 0x27, 0x74, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x6c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x1e, 0x12, 0x1c, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x6c, 0x65, + 0x61, 0x64, 0x65, 0x72, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, + 0xa7, 0x01, 0x0a, 0x0c, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, + 0x12, 0x1e, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x65, + 0x63, 0x6b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x1f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x65, + 0x63, 0x6b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x56, 0x92, 0x41, 0x39, 0x12, 0x0d, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x75, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x73, 0x1a, 0x28, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x20, 0x66, 0x6f, + 0x72, 0x20, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x50, 0x4d, 0x4d, 0x20, + 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x2e, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x14, 0x12, 0x12, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x2f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x12, 0x9d, 0x01, 0x0a, 0x0b, 0x53, 0x74, + 0x61, 0x72, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x1d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4f, 0x92, 0x41, 0x29, 0x12, 0x0c, - 0x53, 0x74, 0x61, 0x72, 0x74, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x1a, 0x19, 0x53, 0x74, - 0x61, 0x72, 0x74, 0x73, 0x20, 0x50, 0x4d, 0x4d, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, - 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x3a, 0x01, 0x2a, - 0x22, 0x18, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x75, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x73, 0x3a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0xad, 0x01, 0x0a, 0x0c, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1e, 0x2e, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x5c, 0x92, 0x41, - 0x32, 0x12, 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x1a, 0x21, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x50, 0x4d, 0x4d, 0x20, 0x53, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x73, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x21, 0x3a, 0x01, 0x2a, 0x22, 0x1c, 0x2f, 0x76, - 0x31, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, - 0x3a, 0x67, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0xa0, 0x01, 0x0a, 0x0b, 0x47, - 0x65, 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x1d, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, - 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4f, 0x92, 0x41, 0x29, 0x12, 0x0c, 0x53, + 0x74, 0x61, 0x72, 0x74, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x1a, 0x19, 0x53, 0x74, 0x61, + 0x72, 0x74, 0x73, 0x20, 0x50, 0x4d, 0x4d, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x75, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x3a, 0x01, 0x2a, 0x22, + 0x18, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x75, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x73, 0x3a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0xad, 0x01, 0x0a, 0x0c, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1e, 0x2e, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x5c, 0x92, 0x41, 0x32, + 0x12, 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x1a, + 0x21, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x50, 0x4d, 0x4d, 0x20, 0x53, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x21, 0x3a, 0x01, 0x2a, 0x22, 0x1c, 0x2f, 0x76, 0x31, + 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x3a, + 0x67, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0xa0, 0x01, 0x0a, 0x0b, 0x47, 0x65, + 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x1d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x52, 0x92, 0x41, 0x34, 0x12, 0x0c, - 0x47, 0x65, 0x74, 0x20, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x1a, 0x24, 0x52, 0x65, - 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x50, 0x4d, - 0x4d, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, - 0x73, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x12, 0x13, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x2f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0xa7, 0x01, - 0x0a, 0x0e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, - 0x12, 0x20, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, - 0x6e, 0x67, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, - 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x50, 0x92, 0x41, 0x2f, 0x12, 0x0f, 0x43, 0x68, 0x61, 0x6e, - 0x67, 0x65, 0x20, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x1a, 0x1c, 0x43, 0x68, 0x61, - 0x6e, 0x67, 0x65, 0x73, 0x20, 0x50, 0x4d, 0x4d, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, - 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x3a, - 0x01, 0x2a, 0x1a, 0x13, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x73, - 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0xaf, 0x01, 0x0a, 0x10, 0x41, 0x57, 0x53, 0x49, - 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x22, 0x2e, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x57, 0x53, 0x49, 0x6e, 0x73, 0x74, - 0x61, 0x6e, 0x63, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x23, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x57, 0x53, - 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x52, 0x92, 0x41, 0x31, 0x12, 0x12, 0x41, 0x57, 0x53, 0x20, - 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x1a, 0x1b, - 0x43, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x20, 0x41, 0x57, 0x53, 0x20, 0x45, 0x43, 0x32, 0x20, 0x69, - 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x49, 0x44, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x18, 0x12, 0x16, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x41, 0x57, - 0x53, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x42, 0x90, 0x01, 0x0a, 0x0d, 0x63, 0x6f, - 0x6d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x42, 0x0b, 0x53, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2d, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x61, 0x2f, 0x70, - 0x6d, 0x6d, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x76, 0x31, - 0x3b, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x53, 0x58, 0x58, 0xaa, - 0x02, 0x09, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x09, 0x53, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x15, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, - 0x02, 0x0a, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x52, 0x92, 0x41, 0x34, 0x12, 0x0c, 0x47, + 0x65, 0x74, 0x20, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x1a, 0x24, 0x52, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x73, 0x20, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x50, 0x4d, 0x4d, + 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, + 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x12, 0x13, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x2f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0xa7, 0x01, 0x0a, + 0x0e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, + 0x20, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x21, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, + 0x61, 0x6e, 0x67, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x50, 0x92, 0x41, 0x2f, 0x12, 0x0f, 0x43, 0x68, 0x61, 0x6e, 0x67, + 0x65, 0x20, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x1a, 0x1c, 0x43, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x73, 0x20, 0x50, 0x4d, 0x4d, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73, + 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x3a, 0x01, + 0x2a, 0x1a, 0x13, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x73, 0x65, + 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x42, 0x90, 0x01, 0x0a, 0x0d, 0x63, 0x6f, 0x6d, 0x2e, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x42, 0x0b, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x61, 0x2f, 0x70, 0x6d, 0x6d, 0x2f, + 0x61, 0x70, 0x69, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x3b, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x53, 0x58, 0x58, 0xaa, 0x02, 0x09, 0x53, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x09, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x15, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5c, 0x56, 0x31, + 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0a, 0x53, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, } var ( @@ -1958,7 +1855,7 @@ func file_server_v1_server_proto_rawDescGZIP() []byte { var ( file_server_v1_server_proto_enumTypes = make([]protoimpl.EnumInfo, 1) - file_server_v1_server_proto_msgTypes = make([]protoimpl.MessageInfo, 23) + file_server_v1_server_proto_msgTypes = make([]protoimpl.MessageInfo, 21) file_server_v1_server_proto_goTypes = []any{ (DistributionMethod)(0), // 0: server.v1.DistributionMethod (*VersionInfo)(nil), // 1: server.v1.VersionInfo @@ -1982,36 +1879,34 @@ var ( (*GetSettingsResponse)(nil), // 19: server.v1.GetSettingsResponse (*ChangeSettingsRequest)(nil), // 20: server.v1.ChangeSettingsRequest (*ChangeSettingsResponse)(nil), // 21: server.v1.ChangeSettingsResponse - (*AWSInstanceCheckRequest)(nil), // 22: server.v1.AWSInstanceCheckRequest - (*AWSInstanceCheckResponse)(nil), // 23: server.v1.AWSInstanceCheckResponse - (*timestamppb.Timestamp)(nil), // 24: google.protobuf.Timestamp - (*durationpb.Duration)(nil), // 25: google.protobuf.Duration - (*common.StringArray)(nil), // 26: common.StringArray + (*timestamppb.Timestamp)(nil), // 22: google.protobuf.Timestamp + (*durationpb.Duration)(nil), // 23: google.protobuf.Duration + (*common.StringArray)(nil), // 24: common.StringArray } ) var file_server_v1_server_proto_depIdxs = []int32{ - 24, // 0: server.v1.VersionInfo.timestamp:type_name -> google.protobuf.Timestamp + 22, // 0: server.v1.VersionInfo.timestamp:type_name -> google.protobuf.Timestamp 1, // 1: server.v1.VersionResponse.server:type_name -> server.v1.VersionInfo 1, // 2: server.v1.VersionResponse.managed:type_name -> server.v1.VersionInfo 0, // 3: server.v1.VersionResponse.distribution_method:type_name -> server.v1.DistributionMethod - 24, // 4: server.v1.DockerVersionInfo.timestamp:type_name -> google.protobuf.Timestamp + 22, // 4: server.v1.DockerVersionInfo.timestamp:type_name -> google.protobuf.Timestamp 1, // 5: server.v1.CheckUpdatesResponse.installed:type_name -> server.v1.VersionInfo 9, // 6: server.v1.CheckUpdatesResponse.latest:type_name -> server.v1.DockerVersionInfo - 24, // 7: server.v1.CheckUpdatesResponse.last_check:type_name -> google.protobuf.Timestamp - 25, // 8: server.v1.MetricsResolutions.hr:type_name -> google.protobuf.Duration - 25, // 9: server.v1.MetricsResolutions.mr:type_name -> google.protobuf.Duration - 25, // 10: server.v1.MetricsResolutions.lr:type_name -> google.protobuf.Duration - 25, // 11: server.v1.AdvisorRunIntervals.standard_interval:type_name -> google.protobuf.Duration - 25, // 12: server.v1.AdvisorRunIntervals.rare_interval:type_name -> google.protobuf.Duration - 25, // 13: server.v1.AdvisorRunIntervals.frequent_interval:type_name -> google.protobuf.Duration + 22, // 7: server.v1.CheckUpdatesResponse.last_check:type_name -> google.protobuf.Timestamp + 23, // 8: server.v1.MetricsResolutions.hr:type_name -> google.protobuf.Duration + 23, // 9: server.v1.MetricsResolutions.mr:type_name -> google.protobuf.Duration + 23, // 10: server.v1.MetricsResolutions.lr:type_name -> google.protobuf.Duration + 23, // 11: server.v1.AdvisorRunIntervals.standard_interval:type_name -> google.protobuf.Duration + 23, // 12: server.v1.AdvisorRunIntervals.rare_interval:type_name -> google.protobuf.Duration + 23, // 13: server.v1.AdvisorRunIntervals.frequent_interval:type_name -> google.protobuf.Duration 15, // 14: server.v1.Settings.metrics_resolutions:type_name -> server.v1.MetricsResolutions - 25, // 15: server.v1.Settings.data_retention:type_name -> google.protobuf.Duration + 23, // 15: server.v1.Settings.data_retention:type_name -> google.protobuf.Duration 16, // 16: server.v1.Settings.advisor_run_intervals:type_name -> server.v1.AdvisorRunIntervals 17, // 17: server.v1.GetSettingsResponse.settings:type_name -> server.v1.Settings 15, // 18: server.v1.ChangeSettingsRequest.metrics_resolutions:type_name -> server.v1.MetricsResolutions - 25, // 19: server.v1.ChangeSettingsRequest.data_retention:type_name -> google.protobuf.Duration - 26, // 20: server.v1.ChangeSettingsRequest.aws_partitions:type_name -> common.StringArray + 23, // 19: server.v1.ChangeSettingsRequest.data_retention:type_name -> google.protobuf.Duration + 24, // 20: server.v1.ChangeSettingsRequest.aws_partitions:type_name -> common.StringArray 16, // 21: server.v1.ChangeSettingsRequest.advisor_run_intervals:type_name -> server.v1.AdvisorRunIntervals 17, // 22: server.v1.ChangeSettingsResponse.settings:type_name -> server.v1.Settings 2, // 23: server.v1.ServerService.Version:input_type -> server.v1.VersionRequest @@ -2022,18 +1917,16 @@ var file_server_v1_server_proto_depIdxs = []int32{ 13, // 28: server.v1.ServerService.UpdateStatus:input_type -> server.v1.UpdateStatusRequest 18, // 29: server.v1.ServerService.GetSettings:input_type -> server.v1.GetSettingsRequest 20, // 30: server.v1.ServerService.ChangeSettings:input_type -> server.v1.ChangeSettingsRequest - 22, // 31: server.v1.ServerService.AWSInstanceCheck:input_type -> server.v1.AWSInstanceCheckRequest - 3, // 32: server.v1.ServerService.Version:output_type -> server.v1.VersionResponse - 5, // 33: server.v1.ServerService.Readiness:output_type -> server.v1.ReadinessResponse - 7, // 34: server.v1.ServerService.LeaderHealthCheck:output_type -> server.v1.LeaderHealthCheckResponse - 10, // 35: server.v1.ServerService.CheckUpdates:output_type -> server.v1.CheckUpdatesResponse - 12, // 36: server.v1.ServerService.StartUpdate:output_type -> server.v1.StartUpdateResponse - 14, // 37: server.v1.ServerService.UpdateStatus:output_type -> server.v1.UpdateStatusResponse - 19, // 38: server.v1.ServerService.GetSettings:output_type -> server.v1.GetSettingsResponse - 21, // 39: server.v1.ServerService.ChangeSettings:output_type -> server.v1.ChangeSettingsResponse - 23, // 40: server.v1.ServerService.AWSInstanceCheck:output_type -> server.v1.AWSInstanceCheckResponse - 32, // [32:41] is the sub-list for method output_type - 23, // [23:32] is the sub-list for method input_type + 3, // 31: server.v1.ServerService.Version:output_type -> server.v1.VersionResponse + 5, // 32: server.v1.ServerService.Readiness:output_type -> server.v1.ReadinessResponse + 7, // 33: server.v1.ServerService.LeaderHealthCheck:output_type -> server.v1.LeaderHealthCheckResponse + 10, // 34: server.v1.ServerService.CheckUpdates:output_type -> server.v1.CheckUpdatesResponse + 12, // 35: server.v1.ServerService.StartUpdate:output_type -> server.v1.StartUpdateResponse + 14, // 36: server.v1.ServerService.UpdateStatus:output_type -> server.v1.UpdateStatusResponse + 19, // 37: server.v1.ServerService.GetSettings:output_type -> server.v1.GetSettingsResponse + 21, // 38: server.v1.ServerService.ChangeSettings:output_type -> server.v1.ChangeSettingsResponse + 31, // [31:39] is the sub-list for method output_type + 23, // [23:31] is the sub-list for method input_type 23, // [23:23] is the sub-list for extension type_name 23, // [23:23] is the sub-list for extension extendee 0, // [0:23] is the sub-list for field type_name @@ -2297,30 +2190,6 @@ func file_server_v1_server_proto_init() { return nil } } - file_server_v1_server_proto_msgTypes[21].Exporter = func(v any, i int) any { - switch v := v.(*AWSInstanceCheckRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_server_v1_server_proto_msgTypes[22].Exporter = func(v any, i int) any { - switch v := v.(*AWSInstanceCheckResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } } file_server_v1_server_proto_msgTypes[19].OneofWrappers = []any{} type x struct{} @@ -2329,7 +2198,7 @@ func file_server_v1_server_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_server_v1_server_proto_rawDesc, NumEnums: 1, - NumMessages: 23, + NumMessages: 21, NumExtensions: 0, NumServices: 1, }, diff --git a/api/server/v1/server.pb.gw.go b/api/server/v1/server.pb.gw.go index 4fa1614e6c..ba65789293 100644 --- a/api/server/v1/server.pb.gw.go +++ b/api/server/v1/server.pb.gw.go @@ -217,38 +217,6 @@ func local_request_ServerService_ChangeSettings_0(ctx context.Context, marshaler return msg, metadata, err } -var filter_ServerService_AWSInstanceCheck_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} - -func request_ServerService_AWSInstanceCheck_0(ctx context.Context, marshaler runtime.Marshaler, client ServerServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq AWSInstanceCheckRequest - var metadata runtime.ServerMetadata - - if err := req.ParseForm(); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_ServerService_AWSInstanceCheck_0); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - - msg, err := client.AWSInstanceCheck(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) - return msg, metadata, err -} - -func local_request_ServerService_AWSInstanceCheck_0(ctx context.Context, marshaler runtime.Marshaler, server ServerServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq AWSInstanceCheckRequest - var metadata runtime.ServerMetadata - - if err := req.ParseForm(); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_ServerService_AWSInstanceCheck_0); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - - msg, err := server.AWSInstanceCheck(ctx, &protoReq) - return msg, metadata, err -} - // RegisterServerServiceHandlerServer registers the http handlers for service ServerService to "mux". // UnaryRPC :call ServerServiceServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. @@ -446,30 +414,6 @@ func RegisterServerServiceHandlerServer(ctx context.Context, mux *runtime.ServeM forward_ServerService_ChangeSettings_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) - mux.Handle("GET", pattern_ServerService_AWSInstanceCheck_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) - defer cancel() - var stream runtime.ServerTransportStream - ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - var err error - var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/server.v1.ServerService/AWSInstanceCheck", runtime.WithHTTPPathPattern("/v1/server/AWSInstance")) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := local_request_ServerService_AWSInstanceCheck_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_ServerService_AWSInstanceCheck_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - }) - return nil } @@ -678,27 +622,6 @@ func RegisterServerServiceHandlerClient(ctx context.Context, mux *runtime.ServeM forward_ServerService_ChangeSettings_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) - mux.Handle("GET", pattern_ServerService_AWSInstanceCheck_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) - defer cancel() - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - var err error - var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/server.v1.ServerService/AWSInstanceCheck", runtime.WithHTTPPathPattern("/v1/server/AWSInstance")) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := request_ServerService_AWSInstanceCheck_0(annotatedContext, inboundMarshaler, client, req, pathParams) - annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) - if err != nil { - runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) - return - } - - forward_ServerService_AWSInstanceCheck_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - }) - return nil } @@ -718,8 +641,6 @@ var ( pattern_ServerService_GetSettings_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "server", "settings"}, "")) pattern_ServerService_ChangeSettings_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "server", "settings"}, "")) - - pattern_ServerService_AWSInstanceCheck_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "server", "AWSInstance"}, "")) ) var ( @@ -738,6 +659,4 @@ var ( forward_ServerService_GetSettings_0 = runtime.ForwardResponseMessage forward_ServerService_ChangeSettings_0 = runtime.ForwardResponseMessage - - forward_ServerService_AWSInstanceCheck_0 = runtime.ForwardResponseMessage ) diff --git a/api/server/v1/server.pb.validate.go b/api/server/v1/server.pb.validate.go index 42336b9c6d..39897b8317 100644 --- a/api/server/v1/server.pb.validate.go +++ b/api/server/v1/server.pb.validate.go @@ -2900,218 +2900,3 @@ var _ interface { Cause() error ErrorName() string } = ChangeSettingsResponseValidationError{} - -// Validate checks the field values on AWSInstanceCheckRequest 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 *AWSInstanceCheckRequest) Validate() error { - return m.validate(false) -} - -// ValidateAll checks the field values on AWSInstanceCheckRequest 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 -// AWSInstanceCheckRequestMultiError, or nil if none found. -func (m *AWSInstanceCheckRequest) ValidateAll() error { - return m.validate(true) -} - -func (m *AWSInstanceCheckRequest) validate(all bool) error { - if m == nil { - return nil - } - - var errors []error - - if utf8.RuneCountInString(m.GetInstanceId()) < 1 { - err := AWSInstanceCheckRequestValidationError{ - field: "InstanceId", - reason: "value length must be at least 1 runes", - } - if !all { - return err - } - errors = append(errors, err) - } - - if len(errors) > 0 { - return AWSInstanceCheckRequestMultiError(errors) - } - - return nil -} - -// AWSInstanceCheckRequestMultiError is an error wrapping multiple validation -// errors returned by AWSInstanceCheckRequest.ValidateAll() if the designated -// constraints aren't met. -type AWSInstanceCheckRequestMultiError []error - -// Error returns a concatenation of all the error messages it wraps. -func (m AWSInstanceCheckRequestMultiError) 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 AWSInstanceCheckRequestMultiError) AllErrors() []error { return m } - -// AWSInstanceCheckRequestValidationError is the validation error returned by -// AWSInstanceCheckRequest.Validate if the designated constraints aren't met. -type AWSInstanceCheckRequestValidationError struct { - field string - reason string - cause error - key bool -} - -// Field function returns field value. -func (e AWSInstanceCheckRequestValidationError) Field() string { return e.field } - -// Reason function returns reason value. -func (e AWSInstanceCheckRequestValidationError) Reason() string { return e.reason } - -// Cause function returns cause value. -func (e AWSInstanceCheckRequestValidationError) Cause() error { return e.cause } - -// Key function returns key value. -func (e AWSInstanceCheckRequestValidationError) Key() bool { return e.key } - -// ErrorName returns error name. -func (e AWSInstanceCheckRequestValidationError) ErrorName() string { - return "AWSInstanceCheckRequestValidationError" -} - -// Error satisfies the builtin error interface -func (e AWSInstanceCheckRequestValidationError) 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 %sAWSInstanceCheckRequest.%s: %s%s", - key, - e.field, - e.reason, - cause) -} - -var _ error = AWSInstanceCheckRequestValidationError{} - -var _ interface { - Field() string - Reason() string - Key() bool - Cause() error - ErrorName() string -} = AWSInstanceCheckRequestValidationError{} - -// Validate checks the field values on AWSInstanceCheckResponse 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 *AWSInstanceCheckResponse) Validate() error { - return m.validate(false) -} - -// ValidateAll checks the field values on AWSInstanceCheckResponse 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 -// AWSInstanceCheckResponseMultiError, or nil if none found. -func (m *AWSInstanceCheckResponse) ValidateAll() error { - return m.validate(true) -} - -func (m *AWSInstanceCheckResponse) validate(all bool) error { - if m == nil { - return nil - } - - var errors []error - - if len(errors) > 0 { - return AWSInstanceCheckResponseMultiError(errors) - } - - return nil -} - -// AWSInstanceCheckResponseMultiError is an error wrapping multiple validation -// errors returned by AWSInstanceCheckResponse.ValidateAll() if the designated -// constraints aren't met. -type AWSInstanceCheckResponseMultiError []error - -// Error returns a concatenation of all the error messages it wraps. -func (m AWSInstanceCheckResponseMultiError) 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 AWSInstanceCheckResponseMultiError) AllErrors() []error { return m } - -// AWSInstanceCheckResponseValidationError is the validation error returned by -// AWSInstanceCheckResponse.Validate if the designated constraints aren't met. -type AWSInstanceCheckResponseValidationError struct { - field string - reason string - cause error - key bool -} - -// Field function returns field value. -func (e AWSInstanceCheckResponseValidationError) Field() string { return e.field } - -// Reason function returns reason value. -func (e AWSInstanceCheckResponseValidationError) Reason() string { return e.reason } - -// Cause function returns cause value. -func (e AWSInstanceCheckResponseValidationError) Cause() error { return e.cause } - -// Key function returns key value. -func (e AWSInstanceCheckResponseValidationError) Key() bool { return e.key } - -// ErrorName returns error name. -func (e AWSInstanceCheckResponseValidationError) ErrorName() string { - return "AWSInstanceCheckResponseValidationError" -} - -// Error satisfies the builtin error interface -func (e AWSInstanceCheckResponseValidationError) 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 %sAWSInstanceCheckResponse.%s: %s%s", - key, - e.field, - e.reason, - cause) -} - -var _ error = AWSInstanceCheckResponseValidationError{} - -var _ interface { - Field() string - Reason() string - Key() bool - Cause() error - ErrorName() string -} = AWSInstanceCheckResponseValidationError{} diff --git a/api/server/v1/server.proto b/api/server/v1/server.proto index c65d7c3a65..527ff71a27 100644 --- a/api/server/v1/server.proto +++ b/api/server/v1/server.proto @@ -202,13 +202,6 @@ message ChangeSettingsResponse { Settings settings = 1; } -message AWSInstanceCheckRequest { - // AWS EC2 instance ID (i-1234567890abcdef0). - string instance_id = 1 [(validate.rules).string.min_len = 1]; -} - -message AWSInstanceCheckResponse {} - // Server service provides generic PMM Server public APIs. service ServerService { // Version returns PMM Server versions. @@ -285,12 +278,4 @@ service ServerService { description: "Changes PMM Server settings." }; } - // AWSInstanceCheck checks AWS EC2 instance ID. - rpc AWSInstanceCheck(AWSInstanceCheckRequest) returns (AWSInstanceCheckResponse) { - option (google.api.http) = {get: "/v1/server/AWSInstance"}; - option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { - summary: "AWS instance check" - description: "Checks AWS EC2 instance ID." - }; - } } diff --git a/api/server/v1/server_grpc.pb.go b/api/server/v1/server_grpc.pb.go index 67d9f22312..528ca59472 100644 --- a/api/server/v1/server_grpc.pb.go +++ b/api/server/v1/server_grpc.pb.go @@ -28,7 +28,6 @@ const ( ServerService_UpdateStatus_FullMethodName = "/server.v1.ServerService/UpdateStatus" ServerService_GetSettings_FullMethodName = "/server.v1.ServerService/GetSettings" ServerService_ChangeSettings_FullMethodName = "/server.v1.ServerService/ChangeSettings" - ServerService_AWSInstanceCheck_FullMethodName = "/server.v1.ServerService/AWSInstanceCheck" ) // ServerServiceClient is the client API for ServerService service. @@ -54,8 +53,6 @@ type ServerServiceClient interface { GetSettings(ctx context.Context, in *GetSettingsRequest, opts ...grpc.CallOption) (*GetSettingsResponse, error) // ChangeSettings changes PMM Server settings. ChangeSettings(ctx context.Context, in *ChangeSettingsRequest, opts ...grpc.CallOption) (*ChangeSettingsResponse, error) - // AWSInstanceCheck checks AWS EC2 instance ID. - AWSInstanceCheck(ctx context.Context, in *AWSInstanceCheckRequest, opts ...grpc.CallOption) (*AWSInstanceCheckResponse, error) } type serverServiceClient struct { @@ -146,16 +143,6 @@ func (c *serverServiceClient) ChangeSettings(ctx context.Context, in *ChangeSett return out, nil } -func (c *serverServiceClient) AWSInstanceCheck(ctx context.Context, in *AWSInstanceCheckRequest, opts ...grpc.CallOption) (*AWSInstanceCheckResponse, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(AWSInstanceCheckResponse) - err := c.cc.Invoke(ctx, ServerService_AWSInstanceCheck_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - // ServerServiceServer is the server API for ServerService service. // All implementations must embed UnimplementedServerServiceServer // for forward compatibility @@ -179,8 +166,6 @@ type ServerServiceServer interface { GetSettings(context.Context, *GetSettingsRequest) (*GetSettingsResponse, error) // ChangeSettings changes PMM Server settings. ChangeSettings(context.Context, *ChangeSettingsRequest) (*ChangeSettingsResponse, error) - // AWSInstanceCheck checks AWS EC2 instance ID. - AWSInstanceCheck(context.Context, *AWSInstanceCheckRequest) (*AWSInstanceCheckResponse, error) mustEmbedUnimplementedServerServiceServer() } @@ -218,10 +203,6 @@ func (UnimplementedServerServiceServer) GetSettings(context.Context, *GetSetting func (UnimplementedServerServiceServer) ChangeSettings(context.Context, *ChangeSettingsRequest) (*ChangeSettingsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ChangeSettings not implemented") } - -func (UnimplementedServerServiceServer) AWSInstanceCheck(context.Context, *AWSInstanceCheckRequest) (*AWSInstanceCheckResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method AWSInstanceCheck not implemented") -} func (UnimplementedServerServiceServer) mustEmbedUnimplementedServerServiceServer() {} // UnsafeServerServiceServer may be embedded to opt out of forward compatibility for this service. @@ -379,24 +360,6 @@ func _ServerService_ChangeSettings_Handler(srv interface{}, ctx context.Context, return interceptor(ctx, in, info, handler) } -func _ServerService_AWSInstanceCheck_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(AWSInstanceCheckRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ServerServiceServer).AWSInstanceCheck(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: ServerService_AWSInstanceCheck_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ServerServiceServer).AWSInstanceCheck(ctx, req.(*AWSInstanceCheckRequest)) - } - return interceptor(ctx, in, info, handler) -} - // ServerService_ServiceDesc is the grpc.ServiceDesc for ServerService service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -436,10 +399,6 @@ var ServerService_ServiceDesc = grpc.ServiceDesc{ MethodName: "ChangeSettings", Handler: _ServerService_ChangeSettings_Handler, }, - { - MethodName: "AWSInstanceCheck", - Handler: _ServerService_AWSInstanceCheck_Handler, - }, }, Streams: []grpc.StreamDesc{}, Metadata: "server/v1/server.proto", diff --git a/api/swagger/swagger-dev.json b/api/swagger/swagger-dev.json index 917c75e4ca..cf32bb6f3a 100644 --- a/api/swagger/swagger-dev.json +++ b/api/swagger/swagger-dev.json @@ -26706,65 +26706,6 @@ } } }, - "/v1/server/AWSInstance": { - "get": { - "description": "Checks AWS EC2 instance ID.", - "tags": [ - "ServerService" - ], - "summary": "AWS instance check", - "operationId": "AWSInstanceCheck", - "parameters": [ - { - "type": "string", - "description": "AWS EC2 instance ID (i-1234567890abcdef0).", - "name": "instance_id", - "in": "query" - } - ], - "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": { - "description": "`Any` contains an arbitrary serialized protocol buffer message along with a\nURL that describes the type of the serialized message.\n\nProtobuf library provides support to pack/unpack Any values in the form\nof utility functions or additional generated methods of the Any type.\n\nExample 1: Pack and unpack a message in C++.\n\n Foo foo = ...;\n Any any;\n any.PackFrom(foo);\n ...\n if (any.UnpackTo(\u0026foo)) {\n ...\n }\n\nExample 2: Pack and unpack a message in Java.\n\n Foo foo = ...;\n Any any = Any.pack(foo);\n ...\n if (any.is(Foo.class)) {\n foo = any.unpack(Foo.class);\n }\n // or ...\n if (any.isSameTypeAs(Foo.getDefaultInstance())) {\n foo = any.unpack(Foo.getDefaultInstance());\n }\n\n Example 3: Pack and unpack a message in Python.\n\n foo = Foo(...)\n any = Any()\n any.Pack(foo)\n ...\n if any.Is(Foo.DESCRIPTOR):\n any.Unpack(foo)\n ...\n\n Example 4: Pack and unpack a message in Go\n\n foo := \u0026pb.Foo{...}\n any, err := anypb.New(foo)\n if err != nil {\n ...\n }\n ...\n foo := \u0026pb.Foo{}\n if err := any.UnmarshalTo(foo); err != nil {\n ...\n }\n\nThe pack methods provided by protobuf library will by default use\n'type.googleapis.com/full.type.name' as the type URL and the unpack\nmethods only use the fully qualified type name after the last '/'\nin the type URL, for example \"foo.bar.com/x/y.z\" will yield type\nname \"y.z\".\n\nJSON\n====\nThe JSON representation of an `Any` value uses the regular\nrepresentation of the deserialized, embedded message, with an\nadditional field `@type` which contains the type URL. Example:\n\n package google.profile;\n message Person {\n string first_name = 1;\n string last_name = 2;\n }\n\n {\n \"@type\": \"type.googleapis.com/google.profile.Person\",\n \"firstName\": \u003cstring\u003e,\n \"lastName\": \u003cstring\u003e\n }\n\nIf the embedded message type is well-known and has a custom JSON\nrepresentation, that representation will be embedded adding a field\n`value` which holds the custom JSON in addition to the `@type`\nfield. Example (for message [google.protobuf.Duration][]):\n\n {\n \"@type\": \"type.googleapis.com/google.protobuf.Duration\",\n \"value\": \"1.212s\"\n }", - "type": "object", - "properties": { - "@type": { - "description": "A URL/resource name that uniquely identifies the type of the serialized\nprotocol buffer message. This string must contain at least\none \"/\" character. The last segment of the URL's path must represent\nthe fully qualified name of the type (as in\n`path/google.protobuf.Duration`). The name should be in a canonical form\n(e.g., leading \".\" is not accepted).\n\nIn practice, teams usually precompile into the binary all types that they\nexpect it to use in the context of Any. However, for URLs which use the\nscheme `http`, `https`, or no scheme, one can optionally set up a type\nserver that maps type URLs to message definitions as follows:\n\n* If no scheme is provided, `https` is assumed.\n* An HTTP GET on the URL must yield a [google.protobuf.Type][]\n value in binary format, or produce an error.\n* Applications are allowed to cache lookup results based on the\n URL, or have them precompiled into a binary to avoid any\n lookup. Therefore, binary compatibility needs to be preserved\n on changes to types. (Use versioned type names to manage\n breaking changes.)\n\nNote: this functionality is not currently available in the official\nprotobuf release, and it is not used for type URLs beginning with\ntype.googleapis.com. As of May 2023, there are no widely used type server\nimplementations and no plans to implement one.\n\nSchemes other than `http`, `https` (or the empty scheme) might be\nused with implementation specific semantics.", - "type": "string", - "x-order": 0 - } - }, - "additionalProperties": false - }, - "x-order": 2 - } - } - } - } - } - } - }, "/v1/server/leaderHealthCheck": { "get": { "description": "Checks if the instance is the leader in a cluster. Returns an error if the instance isn't the leader.", diff --git a/api/swagger/swagger.json b/api/swagger/swagger.json index 765fbdcdd3..53ea07bff3 100644 --- a/api/swagger/swagger.json +++ b/api/swagger/swagger.json @@ -25748,65 +25748,6 @@ } } }, - "/v1/server/AWSInstance": { - "get": { - "description": "Checks AWS EC2 instance ID.", - "tags": [ - "ServerService" - ], - "summary": "AWS instance check", - "operationId": "AWSInstanceCheck", - "parameters": [ - { - "type": "string", - "description": "AWS EC2 instance ID (i-1234567890abcdef0).", - "name": "instance_id", - "in": "query" - } - ], - "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": { - "description": "`Any` contains an arbitrary serialized protocol buffer message along with a\nURL that describes the type of the serialized message.\n\nProtobuf library provides support to pack/unpack Any values in the form\nof utility functions or additional generated methods of the Any type.\n\nExample 1: Pack and unpack a message in C++.\n\n Foo foo = ...;\n Any any;\n any.PackFrom(foo);\n ...\n if (any.UnpackTo(\u0026foo)) {\n ...\n }\n\nExample 2: Pack and unpack a message in Java.\n\n Foo foo = ...;\n Any any = Any.pack(foo);\n ...\n if (any.is(Foo.class)) {\n foo = any.unpack(Foo.class);\n }\n // or ...\n if (any.isSameTypeAs(Foo.getDefaultInstance())) {\n foo = any.unpack(Foo.getDefaultInstance());\n }\n\n Example 3: Pack and unpack a message in Python.\n\n foo = Foo(...)\n any = Any()\n any.Pack(foo)\n ...\n if any.Is(Foo.DESCRIPTOR):\n any.Unpack(foo)\n ...\n\n Example 4: Pack and unpack a message in Go\n\n foo := \u0026pb.Foo{...}\n any, err := anypb.New(foo)\n if err != nil {\n ...\n }\n ...\n foo := \u0026pb.Foo{}\n if err := any.UnmarshalTo(foo); err != nil {\n ...\n }\n\nThe pack methods provided by protobuf library will by default use\n'type.googleapis.com/full.type.name' as the type URL and the unpack\nmethods only use the fully qualified type name after the last '/'\nin the type URL, for example \"foo.bar.com/x/y.z\" will yield type\nname \"y.z\".\n\nJSON\n====\nThe JSON representation of an `Any` value uses the regular\nrepresentation of the deserialized, embedded message, with an\nadditional field `@type` which contains the type URL. Example:\n\n package google.profile;\n message Person {\n string first_name = 1;\n string last_name = 2;\n }\n\n {\n \"@type\": \"type.googleapis.com/google.profile.Person\",\n \"firstName\": \u003cstring\u003e,\n \"lastName\": \u003cstring\u003e\n }\n\nIf the embedded message type is well-known and has a custom JSON\nrepresentation, that representation will be embedded adding a field\n`value` which holds the custom JSON in addition to the `@type`\nfield. Example (for message [google.protobuf.Duration][]):\n\n {\n \"@type\": \"type.googleapis.com/google.protobuf.Duration\",\n \"value\": \"1.212s\"\n }", - "type": "object", - "properties": { - "@type": { - "description": "A URL/resource name that uniquely identifies the type of the serialized\nprotocol buffer message. This string must contain at least\none \"/\" character. The last segment of the URL's path must represent\nthe fully qualified name of the type (as in\n`path/google.protobuf.Duration`). The name should be in a canonical form\n(e.g., leading \".\" is not accepted).\n\nIn practice, teams usually precompile into the binary all types that they\nexpect it to use in the context of Any. However, for URLs which use the\nscheme `http`, `https`, or no scheme, one can optionally set up a type\nserver that maps type URLs to message definitions as follows:\n\n* If no scheme is provided, `https` is assumed.\n* An HTTP GET on the URL must yield a [google.protobuf.Type][]\n value in binary format, or produce an error.\n* Applications are allowed to cache lookup results based on the\n URL, or have them precompiled into a binary to avoid any\n lookup. Therefore, binary compatibility needs to be preserved\n on changes to types. (Use versioned type names to manage\n breaking changes.)\n\nNote: this functionality is not currently available in the official\nprotobuf release, and it is not used for type URLs beginning with\ntype.googleapis.com. As of May 2023, there are no widely used type server\nimplementations and no plans to implement one.\n\nSchemes other than `http`, `https` (or the empty scheme) might be\nused with implementation specific semantics.", - "type": "string", - "x-order": 0 - } - }, - "additionalProperties": false - }, - "x-order": 2 - } - } - } - } - } - } - }, "/v1/server/leaderHealthCheck": { "get": { "description": "Checks if the instance is the leader in a cluster. Returns an error if the instance isn't the leader.", diff --git a/build/Makefile b/build/Makefile index 66da3fddb0..8640220610 100644 --- a/build/Makefile +++ b/build/Makefile @@ -1,5 +1,6 @@ export PACKER_CACHE_DIR := .cache export PACKER_VERSION := 1.9.4 +export PMM_SERVER_IMAGE ?= docker.io/perconalab/pmm-server:3-dev-latest ## ----------------- PACKER ------------------ fetch: @@ -21,8 +22,7 @@ deps: unzip -o ${PACKER_CACHE_DIR}/packer.zip -d ~/bin pmm-ovf: fetch - /usr/bin/packer build \ - -only virtualbox-ovf -color=false packer/pmm.json | tee build.log + /usr/bin/packer build -var 'pmm_server_image_name=${PMM_SERVER_IMAGE}' -only virtualbox-ovf -color=false packer/pmm.json | tee build.log pmm-digitalocean: packer build -only digitalocean -var 'single_disk=true' packer/pmm.json @@ -32,7 +32,7 @@ pmm-azure: pmm-ami: docker run --rm -v ${HOME}/.aws:/root/.aws -v `pwd`:/build -w /build \hashicorp/packer:${PACKER_VERSION} \ - build -only amazon-ebs -color=false packer/pmm.json | tee build.log + build -var 'pmm_server_image_name=${PMM_SERVER_IMAGE}' -only amazon-ebs -color=false packer/pmm.json | tee build.log ## ----------------- PACKER ------------------ check: ## Run required checks and linters diff --git a/build/ansible/roles/init-admin-password-ami/tasks/main.yml b/build/ansible/roles/init-admin-password-ami/tasks/main.yml new file mode 100644 index 0000000000..9275e0dd56 --- /dev/null +++ b/build/ansible/roles/init-admin-password-ami/tasks/main.yml @@ -0,0 +1,10 @@ +- name: Fetch instance metadata + uri: + url: http://169.254.169.254/latest/meta-data/instance-id + return_content: yes + register: jsondata + +- debug: msg="Instance ID {{ jsondata['content'] }}" + +- name: change admin password + command: change-admin-password {{ jsondata['content'] }} diff --git a/build/ansible/roles/initialization/tasks/main.yml b/build/ansible/roles/initialization/tasks/main.yml index fdbe31c9b2..8715815ad3 100644 --- a/build/ansible/roles/initialization/tasks/main.yml +++ b/build/ansible/roles/initialization/tasks/main.yml @@ -1,5 +1,21 @@ --- # This role contains tasks executed during initialization of PMM Server +- name: detect /srv/pmm-distribution + slurp: + path: /srv/pmm-distribution + register: pmm_distribution + ignore_errors: True + +- name: detect AMI + set_fact: + is_ami: "{{ pmm_distribution['content'] | b64decode | trim == 'ami' }}" + when: pmm_distribution['failed'] == false + +- name: Set PMM distribution + set_fact: + is_ami: "False" + when: pmm_distribution['failed'] == true + - name: Get current version slurp: src: /srv/grafana/PERCONA_DASHBOARDS_VERSION @@ -25,63 +41,102 @@ set_fact: pmm_image_version: "{{ image_version_file['content'] | b64decode | trim }}" +- name: Set need_initialization fact + set_fact: + need_initialization: "{{ current_version_file['failed'] == true }}" + - name: Set need_upgrade fact set_fact: need_upgrade: "{{ pmm_current_version is version(pmm_image_version, '<') }}" +- name: Print PMM distribution + debug: + msg: "PMM distribution: {{ pmm_distribution }}, Is AMI: {{ is_ami }}" + - name: Print current PMM and image versions debug: msg: "Current version: {{ pmm_current_version }} Image Version: {{ pmm_image_version }}" +- name: Print need_initialization fact + debug: + msg: "Need initialization: {{ need_initialization }}" + - name: Print need_upgrade fact debug: msg: "Need upgrade: {{ need_upgrade }}" -- name: Perform upgrade tasks +- name: Perform upgrade & init tasks block: - - name: Enable maintenance mode before upgrade - copy: - src: maintenance.html - dest: /usr/share/pmm-server/maintenance/ - owner: pmm - group: pmm - mode: 0644 - - - name: Upgrade dashboards - include_role: - name: dashboards - - - name: Copy file with image version - copy: - src: /usr/share/percona-dashboards/VERSION - dest: /srv/grafana/PERCONA_DASHBOARDS_VERSION - owner: pmm - group: pmm - mode: 0644 - remote_src: yes - - - name: Create a backup directory - file: - path: /srv/backup - state: directory - owner: pmm - group: pmm - mode: 0775 - - # Note: we want to leave this for some time until we achieve stable builds - - name: Output pmm-managed logs - shell: sleep 10 && tail -n 300 /srv/logs/pmm-managed.log - - - name: Wait for PMM to be ready - ansible.builtin.uri: - url: "http://127.0.0.1:7772/v1/server/readyz" - status_code: 200 - method: GET - retries: 20 - delay: 5 - - - name: Disable maintenance mode - file: - state: absent - path: /usr/share/pmm-server/maintenance/maintenance.html - when: need_upgrade + - name: Enable maintenance mode before upgrade + copy: + src: maintenance.html + dest: /usr/share/pmm-server/maintenance/ + owner: pmm + group: pmm + mode: 0644 + + - name: Create grafana DB + block: + - name: Create grafana database in postgres + postgresql_db: + name: grafana + login_user: postgres + state: present + + - name: Create grafana user in postgres + postgresql_user: + db: grafana + name: grafana + password: grafana + priv: 'ALL' + expires: infinity + login_user: postgres + state: present + when: not ansible_check_mode + when: lookup('env','GF_DATABASE_URL') == '' and lookup('env','GF_DATABASE_HOST') == '' and need_initialization + + - name: Upgrade/Install dashboards + include_role: + name: dashboards + + - name: Copy file with image version + copy: + src: /usr/share/percona-dashboards/VERSION + dest: /srv/grafana/PERCONA_DASHBOARDS_VERSION + owner: pmm + group: pmm + mode: 0644 + remote_src: yes + + - name: Create a backup directory + file: + path: /srv/backup + state: directory + owner: pmm + group: pmm + mode: 0775 + when: need_upgrade + + # Note: we want to leave this for some time until we achieve stable builds + - name: Output pmm-managed logs + shell: sleep 10 && tail -n 300 /srv/logs/pmm-managed.log + + - name: Wait for PMM to be ready + ansible.builtin.uri: + url: "http://127.0.0.1:7772/v1/server/readyz" + status_code: 200 + method: GET + retries: 20 + delay: 5 + ignore_errors: yes + + - name: init admin password on AMI + include_role: + name: init-admin-password-ami + when: need_initialization and is_ami + + - name: Disable maintenance mode + file: + state: absent + path: /usr/share/pmm-server/maintenance/maintenance.html + when: need_initialization or need_upgrade diff --git a/build/ansible/roles/nginx/files/conf.d/pmm.conf b/build/ansible/roles/nginx/files/conf.d/pmm.conf index 21623d8831..c4ac6155bd 100644 --- a/build/ansible/roles/nginx/files/conf.d/pmm.conf +++ b/build/ansible/roles/nginx/files/conf.d/pmm.conf @@ -73,13 +73,9 @@ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # Enable auth_request for all locations, including root - # (but excluding /auth_request and /setup below). + # (but excluding /auth_request). auth_request /auth_request; - # Store the value of X-Must-Setup header of auth_request subrequest response in the variable. - # It is used below in /auth_request. - auth_request_set $auth_request_must_setup $upstream_http_x_must_setup; - # Store the value of X-Proxy-Filter header of auth_request subrequest response in the variable. auth_request_set $auth_request_proxy_filter $upstream_http_x_proxy_filter; proxy_set_header X-Proxy-Filter $auth_request_proxy_filter; @@ -109,23 +105,11 @@ proxy_http_version 1.1; proxy_set_header Connection ""; - # This header is set only for to the second request, not for the first subrequest. - # That variable is set above. - proxy_set_header X-Must-Setup $auth_request_must_setup; - # Those headers are set for both subrequest and normal request. proxy_set_header X-Original-Uri $request_uri; proxy_set_header X-Original-Method $request_method; } - # AWS setup wizard - location /setup { - auth_request off; - - alias /usr/share/percona-dashboards/setup-page; - try_files $uri /index.html break; - } - # PMM UI location /pmm-ui { # Will redirect on FE to login page if user is not authenticated diff --git a/build/docker/server/entrypoint.sh b/build/docker/server/entrypoint.sh index df1e5b755e..4b7b0b7f93 100755 --- a/build/docker/server/entrypoint.sh +++ b/build/docker/server/entrypoint.sh @@ -1,6 +1,8 @@ #!/bin/bash set -o errexit +PMM_DISTRIBUTION_METHOD="${PMM_DISTRIBUTION_METHOD:-docker}" + if [ ! -w /srv ]; then echo "FATAL: /srv is not writable for $(whoami) user." >&2 echo "Please make sure that /srv is owned by uid $(id -u) and gid $(id -g) and try again." >&2 @@ -11,12 +13,12 @@ fi # Initialize /srv if empty DIST_FILE=/srv/pmm-distribution if [ ! -f $DIST_FILE ]; then - echo "File $DIST_FILE doesn't exist. Initializing /srv..." - echo docker > $DIST_FILE + echo $PMM_DISTRIBUTION_METHOD > $DIST_FILE + echo "Initializing /srv..." mkdir -p /srv/{backup,clickhouse,grafana,logs,nginx,postgres14,prometheus,victoriametrics} echo "Copying grafana plugins and the VERSION file..." + mkdir -p /srv/grafana/plugins cp -r /usr/share/percona-dashboards/panels/* /srv/grafana/plugins - cp /usr/share/percona-dashboards/VERSION /srv/grafana/PERCONA_DASHBOARDS_VERSION echo "Generating self-signed certificates for nginx..." bash /var/lib/cloud/scripts/per-boot/generate-ssl-certificate @@ -26,8 +28,6 @@ if [ ! -f $DIST_FILE ]; then echo "Enabling pg_stat_statements extension for PostgreSQL..." /usr/pgsql-14/bin/pg_ctl start -D /srv/postgres14 -o '-c logging_collector=off' - # We create the postgres user with superuser privileges to not break the code that connects pmm-managed to postgres. - /usr/pgsql-14/bin/createuser --echo --superuser --host=/run/postgresql --no-password postgres /usr/bin/psql postgres postgres -c 'CREATE EXTENSION pg_stat_statements SCHEMA public' /usr/pgsql-14/bin/pg_ctl stop -D /srv/postgres14 fi diff --git a/build/packages/rpm/server/SPECS/percona-dashboards.spec b/build/packages/rpm/server/SPECS/percona-dashboards.spec index 5a1a895ed3..eb964ce17f 100644 --- a/build/packages/rpm/server/SPECS/percona-dashboards.spec +++ b/build/packages/rpm/server/SPECS/percona-dashboards.spec @@ -7,7 +7,7 @@ %global commit ad4af6808bcd361284e8eb8cd1f36b1e98e32bce %global shortcommit %(c=%{commit}; echo ${c:0:7}) %define build_timestamp %(date -u +"%y%m%d%H%M") -%define release 21 +%define release 22 %define rpm_release %{release}.%{build_timestamp}.%{shortcommit}%{?dist} Name: percona-dashboards @@ -42,11 +42,9 @@ make release %install install -d %{buildroot}%{_datadir}/%{name} install -d %{buildroot}%{_datadir}/%{name}/panels/pmm-app -install -d %{buildroot}%{_datadir}/%{name}/setup-page cp -a ./panels %{buildroot}%{_datadir}/%{name} cp -a ./pmm-app/dist %{buildroot}%{_datadir}/%{name}/panels/pmm-app -cp -ra ./setup-page/build/* %{buildroot}%{_datadir}/%{name}/setup-page echo %{version} > %{buildroot}%{_datadir}/%{name}/VERSION @@ -57,6 +55,9 @@ echo %{version} > %{buildroot}%{_datadir}/%{name}/VERSION %changelog +* Tue Jul 23 2024 Nurlan Moldomurov - 3.0.0-22 +- PMM-13053 Remove /setup page + * Wed Nov 29 2023 Alex Demidoff - 3.0.0-21 - PMM-12693 Run Grafana as non-root user diff --git a/build/packer/ansible/roles/cloud-node/files/show-url b/build/packer/ansible/roles/cloud-node/files/show-url index a72488a9b0..c7f3f13410 100644 --- a/build/packer/ansible/roles/cloud-node/files/show-url +++ b/build/packer/ansible/roles/cloud-node/files/show-url @@ -5,8 +5,7 @@ SOURCE= if [ -f /var/lib/cloud/data/status.json ]; then SOURCE=$( - cat /var/lib/cloud/data/status.json 2>/dev/null \ - | python -c 'import json, sys; print json.load(sys.stdin)["v1"]["datasource"];' 2>/dev/null + cat /var/lib/cloud/data/status.json 2>/dev/null | jq -r '.v1.datasource' 2>/dev/null ) fi diff --git a/build/packer/ansible/roles/cloud-node/tasks/ovf.yml b/build/packer/ansible/roles/cloud-node/tasks/ovf.yml index db520b2959..786d521d9e 100644 --- a/build/packer/ansible/roles/cloud-node/tasks/ovf.yml +++ b/build/packer/ansible/roles/cloud-node/tasks/ovf.yml @@ -13,3 +13,21 @@ retries: 2 dest: /etc/cloud/cloud.cfg.d/90_disable-cloud.cfg mode: 0644 + +- name: Create user-specific .ssh directory + when: ansible_virtualization_type == "virtualbox" + file: + path: /home/admin/.ssh + state: directory + owner: admin + group: admin + mode: '0700' + +- name: create authorized_keys file + when: ansible_virtualization_type == "virtualbox" + file: + path: /home/admin/.ssh/authorized_keys + state: touch + owner: admin + group: admin + mode: '0600' \ No newline at end of file diff --git a/build/packer/ansible/roles/lvm-init/vars/main.yml b/build/packer/ansible/roles/lvm-init/vars/main.yml index 3568493682..8934b62d03 100644 --- a/build/packer/ansible/roles/lvm-init/vars/main.yml +++ b/build/packer/ansible/roles/lvm-init/vars/main.yml @@ -1,5 +1,5 @@ --- -data_partition: "/srv" +data_partition: "/home/admin/volume" create_admin: "true" enable_lvm: "true" single_disk: "false" diff --git a/build/packer/ansible/roles/podman-setup/tasks/main.yml b/build/packer/ansible/roles/podman-setup/tasks/main.yml index 7854d0b157..5c53c631cb 100644 --- a/build/packer/ansible/roles/podman-setup/tasks/main.yml +++ b/build/packer/ansible/roles/podman-setup/tasks/main.yml @@ -1,23 +1,38 @@ +- name: Create user-specific volume directory + file: + path: /home/admin/volume/srv/ + state: directory + owner: admin + group: admin + mode: '0755' + - name: Set distribution for OVF when: ansible_virtualization_type == "virtualbox" - copy: - content: ovf - dest: /srv/pmm-distribution + set_fact: + pmm_distribution_method: ovf - name: Set distribution for AMI when: > ( ansible_virtualization_type == "xen" or ansible_virtualization_type == "kvm" ) and ansible_system_vendor != "DigitalOcean" - copy: - content: ami - dest: /srv/pmm-distribution + set_fact: + pmm_distribution_method: ami -- name: Pull the PMM image - command: podman pull {{ pmm_server_image_name }} +- name: Set SELinux in permissive mode for watchtower + selinux: + policy: targeted + state: permissive - name: Create a volume on the host command: podman volume create pmm-data + become: true + become_user: admin + +- name: Create a network + command: podman network create pmm_default + become: true + become_user: admin - name: Enable privileged port become: true @@ -33,7 +48,23 @@ group: admin mode: '0755' -- name: Copy systemd service file to user-specific directory +- name: Copy pmm-server environment file for service to user-specific directory + template: + src: pmm-server.env + dest: /home/admin/.config/systemd/user/ + owner: admin + group: admin + mode: '0644' + +- name: Display the contents of the environment file + command: cat /home/admin/.config/systemd/user/pmm-server.env + register: command_output + +- name: Print to console + debug: + msg: "{{command_output.stdout}}" + +- name: Copy pmm-server systemd service file to user-specific directory template: src: pmm-server.service dest: /home/admin/.config/systemd/user/ @@ -41,6 +72,14 @@ group: admin mode: '0644' +- name: Copy watchtower systemd service file to user-specific directory + template: + src: watchtower.service + dest: /home/admin/.config/systemd/user/ + owner: admin + group: admin + mode: '0644' + - name: Get user ID of admin user command: id -u admin register: admin_user_id @@ -48,9 +87,32 @@ - name: Enable linger for the admin user command: loginctl enable-linger {{ admin_user_id.stdout }} +- name: Pull the PMM image + command: podman pull {{ pmm_server_image_name }} + become: true + become_user: admin + - name: Enable and start PMM container as a user service command: systemctl --user enable --now pmm-server become: true become_user: admin environment: DBUS_SESSION_BUS_ADDRESS: "unix:path=/run/user/{{ admin_user_id.stdout }}/bus" + +- name: Enable socket + command: systemctl --user enable --now podman.socket + become: true + become_user: admin + environment: + DBUS_SESSION_BUS_ADDRESS: "unix:path=/run/user/{{ admin_user_id.stdout }}/bus" + +- name: Enable and start watchtower container as a user service + command: systemctl --user enable --now watchtower + become: true + become_user: admin + environment: + DBUS_SESSION_BUS_ADDRESS: "unix:path=/run/user/{{ admin_user_id.stdout }}/bus" + +- name: Sleep for 1 minute + pause: + minutes: 1 diff --git a/build/packer/ansible/roles/podman-setup/templates/pmm-server.env b/build/packer/ansible/roles/podman-setup/templates/pmm-server.env new file mode 100644 index 0000000000..88936af0a7 --- /dev/null +++ b/build/packer/ansible/roles/podman-setup/templates/pmm-server.env @@ -0,0 +1,5 @@ +PMM_WATCHTOWER_HOST=http://watchtower:8080 +PMM_WATCHTOWER_TOKEN=123 +PMM_SERVER_UPDATE_VERSION=docker.io/perconalab/pmm-server:3-dev-container +PMM_IMAGE={{ pmm_server_image_name }} +PMM_DISTRIBUTION_METHOD={{ pmm_distribution_method }} \ No newline at end of file diff --git a/build/packer/ansible/roles/podman-setup/templates/pmm-server.service b/build/packer/ansible/roles/podman-setup/templates/pmm-server.service index ecb10f37df..dc862129e3 100644 --- a/build/packer/ansible/roles/podman-setup/templates/pmm-server.service +++ b/build/packer/ansible/roles/podman-setup/templates/pmm-server.service @@ -6,11 +6,21 @@ After=nss-user-lookup.target nss-lookup.target After=time-sync.target [Service] -TimeoutStartSec=0 -Restart=always +EnvironmentFile=/home/admin/.config/systemd/user/pmm-server.env -ExecStart=/usr/bin/podman run --volume pmm-data:/srv/ --rm --name %N \ - -p 443:8443/tcp --ulimit=host {{ pmm_server_image_name }} +Restart=on-failure +RestartSec=20 + +ExecStart=/usr/bin/podman run \ + --volume /home/admin/volume/srv:/srv \ + --volume /home/admin/.ssh/:/home/pmm/.ssh/ \ + --volume /home/admin/.config/:/home/pmm/config/ \ + --rm --replace=true --name %N \ + --env-file=/home/admin/.config/systemd/user/pmm-server.env \ + --net pmm_default \ + --cap-add=net_admin,net_raw \ + --userns=keep-id:uid=1000,gid=1000 \ + -p 443:8443/tcp --ulimit=host ${PMM_IMAGE} ExecStop=/usr/bin/podman stop -t 10 %N diff --git a/build/packer/ansible/roles/podman-setup/templates/watchtower.service b/build/packer/ansible/roles/podman-setup/templates/watchtower.service new file mode 100644 index 0000000000..96c1e93202 --- /dev/null +++ b/build/packer/ansible/roles/podman-setup/templates/watchtower.service @@ -0,0 +1,30 @@ +[Unit] +Description=watchtower +Wants=network-online.target +After=network-online.target +After=nss-user-lookup.target nss-lookup.target +After=time-sync.target + +[Service] +Restart=on-failure +RestartSec=20 + +Environment=WATCHTOWER_HTTP_API_UPDATE=1 +Environment=WATCHTOWER_HTTP_API_TOKEN=123 +Environment=WATCHTOWER_NO_RESTART=1 +Environment=WATCHTOWER_DEBUG=1 + +ExecStart=/usr/bin/podman run --rm --replace=true --name %N \ + -v ${XDG_RUNTIME_DIR}/podman/podman.sock:/var/run/docker.sock \ + -e WATCHTOWER_HTTP_API_UPDATE=${WATCHTOWER_HTTP_API_UPDATE} \ + -e WATCHTOWER_HTTP_API_TOKEN=${WATCHTOWER_HTTP_API_TOKEN} \ + -e WATCHTOWER_NO_RESTART=${WATCHTOWER_NO_RESTART} \ + -e WATCHTOWER_DEBUG=${WATCHTOWER_DEBUG} \ + --net pmm_default \ + --cap-add=net_admin,net_raw \ + -p 8080:8080/tcp docker.io/perconalab/watchtower + +ExecStop=/usr/bin/podman stop -t 10 %N + +[Install] +WantedBy=default.target diff --git a/build/packer/pmm.json b/build/packer/pmm.json index 3262b48916..5fd2f79a43 100644 --- a/build/packer/pmm.json +++ b/build/packer/pmm.json @@ -12,7 +12,7 @@ { "delete_on_termination": true, "device_name": "/dev/sda1", - "volume_size": 10, + "volume_size": 20, "volume_type": "gp3" }, { diff --git a/descriptor.bin b/descriptor.bin index a588614ad1..b6d4384871 100644 Binary files a/descriptor.bin and b/descriptor.bin differ diff --git a/managed/cmd/pmm-managed/main.go b/managed/cmd/pmm-managed/main.go index 4bb4ee1a02..6b102c046f 100644 --- a/managed/cmd/pmm-managed/main.go +++ b/managed/cmd/pmm-managed/main.go @@ -102,6 +102,7 @@ import ( "github.com/percona/pmm/managed/services/victoriametrics" "github.com/percona/pmm/managed/services/vmalert" "github.com/percona/pmm/managed/utils/clean" + "github.com/percona/pmm/managed/utils/distribution" "github.com/percona/pmm/managed/utils/envvars" "github.com/percona/pmm/managed/utils/interceptors" platformClient "github.com/percona/pmm/managed/utils/platform" @@ -131,6 +132,9 @@ const ( clickhouseMaxIdleConns = 5 clickhouseMaxOpenConns = 10 + + distributionInfoFilePath = "/srv/pmm-distribution" + osInfoFilePath = "/proc/version" ) var pprofSemaphore = semaphore.NewWeighted(1) @@ -892,12 +896,12 @@ func main() { //nolint:maintidx,cyclop telemetry.UIEventsExtension: uieventsService, } - telemetry, err := telemetry.NewService(db, platformClient, version.Version, cfg.Config.Services.Telemetry, telemetryExtensions) + dus := distribution.NewService(distributionInfoFilePath, osInfoFilePath, l) + telemetry, err := telemetry.NewService(db, platformClient, version.Version, dus, cfg.Config.Services.Telemetry, telemetryExtensions) if err != nil { l.Fatalf("Could not create telemetry service: %s", err) } - awsInstanceChecker := server.NewAWSInstanceChecker(db, telemetry) grafanaClient := grafana.NewClient(*grafanaAddrF) prom.MustRegister(grafanaClient) @@ -948,10 +952,10 @@ func main() { //nolint:maintidx,cyclop TemplatesService: alertingService, Supervisord: supervisord, TelemetryService: telemetry, - AwsInstanceChecker: awsInstanceChecker, GrafanaClient: grafanaClient, VMAlertExternalRules: externalRules, Updater: updater, + Dus: dus, } server, err := server.NewServer(serverParams) @@ -1019,7 +1023,7 @@ func main() { //nolint:maintidx,cyclop l.Fatalf("Failed to get settings: %+v.", err) } - authServer := grafana.NewAuthServer(grafanaClient, awsInstanceChecker, db) + authServer := grafana.NewAuthServer(grafanaClient, db) l.Info("Starting services...") var wg sync.WaitGroup diff --git a/managed/services/grafana/auth_server.go b/managed/services/grafana/auth_server.go index 4379d23ad0..71c7167448 100644 --- a/managed/services/grafana/auth_server.go +++ b/managed/services/grafana/auth_server.go @@ -94,14 +94,13 @@ var rules = map[string]role{ "/v1/qan": viewer, "/v1/qan:": viewer, - // mustSetupRules group "/prometheus": admin, "/victoriametrics": admin, "/graph": none, "/swagger": none, "/v1/server/logs.zip": admin, - // "/auth_request" and "/setup" have auth_request disabled in nginx config + // "/auth_request" has auth_request disabled in nginx config // "/" is a special case in this code } @@ -115,16 +114,6 @@ var vmProxyPrefixes = []string{ const vmProxyHeaderName = "X-Proxy-Filter" -// Only UI is blocked by setup wizard; APIs can be used. -// Critically, AWSInstanceCheck must be available for the setup wizard itself to work; -// and /agent.v1.AgentService/Connect and Management APIs should be available for pmm-agent on PMM Server registration. -var mustSetupRules = []string{ - "/prometheus", - "/victoriametrics", - "/graph", - "/swagger", -} - // nginx auth_request directive supports only 401 and 403 - every other code results in 500. // Our APIs can return codes.PermissionDenied which maps to 403 / http.StatusForbidden. // Our APIs MUST NOT return codes.Unauthenticated which maps to 401 / http.StatusUnauthorized @@ -158,10 +147,9 @@ type clientInterface interface { // AuthServer authenticates incoming requests via Grafana API. type AuthServer struct { - c clientInterface - checker awsInstanceChecker - db *reform.DB - l *logrus.Entry + c clientInterface + db *reform.DB + l *logrus.Entry cache map[string]cacheItem rw sync.RWMutex @@ -172,13 +160,12 @@ type AuthServer struct { } // NewAuthServer creates new AuthServer. -func NewAuthServer(c clientInterface, checker awsInstanceChecker, db *reform.DB) *AuthServer { +func NewAuthServer(c clientInterface, db *reform.DB) *AuthServer { return &AuthServer{ - c: c, - checker: checker, - db: db, - l: logrus.WithField("component", "grafana/auth"), - cache: make(map[string]cacheItem), + c: c, + db: db, + l: logrus.WithField("component", "grafana/auth"), + cache: make(map[string]cacheItem), accessControl: &accessControl{ db: db, }, @@ -227,10 +214,6 @@ func (s *AuthServer) ServeHTTP(rw http.ResponseWriter, req *http.Request) { l := s.l.WithField("req", fmt.Sprintf("%s %s", req.Method, req.URL.Path)) // TODO l := logger.Get(ctx) once we have it after https://jira.percona.com/browse/PMM-4326 - if s.mustSetup(rw, req, l) { - return - } - // fail-safe ctx, cancel := context.WithTimeout(req.Context(), 3*time.Second) defer cancel() @@ -404,51 +387,6 @@ func extractOriginalRequest(req *http.Request) error { return nil } -// mustSetup returns true if AWS instance ID must be checked. -func (s *AuthServer) mustSetup(rw http.ResponseWriter, req *http.Request, l *logrus.Entry) bool { - // Only UI is blocked by setup wizard; APIs can be used. - var found bool - for _, r := range mustSetupRules { - if strings.HasPrefix(req.URL.Path, r) { - found = true - break - } - } - if !found { - return false - } - - // This header is used to pass information that setup is required from auth_request subrequest - // to normal request to return redirect with location - something that auth_request can't do. - const mustSetupHeader = "X-Must-Setup" - - // Redirect to /setup page. - if req.Header.Get(mustSetupHeader) != "" { - const redirectCode = 303 // temporary, not cacheable, always GET - l.Warnf("AWS instance ID must be checked, returning %d with Location.", redirectCode) - rw.Header().Set("Location", "/setup") - rw.WriteHeader(redirectCode) - return true - } - - // Use X-Test-Must-Setup header for testing. - // There is no way to skip check, only to enforce it. - mustCheck := s.checker.MustCheck() - if req.Header.Get("X-Test-Must-Setup") != "" { - l.Debug("X-Test-Must-Setup is present, enforcing AWS instance ID check.") - mustCheck = true - } - - if mustCheck { - l.Warnf("AWS instance ID must be checked, returning %d with %s.", authenticationErrorCode, mustSetupHeader) - rw.Header().Set(mustSetupHeader, "1") // any non-empty value is ok - rw.WriteHeader(authenticationErrorCode) - return true - } - - return false -} - // nextPrefix returns path's prefix, stopping on slashes, dots, and colons, e.g.: // /inventory.Nodes/ListNodes -> /inventory.Nodes/ -> /inventory.Nodes -> /inventory. -> /inventory -> / // /v1/inventory/Nodes/List -> /v1/inventory/Nodes/ -> /v1/inventory/Nodes -> /v1/inventory/ -> /v1/inventory -> /v1/ -> /v1 -> / diff --git a/managed/services/grafana/auth_server_test.go b/managed/services/grafana/auth_server_test.go index 54ab827128..42aa225fac 100644 --- a/managed/services/grafana/auth_server_test.go +++ b/managed/services/grafana/auth_server_test.go @@ -20,7 +20,6 @@ import ( "encoding/base64" "encoding/json" "fmt" - "io" "net/http" "net/http/httptest" "testing" @@ -65,112 +64,12 @@ func TestNextPrefix(t *testing.T) { } } -func TestAuthServerMustSetup(t *testing.T) { - t.Run("MustCheck", func(t *testing.T) { - req, err := http.NewRequest(http.MethodGet, "/graph", nil) - require.NoError(t, err) - - checker := &mockAwsInstanceChecker{} - checker.Test(t) - defer checker.AssertExpectations(t) - - s := NewAuthServer(nil, checker, nil) - - t.Run("Subrequest", func(t *testing.T) { - checker.On("MustCheck").Return(true) - rw := httptest.NewRecorder() - assert.True(t, s.mustSetup(rw, req, logrus.WithField("test", t.Name()))) - - resp := rw.Result() - defer resp.Body.Close() //nolint:gosec,errcheck,nolintlint - assert.Equal(t, 401, resp.StatusCode) - assert.Equal(t, "1", resp.Header.Get("X-Must-Setup")) - assert.Equal(t, "", resp.Header.Get("Location")) - b, err := io.ReadAll(resp.Body) - assert.NoError(t, err) - assert.Empty(t, b) - }) - - t.Run("Request", func(t *testing.T) { - req.Header.Set("X-Must-Setup", "1") - - checker.On("MustCheck").Return(true) - rw := httptest.NewRecorder() - assert.True(t, s.mustSetup(rw, req, logrus.WithField("test", t.Name()))) - - resp := rw.Result() - defer resp.Body.Close() //nolint:gosec,errcheck,nolintlint - assert.Equal(t, 303, resp.StatusCode) - assert.Equal(t, "", resp.Header.Get("X-Must-Setup")) - assert.Equal(t, "/setup", resp.Header.Get("Location")) - b, err := io.ReadAll(resp.Body) - assert.NoError(t, err) - assert.Empty(t, b) - }) - }) - - t.Run("MustNotCheck", func(t *testing.T) { - req, err := http.NewRequest(http.MethodGet, "/graph", nil) - require.NoError(t, err) - - checker := &mockAwsInstanceChecker{} - checker.Test(t) - defer checker.AssertExpectations(t) - - s := NewAuthServer(nil, checker, nil) - - t.Run("Subrequest", func(t *testing.T) { - checker.On("MustCheck").Return(false) - rw := httptest.NewRecorder() - assert.False(t, s.mustSetup(rw, req, logrus.WithField("test", t.Name()))) - - resp := rw.Result() - defer resp.Body.Close() //nolint:gosec,errcheck,nolintlint - assert.Equal(t, 200, resp.StatusCode) - assert.Equal(t, "", resp.Header.Get("X-Must-Setup")) - assert.Equal(t, "", resp.Header.Get("Location")) - b, err := io.ReadAll(resp.Body) - assert.NoError(t, err) - assert.Empty(t, b) - }) - }) - - t.Run("SkipNonUI", func(t *testing.T) { - req, err := http.NewRequest(http.MethodGet, "/dummy", nil) - require.NoError(t, err) - - checker := &mockAwsInstanceChecker{} - checker.Test(t) - defer checker.AssertExpectations(t) - - s := NewAuthServer(nil, checker, nil) - - t.Run("Subrequest", func(t *testing.T) { - rw := httptest.NewRecorder() - assert.False(t, s.mustSetup(rw, req, logrus.WithField("test", t.Name()))) - - resp := rw.Result() - defer resp.Body.Close() //nolint:gosec,errcheck,nolintlint - assert.Equal(t, 200, resp.StatusCode) - assert.Equal(t, "", resp.Header.Get("X-Must-Setup")) - assert.Equal(t, "", resp.Header.Get("Location")) - b, err := io.ReadAll(resp.Body) - assert.NoError(t, err) - assert.Empty(t, b) - }) - }) -} - func TestAuthServerAuthenticate(t *testing.T) { t.Parallel() - checker := &mockAwsInstanceChecker{} - checker.Test(t) - t.Cleanup(func() { checker.AssertExpectations(t) }) - ctx := context.Background() c := NewClient("127.0.0.1:3000") - s := NewAuthServer(c, checker, nil) + s := NewAuthServer(c, nil) req, err := http.NewRequestWithContext(ctx, http.MethodGet, "/dummy", nil) require.NoError(t, err) @@ -283,13 +182,9 @@ func TestAuthServerAuthenticate(t *testing.T) { func TestServerClientConnection(t *testing.T) { t.Parallel() - checker := &mockAwsInstanceChecker{} - checker.Test(t) - t.Cleanup(func() { checker.AssertExpectations(t) }) - ctx := context.Background() c := NewClient("127.0.0.1:3000") - s := NewAuthServer(c, checker, nil) + s := NewAuthServer(c, nil) t.Run("Basic auth - success", func(t *testing.T) { t.Parallel() @@ -365,12 +260,8 @@ func TestAuthServerAddVMGatewayToken(t *testing.T) { require.NoError(t, sqlDB.Close()) }(t) - var checker mockAwsInstanceChecker - checker.Test(t) - defer checker.AssertExpectations(t) - c := NewClient("127.0.0.1:3000") - s := NewAuthServer(c, &checker, db) + s := NewAuthServer(c, db) roleA := models.Role{ Title: "Role A", diff --git a/managed/services/grafana/deps.go b/managed/services/grafana/deps.go index fe4f32012e..39862b3980 100644 --- a/managed/services/grafana/deps.go +++ b/managed/services/grafana/deps.go @@ -14,9 +14,3 @@ // along with this program. If not, see . package grafana - -// checker is a subset of methods of server.AWSInstanceChecker used by this package. -// We use it instead of real type for testing and to avoid dependency cycle. -type awsInstanceChecker interface { - MustCheck() bool -} diff --git a/managed/services/grafana/mock_aws_instance_checker_test.go b/managed/services/grafana/mock_aws_instance_checker_test.go deleted file mode 100644 index f502ba06d3..0000000000 --- a/managed/services/grafana/mock_aws_instance_checker_test.go +++ /dev/null @@ -1,43 +0,0 @@ -// Code generated by mockery. DO NOT EDIT. - -package grafana - -import mock "github.com/stretchr/testify/mock" - -// mockAwsInstanceChecker is an autogenerated mock type for the awsInstanceChecker type -type mockAwsInstanceChecker struct { - mock.Mock -} - -// MustCheck provides a mock function with given fields: -func (_m *mockAwsInstanceChecker) MustCheck() bool { - ret := _m.Called() - - if len(ret) == 0 { - panic("no return value specified for MustCheck") - } - - var r0 bool - if rf, ok := ret.Get(0).(func() bool); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(bool) - } - - return r0 -} - -// newMockAwsInstanceChecker creates a new instance of mockAwsInstanceChecker. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func newMockAwsInstanceChecker(t interface { - mock.TestingT - Cleanup(func()) -}, -) *mockAwsInstanceChecker { - mock := &mockAwsInstanceChecker{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/managed/services/server/aws_instance_checker.go b/managed/services/server/aws_instance_checker.go deleted file mode 100644 index b4b047f1cb..0000000000 --- a/managed/services/server/aws_instance_checker.go +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright (C) 2023 Percona LLC -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package server - -import ( - "crypto/subtle" - "sync" - - "github.com/aws/aws-sdk-go/aws/ec2metadata" - "github.com/aws/aws-sdk-go/aws/session" - "github.com/pkg/errors" - "github.com/sirupsen/logrus" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - "gopkg.in/reform.v1" - - serverv1 "github.com/percona/pmm/api/server/v1" - "github.com/percona/pmm/managed/models" -) - -// AWSInstanceChecker checks AWS EC2 instance ID for AMI. -type AWSInstanceChecker struct { - db *reform.DB - telemetryService telemetryService - l *logrus.Entry - - rw sync.RWMutex - checked bool -} - -// NewAWSInstanceChecker creates a new AWSInstanceChecker. -func NewAWSInstanceChecker(db *reform.DB, telemetryService telemetryService) *AWSInstanceChecker { - return &AWSInstanceChecker{ - db: db, - telemetryService: telemetryService, - l: logrus.WithField("component", "server/awsInstanceChecker"), - } -} - -// MustCheck returns true if instance ID must be checked: this is AMI, and it wasn't checked already. -func (c *AWSInstanceChecker) MustCheck() bool { - // fast-path without hitting database - c.rw.RLock() - checked := c.checked - c.rw.RUnlock() - if checked { - return false - } - - c.rw.Lock() - defer c.rw.Unlock() - - if c.telemetryService.DistributionMethod() != serverv1.DistributionMethod_DISTRIBUTION_METHOD_AMI { - c.checked = true - return false - } - - settings, err := models.GetSettings(c.db.Querier) - if err != nil { - c.l.Error(err) - return true - } - if settings.AWSInstanceChecked { - c.checked = true - return false - } - - return true -} - -// check performs instance ID check and stores successful result flag in settings. -func (c *AWSInstanceChecker) check(instanceID string) error { - // do not allow more AWS API calls if instance is already checked - if !c.MustCheck() { - return nil - } - - sess, err := session.NewSession() - if err != nil { - return errors.Wrap(err, "cannot create AWS session") - } - doc, err := ec2metadata.New(sess).GetInstanceIdentityDocument() - if err != nil { - c.l.Error(err) - return status.Error(codes.Unavailable, "cannot get instance metadata") - } - if subtle.ConstantTimeCompare([]byte(instanceID), []byte(doc.InstanceID)) == 0 { - return status.Error(codes.InvalidArgument, "invalid instance ID") - } - - if e := c.db.InTransaction(func(tx *reform.TX) error { - settings, err := models.GetSettings(tx.Querier) - if err != nil { - return err - } - - settings.AWSInstanceChecked = true - return models.SaveSettings(tx.Querier, settings) - }); e != nil { - return e - } - - c.rw.Lock() - c.checked = true - c.rw.Unlock() - - return nil -} diff --git a/managed/services/server/aws_instance_checker_test.go b/managed/services/server/aws_instance_checker_test.go deleted file mode 100644 index f82d0a8b63..0000000000 --- a/managed/services/server/aws_instance_checker_test.go +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (C) 2023 Percona LLC -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package server - -import ( - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - "gopkg.in/reform.v1" - "gopkg.in/reform.v1/dialects/postgresql" - - serverv1 "github.com/percona/pmm/api/server/v1" - "github.com/percona/pmm/managed/models" - "github.com/percona/pmm/managed/utils/testdb" - "github.com/percona/pmm/managed/utils/tests" -) - -func TestAWSInstanceChecker(t *testing.T) { - setup := func(t *testing.T) (db *reform.DB, teardown func()) { - t.Helper() - sqlDB := testdb.Open(t, models.SkipFixtures, nil) - db = reform.NewDB(sqlDB, postgresql.Dialect, reform.NewPrintfLogger(t.Logf)) - - teardown = func() { - t.Helper() - require.NoError(t, sqlDB.Close()) - } - - return - } - - t.Run("Docker", func(t *testing.T) { - db, teardown := setup(t) - defer teardown() - - telemetry := &mockTelemetryService{} - telemetry.Test(t) - telemetry.On("DistributionMethod").Return(serverv1.DistributionMethod_DISTRIBUTION_METHOD_DOCKER) - defer telemetry.AssertExpectations(t) - - checker := NewAWSInstanceChecker(db, telemetry) - assert.False(t, checker.MustCheck()) - assert.NoError(t, checker.check("foo")) - }) - - t.Run("AMI", func(t *testing.T) { - db, teardown := setup(t) - defer teardown() - - telemetry := &mockTelemetryService{} - telemetry.Test(t) - telemetry.On("DistributionMethod").Return(serverv1.DistributionMethod_DISTRIBUTION_METHOD_AMI) - defer telemetry.AssertExpectations(t) - - checker := NewAWSInstanceChecker(db, telemetry) - assert.True(t, checker.MustCheck()) - tests.AssertGRPCError(t, status.New(codes.Unavailable, `cannot get instance metadata`), checker.check("foo")) - }) - - t.Run("AMI/Checked", func(t *testing.T) { - db, teardown := setup(t) - defer teardown() - - settings, err := models.GetSettings(db.Querier) - require.NoError(t, err) - settings.AWSInstanceChecked = true - err = models.SaveSettings(db.Querier, settings) - require.NoError(t, err) - - telemetry := &mockTelemetryService{} - telemetry.Test(t) - telemetry.On("DistributionMethod").Return(serverv1.DistributionMethod_DISTRIBUTION_METHOD_AMI) - defer telemetry.AssertExpectations(t) - - checker := NewAWSInstanceChecker(db, telemetry) - assert.False(t, checker.MustCheck()) - assert.NoError(t, checker.check("foo")) - }) -} diff --git a/managed/services/server/server.go b/managed/services/server/server.go index 2bd2cd502d..051214bf8c 100644 --- a/managed/services/server/server.go +++ b/managed/services/server/server.go @@ -43,6 +43,7 @@ import ( serverv1 "github.com/percona/pmm/api/server/v1" "github.com/percona/pmm/managed/models" + "github.com/percona/pmm/managed/utils/distribution" "github.com/percona/pmm/managed/utils/envvars" "github.com/percona/pmm/version" ) @@ -58,7 +59,6 @@ type Server struct { templatesService templatesService supervisord supervisordService telemetryService telemetryService - awsInstanceChecker *AWSInstanceChecker grafanaClient grafanaClient haService haService updater *Updater @@ -91,9 +91,9 @@ type Params struct { VMAlertExternalRules vmAlertExternalRules Supervisord supervisordService TelemetryService telemetryService - AwsInstanceChecker *AWSInstanceChecker GrafanaClient grafanaClient Updater *Updater + Dus *distribution.Service } // NewServer returns new server for Server service. @@ -114,7 +114,6 @@ func NewServer(params *Params) (*Server, error) { vmalertExternalRules: params.VMAlertExternalRules, supervisord: params.Supervisord, telemetryService: params.TelemetryService, - awsInstanceChecker: params.AwsInstanceChecker, grafanaClient: params.GrafanaClient, updater: params.Updater, l: logrus.WithField("component", "server"), @@ -666,6 +665,11 @@ func (s *Server) writeSSHKey(sshKey string) error { s.sshKeyM.Lock() defer s.sshKeyM.Unlock() + distributionMethod := s.telemetryService.DistributionMethod() + if distributionMethod != serverv1.DistributionMethod_DISTRIBUTION_METHOD_AMI && distributionMethod != serverv1.DistributionMethod_DISTRIBUTION_METHOD_OVF { + return errors.New("SSH key can be set only on AMI and OVF distributions") + } + username := "pmm" usr, err := user.Lookup(username) if err != nil { @@ -676,35 +680,13 @@ func (s *Server) writeSSHKey(sshKey string) error { return errors.WithStack(err) } - uid, err := strconv.Atoi(usr.Uid) - if err != nil { - return errors.WithStack(err) - } - gid, err := strconv.Atoi(usr.Gid) - if err != nil { - return errors.WithStack(err) - } - if err = os.Chown(sshDirPath, uid, gid); err != nil { - return errors.WithStack(err) - } keysPath := path.Join(sshDirPath, "authorized_keys") if err = os.WriteFile(keysPath, []byte(sshKey), 0o600); err != nil { return errors.WithStack(err) } - if err = os.Chown(keysPath, uid, gid); err != nil { - return errors.WithStack(err) - } return nil } -// AWSInstanceCheck checks AWS EC2 instance ID. -func (s *Server) AWSInstanceCheck(ctx context.Context, req *serverv1.AWSInstanceCheckRequest) (*serverv1.AWSInstanceCheckResponse, error) { //nolint:revive - if err := s.awsInstanceChecker.check(req.InstanceId); err != nil { - return nil, err - } - return &serverv1.AWSInstanceCheckResponse{}, nil -} - // isAgentsStateUpdateNeeded - checks metrics resolution changes, // if it was changed, agents state must be updated. func isAgentsStateUpdateNeeded(mr *serverv1.MetricsResolutions) bool { diff --git a/managed/services/server/updater.go b/managed/services/server/updater.go index 0240536e19..62683a7643 100644 --- a/managed/services/server/updater.go +++ b/managed/services/server/updater.go @@ -147,7 +147,6 @@ func (up *Updater) StartUpdate(ctx context.Context, newImageName string) error { return errors.New("update already in progress") } up.running = true - up.performM.Unlock() if newImageName == "" { return errors.New("newImageName is empty") } diff --git a/managed/services/telemetry/deps.go b/managed/services/telemetry/deps.go index b10e89310b..603e669505 100644 --- a/managed/services/telemetry/deps.go +++ b/managed/services/telemetry/deps.go @@ -26,7 +26,7 @@ import ( // distributionUtilService service to get info about OS on which pmm server is running. type distributionUtilService interface { - getDistributionMethodAndOS() (serverv1.DistributionMethod, pmmv1.DistributionMethod, string) + GetDistributionMethodAndOS() (serverv1.DistributionMethod, pmmv1.DistributionMethod, string) } // sender is interface which defines method for client which sends report with metrics. diff --git a/managed/services/telemetry/mock_distribution_util_service_test.go b/managed/services/telemetry/mock_distribution_util_service_test.go index b8a33e7fb9..baa81ac8e8 100644 --- a/managed/services/telemetry/mock_distribution_util_service_test.go +++ b/managed/services/telemetry/mock_distribution_util_service_test.go @@ -14,12 +14,12 @@ type mockDistributionUtilService struct { mock.Mock } -// getDistributionMethodAndOS provides a mock function with given fields: -func (_m *mockDistributionUtilService) getDistributionMethodAndOS() (serverv1.DistributionMethod, pmmv1.DistributionMethod, string) { +// GetDistributionMethodAndOS provides a mock function with given fields: +func (_m *mockDistributionUtilService) GetDistributionMethodAndOS() (serverv1.DistributionMethod, pmmv1.DistributionMethod, string) { ret := _m.Called() if len(ret) == 0 { - panic("no return value specified for getDistributionMethodAndOS") + panic("no return value specified for GetDistributionMethodAndOS") } var r0 serverv1.DistributionMethod diff --git a/managed/services/telemetry/telemetry.go b/managed/services/telemetry/telemetry.go index c303094368..966ee5ec27 100644 --- a/managed/services/telemetry/telemetry.go +++ b/managed/services/telemetry/telemetry.go @@ -38,9 +38,7 @@ import ( ) const ( - distributionInfoFilePath = "/srv/pmm-distribution" - osInfoFilePath = "/proc/version" - sendChSize = 10 + sendChSize = 10 ) // Service reports telemetry. @@ -69,7 +67,9 @@ var ( ) // NewService creates a new service. -func NewService(db *reform.DB, portalClient *platform.Client, pmmVersion string, config ServiceConfig, extensions map[ExtensionType]Extension) (*Service, error) { +func NewService(db *reform.DB, portalClient *platform.Client, pmmVersion string, + dus distributionUtilService, config ServiceConfig, extensions map[ExtensionType]Extension, +) (*Service, error) { if config.SaasHostname == "" { return nil, errors.New("empty host") } @@ -80,7 +80,6 @@ func NewService(db *reform.DB, portalClient *platform.Client, pmmVersion string, if err != nil { return nil, err } - dus := newDistributionUtilServiceImpl(distributionInfoFilePath, osInfoFilePath, l) s := &Service{ db: db, l: l, @@ -94,7 +93,7 @@ func NewService(db *reform.DB, portalClient *platform.Client, pmmVersion string, extensions: extensions, } - s.sDistributionMethod, s.tDistributionMethod, s.os = dus.getDistributionMethodAndOS() + s.sDistributionMethod, s.tDistributionMethod, s.os = dus.GetDistributionMethodAndOS() s.dataSourcesMap = s.locateDataSources(config.telemetry) return s, nil @@ -360,7 +359,7 @@ func (s *Service) makeMetric(ctx context.Context) (*pmmv1.ServerMetric, error) { if err != nil { return nil, errors.Wrapf(err, "failed to decode UUID %s", serverIDToUse) } - _, distMethod, _ := s.dus.getDistributionMethodAndOS() + _, distMethod, _ := s.dus.GetDistributionMethodAndOS() eventID := uuid.New() return &pmmv1.ServerMetric{ diff --git a/managed/services/telemetry/telemetry_test.go b/managed/services/telemetry/telemetry_test.go index 16dcf8722b..ac463b6589 100644 --- a/managed/services/telemetry/telemetry_test.go +++ b/managed/services/telemetry/telemetry_test.go @@ -34,6 +34,7 @@ import ( serverv1 "github.com/percona/pmm/api/server/v1" "github.com/percona/pmm/managed/models" + "github.com/percona/pmm/managed/utils/distribution" "github.com/percona/pmm/managed/utils/testdb" ) @@ -258,7 +259,7 @@ func getServiceConfig(pgPortHost string, qanDSN string, vmDSN string) ServiceCon return serviceConfig } -func getDistributionUtilService(t *testing.T, l *logrus.Entry) *distributionUtilServiceImpl { +func getDistributionUtilService(t *testing.T, l *logrus.Entry) distributionUtilService { t.Helper() const ( tmpDistributionFile = "/tmp/distribution" @@ -269,7 +270,7 @@ func getDistributionUtilService(t *testing.T, l *logrus.Entry) *distributionUtil assert.Fail(t, "cannot write to file: ", err) return nil } - dus := newDistributionUtilServiceImpl(tmpDistributionFile, osInfoFilePath, l) + dus := distribution.NewService(tmpDistributionFile, "/proc/version", l) return dus } diff --git a/managed/services/telemetry/distribution_util.go b/managed/utils/distribution/distribution_util.go similarity index 73% rename from managed/services/telemetry/distribution_util.go rename to managed/utils/distribution/distribution_util.go index 986ee00f55..e25f21b3b5 100644 --- a/managed/services/telemetry/distribution_util.go +++ b/managed/utils/distribution/distribution_util.go @@ -13,7 +13,8 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -package telemetry +// Package distribution provides structures and methods to determine the distribution method and OS of the PMM Server. +package distribution import ( "bytes" @@ -26,29 +27,36 @@ import ( serverv1 "github.com/percona/pmm/api/server/v1" ) -type distributionUtilServiceImpl struct { +// Service provides methods to determine the distribution method and OS of the PMM Server. +type Service struct { distributionInfoFilePath string osInfoFilePath string l *logrus.Entry } -func newDistributionUtilServiceImpl(distributionFilePath, osInfoFilePath string, l *logrus.Entry) *distributionUtilServiceImpl { - return &distributionUtilServiceImpl{ +// NewService creates a new Distribution Service. +func NewService(distributionFilePath, osInfoFilePath string, l *logrus.Entry) *Service { + return &Service{ distributionInfoFilePath: distributionFilePath, osInfoFilePath: osInfoFilePath, l: l, } } -func (d distributionUtilServiceImpl) getDistributionMethodAndOS() (serverv1.DistributionMethod, pmmv1.DistributionMethod, string) { - b, err := os.ReadFile(d.distributionInfoFilePath) - if err != nil { - d.l.Debugf("Failed to read %s: %s", d.distributionInfoFilePath, err) - } +// GetDistributionMethodAndOS returns the distribution method and OS of the PMM Server. +func (d Service) GetDistributionMethodAndOS() (serverv1.DistributionMethod, pmmv1.DistributionMethod, string) { + dm := os.Getenv("PMM_DISTRIBUTION_METHOD") + if dm == "" { + b, err := os.ReadFile(d.distributionInfoFilePath) + if err != nil { + d.l.Debugf("Failed to read %s: %s", d.distributionInfoFilePath, err) + } - b = bytes.ToLower(bytes.TrimSpace(b)) - switch string(b) { + b = bytes.ToLower(bytes.TrimSpace(b)) + dm = string(b) + } + switch dm { case "ovf": return serverv1.DistributionMethod_DISTRIBUTION_METHOD_OVF, pmmv1.DistributionMethod_OVF, "ovf" case "ami": @@ -58,7 +66,8 @@ func (d distributionUtilServiceImpl) getDistributionMethodAndOS() (serverv1.Dist case "digitalocean": return serverv1.DistributionMethod_DISTRIBUTION_METHOD_DO, pmmv1.DistributionMethod_DO, "digitalocean" case "docker", "": // /srv/pmm-distribution does not exist in PMM 2.0. - if b, err = os.ReadFile(d.osInfoFilePath); err != nil { + b, err := os.ReadFile(d.osInfoFilePath) + if err != nil { d.l.Debugf("Failed to read %s: %s", d.osInfoFilePath, err) } return serverv1.DistributionMethod_DISTRIBUTION_METHOD_DOCKER, pmmv1.DistributionMethod_DOCKER, d.getLinuxDistribution(string(b)) @@ -85,7 +94,7 @@ var procVersionRegexps = []pair{ } // getLinuxDistribution detects Linux distribution and version from /proc/version information. -func (d distributionUtilServiceImpl) getLinuxDistribution(procVersion string) string { +func (d Service) getLinuxDistribution(procVersion string) string { for _, p := range procVersionRegexps { match := p.re.FindStringSubmatchIndex(procVersion) if match != nil { diff --git a/managed/services/telemetry/distribution_util_test.go b/managed/utils/distribution/distribution_util_test.go similarity index 94% rename from managed/services/telemetry/distribution_util_test.go rename to managed/utils/distribution/distribution_util_test.go index 596b0ce373..dca253ccd0 100644 --- a/managed/services/telemetry/distribution_util_test.go +++ b/managed/utils/distribution/distribution_util_test.go @@ -13,7 +13,7 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -package telemetry +package distribution import ( "os" @@ -132,11 +132,11 @@ func Test_distributionUtilServiceImpl_getDistributionMethodAndOS(t *testing.T) { tmpOsInfoFilePath = f2.Name() } - d := newDistributionUtilServiceImpl(tmpDistributionFilePath, tmpOsInfoFilePath, logEntry) - got, got1, got2 := d.getDistributionMethodAndOS() - assert.Equalf(t, tt.want, got, "getDistributionMethodAndOS() serverv1.DistributionMethod") - assert.Equalf(t, tt.want1, got1, "getDistributionMethodAndOS() pmmv1.DistributionMethod") - assert.Equalf(t, tt.want2, got2, "getDistributionMethodAndOS() name") + d := NewService(tmpDistributionFilePath, tmpOsInfoFilePath, logEntry) + got, got1, got2 := d.GetDistributionMethodAndOS() + assert.Equalf(t, tt.want, got, "GetDistributionMethodAndOS() serverv1.DistributionMethod") + assert.Equalf(t, tt.want1, got1, "GetDistributionMethodAndOS() pmmv1.DistributionMethod") + assert.Equalf(t, tt.want2, got2, "GetDistributionMethodAndOS() name") }) } } @@ -228,7 +228,7 @@ func Test_distributionUtilServiceImpl_getLinuxDistribution(t *testing.T) { t.Run(tt.name, func(t *testing.T) { t.Parallel() - d := distributionUtilServiceImpl{ + d := Service{ distributionInfoFilePath: tmpDistributionFile, osInfoFilePath: tmpOsInfoFilePath, l: logEntry, diff --git a/managed/utils/envvars/parser.go b/managed/utils/envvars/parser.go index d2515f5ea3..6d68a85187 100644 --- a/managed/utils/envvars/parser.go +++ b/managed/utils/envvars/parser.go @@ -176,7 +176,7 @@ func ParseEnvVars(envs []string) (*models.ChangeSettingsParams, []error, []strin err = fmt.Errorf("invalid value %q for environment variable %q", v, k) } - case "PMM_INSTALL_METHOD": + case "PMM_INSTALL_METHOD", "PMM_DISTRIBUTION_METHOD": continue case envEnableAccessControl: