Migrate to idiomatic error handling in support_package.go (#24382)

This commit is contained in:
Ben Schumacher 2023-09-04 19:36:46 +02:00 committed by GitHub
parent dfbe0c14e7
commit 01e7e96448
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 212 additions and 196 deletions

View File

@ -5,15 +5,16 @@ package app
import ( import (
"encoding/json" "encoding/json"
"fmt"
"os" "os"
"runtime" "runtime"
"strings" "strings"
"github.com/hashicorp/go-multierror"
"github.com/pkg/errors" "github.com/pkg/errors"
"gopkg.in/yaml.v2" "gopkg.in/yaml.v2"
"github.com/mattermost/mattermost/server/public/model" "github.com/mattermost/mattermost/server/public/model"
"github.com/mattermost/mattermost/server/public/shared/mlog"
"github.com/mattermost/mattermost/server/v8/config" "github.com/mattermost/mattermost/server/v8/config"
) )
@ -25,21 +26,21 @@ func (a *App) GenerateSupportPacket() []model.FileData {
fileDatas := []model.FileData{} fileDatas := []model.FileData{}
// A array of the functions that we can iterate through since they all have the same return value // A array of the functions that we can iterate through since they all have the same return value
functions := []func() (*model.FileData, string){ functions := map[string]func() (*model.FileData, error){
a.generateSupportPacketYaml, "support package": a.generateSupportPacketYaml,
a.createPluginsFile, "plugins": a.createPluginsFile,
a.createSanitizedConfigFile, "config": a.createSanitizedConfigFile,
a.getMattermostLog, "mattermost log": a.getMattermostLog,
a.getNotificationsLog, "notification log": a.getNotificationsLog,
} }
for _, fn := range functions { for name, fn := range functions {
fileData, warning := fn() fileData, err := fn()
if err != nil {
if fileData != nil { mlog.Error("Failed to generate file for support package", mlog.Err(err), mlog.String("file", name))
warnings = append(warnings, err.Error())
} else if fileData != nil {
fileDatas = append(fileDatas, *fileData) fileDatas = append(fileDatas, *fileData)
} else {
warnings = append(warnings, warning)
} }
} }
@ -55,7 +56,9 @@ func (a *App) GenerateSupportPacket() []model.FileData {
return fileDatas return fileDatas
} }
func (a *App) generateSupportPacketYaml() (*model.FileData, string) { func (a *App) generateSupportPacketYaml() (*model.FileData, error) {
var rErr error
// Here we are getting information regarding Elastic Search // Here we are getting information regarding Elastic Search
var elasticServerVersion string var elasticServerVersion string
var elasticServerPlugins []string var elasticServerPlugins []string
@ -73,26 +76,41 @@ func (a *App) generateSupportPacketYaml() (*model.FileData, string) {
// Here we are getting information regarding the database (mysql/postgres + current schema version) // Here we are getting information regarding the database (mysql/postgres + current schema version)
databaseType, databaseSchemaVersion := a.Srv().DatabaseTypeAndSchemaVersion() databaseType, databaseSchemaVersion := a.Srv().DatabaseTypeAndSchemaVersion()
databaseVersion, _ := a.Srv().Store().GetDbVersion(false) databaseVersion, _ := a.Srv().Store().GetDbVersion(false)
uniqueUserCount, err := a.Srv().Store().User().Count(model.UserCountOptions{}) uniqueUserCount, err := a.Srv().Store().User().Count(model.UserCountOptions{})
if err != nil { if err != nil {
return nil, errors.Wrap(err, "error while getting user count").Error() rErr = multierror.Append(errors.Wrap(err, "error while getting user count"))
} }
analytics, err := a.GetAnalytics("standard", "") dataRetentionJobs, err := a.Srv().Store().Job().GetAllByTypePage(model.JobTypeDataRetention, 0, 2)
if analytics == nil { if err != nil {
return nil, errors.Wrap(err, "error while getting analytics").Error() rErr = multierror.Append(errors.Wrap(err, "error while getting data retention jobs"))
}
messageExportJobs, err := a.Srv().Store().Job().GetAllByTypePage(model.JobTypeMessageExport, 0, 2)
if err != nil {
rErr = multierror.Append(errors.Wrap(err, "error while getting message export jobs"))
}
elasticPostIndexingJobs, err := a.Srv().Store().Job().GetAllByTypePage(model.JobTypeElasticsearchPostIndexing, 0, 2)
if err != nil {
rErr = multierror.Append(errors.Wrap(err, "error while getting ES post indexing jobs"))
}
elasticPostAggregationJobs, _ := a.Srv().Store().Job().GetAllByTypePage(model.JobTypeElasticsearchPostAggregation, 0, 2)
if err != nil {
rErr = multierror.Append(errors.Wrap(err, "error while getting ES post aggregation jobs"))
}
blevePostIndexingJobs, _ := a.Srv().Store().Job().GetAllByTypePage(model.JobTypeBlevePostIndexing, 0, 2)
if err != nil {
rErr = multierror.Append(errors.Wrap(err, "error while getting bleve post indexing jobs"))
}
ldapSyncJobs, err := a.Srv().Store().Job().GetAllByTypePage(model.JobTypeLdapSync, 0, 2)
if err != nil {
rErr = multierror.Append(errors.Wrap(err, "error while getting LDAP sync jobs"))
}
migrationJobs, err := a.Srv().Store().Job().GetAllByTypePage(model.JobTypeMigrations, 0, 2)
if err != nil {
rErr = multierror.Append(errors.Wrap(err, "error while getting migration jobs"))
} }
elasticPostIndexing, _ := a.Srv().Store().Job().GetAllByTypePage("elasticsearch_post_indexing", 0, 2)
elasticPostAggregation, _ := a.Srv().Store().Job().GetAllByTypePage("elasticsearch_post_aggregation", 0, 2)
ldapSyncJobs, _ := a.Srv().Store().Job().GetAllByTypePage("ldap_sync", 0, 2)
messageExport, _ := a.Srv().Store().Job().GetAllByTypePage("message_export", 0, 2)
dataRetentionJobs, _ := a.Srv().Store().Job().GetAllByTypePage("data_retention", 0, 2)
complianceJobs, _ := a.Srv().Store().Job().GetAllByTypePage("compliance", 0, 2)
migrationJobs, _ := a.Srv().Store().Job().GetAllByTypePage("migrations", 0, 2)
licenseTo := "" licenseTo := ""
supportedUsers := 0 supportedUsers := 0
@ -103,140 +121,128 @@ func (a *App) generateSupportPacketYaml() (*model.FileData, string) {
// Creating the struct for support packet yaml file // Creating the struct for support packet yaml file
supportPacket := model.SupportPacket{ supportPacket := model.SupportPacket{
LicenseTo: licenseTo, LicenseTo: licenseTo,
ServerOS: runtime.GOOS, ServerOS: runtime.GOOS,
ServerArchitecture: runtime.GOARCH, ServerArchitecture: runtime.GOARCH,
ServerVersion: model.CurrentVersion, ServerVersion: model.CurrentVersion,
BuildHash: model.BuildHash, BuildHash: model.BuildHash,
DatabaseType: databaseType, DatabaseType: databaseType,
DatabaseVersion: databaseVersion, DatabaseVersion: databaseVersion,
DatabaseSchemaVersion: databaseSchemaVersion, DatabaseSchemaVersion: databaseSchemaVersion,
LdapVendorName: vendorName, LdapVendorName: vendorName,
LdapVendorVersion: vendorVersion, LdapVendorVersion: vendorVersion,
ElasticServerVersion: elasticServerVersion, ElasticServerVersion: elasticServerVersion,
ElasticServerPlugins: elasticServerPlugins, ElasticServerPlugins: elasticServerPlugins,
ActiveUsers: int(uniqueUserCount), ActiveUsers: int(uniqueUserCount),
LicenseSupportedUsers: supportedUsers, LicenseSupportedUsers: supportedUsers,
TotalChannels: int(analytics[0].Value) + int(analytics[1].Value),
TotalPosts: int(analytics[2].Value), // Jobs
TotalTeams: int(analytics[4].Value),
WebsocketConnections: int(analytics[5].Value),
MasterDbConnections: int(analytics[6].Value),
ReplicaDbConnections: int(analytics[7].Value),
DailyActiveUsers: int(analytics[8].Value),
MonthlyActiveUsers: int(analytics[9].Value),
InactiveUserCount: int(analytics[10].Value),
ElasticPostIndexingJobs: elasticPostIndexing,
ElasticPostAggregationJobs: elasticPostAggregation,
LdapSyncJobs: ldapSyncJobs,
MessageExportJobs: messageExport,
DataRetentionJobs: dataRetentionJobs, DataRetentionJobs: dataRetentionJobs,
ComplianceJobs: complianceJobs, MessageExportJobs: messageExportJobs,
ElasticPostIndexingJobs: elasticPostIndexingJobs,
ElasticPostAggregationJobs: elasticPostAggregationJobs,
BlevePostIndexingJobs: blevePostIndexingJobs,
LdapSyncJobs: ldapSyncJobs,
MigrationJobs: migrationJobs, MigrationJobs: migrationJobs,
} }
analytics, appErr := a.GetAnalytics("standard", "")
if appErr != nil {
rErr = multierror.Append(errors.Wrap(appErr, "error while getting analytics"))
}
if len(analytics) < 11 {
rErr = multierror.Append(errors.New("not enought analytics information found"))
} else {
supportPacket.TotalChannels = int(analytics[0].Value) + int(analytics[1].Value)
supportPacket.TotalPosts = int(analytics[2].Value)
supportPacket.TotalTeams = int(analytics[4].Value)
supportPacket.WebsocketConnections = int(analytics[5].Value)
supportPacket.MasterDbConnections = int(analytics[6].Value)
supportPacket.ReplicaDbConnections = int(analytics[7].Value)
supportPacket.DailyActiveUsers = int(analytics[8].Value)
supportPacket.MonthlyActiveUsers = int(analytics[9].Value)
supportPacket.InactiveUserCount = int(analytics[10].Value)
}
// Marshal to a Yaml File // Marshal to a Yaml File
supportPacketYaml, err := yaml.Marshal(&supportPacket) supportPacketYaml, err := yaml.Marshal(&supportPacket)
if err == nil { if err != nil {
fileData := model.FileData{ rErr = multierror.Append(errors.Wrap(err, "failed to marshal support package into yaml"))
Filename: "support_packet.yaml",
Body: supportPacketYaml,
}
return &fileData, ""
} }
warning := fmt.Sprintf("yaml.Marshal(&supportPacket) Error: %s", err.Error()) fileData := &model.FileData{
return nil, warning Filename: "support_packet.yaml",
Body: supportPacketYaml,
}
return fileData, rErr
} }
func (a *App) createPluginsFile() (*model.FileData, string) { func (a *App) createPluginsFile() (*model.FileData, error) {
var warning string
// Getting the plugins installed on the server, prettify it, and then add them to the file data array // Getting the plugins installed on the server, prettify it, and then add them to the file data array
pluginsResponse, appErr := a.GetPlugins() pluginsResponse, appErr := a.GetPlugins()
if appErr == nil { if appErr != nil {
pluginsPrettyJSON, err := json.MarshalIndent(pluginsResponse, "", " ") return nil, errors.Wrap(appErr, "failed to get plugin list for support package")
if err == nil {
fileData := model.FileData{
Filename: "plugins.json",
Body: pluginsPrettyJSON,
}
return &fileData, ""
}
warning = fmt.Sprintf("json.MarshalIndent(pluginsResponse) Error: %s", err.Error())
} else {
warning = fmt.Sprintf("c.App.GetPlugins() Error: %s", appErr.Error())
} }
return nil, warning pluginsPrettyJSON, err := json.MarshalIndent(pluginsResponse, "", " ")
} if err != nil {
return nil, errors.Wrap(err, "failed to marshal plugin list into json")
func (a *App) getNotificationsLog() (*model.FileData, string) {
var warning string
// Getting notifications.log
if *a.Config().NotificationLogSettings.EnableFile {
// notifications.log
notificationsLog := config.GetNotificationsLogFileLocation(*a.Config().LogSettings.FileLocation)
notificationsLogFileData, notificationsLogFileDataErr := os.ReadFile(notificationsLog)
if notificationsLogFileDataErr == nil {
fileData := model.FileData{
Filename: "notifications.log",
Body: notificationsLogFileData,
}
return &fileData, ""
}
warning = fmt.Sprintf("os.ReadFile(notificationsLog) Error: %s", notificationsLogFileDataErr.Error())
} else {
warning = "Unable to retrieve notifications.log because LogSettings: EnableFile is false in config.json"
} }
return nil, warning fileData := &model.FileData{
Filename: "plugins.json",
Body: pluginsPrettyJSON,
}
return fileData, nil
} }
func (a *App) getMattermostLog() (*model.FileData, string) { func (a *App) getNotificationsLog() (*model.FileData, error) {
var warning string if !*a.Config().NotificationLogSettings.EnableFile {
return nil, errors.New("Unable to retrieve notifications.log because LogSettings: EnableFile is set to false")
// Getting mattermost.log
if *a.Config().LogSettings.EnableFile {
// mattermost.log
mattermostLog := config.GetLogFileLocation(*a.Config().LogSettings.FileLocation)
mattermostLogFileData, mattermostLogFileDataErr := os.ReadFile(mattermostLog)
if mattermostLogFileDataErr == nil {
fileData := model.FileData{
Filename: "mattermost.log",
Body: mattermostLogFileData,
}
return &fileData, ""
}
warning = fmt.Sprintf("os.ReadFile(mattermostLog) Error: %s", mattermostLogFileDataErr.Error())
} else {
warning = "Unable to retrieve mattermost.log because LogSettings: EnableFile is false in config.json"
} }
return nil, warning notificationsLog := config.GetNotificationsLogFileLocation(*a.Config().LogSettings.FileLocation)
notificationsLogFileData, err := os.ReadFile(notificationsLog)
if err != nil {
return nil, errors.Wrapf(err, "failed read notifcation log file at path %s", notificationsLog)
}
fileData := &model.FileData{
Filename: "notifications.log",
Body: notificationsLogFileData,
}
return fileData, nil
} }
func (a *App) createSanitizedConfigFile() (*model.FileData, string) { func (a *App) getMattermostLog() (*model.FileData, error) {
if !*a.Config().LogSettings.EnableFile {
return nil, errors.New("Unable to retrieve mattermost.log because LogSettings: EnableFile is set to false")
}
mattermostLog := config.GetLogFileLocation(*a.Config().LogSettings.FileLocation)
mattermostLogFileData, err := os.ReadFile(mattermostLog)
if err != nil {
return nil, errors.Wrapf(err, "failed read mattermost log file at path %s", mattermostLog)
}
fileData := &model.FileData{
Filename: "mattermost.log",
Body: mattermostLogFileData,
}
return fileData, nil
}
func (a *App) createSanitizedConfigFile() (*model.FileData, error) {
// Getting sanitized config, prettifying it, and then adding it to our file data array // Getting sanitized config, prettifying it, and then adding it to our file data array
sanitizedConfigPrettyJSON, err := json.MarshalIndent(a.GetSanitizedConfig(), "", " ") sanitizedConfigPrettyJSON, err := json.MarshalIndent(a.GetSanitizedConfig(), "", " ")
if err == nil { if err != nil {
fileData := model.FileData{ return nil, errors.Wrap(err, "failed to sanitized config into json")
Filename: "sanitized_config.json",
Body: sanitizedConfigPrettyJSON,
}
return &fileData, ""
} }
warning := fmt.Sprintf("json.MarshalIndent(c.App.GetSanitizedConfig()) Error: %s", err.Error()) fileData := &model.FileData{
return nil, warning Filename: "sanitized_config.json",
Body: sanitizedConfigPrettyJSON,
}
return fileData, nil
} }

View File

@ -18,12 +18,12 @@ func TestCreatePluginsFile(t *testing.T) {
th := Setup(t) th := Setup(t)
defer th.TearDown() defer th.TearDown()
// Happy path where we have a plugins file with no warning // Happy path where we have a plugins file with no err
fileData, warning := th.App.createPluginsFile() fileData, err := th.App.createPluginsFile()
require.NotNil(t, fileData) require.NotNil(t, fileData)
assert.Equal(t, "plugins.json", fileData.Filename) assert.Equal(t, "plugins.json", fileData.Filename)
assert.Positive(t, len(fileData.Body)) assert.Positive(t, len(fileData.Body))
assert.Empty(t, warning) assert.NoError(t, err)
// Turn off plugins so we can get an error // Turn off plugins so we can get an error
th.App.UpdateConfig(func(cfg *model.Config) { th.App.UpdateConfig(func(cfg *model.Config) {
@ -31,9 +31,9 @@ func TestCreatePluginsFile(t *testing.T) {
}) })
// Plugins off in settings so no fileData and we get a warning instead // Plugins off in settings so no fileData and we get a warning instead
fileData, warning = th.App.createPluginsFile() fileData, err = th.App.createPluginsFile()
assert.Nil(t, fileData) assert.Nil(t, fileData)
assert.Contains(t, warning, "c.App.GetPlugins() Error:") assert.ErrorContains(t, err, "failed to get plugin list for support package")
} }
func TestGenerateSupportPacketYaml(t *testing.T) { func TestGenerateSupportPacketYaml(t *testing.T) {
@ -46,16 +46,17 @@ func TestGenerateSupportPacketYaml(t *testing.T) {
th.App.Srv().SetLicense(license) th.App.Srv().SetLicense(license)
// Happy path where we have a support packet yaml file without any warnings // Happy path where we have a support packet yaml file without any warnings
fileData, warning := th.App.generateSupportPacketYaml() fileData, err := th.App.generateSupportPacketYaml()
require.NotNil(t, fileData) require.NotNil(t, fileData)
assert.Equal(t, "support_packet.yaml", fileData.Filename) assert.Equal(t, "support_packet.yaml", fileData.Filename)
assert.Positive(t, len(fileData.Body)) assert.Positive(t, len(fileData.Body))
assert.Empty(t, warning) assert.NoError(t, err)
var packet model.SupportPacket var packet model.SupportPacket
require.NoError(t, yaml.Unmarshal(fileData.Body, &packet)) require.NoError(t, yaml.Unmarshal(fileData.Body, &packet))
assert.Equal(t, 3, packet.ActiveUsers) // from InitBasic. assert.Equal(t, 3, packet.ActiveUsers) // from InitBasic.
assert.Equal(t, licenseUsers, packet.LicenseSupportedUsers) assert.Equal(t, licenseUsers, packet.LicenseSupportedUsers)
} }
func TestGenerateSupportPacket(t *testing.T) { func TestGenerateSupportPacket(t *testing.T) {
th := Setup(t) th := Setup(t)
defer th.TearDown() defer th.TearDown()
@ -67,12 +68,15 @@ func TestGenerateSupportPacket(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
fileDatas := th.App.GenerateSupportPacket() fileDatas := th.App.GenerateSupportPacket()
var rFileNames []string
testFiles := []string{"support_packet.yaml", "plugins.json", "sanitized_config.json", "mattermost.log", "notifications.log"} testFiles := []string{"support_packet.yaml", "plugins.json", "sanitized_config.json", "mattermost.log", "notifications.log"}
for i, fileData := range fileDatas { for _, fileData := range fileDatas {
require.NotNil(t, fileData) require.NotNil(t, fileData)
assert.Equal(t, testFiles[i], fileData.Filename)
assert.Positive(t, len(fileData.Body)) assert.Positive(t, len(fileData.Body))
rFileNames = append(rFileNames, fileData.Filename)
} }
assert.ElementsMatch(t, testFiles, rFileNames)
// Remove these two files and ensure that warning.txt file is generated // Remove these two files and ensure that warning.txt file is generated
err = os.Remove("notifications.log") err = os.Remove("notifications.log")
@ -81,11 +85,14 @@ func TestGenerateSupportPacket(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
fileDatas = th.App.GenerateSupportPacket() fileDatas = th.App.GenerateSupportPacket()
testFiles = []string{"support_packet.yaml", "plugins.json", "sanitized_config.json", "warning.txt"} testFiles = []string{"support_packet.yaml", "plugins.json", "sanitized_config.json", "warning.txt"}
for i, fileData := range fileDatas { rFileNames = nil
for _, fileData := range fileDatas {
require.NotNil(t, fileData) require.NotNil(t, fileData)
assert.Equal(t, testFiles[i], fileData.Filename)
assert.Positive(t, len(fileData.Body)) assert.Positive(t, len(fileData.Body))
rFileNames = append(rFileNames, fileData.Filename)
} }
assert.ElementsMatch(t, testFiles, rFileNames)
} }
func TestGetNotificationsLog(t *testing.T) { func TestGetNotificationsLog(t *testing.T) {
@ -97,9 +104,9 @@ func TestGetNotificationsLog(t *testing.T) {
*cfg.NotificationLogSettings.EnableFile = false *cfg.NotificationLogSettings.EnableFile = false
}) })
fileData, warning := th.App.getNotificationsLog() fileData, err := th.App.getNotificationsLog()
assert.Nil(t, fileData) assert.Nil(t, fileData)
assert.Equal(t, warning, "Unable to retrieve notifications.log because LogSettings: EnableFile is false in config.json") assert.ErrorContains(t, err, "Unable to retrieve notifications.log because LogSettings: EnableFile is set to false")
// Enable notifications file but delete any notifications file to get an error trying to read the file // Enable notifications file but delete any notifications file to get an error trying to read the file
th.App.UpdateConfig(func(cfg *model.Config) { th.App.UpdateConfig(func(cfg *model.Config) {
@ -109,21 +116,21 @@ func TestGetNotificationsLog(t *testing.T) {
// If any previous notifications.log file, lets delete it // If any previous notifications.log file, lets delete it
os.Remove("notifications.log") os.Remove("notifications.log")
fileData, warning = th.App.getNotificationsLog() fileData, err = th.App.getNotificationsLog()
assert.Nil(t, fileData) assert.Nil(t, fileData)
assert.Contains(t, warning, "os.ReadFile(notificationsLog) Error:") assert.ErrorContains(t, err, "failed read notifcation log file at path")
// Happy path where we have file and no warning // Happy path where we have file and no error
d1 := []byte("hello\ngo\n") d1 := []byte("hello\ngo\n")
err := os.WriteFile("notifications.log", d1, 0777) err = os.WriteFile("notifications.log", d1, 0777)
defer os.Remove("notifications.log") defer os.Remove("notifications.log")
require.NoError(t, err) require.NoError(t, err)
fileData, warning = th.App.getNotificationsLog() fileData, err = th.App.getNotificationsLog()
require.NotNil(t, fileData) require.NotNil(t, fileData)
assert.Equal(t, "notifications.log", fileData.Filename) assert.Equal(t, "notifications.log", fileData.Filename)
assert.Positive(t, len(fileData.Body)) assert.Positive(t, len(fileData.Body))
assert.Empty(t, warning) assert.NoError(t, err)
} }
func TestGetMattermostLog(t *testing.T) { func TestGetMattermostLog(t *testing.T) {
@ -135,9 +142,9 @@ func TestGetMattermostLog(t *testing.T) {
*cfg.LogSettings.EnableFile = false *cfg.LogSettings.EnableFile = false
}) })
fileData, warning := th.App.getMattermostLog() fileData, err := th.App.getMattermostLog()
assert.Nil(t, fileData) assert.Nil(t, fileData)
assert.Equal(t, "Unable to retrieve mattermost.log because LogSettings: EnableFile is false in config.json", warning) assert.ErrorContains(t, err, "Unable to retrieve mattermost.log because LogSettings: EnableFile is set to false")
// We enable the setting but delete any mattermost log file // We enable the setting but delete any mattermost log file
th.App.UpdateConfig(func(cfg *model.Config) { th.App.UpdateConfig(func(cfg *model.Config) {
@ -147,31 +154,31 @@ func TestGetMattermostLog(t *testing.T) {
// If any previous mattermost.log file, lets delete it // If any previous mattermost.log file, lets delete it
os.Remove("mattermost.log") os.Remove("mattermost.log")
fileData, warning = th.App.getMattermostLog() fileData, err = th.App.getMattermostLog()
assert.Nil(t, fileData) assert.Nil(t, fileData)
assert.Contains(t, warning, "os.ReadFile(mattermostLog) Error:") assert.ErrorContains(t, err, "failed read mattermost log file at path mattermost.log")
// Happy path where we get a log file and no warning // Happy path where we get a log file and no warning
d1 := []byte("hello\ngo\n") d1 := []byte("hello\ngo\n")
err := os.WriteFile("mattermost.log", d1, 0777) err = os.WriteFile("mattermost.log", d1, 0777)
defer os.Remove("mattermost.log") defer os.Remove("mattermost.log")
require.NoError(t, err) require.NoError(t, err)
fileData, warning = th.App.getMattermostLog() fileData, err = th.App.getMattermostLog()
require.NotNil(t, fileData) require.NotNil(t, fileData)
assert.Equal(t, "mattermost.log", fileData.Filename) assert.Equal(t, "mattermost.log", fileData.Filename)
assert.Positive(t, len(fileData.Body)) assert.Positive(t, len(fileData.Body))
assert.Empty(t, warning) assert.NoError(t, err)
} }
func TestCreateSanitizedConfigFile(t *testing.T) { func TestCreateSanitizedConfigFile(t *testing.T) {
th := Setup(t) th := Setup(t)
defer th.TearDown() defer th.TearDown()
// Happy path where we have a sanitized config file with no warning // Happy path where we have a sanitized config file with no err
fileData, warning := th.App.createSanitizedConfigFile() fileData, err := th.App.createSanitizedConfigFile()
require.NotNil(t, fileData) require.NotNil(t, fileData)
assert.Equal(t, "sanitized_config.json", fileData.Filename) assert.Equal(t, "sanitized_config.json", fileData.Filename)
assert.Positive(t, len(fileData.Body)) assert.Positive(t, len(fileData.Body))
assert.Empty(t, warning) assert.NoError(t, err)
} }

View File

@ -78,36 +78,39 @@ type ServerBusyState struct {
} }
type SupportPacket struct { type SupportPacket struct {
LicenseTo string `yaml:"license_to"` LicenseTo string `yaml:"license_to"`
ServerOS string `yaml:"server_os"` ServerOS string `yaml:"server_os"`
ServerArchitecture string `yaml:"server_architecture"` ServerArchitecture string `yaml:"server_architecture"`
ServerVersion string `yaml:"server_version"` ServerVersion string `yaml:"server_version"`
BuildHash string `yaml:"build_hash,omitempty"` BuildHash string `yaml:"build_hash,omitempty"`
DatabaseType string `yaml:"database_type"` DatabaseType string `yaml:"database_type"`
DatabaseVersion string `yaml:"database_version"` DatabaseVersion string `yaml:"database_version"`
DatabaseSchemaVersion string `yaml:"database_schema_version"` DatabaseSchemaVersion string `yaml:"database_schema_version"`
LdapVendorName string `yaml:"ldap_vendor_name,omitempty"` LdapVendorName string `yaml:"ldap_vendor_name,omitempty"`
LdapVendorVersion string `yaml:"ldap_vendor_version,omitempty"` LdapVendorVersion string `yaml:"ldap_vendor_version,omitempty"`
ElasticServerVersion string `yaml:"elastic_server_version,omitempty"` ElasticServerVersion string `yaml:"elastic_server_version,omitempty"`
ElasticServerPlugins []string `yaml:"elastic_server_plugins,omitempty"` ElasticServerPlugins []string `yaml:"elastic_server_plugins,omitempty"`
ActiveUsers int `yaml:"active_users"` ActiveUsers int `yaml:"active_users"`
LicenseSupportedUsers int `yaml:"license_supported_users,omitempty"` LicenseSupportedUsers int `yaml:"license_supported_users,omitempty"`
TotalChannels int `yaml:"total_channels"` TotalChannels int `yaml:"total_channels"`
TotalPosts int `yaml:"total_posts"` TotalPosts int `yaml:"total_posts"`
TotalTeams int `yaml:"total_teams"` TotalTeams int `yaml:"total_teams"`
DailyActiveUsers int `yaml:"daily_active_users"` DailyActiveUsers int `yaml:"daily_active_users"`
MonthlyActiveUsers int `yaml:"monthly_active_users"` MonthlyActiveUsers int `yaml:"monthly_active_users"`
WebsocketConnections int `yaml:"websocket_connections"` WebsocketConnections int `yaml:"websocket_connections"`
MasterDbConnections int `yaml:"master_db_connections"` MasterDbConnections int `yaml:"master_db_connections"`
ReplicaDbConnections int `yaml:"read_db_connections"` ReplicaDbConnections int `yaml:"read_db_connections"`
InactiveUserCount int `yaml:"inactive_user_count"` InactiveUserCount int `yaml:"inactive_user_count"`
ElasticPostIndexingJobs []*Job `yaml:"elastic_post_indexing_jobs"`
ElasticPostAggregationJobs []*Job `yaml:"elastic_post_aggregation_jobs"` // Jobs
LdapSyncJobs []*Job `yaml:"ldap_sync_jobs"` DataRetentionJobs []*Job `yaml:"data_retention_jobs"`
MessageExportJobs []*Job `yaml:"message_export_jobs"` MessageExportJobs []*Job `yaml:"message_export_jobs"`
DataRetentionJobs []*Job `yaml:"data_retention_jobs"` ElasticPostIndexingJobs []*Job `yaml:"elastic_post_indexing_jobs"`
ComplianceJobs []*Job `yaml:"compliance_jobs"` ElasticPostAggregationJobs []*Job `yaml:"elastic_post_aggregation_jobs"`
MigrationJobs []*Job `yaml:"migration_jobs"` BlevePostIndexingJobs []*Job `yaml:"bleve_post_indexin_jobs"`
LdapSyncJobs []*Job `yaml:"ldap_sync_jobs"`
MigrationJobs []*Job `yaml:"migration_jobs"`
ComplianceJobs []*Job `yaml:"compliance_jobs"`
} }
type FileData struct { type FileData struct {