[MM-57295] Bulk export: add roles and permission schemes (#26523)
* Bulk export: add roles and permission schemes * Update mmctl docs * Fix log * Update mmctl tests * Update mmctl unit tests * Refactor to avoid extra calls * Update translations * Add test case * Fix test * Fix test
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
c7da6b4741
Коммит
4d6602aff0
@@ -102,6 +102,7 @@ func init() {
|
||||
ExportCreateCmd.Flags().Bool("no-attachments", false, "Exclude file attachments from the export file.")
|
||||
ExportCreateCmd.Flags().Bool("include-archived-channels", false, "Include archived channels in the export file.")
|
||||
ExportCreateCmd.Flags().Bool("include-profile-pictures", false, "Include profile pictures in the export file.")
|
||||
ExportCreateCmd.Flags().Bool("no-roles-and-schemes", false, "Exclude roles and custom permission schemes from the export file.")
|
||||
|
||||
ExportDownloadCmd.Flags().Bool("resume", false, "Set to true to resume an export download.")
|
||||
_ = ExportDownloadCmd.Flags().MarkHidden("resume")
|
||||
@@ -138,6 +139,11 @@ func exportCreateCmdF(c client.Client, command *cobra.Command, args []string) er
|
||||
data["include_attachments"] = "true"
|
||||
}
|
||||
|
||||
excludeRolesAndSchemes, _ := command.Flags().GetBool("no-roles-and-schemes")
|
||||
if !excludeRolesAndSchemes {
|
||||
data["include_roles_and_schemes"] = "true"
|
||||
}
|
||||
|
||||
includeArchivedChannels, _ := command.Flags().GetBool("include-archived-channels")
|
||||
if includeArchivedChannels {
|
||||
data["include_archived_channels"] = "true"
|
||||
|
||||
@@ -145,6 +145,7 @@ func (s *MmctlE2ETestSuite) TestExportCreateCmdF() {
|
||||
s.Require().Len(printer.GetLines(), 1)
|
||||
s.Require().Empty(printer.GetErrorLines())
|
||||
s.Require().Equal("true", printer.GetLines()[0].(*model.Job).Data["include_attachments"])
|
||||
s.Require().Equal("true", printer.GetLines()[0].(*model.Job).Data["include_roles_and_schemes"])
|
||||
})
|
||||
|
||||
s.RunForSystemAdminAndLocal("MM-T3878 - create export without attachments", func(c client.Client) {
|
||||
@@ -158,7 +159,21 @@ func (s *MmctlE2ETestSuite) TestExportCreateCmdF() {
|
||||
s.Require().Nil(err)
|
||||
s.Require().Len(printer.GetLines(), 1)
|
||||
s.Require().Empty(printer.GetErrorLines())
|
||||
s.Require().Empty(printer.GetLines()[0].(*model.Job).Data)
|
||||
s.Require().Equal("", printer.GetLines()[0].(*model.Job).Data["include_attachments"])
|
||||
})
|
||||
|
||||
s.RunForSystemAdminAndLocal("create export without roles and schemes", func(c client.Client) {
|
||||
printer.Clean()
|
||||
|
||||
cmd := &cobra.Command{}
|
||||
|
||||
cmd.Flags().Bool("no-roles-and-schemes", true, "")
|
||||
|
||||
err := exportCreateCmdF(c, cmd, nil)
|
||||
s.Require().Nil(err)
|
||||
s.Require().Len(printer.GetLines(), 1)
|
||||
s.Require().Empty(printer.GetErrorLines())
|
||||
s.Require().Equal("", printer.GetLines()[0].(*model.Job).Data["include_roles_and_schemes"])
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,10 @@ func (s *MmctlUnitTestSuite) TestExportCreateCmdF() {
|
||||
printer.Clean()
|
||||
mockJob := &model.Job{
|
||||
Type: model.JobTypeExportProcess,
|
||||
Data: map[string]string{"include_attachments": "true"},
|
||||
Data: map[string]string{
|
||||
"include_attachments": "true",
|
||||
"include_roles_and_schemes": "true",
|
||||
},
|
||||
}
|
||||
|
||||
s.client.
|
||||
@@ -39,7 +42,9 @@ func (s *MmctlUnitTestSuite) TestExportCreateCmdF() {
|
||||
printer.Clean()
|
||||
mockJob := &model.Job{
|
||||
Type: model.JobTypeExportProcess,
|
||||
Data: make(map[string]string),
|
||||
Data: map[string]string{
|
||||
"include_roles_and_schemes": "true",
|
||||
},
|
||||
}
|
||||
|
||||
s.client.
|
||||
@@ -57,6 +62,31 @@ func (s *MmctlUnitTestSuite) TestExportCreateCmdF() {
|
||||
s.Empty(printer.GetErrorLines())
|
||||
s.Equal(mockJob, printer.GetLines()[0].(*model.Job))
|
||||
})
|
||||
|
||||
s.Run("create export without roles and schemes", func() {
|
||||
printer.Clean()
|
||||
mockJob := &model.Job{
|
||||
Type: model.JobTypeExportProcess,
|
||||
Data: map[string]string{
|
||||
"include_attachments": "true",
|
||||
},
|
||||
}
|
||||
|
||||
s.client.
|
||||
EXPECT().
|
||||
CreateJob(context.TODO(), mockJob).
|
||||
Return(mockJob, &model.Response{}, nil).
|
||||
Times(1)
|
||||
|
||||
cmd := &cobra.Command{}
|
||||
cmd.Flags().Bool("no-roles-and-schemes", true, "")
|
||||
|
||||
err := exportCreateCmdF(s.client, cmd, nil)
|
||||
s.Require().Nil(err)
|
||||
s.Len(printer.GetLines(), 1)
|
||||
s.Empty(printer.GetErrorLines())
|
||||
s.Equal(mockJob, printer.GetLines()[0].(*model.Job))
|
||||
})
|
||||
}
|
||||
|
||||
func (s *MmctlUnitTestSuite) TestExportDeleteCmdF() {
|
||||
|
||||
@@ -366,6 +366,7 @@ func importJobListCmdF(c client.Client, command *cobra.Command, args []string) e
|
||||
}
|
||||
|
||||
type Statistics struct {
|
||||
Roles uint64 `json:"roles"`
|
||||
Schemes uint64 `json:"schemes"`
|
||||
Teams uint64 `json:"teams"`
|
||||
Channels uint64 `json:"channels"`
|
||||
@@ -495,6 +496,7 @@ func importValidateCmdF(command *cobra.Command, args []string) error {
|
||||
}
|
||||
|
||||
stat := Statistics{
|
||||
Roles: validator.Roles(),
|
||||
Schemes: validator.Schemes(),
|
||||
Teams: validator.TeamCount(),
|
||||
Channels: validator.ChannelCount(),
|
||||
@@ -542,6 +544,7 @@ func configurePrinter() {
|
||||
|
||||
func printStatistics(stat Statistics) {
|
||||
tmpl := "\n" +
|
||||
"Roles {{ .Roles }}\n" +
|
||||
"Schemes {{ .Schemes }}\n" +
|
||||
"Teams {{ .Teams }}\n" +
|
||||
"Channels {{ .Channels }}\n" +
|
||||
|
||||
@@ -58,6 +58,7 @@ type Validator struct { //nolint:govet
|
||||
attachmentsUsed map[string]uint64
|
||||
allFileNames []string
|
||||
|
||||
roles map[string]ImportFileInfo
|
||||
schemes map[string]ImportFileInfo
|
||||
teams map[string]ImportFileInfo
|
||||
channels map[ChannelTeam]ImportFileInfo
|
||||
@@ -75,6 +76,7 @@ type Validator struct { //nolint:govet
|
||||
|
||||
const (
|
||||
LineTypeVersion = "version"
|
||||
LineTypeRole = "role"
|
||||
LineTypeScheme = "scheme"
|
||||
LineTypeTeam = "team"
|
||||
LineTypeChannel = "channel"
|
||||
@@ -110,6 +112,7 @@ func NewValidator(
|
||||
attachments: make(map[string]*zip.File),
|
||||
attachmentsUsed: make(map[string]uint64),
|
||||
|
||||
roles: map[string]ImportFileInfo{},
|
||||
schemes: map[string]ImportFileInfo{},
|
||||
teams: map[string]ImportFileInfo{},
|
||||
channels: map[ChannelTeam]ImportFileInfo{},
|
||||
@@ -121,6 +124,10 @@ func NewValidator(
|
||||
return v
|
||||
}
|
||||
|
||||
func (v *Validator) Roles() uint64 {
|
||||
return uint64(len(v.roles))
|
||||
}
|
||||
|
||||
func (v *Validator) Schemes() uint64 {
|
||||
return uint64(len(v.schemes))
|
||||
}
|
||||
@@ -388,6 +395,8 @@ func (v *Validator) validateLine(info ImportFileInfo, line imports.LineImportDat
|
||||
switch line.Type {
|
||||
case LineTypeVersion:
|
||||
err = v.validateVersion(info, line)
|
||||
case LineTypeRole:
|
||||
err = v.validateRole(info, line)
|
||||
case LineTypeScheme:
|
||||
err = v.validateScheme(info, line)
|
||||
case LineTypeTeam:
|
||||
@@ -444,6 +453,37 @@ func (v *Validator) validateVersion(info ImportFileInfo, line imports.LineImport
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *Validator) validateRole(info ImportFileInfo, line imports.LineImportData) (err error) {
|
||||
ivErr := validateNotNil(info, "role", line.Role, func(data imports.RoleImportData) *ImportValidationError {
|
||||
appErr := imports.ValidateRoleImportData(&data)
|
||||
if appErr != nil {
|
||||
return &ImportValidationError{
|
||||
ImportFileInfo: info,
|
||||
FieldName: "role",
|
||||
Err: appErr,
|
||||
}
|
||||
}
|
||||
|
||||
if data.Name != nil {
|
||||
if existing, ok := v.roles[*data.Name]; ok {
|
||||
return &ImportValidationError{
|
||||
ImportFileInfo: info,
|
||||
FieldName: "role",
|
||||
Err: fmt.Errorf("duplicate entry, previous was in line: %d", existing.CurrentLine),
|
||||
}
|
||||
}
|
||||
v.roles[*data.Name] = info
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if ivErr != nil {
|
||||
return v.onError(ivErr)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *Validator) validateScheme(info ImportFileInfo, line imports.LineImportData) (err error) {
|
||||
ivErr := validateNotNil(info, "scheme", line.Scheme, func(data imports.SchemeImportData) *ImportValidationError {
|
||||
appErr := imports.ValidateSchemeImportData(&data)
|
||||
|
||||
Ссылка в новой задаче
Block a user