mirror of
https://github.com/mattermost/mattermost.git
synced 2025-02-25 18:55:24 -06:00
[MM-56348] system/ping: add new method with options (#26079)
This commit is contained in:
parent
0aaa047ea3
commit
7d8a56019b
@ -47,6 +47,11 @@
|
|||||||
|
|
||||||
__Minimum server version__: 6.5
|
__Minimum server version__: 6.5
|
||||||
|
|
||||||
|
If "use_rest_semantics" is set to true in the query, the endpoint will not return
|
||||||
|
an error status code in the header if the request is somehow completed successfully.
|
||||||
|
|
||||||
|
__Minimum server version__: 9.6
|
||||||
|
|
||||||
##### Permissions
|
##### Permissions
|
||||||
|
|
||||||
None.
|
None.
|
||||||
@ -64,6 +69,12 @@
|
|||||||
required: false
|
required: false
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
|
- name: use_rest_semantics
|
||||||
|
in: query
|
||||||
|
description: Returns 200 status code even if the server status is unhealthy.
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: boolean
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: Status of the system
|
description: Status of the system
|
||||||
|
@ -179,6 +179,7 @@ func getSystemPing(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
s[filestoreStatusKey] = model.StatusOk
|
s[filestoreStatusKey] = model.StatusOk
|
||||||
appErr := c.App.TestFileStoreConnection()
|
appErr := c.App.TestFileStoreConnection()
|
||||||
if appErr != nil {
|
if appErr != nil {
|
||||||
|
c.Logger.Warn("Unable to test filestore connection.", mlog.Err(appErr))
|
||||||
s[filestoreStatusKey] = model.StatusUnhealthy
|
s[filestoreStatusKey] = model.StatusUnhealthy
|
||||||
s[model.STATUS] = model.StatusUnhealthy
|
s[model.STATUS] = model.StatusUnhealthy
|
||||||
}
|
}
|
||||||
@ -194,7 +195,7 @@ func getSystemPing(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
s["ActiveSearchBackend"] = c.App.ActiveSearchBackend()
|
s["ActiveSearchBackend"] = c.App.ActiveSearchBackend()
|
||||||
|
|
||||||
if s[model.STATUS] != model.StatusOk {
|
if s[model.STATUS] != model.StatusOk && r.FormValue("use_rest_semantics") != "true" {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
w.Write([]byte(model.MapToJSON(s)))
|
w.Write([]byte(model.MapToJSON(s)))
|
||||||
|
@ -119,6 +119,7 @@ type Client interface {
|
|||||||
MigrateAuthToSaml(ctx context.Context, fromAuthService string, usersMap map[string]string, auto bool) (*model.Response, error)
|
MigrateAuthToSaml(ctx context.Context, fromAuthService string, usersMap map[string]string, auto bool) (*model.Response, error)
|
||||||
GetPing(ctx context.Context) (string, *model.Response, error)
|
GetPing(ctx context.Context) (string, *model.Response, error)
|
||||||
GetPingWithFullServerStatus(ctx context.Context) (map[string]string, *model.Response, error)
|
GetPingWithFullServerStatus(ctx context.Context) (map[string]string, *model.Response, error)
|
||||||
|
GetPingWithOptions(ctx context.Context, options model.SystemPingOptions) (map[string]string, *model.Response, error)
|
||||||
CreateUpload(ctx context.Context, us *model.UploadSession) (*model.UploadSession, *model.Response, error)
|
CreateUpload(ctx context.Context, us *model.UploadSession) (*model.UploadSession, *model.Response, error)
|
||||||
GetUpload(ctx context.Context, uploadID string) (*model.UploadSession, *model.Response, error)
|
GetUpload(ctx context.Context, uploadID string) (*model.UploadSession, *model.Response, error)
|
||||||
GetUploadsForUser(ctx context.Context, userID string) ([]*model.UploadSession, *model.Response, error)
|
GetUploadsForUser(ctx context.Context, userID string) ([]*model.UploadSession, *model.Response, error)
|
||||||
|
@ -12,6 +12,7 @@ import (
|
|||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
"github.com/mattermost/mattermost/server/public/model"
|
||||||
"github.com/mattermost/mattermost/server/v8/cmd/mmctl/client"
|
"github.com/mattermost/mattermost/server/v8/cmd/mmctl/client"
|
||||||
"github.com/mattermost/mattermost/server/v8/cmd/mmctl/printer"
|
"github.com/mattermost/mattermost/server/v8/cmd/mmctl/printer"
|
||||||
)
|
)
|
||||||
@ -150,7 +151,10 @@ func systemVersionCmdF(c client.Client, cmd *cobra.Command, _ []string) error {
|
|||||||
func systemStatusCmdF(c client.Client, cmd *cobra.Command, _ []string) error {
|
func systemStatusCmdF(c client.Client, cmd *cobra.Command, _ []string) error {
|
||||||
printer.SetSingle(true)
|
printer.SetSingle(true)
|
||||||
|
|
||||||
status, _, err := c.GetPingWithFullServerStatus(context.TODO())
|
status, _, err := c.GetPingWithOptions(context.TODO(), model.SystemPingOptions{
|
||||||
|
FullStatus: true,
|
||||||
|
RESTSemantics: true,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to fetch server status: %w", err)
|
return fmt.Errorf("unable to fetch server status: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -188,7 +188,10 @@ func (s *MmctlUnitTestSuite) TestServerStatusCmd() {
|
|||||||
expectedStatus := map[string]string{"status": "OK"}
|
expectedStatus := map[string]string{"status": "OK"}
|
||||||
s.client.
|
s.client.
|
||||||
EXPECT().
|
EXPECT().
|
||||||
GetPingWithFullServerStatus(context.Background()).
|
GetPingWithOptions(context.Background(), model.SystemPingOptions{
|
||||||
|
FullStatus: true,
|
||||||
|
RESTSemantics: true,
|
||||||
|
}).
|
||||||
Return(expectedStatus, &model.Response{}, nil).
|
Return(expectedStatus, &model.Response{}, nil).
|
||||||
Times(1)
|
Times(1)
|
||||||
|
|
||||||
@ -204,7 +207,10 @@ func (s *MmctlUnitTestSuite) TestServerStatusCmd() {
|
|||||||
|
|
||||||
s.client.
|
s.client.
|
||||||
EXPECT().
|
EXPECT().
|
||||||
GetPingWithFullServerStatus(context.Background()).
|
GetPingWithOptions(context.Background(), model.SystemPingOptions{
|
||||||
|
FullStatus: true,
|
||||||
|
RESTSemantics: true,
|
||||||
|
}).
|
||||||
Return(nil, &model.Response{}, errors.New("mock error")).
|
Return(nil, &model.Response{}, errors.New("mock error")).
|
||||||
Times(1)
|
Times(1)
|
||||||
|
|
||||||
|
@ -1054,6 +1054,22 @@ func (mr *MockClientMockRecorder) GetPingWithFullServerStatus(arg0 interface{})
|
|||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPingWithFullServerStatus", reflect.TypeOf((*MockClient)(nil).GetPingWithFullServerStatus), arg0)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPingWithFullServerStatus", reflect.TypeOf((*MockClient)(nil).GetPingWithFullServerStatus), arg0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetPingWithOptions mocks base method.
|
||||||
|
func (m *MockClient) GetPingWithOptions(arg0 context.Context, arg1 model.SystemPingOptions) (map[string]string, *model.Response, error) {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "GetPingWithOptions", arg0, arg1)
|
||||||
|
ret0, _ := ret[0].(map[string]string)
|
||||||
|
ret1, _ := ret[1].(*model.Response)
|
||||||
|
ret2, _ := ret[2].(error)
|
||||||
|
return ret0, ret1, ret2
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPingWithOptions indicates an expected call of GetPingWithOptions.
|
||||||
|
func (mr *MockClientMockRecorder) GetPingWithOptions(arg0, arg1 interface{}) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPingWithOptions", reflect.TypeOf((*MockClient)(nil).GetPingWithOptions), arg0, arg1)
|
||||||
|
}
|
||||||
|
|
||||||
// GetPlugins mocks base method.
|
// GetPlugins mocks base method.
|
||||||
func (m *MockClient) GetPlugins(arg0 context.Context) (*model.PluginsResponse, *model.Response, error) {
|
func (m *MockClient) GetPlugins(arg0 context.Context) (*model.PluginsResponse, *model.Response, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
|
@ -4607,38 +4607,46 @@ func (c *Client4) GenerateSupportPacket(ctx context.Context) ([]byte, *Response,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetPing will return ok if the running goRoutines are below the threshold and unhealthy for above.
|
// GetPing will return ok if the running goRoutines are below the threshold and unhealthy for above.
|
||||||
|
// DEPRECATED: Use GetPingWithOptions method instead.
|
||||||
func (c *Client4) GetPing(ctx context.Context) (string, *Response, error) {
|
func (c *Client4) GetPing(ctx context.Context) (string, *Response, error) {
|
||||||
r, err := c.DoAPIGet(ctx, c.systemRoute()+"/ping", "")
|
ping, resp, err := c.GetPingWithOptions(ctx, SystemPingOptions{})
|
||||||
if r != nil && r.StatusCode == 500 {
|
status := ""
|
||||||
defer r.Body.Close()
|
if ping != nil {
|
||||||
return StatusUnhealthy, BuildResponse(r), err
|
status = ping["status"]
|
||||||
}
|
}
|
||||||
if err != nil {
|
return status, resp, err
|
||||||
return "", BuildResponse(r), err
|
|
||||||
}
|
|
||||||
defer closeBody(r)
|
|
||||||
return MapFromJSON(r.Body)["status"], BuildResponse(r), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPingWithServerStatus will return ok if several basic server health checks
|
// GetPingWithServerStatus will return ok if several basic server health checks
|
||||||
// all pass successfully.
|
// all pass successfully.
|
||||||
|
// DEPRECATED: Use GetPingWithOptions method instead.
|
||||||
func (c *Client4) GetPingWithServerStatus(ctx context.Context) (string, *Response, error) {
|
func (c *Client4) GetPingWithServerStatus(ctx context.Context) (string, *Response, error) {
|
||||||
r, err := c.DoAPIGet(ctx, c.systemRoute()+"/ping?get_server_status="+c.boolString(true), "")
|
ping, resp, err := c.GetPingWithOptions(ctx, SystemPingOptions{FullStatus: true})
|
||||||
if r != nil && r.StatusCode == 500 {
|
status := ""
|
||||||
defer r.Body.Close()
|
if ping != nil {
|
||||||
return StatusUnhealthy, BuildResponse(r), err
|
status = ping["status"]
|
||||||
}
|
}
|
||||||
if err != nil {
|
return status, resp, err
|
||||||
return "", BuildResponse(r), err
|
|
||||||
}
|
|
||||||
defer closeBody(r)
|
|
||||||
return MapFromJSON(r.Body)["status"], BuildResponse(r), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPingWithFullServerStatus will return the full status if several basic server
|
// GetPingWithFullServerStatus will return the full status if several basic server
|
||||||
// health checks all pass successfully.
|
// health checks all pass successfully.
|
||||||
|
// DEPRECATED: Use GetPingWithOptions method instead.
|
||||||
func (c *Client4) GetPingWithFullServerStatus(ctx context.Context) (map[string]string, *Response, error) {
|
func (c *Client4) GetPingWithFullServerStatus(ctx context.Context) (map[string]string, *Response, error) {
|
||||||
r, err := c.DoAPIGet(ctx, c.systemRoute()+"/ping?get_server_status="+c.boolString(true), "")
|
return c.GetPingWithOptions(ctx, SystemPingOptions{FullStatus: true})
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPingWithOptions will return the status according to the options
|
||||||
|
func (c *Client4) GetPingWithOptions(ctx context.Context, options SystemPingOptions) (map[string]string, *Response, error) {
|
||||||
|
pingURL, err := url.Parse(c.systemRoute() + "/ping")
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("could not parse query: %w", err)
|
||||||
|
}
|
||||||
|
values := pingURL.Query()
|
||||||
|
values.Set("get_server_status", c.boolString(options.FullStatus))
|
||||||
|
values.Set("use_rest_semantics", c.boolString(options.RESTSemantics))
|
||||||
|
pingURL.RawQuery = values.Encode()
|
||||||
|
r, err := c.DoAPIGet(ctx, pingURL.String(), "")
|
||||||
if r != nil && r.StatusCode == 500 {
|
if r != nil && r.StatusCode == 500 {
|
||||||
defer r.Body.Close()
|
defer r.Body.Close()
|
||||||
return map[string]string{"status": StatusUnhealthy}, BuildResponse(r), err
|
return map[string]string{"status": StatusUnhealthy}, BuildResponse(r), err
|
||||||
|
@ -245,3 +245,14 @@ type LogEntry struct {
|
|||||||
Timestamp string
|
Timestamp string
|
||||||
Level string
|
Level string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SystemPingOptions is the options for setting contents of the system ping
|
||||||
|
// response.
|
||||||
|
type SystemPingOptions struct {
|
||||||
|
// FullStatus allows server to set the detailed information about
|
||||||
|
// the system status.
|
||||||
|
FullStatus bool
|
||||||
|
// RestSemantics allows server to return 200 code even if the server
|
||||||
|
// status is unhealthy.
|
||||||
|
RESTSemantics bool
|
||||||
|
}
|
||||||
|
@ -2456,8 +2456,8 @@ export default class Client4 {
|
|||||||
database_status: string;
|
database_status: string;
|
||||||
filestore_status: string;
|
filestore_status: string;
|
||||||
}>(
|
}>(
|
||||||
`${this.getBaseRoute()}/system/ping${buildQueryString({get_server_status: getServerStatus, device_id: deviceId})}`,
|
`${this.getBaseRoute()}/system/ping${buildQueryString({get_server_status: getServerStatus, device_id: deviceId, use_rest_semantics: true})}`,
|
||||||
{method: 'get', ignoreStatus: true},
|
{method: 'get'},
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user