[MM-25657] api4/config: add config migrate endpoint (#14928)
* api4/config: add config migrate endpoint * api4/config: reflect review comments * fix i18n lint error Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
bda24c8fe0
Коммит
16ffb6712f
@@ -20,6 +20,7 @@ func (api *API) InitConfig() {
|
|||||||
api.BaseRoutes.ApiRoot.Handle("/config/reload", api.ApiSessionRequired(configReload)).Methods("POST")
|
api.BaseRoutes.ApiRoot.Handle("/config/reload", api.ApiSessionRequired(configReload)).Methods("POST")
|
||||||
api.BaseRoutes.ApiRoot.Handle("/config/client", api.ApiHandler(getClientConfig)).Methods("GET")
|
api.BaseRoutes.ApiRoot.Handle("/config/client", api.ApiHandler(getClientConfig)).Methods("GET")
|
||||||
api.BaseRoutes.ApiRoot.Handle("/config/environment", api.ApiSessionRequired(getEnvironmentConfig)).Methods("GET")
|
api.BaseRoutes.ApiRoot.Handle("/config/environment", api.ApiSessionRequired(getEnvironmentConfig)).Methods("GET")
|
||||||
|
api.BaseRoutes.ApiRoot.Handle("/config/migrate", api.ApiSessionRequired(migrateConfig)).Methods("POST")
|
||||||
}
|
}
|
||||||
|
|
||||||
func getConfig(c *Context, w http.ResponseWriter, r *http.Request) {
|
func getConfig(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||||
@@ -227,3 +228,36 @@ func patchConfig(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
|
w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
|
||||||
w.Write([]byte(c.App.GetSanitizedConfig().ToJson()))
|
w.Write([]byte(c.App.GetSanitizedConfig().ToJson()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func migrateConfig(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||||
|
props := model.StringInterfaceFromJson(r.Body)
|
||||||
|
from, ok := props["from"].(string)
|
||||||
|
if !ok {
|
||||||
|
c.SetInvalidParam("from")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
to, ok := props["to"].(string)
|
||||||
|
if !ok {
|
||||||
|
c.SetInvalidParam("to")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
auditRec := c.MakeAuditRecord("migrateConfig", audit.Fail)
|
||||||
|
auditRec.AddMeta("from", from)
|
||||||
|
auditRec.AddMeta("to", to)
|
||||||
|
defer c.LogAuditRec(auditRec)
|
||||||
|
|
||||||
|
if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_MANAGE_SYSTEM) {
|
||||||
|
c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err := config.Migrate(from, to)
|
||||||
|
if err != nil {
|
||||||
|
c.Err = model.NewAppError("migrateConfig", "api.config.migrate_config.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
auditRec.Success()
|
||||||
|
ReturnStatusOK(w)
|
||||||
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ func (api *API) InitConfigLocal() {
|
|||||||
api.BaseRoutes.ApiRoot.Handle("/config", api.ApiLocal(getConfig)).Methods("GET")
|
api.BaseRoutes.ApiRoot.Handle("/config", api.ApiLocal(getConfig)).Methods("GET")
|
||||||
api.BaseRoutes.ApiRoot.Handle("/config", api.ApiLocal(localUpdateConfig)).Methods("PUT")
|
api.BaseRoutes.ApiRoot.Handle("/config", api.ApiLocal(localUpdateConfig)).Methods("PUT")
|
||||||
api.BaseRoutes.ApiRoot.Handle("/config/patch", api.ApiLocal(localPatchConfig)).Methods("PUT")
|
api.BaseRoutes.ApiRoot.Handle("/config/patch", api.ApiLocal(localPatchConfig)).Methods("PUT")
|
||||||
|
api.BaseRoutes.ApiRoot.Handle("/config/migrate", api.ApiLocal(migrateConfig)).Methods("POST")
|
||||||
}
|
}
|
||||||
|
|
||||||
func localUpdateConfig(c *Context, w http.ResponseWriter, r *http.Request) {
|
func localUpdateConfig(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/mattermost/mattermost-server/v5/config"
|
||||||
"github.com/mattermost/mattermost-server/v5/model"
|
"github.com/mattermost/mattermost-server/v5/model"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
@@ -551,3 +552,26 @@ func TestPatchConfig(t *testing.T) {
|
|||||||
require.Equal(t, nonEmptyURL, *cfg.ServiceSettings.SiteURL)
|
require.Equal(t, nonEmptyURL, *cfg.ServiceSettings.SiteURL)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMigrateConfig(t *testing.T) {
|
||||||
|
th := Setup(t).InitBasic()
|
||||||
|
defer th.TearDown()
|
||||||
|
|
||||||
|
t.Run("user is not system admin", func(t *testing.T) {
|
||||||
|
_, response := th.Client.MigrateConfig("from", "to")
|
||||||
|
CheckForbiddenStatus(t, response)
|
||||||
|
})
|
||||||
|
|
||||||
|
th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
|
||||||
|
f, err := config.NewStore("from.json", false)
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer f.RemoveFile("from.json")
|
||||||
|
|
||||||
|
_, err = config.NewStore("to.json", false)
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer f.RemoveFile("to.json")
|
||||||
|
|
||||||
|
_, response := client.MigrateConfig("from.json", "to.json")
|
||||||
|
CheckNoError(t, response)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -1110,6 +1110,10 @@
|
|||||||
"id": "api.config.client.old_format.app_error",
|
"id": "api.config.client.old_format.app_error",
|
||||||
"translation": "New format for the client configuration is not supported yet. Please specify format=old in the query string."
|
"translation": "New format for the client configuration is not supported yet. Please specify format=old in the query string."
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "api.config.migrate_config.app_error",
|
||||||
|
"translation": "Failed to migrate config store."
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "api.config.update_config.clear_siteurl.app_error",
|
"id": "api.config.update_config.clear_siteurl.app_error",
|
||||||
"translation": "Site URL cannot be cleared."
|
"translation": "Site URL cannot be cleared."
|
||||||
|
|||||||
@@ -3364,6 +3364,19 @@ func (c *Client4) UpdateConfig(config *Config) (*Config, *Response) {
|
|||||||
return ConfigFromJson(r.Body), BuildResponse(r)
|
return ConfigFromJson(r.Body), BuildResponse(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MigrateConfig will migrate existing config to the new one.
|
||||||
|
func (c *Client4) MigrateConfig(from, to string) (bool, *Response) {
|
||||||
|
m := make(map[string]string, 2)
|
||||||
|
m["from"] = from
|
||||||
|
m["to"] = to
|
||||||
|
r, err := c.DoApiPost(c.GetConfigRoute()+"/migrate", MapToJson(m))
|
||||||
|
if err != nil {
|
||||||
|
return false, BuildErrorResponse(r, err)
|
||||||
|
}
|
||||||
|
defer closeBody(r)
|
||||||
|
return true, BuildResponse(r)
|
||||||
|
}
|
||||||
|
|
||||||
// UploadLicenseFile will add a license file to the system.
|
// UploadLicenseFile will add a license file to the system.
|
||||||
func (c *Client4) UploadLicenseFile(data []byte) (bool, *Response) {
|
func (c *Client4) UploadLicenseFile(data []byte) (bool, *Response) {
|
||||||
body := &bytes.Buffer{}
|
body := &bytes.Buffer{}
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user