MM-41153: Add seats deployed to support packet (#20125)
Support packet contains 2 new fields: 1. Active users. 2. License supported users. We refactor the code to its separate file. ```release-note NONE ```
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
a096a99542
Коммит
89fac9d485
181
app/server.go
181
app/server.go
@@ -7,11 +7,9 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"hash/maphash"
|
||||
"html/template"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/pprof"
|
||||
@@ -27,8 +25,6 @@ import (
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"gopkg.in/yaml.v2"
|
||||
|
||||
"github.com/getsentry/sentry-go"
|
||||
sentryhttp "github.com/getsentry/sentry-go/http"
|
||||
"github.com/gorilla/handlers"
|
||||
@@ -2093,183 +2089,6 @@ func (s *Server) SetSharedChannelSyncService(sharedChannelService SharedChannelS
|
||||
s.sharedChannelService = sharedChannelService
|
||||
}
|
||||
|
||||
func (a *App) GenerateSupportPacket() []model.FileData {
|
||||
// If any errors we come across within this function, we will log it in a warning.txt file so that we know why certain files did not get produced if any
|
||||
var warnings []string
|
||||
|
||||
// Creating an array of files that we are going to be adding to our zip file
|
||||
fileDatas := []model.FileData{}
|
||||
|
||||
// A array of the functions that we can iterate through since they all have the same return value
|
||||
functions := []func() (*model.FileData, string){
|
||||
a.generateSupportPacketYaml,
|
||||
a.createPluginsFile,
|
||||
a.createSanitizedConfigFile,
|
||||
a.getMattermostLog,
|
||||
a.getNotificationsLog,
|
||||
}
|
||||
|
||||
for _, fn := range functions {
|
||||
fileData, warning := fn()
|
||||
|
||||
if fileData != nil {
|
||||
fileDatas = append(fileDatas, *fileData)
|
||||
} else {
|
||||
warnings = append(warnings, warning)
|
||||
}
|
||||
}
|
||||
|
||||
// Adding a warning.txt file to the fileDatas if any warning
|
||||
if len(warnings) > 0 {
|
||||
finalWarning := strings.Join(warnings, "\n")
|
||||
fileDatas = append(fileDatas, model.FileData{
|
||||
Filename: "warning.txt",
|
||||
Body: []byte(finalWarning),
|
||||
})
|
||||
}
|
||||
|
||||
return fileDatas
|
||||
}
|
||||
|
||||
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 := ioutil.ReadFile(notificationsLog)
|
||||
|
||||
if notificationsLogFileDataErr == nil {
|
||||
fileData := model.FileData{
|
||||
Filename: "notifications.log",
|
||||
Body: notificationsLogFileData,
|
||||
}
|
||||
return &fileData, ""
|
||||
}
|
||||
|
||||
warning = fmt.Sprintf("ioutil.ReadFile(notificationsLog) Error: %s", notificationsLogFileDataErr.Error())
|
||||
|
||||
} else {
|
||||
warning = "Unable to retrieve notifications.log because LogSettings: EnableFile is false in config.json"
|
||||
}
|
||||
|
||||
return nil, warning
|
||||
}
|
||||
|
||||
func (a *App) getMattermostLog() (*model.FileData, string) {
|
||||
var warning string
|
||||
|
||||
// Getting mattermost.log
|
||||
if *a.Config().LogSettings.EnableFile {
|
||||
// mattermost.log
|
||||
mattermostLog := config.GetLogFileLocation(*a.Config().LogSettings.FileLocation)
|
||||
|
||||
mattermostLogFileData, mattermostLogFileDataErr := ioutil.ReadFile(mattermostLog)
|
||||
|
||||
if mattermostLogFileDataErr == nil {
|
||||
fileData := model.FileData{
|
||||
Filename: "mattermost.log",
|
||||
Body: mattermostLogFileData,
|
||||
}
|
||||
return &fileData, ""
|
||||
}
|
||||
warning = fmt.Sprintf("ioutil.ReadFile(mattermostLog) Error: %s", mattermostLogFileDataErr.Error())
|
||||
|
||||
} else {
|
||||
warning = "Unable to retrieve mattermost.log because LogSettings: EnableFile is false in config.json"
|
||||
}
|
||||
|
||||
return nil, warning
|
||||
}
|
||||
|
||||
func (a *App) createSanitizedConfigFile() (*model.FileData, string) {
|
||||
// Getting sanitized config, prettifying it, and then adding it to our file data array
|
||||
sanitizedConfigPrettyJSON, err := json.MarshalIndent(a.GetSanitizedConfig(), "", " ")
|
||||
if err == nil {
|
||||
fileData := model.FileData{
|
||||
Filename: "sanitized_config.json",
|
||||
Body: sanitizedConfigPrettyJSON,
|
||||
}
|
||||
return &fileData, ""
|
||||
}
|
||||
|
||||
warning := fmt.Sprintf("json.MarshalIndent(c.App.GetSanitizedConfig()) Error: %s", err.Error())
|
||||
return nil, warning
|
||||
}
|
||||
|
||||
func (a *App) createPluginsFile() (*model.FileData, string) {
|
||||
var warning string
|
||||
|
||||
// Getting the plugins installed on the server, prettify it, and then add them to the file data array
|
||||
pluginsResponse, appErr := a.GetPlugins()
|
||||
if appErr == nil {
|
||||
pluginsPrettyJSON, err := json.MarshalIndent(pluginsResponse, "", " ")
|
||||
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
|
||||
}
|
||||
|
||||
func (a *App) generateSupportPacketYaml() (*model.FileData, string) {
|
||||
// Here we are getting information regarding Elastic Search
|
||||
var elasticServerVersion string
|
||||
var elasticServerPlugins []string
|
||||
if a.Srv().SearchEngine.ElasticsearchEngine != nil {
|
||||
elasticServerVersion = a.Srv().SearchEngine.ElasticsearchEngine.GetFullVersion()
|
||||
elasticServerPlugins = a.Srv().SearchEngine.ElasticsearchEngine.GetPlugins()
|
||||
}
|
||||
|
||||
// Here we are getting information regarding LDAP
|
||||
ldapInterface := a.ch.Ldap
|
||||
var vendorName, vendorVersion string
|
||||
if ldapInterface != nil {
|
||||
vendorName, vendorVersion = ldapInterface.GetVendorNameAndVendorVersion()
|
||||
}
|
||||
|
||||
// Here we are getting information regarding the database (mysql/postgres + current schema version)
|
||||
databaseType, databaseVersion := a.Srv().DatabaseTypeAndSchemaVersion()
|
||||
|
||||
// Creating the struct for support packet yaml file
|
||||
supportPacket := model.SupportPacket{
|
||||
ServerOS: runtime.GOOS,
|
||||
ServerArchitecture: runtime.GOARCH,
|
||||
ServerVersion: model.CurrentVersion,
|
||||
BuildHash: model.BuildHash,
|
||||
DatabaseType: databaseType,
|
||||
DatabaseVersion: databaseVersion,
|
||||
LdapVendorName: vendorName,
|
||||
LdapVendorVersion: vendorVersion,
|
||||
ElasticServerVersion: elasticServerVersion,
|
||||
ElasticServerPlugins: elasticServerPlugins,
|
||||
}
|
||||
|
||||
// Marshal to a Yaml File
|
||||
supportPacketYaml, err := yaml.Marshal(&supportPacket)
|
||||
if err == nil {
|
||||
fileData := model.FileData{
|
||||
Filename: "support_packet.yaml",
|
||||
Body: supportPacketYaml,
|
||||
}
|
||||
return &fileData, ""
|
||||
}
|
||||
|
||||
warning := fmt.Sprintf("yaml.Marshal(&supportPacket) Error: %s", err.Error())
|
||||
return nil, warning
|
||||
}
|
||||
|
||||
func (s *Server) GetProfileImage(user *model.User) ([]byte, bool, *model.AppError) {
|
||||
if *s.Config().FileSettings.DriverName == "" {
|
||||
img, appErr := s.GetDefaultProfileImage(user)
|
||||
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
@@ -247,161 +246,6 @@ func TestDatabaseTypeAndMattermostVersion(t *testing.T) {
|
||||
assert.GreaterOrEqual(t, mattermostVersion, strconv.Itoa(1))
|
||||
}
|
||||
|
||||
func TestGenerateSupportPacket(t *testing.T) {
|
||||
th := Setup(t)
|
||||
defer th.TearDown()
|
||||
|
||||
d1 := []byte("hello\ngo\n")
|
||||
err := ioutil.WriteFile("mattermost.log", d1, 0777)
|
||||
require.NoError(t, err)
|
||||
err = ioutil.WriteFile("notifications.log", d1, 0777)
|
||||
require.NoError(t, err)
|
||||
|
||||
fileDatas := th.App.GenerateSupportPacket()
|
||||
testFiles := []string{"support_packet.yaml", "plugins.json", "sanitized_config.json", "mattermost.log", "notifications.log"}
|
||||
for i, fileData := range fileDatas {
|
||||
require.NotNil(t, fileData)
|
||||
assert.Equal(t, testFiles[i], fileData.Filename)
|
||||
assert.Positive(t, len(fileData.Body))
|
||||
}
|
||||
|
||||
// Remove these two files and ensure that warning.txt file is generated
|
||||
err = os.Remove("notifications.log")
|
||||
require.NoError(t, err)
|
||||
err = os.Remove("mattermost.log")
|
||||
require.NoError(t, err)
|
||||
fileDatas = th.App.GenerateSupportPacket()
|
||||
testFiles = []string{"support_packet.yaml", "plugins.json", "sanitized_config.json", "warning.txt"}
|
||||
for i, fileData := range fileDatas {
|
||||
require.NotNil(t, fileData)
|
||||
assert.Equal(t, testFiles[i], fileData.Filename)
|
||||
assert.Positive(t, len(fileData.Body))
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetNotificationsLog(t *testing.T) {
|
||||
th := Setup(t)
|
||||
defer th.TearDown()
|
||||
|
||||
// Disable notifications file to get an error
|
||||
th.App.UpdateConfig(func(cfg *model.Config) {
|
||||
*cfg.NotificationLogSettings.EnableFile = false
|
||||
})
|
||||
|
||||
fileData, warning := th.App.getNotificationsLog()
|
||||
assert.Nil(t, fileData)
|
||||
assert.Equal(t, warning, "Unable to retrieve notifications.log because LogSettings: EnableFile is false in config.json")
|
||||
|
||||
// Enable notifications file but delete any notifications file to get an error trying to read the file
|
||||
th.App.UpdateConfig(func(cfg *model.Config) {
|
||||
*cfg.NotificationLogSettings.EnableFile = true
|
||||
})
|
||||
|
||||
// If any previous notifications.log file, lets delete it
|
||||
os.Remove("notifications.log")
|
||||
|
||||
fileData, warning = th.App.getNotificationsLog()
|
||||
assert.Nil(t, fileData)
|
||||
assert.Contains(t, warning, "ioutil.ReadFile(notificationsLog) Error:")
|
||||
|
||||
// Happy path where we have file and no warning
|
||||
d1 := []byte("hello\ngo\n")
|
||||
err := ioutil.WriteFile("notifications.log", d1, 0777)
|
||||
defer os.Remove("notifications.log")
|
||||
require.NoError(t, err)
|
||||
|
||||
fileData, warning = th.App.getNotificationsLog()
|
||||
require.NotNil(t, fileData)
|
||||
assert.Equal(t, "notifications.log", fileData.Filename)
|
||||
assert.Positive(t, len(fileData.Body))
|
||||
assert.Empty(t, warning)
|
||||
}
|
||||
|
||||
func TestGetMattermostLog(t *testing.T) {
|
||||
th := Setup(t)
|
||||
defer th.TearDown()
|
||||
|
||||
// disable mattermost log file setting in config so we should get an warning
|
||||
th.App.UpdateConfig(func(cfg *model.Config) {
|
||||
*cfg.LogSettings.EnableFile = false
|
||||
})
|
||||
|
||||
fileData, warning := th.App.getMattermostLog()
|
||||
assert.Nil(t, fileData)
|
||||
assert.Equal(t, "Unable to retrieve mattermost.log because LogSettings: EnableFile is false in config.json", warning)
|
||||
|
||||
// We enable the setting but delete any mattermost log file
|
||||
th.App.UpdateConfig(func(cfg *model.Config) {
|
||||
*cfg.LogSettings.EnableFile = true
|
||||
})
|
||||
|
||||
// If any previous mattermost.log file, lets delete it
|
||||
os.Remove("mattermost.log")
|
||||
|
||||
fileData, warning = th.App.getMattermostLog()
|
||||
assert.Nil(t, fileData)
|
||||
assert.Contains(t, warning, "ioutil.ReadFile(mattermostLog) Error:")
|
||||
|
||||
// Happy path where we get a log file and no warning
|
||||
d1 := []byte("hello\ngo\n")
|
||||
err := ioutil.WriteFile("mattermost.log", d1, 0777)
|
||||
defer os.Remove("mattermost.log")
|
||||
require.NoError(t, err)
|
||||
|
||||
fileData, warning = th.App.getMattermostLog()
|
||||
require.NotNil(t, fileData)
|
||||
assert.Equal(t, "mattermost.log", fileData.Filename)
|
||||
assert.Positive(t, len(fileData.Body))
|
||||
assert.Empty(t, warning)
|
||||
}
|
||||
|
||||
func TestCreateSanitizedConfigFile(t *testing.T) {
|
||||
th := Setup(t)
|
||||
defer th.TearDown()
|
||||
|
||||
// Happy path where we have a sanitized config file with no warning
|
||||
fileData, warning := th.App.createSanitizedConfigFile()
|
||||
require.NotNil(t, fileData)
|
||||
assert.Equal(t, "sanitized_config.json", fileData.Filename)
|
||||
assert.Positive(t, len(fileData.Body))
|
||||
assert.Empty(t, warning)
|
||||
}
|
||||
|
||||
func TestCreatePluginsFile(t *testing.T) {
|
||||
th := Setup(t)
|
||||
defer th.TearDown()
|
||||
|
||||
// Happy path where we have a plugins file with no warning
|
||||
fileData, warning := th.App.createPluginsFile()
|
||||
require.NotNil(t, fileData)
|
||||
assert.Equal(t, "plugins.json", fileData.Filename)
|
||||
assert.Positive(t, len(fileData.Body))
|
||||
assert.Empty(t, warning)
|
||||
|
||||
// Turn off plugins so we can get an error
|
||||
th.App.UpdateConfig(func(cfg *model.Config) {
|
||||
*cfg.PluginSettings.Enable = false
|
||||
})
|
||||
|
||||
// Plugins off in settings so no fileData and we get a warning instead
|
||||
fileData, warning = th.App.createPluginsFile()
|
||||
assert.Nil(t, fileData)
|
||||
assert.Contains(t, warning, "c.App.GetPlugins() Error:")
|
||||
}
|
||||
|
||||
func TestGenerateSupportPacketYaml(t *testing.T) {
|
||||
th := Setup(t)
|
||||
defer th.TearDown()
|
||||
|
||||
// Happy path where we have a support packet yaml file without any warnings
|
||||
fileData, warning := th.App.generateSupportPacketYaml()
|
||||
require.NotNil(t, fileData)
|
||||
assert.Equal(t, "support_packet.yaml", fileData.Filename)
|
||||
assert.Positive(t, len(fileData.Body))
|
||||
assert.Empty(t, warning)
|
||||
|
||||
}
|
||||
|
||||
func TestStartServerTLSVersion(t *testing.T) {
|
||||
configStore, _ := config.NewMemoryStore()
|
||||
store, _ := config.NewStoreFromBacking(configStore, nil, false)
|
||||
|
||||
206
app/support_packet.go
Обычный файл
206
app/support_packet.go
Обычный файл
@@ -0,0 +1,206 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package app
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/config"
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/pkg/errors"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
func (a *App) GenerateSupportPacket() []model.FileData {
|
||||
// If any errors we come across within this function, we will log it in a warning.txt file so that we know why certain files did not get produced if any
|
||||
var warnings []string
|
||||
|
||||
// Creating an array of files that we are going to be adding to our zip file
|
||||
fileDatas := []model.FileData{}
|
||||
|
||||
// A array of the functions that we can iterate through since they all have the same return value
|
||||
functions := []func() (*model.FileData, string){
|
||||
a.generateSupportPacketYaml,
|
||||
a.createPluginsFile,
|
||||
a.createSanitizedConfigFile,
|
||||
a.getMattermostLog,
|
||||
a.getNotificationsLog,
|
||||
}
|
||||
|
||||
for _, fn := range functions {
|
||||
fileData, warning := fn()
|
||||
|
||||
if fileData != nil {
|
||||
fileDatas = append(fileDatas, *fileData)
|
||||
} else {
|
||||
warnings = append(warnings, warning)
|
||||
}
|
||||
}
|
||||
|
||||
// Adding a warning.txt file to the fileDatas if any warning
|
||||
if len(warnings) > 0 {
|
||||
finalWarning := strings.Join(warnings, "\n")
|
||||
fileDatas = append(fileDatas, model.FileData{
|
||||
Filename: "warning.txt",
|
||||
Body: []byte(finalWarning),
|
||||
})
|
||||
}
|
||||
|
||||
return fileDatas
|
||||
}
|
||||
|
||||
func (a *App) generateSupportPacketYaml() (*model.FileData, string) {
|
||||
// Here we are getting information regarding Elastic Search
|
||||
var elasticServerVersion string
|
||||
var elasticServerPlugins []string
|
||||
if a.Srv().SearchEngine.ElasticsearchEngine != nil {
|
||||
elasticServerVersion = a.Srv().SearchEngine.ElasticsearchEngine.GetFullVersion()
|
||||
elasticServerPlugins = a.Srv().SearchEngine.ElasticsearchEngine.GetPlugins()
|
||||
}
|
||||
|
||||
// Here we are getting information regarding LDAP
|
||||
ldapInterface := a.ch.Ldap
|
||||
var vendorName, vendorVersion string
|
||||
if ldapInterface != nil {
|
||||
vendorName, vendorVersion = ldapInterface.GetVendorNameAndVendorVersion()
|
||||
}
|
||||
|
||||
// Here we are getting information regarding the database (mysql/postgres + current schema version)
|
||||
databaseType, databaseVersion := a.Srv().DatabaseTypeAndSchemaVersion()
|
||||
|
||||
uniqueUserCount, err := a.Srv().Store.User().Count(model.UserCountOptions{})
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "error while getting user count").Error()
|
||||
}
|
||||
|
||||
supportedUsers := 0
|
||||
if license := a.Srv().License(); license != nil {
|
||||
supportedUsers = *license.Features.Users
|
||||
}
|
||||
|
||||
// Creating the struct for support packet yaml file
|
||||
supportPacket := model.SupportPacket{
|
||||
ServerOS: runtime.GOOS,
|
||||
ServerArchitecture: runtime.GOARCH,
|
||||
ServerVersion: model.CurrentVersion,
|
||||
BuildHash: model.BuildHash,
|
||||
DatabaseType: databaseType,
|
||||
DatabaseVersion: databaseVersion,
|
||||
LdapVendorName: vendorName,
|
||||
LdapVendorVersion: vendorVersion,
|
||||
ElasticServerVersion: elasticServerVersion,
|
||||
ElasticServerPlugins: elasticServerPlugins,
|
||||
ActiveUsers: int(uniqueUserCount),
|
||||
LicenseSupportedUsers: supportedUsers,
|
||||
}
|
||||
|
||||
// Marshal to a Yaml File
|
||||
supportPacketYaml, err := yaml.Marshal(&supportPacket)
|
||||
if err == nil {
|
||||
fileData := model.FileData{
|
||||
Filename: "support_packet.yaml",
|
||||
Body: supportPacketYaml,
|
||||
}
|
||||
return &fileData, ""
|
||||
}
|
||||
|
||||
warning := fmt.Sprintf("yaml.Marshal(&supportPacket) Error: %s", err.Error())
|
||||
return nil, warning
|
||||
}
|
||||
|
||||
func (a *App) createPluginsFile() (*model.FileData, string) {
|
||||
var warning string
|
||||
|
||||
// Getting the plugins installed on the server, prettify it, and then add them to the file data array
|
||||
pluginsResponse, appErr := a.GetPlugins()
|
||||
if appErr == nil {
|
||||
pluginsPrettyJSON, err := json.MarshalIndent(pluginsResponse, "", " ")
|
||||
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
|
||||
}
|
||||
|
||||
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 := ioutil.ReadFile(notificationsLog)
|
||||
|
||||
if notificationsLogFileDataErr == nil {
|
||||
fileData := model.FileData{
|
||||
Filename: "notifications.log",
|
||||
Body: notificationsLogFileData,
|
||||
}
|
||||
return &fileData, ""
|
||||
}
|
||||
|
||||
warning = fmt.Sprintf("ioutil.ReadFile(notificationsLog) Error: %s", notificationsLogFileDataErr.Error())
|
||||
|
||||
} else {
|
||||
warning = "Unable to retrieve notifications.log because LogSettings: EnableFile is false in config.json"
|
||||
}
|
||||
|
||||
return nil, warning
|
||||
}
|
||||
|
||||
func (a *App) getMattermostLog() (*model.FileData, string) {
|
||||
var warning string
|
||||
|
||||
// Getting mattermost.log
|
||||
if *a.Config().LogSettings.EnableFile {
|
||||
// mattermost.log
|
||||
mattermostLog := config.GetLogFileLocation(*a.Config().LogSettings.FileLocation)
|
||||
|
||||
mattermostLogFileData, mattermostLogFileDataErr := ioutil.ReadFile(mattermostLog)
|
||||
|
||||
if mattermostLogFileDataErr == nil {
|
||||
fileData := model.FileData{
|
||||
Filename: "mattermost.log",
|
||||
Body: mattermostLogFileData,
|
||||
}
|
||||
return &fileData, ""
|
||||
}
|
||||
warning = fmt.Sprintf("ioutil.ReadFile(mattermostLog) Error: %s", mattermostLogFileDataErr.Error())
|
||||
|
||||
} else {
|
||||
warning = "Unable to retrieve mattermost.log because LogSettings: EnableFile is false in config.json"
|
||||
}
|
||||
|
||||
return nil, warning
|
||||
}
|
||||
|
||||
func (a *App) createSanitizedConfigFile() (*model.FileData, string) {
|
||||
// Getting sanitized config, prettifying it, and then adding it to our file data array
|
||||
sanitizedConfigPrettyJSON, err := json.MarshalIndent(a.GetSanitizedConfig(), "", " ")
|
||||
if err == nil {
|
||||
fileData := model.FileData{
|
||||
Filename: "sanitized_config.json",
|
||||
Body: sanitizedConfigPrettyJSON,
|
||||
}
|
||||
return &fileData, ""
|
||||
}
|
||||
|
||||
warning := fmt.Sprintf("json.MarshalIndent(c.App.GetSanitizedConfig()) Error: %s", err.Error())
|
||||
return nil, warning
|
||||
}
|
||||
177
app/support_packet_test.go
Обычный файл
177
app/support_packet_test.go
Обычный файл
@@ -0,0 +1,177 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package app
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
func TestCreatePluginsFile(t *testing.T) {
|
||||
th := Setup(t)
|
||||
defer th.TearDown()
|
||||
|
||||
// Happy path where we have a plugins file with no warning
|
||||
fileData, warning := th.App.createPluginsFile()
|
||||
require.NotNil(t, fileData)
|
||||
assert.Equal(t, "plugins.json", fileData.Filename)
|
||||
assert.Positive(t, len(fileData.Body))
|
||||
assert.Empty(t, warning)
|
||||
|
||||
// Turn off plugins so we can get an error
|
||||
th.App.UpdateConfig(func(cfg *model.Config) {
|
||||
*cfg.PluginSettings.Enable = false
|
||||
})
|
||||
|
||||
// Plugins off in settings so no fileData and we get a warning instead
|
||||
fileData, warning = th.App.createPluginsFile()
|
||||
assert.Nil(t, fileData)
|
||||
assert.Contains(t, warning, "c.App.GetPlugins() Error:")
|
||||
}
|
||||
|
||||
func TestGenerateSupportPacketYaml(t *testing.T) {
|
||||
th := Setup(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
licenseUsers := 100
|
||||
license := model.NewTestLicense()
|
||||
license.Features.Users = model.NewInt(licenseUsers)
|
||||
th.App.Srv().SetLicense(license)
|
||||
|
||||
// Happy path where we have a support packet yaml file without any warnings
|
||||
fileData, warning := th.App.generateSupportPacketYaml()
|
||||
require.NotNil(t, fileData)
|
||||
assert.Equal(t, "support_packet.yaml", fileData.Filename)
|
||||
assert.Positive(t, len(fileData.Body))
|
||||
assert.Empty(t, warning)
|
||||
var packet model.SupportPacket
|
||||
require.NoError(t, yaml.Unmarshal(fileData.Body, &packet))
|
||||
assert.Equal(t, 3, packet.ActiveUsers) // from InitBasic.
|
||||
assert.Equal(t, licenseUsers, packet.LicenseSupportedUsers)
|
||||
}
|
||||
func TestGenerateSupportPacket(t *testing.T) {
|
||||
th := Setup(t)
|
||||
defer th.TearDown()
|
||||
|
||||
d1 := []byte("hello\ngo\n")
|
||||
err := ioutil.WriteFile("mattermost.log", d1, 0777)
|
||||
require.NoError(t, err)
|
||||
err = ioutil.WriteFile("notifications.log", d1, 0777)
|
||||
require.NoError(t, err)
|
||||
|
||||
fileDatas := th.App.GenerateSupportPacket()
|
||||
testFiles := []string{"support_packet.yaml", "plugins.json", "sanitized_config.json", "mattermost.log", "notifications.log"}
|
||||
for i, fileData := range fileDatas {
|
||||
require.NotNil(t, fileData)
|
||||
assert.Equal(t, testFiles[i], fileData.Filename)
|
||||
assert.Positive(t, len(fileData.Body))
|
||||
}
|
||||
|
||||
// Remove these two files and ensure that warning.txt file is generated
|
||||
err = os.Remove("notifications.log")
|
||||
require.NoError(t, err)
|
||||
err = os.Remove("mattermost.log")
|
||||
require.NoError(t, err)
|
||||
fileDatas = th.App.GenerateSupportPacket()
|
||||
testFiles = []string{"support_packet.yaml", "plugins.json", "sanitized_config.json", "warning.txt"}
|
||||
for i, fileData := range fileDatas {
|
||||
require.NotNil(t, fileData)
|
||||
assert.Equal(t, testFiles[i], fileData.Filename)
|
||||
assert.Positive(t, len(fileData.Body))
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetNotificationsLog(t *testing.T) {
|
||||
th := Setup(t)
|
||||
defer th.TearDown()
|
||||
|
||||
// Disable notifications file to get an error
|
||||
th.App.UpdateConfig(func(cfg *model.Config) {
|
||||
*cfg.NotificationLogSettings.EnableFile = false
|
||||
})
|
||||
|
||||
fileData, warning := th.App.getNotificationsLog()
|
||||
assert.Nil(t, fileData)
|
||||
assert.Equal(t, warning, "Unable to retrieve notifications.log because LogSettings: EnableFile is false in config.json")
|
||||
|
||||
// Enable notifications file but delete any notifications file to get an error trying to read the file
|
||||
th.App.UpdateConfig(func(cfg *model.Config) {
|
||||
*cfg.NotificationLogSettings.EnableFile = true
|
||||
})
|
||||
|
||||
// If any previous notifications.log file, lets delete it
|
||||
os.Remove("notifications.log")
|
||||
|
||||
fileData, warning = th.App.getNotificationsLog()
|
||||
assert.Nil(t, fileData)
|
||||
assert.Contains(t, warning, "ioutil.ReadFile(notificationsLog) Error:")
|
||||
|
||||
// Happy path where we have file and no warning
|
||||
d1 := []byte("hello\ngo\n")
|
||||
err := ioutil.WriteFile("notifications.log", d1, 0777)
|
||||
defer os.Remove("notifications.log")
|
||||
require.NoError(t, err)
|
||||
|
||||
fileData, warning = th.App.getNotificationsLog()
|
||||
require.NotNil(t, fileData)
|
||||
assert.Equal(t, "notifications.log", fileData.Filename)
|
||||
assert.Positive(t, len(fileData.Body))
|
||||
assert.Empty(t, warning)
|
||||
}
|
||||
|
||||
func TestGetMattermostLog(t *testing.T) {
|
||||
th := Setup(t)
|
||||
defer th.TearDown()
|
||||
|
||||
// disable mattermost log file setting in config so we should get an warning
|
||||
th.App.UpdateConfig(func(cfg *model.Config) {
|
||||
*cfg.LogSettings.EnableFile = false
|
||||
})
|
||||
|
||||
fileData, warning := th.App.getMattermostLog()
|
||||
assert.Nil(t, fileData)
|
||||
assert.Equal(t, "Unable to retrieve mattermost.log because LogSettings: EnableFile is false in config.json", warning)
|
||||
|
||||
// We enable the setting but delete any mattermost log file
|
||||
th.App.UpdateConfig(func(cfg *model.Config) {
|
||||
*cfg.LogSettings.EnableFile = true
|
||||
})
|
||||
|
||||
// If any previous mattermost.log file, lets delete it
|
||||
os.Remove("mattermost.log")
|
||||
|
||||
fileData, warning = th.App.getMattermostLog()
|
||||
assert.Nil(t, fileData)
|
||||
assert.Contains(t, warning, "ioutil.ReadFile(mattermostLog) Error:")
|
||||
|
||||
// Happy path where we get a log file and no warning
|
||||
d1 := []byte("hello\ngo\n")
|
||||
err := ioutil.WriteFile("mattermost.log", d1, 0777)
|
||||
defer os.Remove("mattermost.log")
|
||||
require.NoError(t, err)
|
||||
|
||||
fileData, warning = th.App.getMattermostLog()
|
||||
require.NotNil(t, fileData)
|
||||
assert.Equal(t, "mattermost.log", fileData.Filename)
|
||||
assert.Positive(t, len(fileData.Body))
|
||||
assert.Empty(t, warning)
|
||||
}
|
||||
|
||||
func TestCreateSanitizedConfigFile(t *testing.T) {
|
||||
th := Setup(t)
|
||||
defer th.TearDown()
|
||||
|
||||
// Happy path where we have a sanitized config file with no warning
|
||||
fileData, warning := th.App.createSanitizedConfigFile()
|
||||
require.NotNil(t, fileData)
|
||||
assert.Equal(t, "sanitized_config.json", fileData.Filename)
|
||||
assert.Positive(t, len(fileData.Body))
|
||||
assert.Empty(t, warning)
|
||||
}
|
||||
@@ -73,16 +73,18 @@ type ServerBusyState struct {
|
||||
}
|
||||
|
||||
type SupportPacket struct {
|
||||
ServerOS string `yaml:"server_os"`
|
||||
ServerArchitecture string `yaml:"server_architecture"`
|
||||
ServerVersion string `yaml:"server_version"`
|
||||
BuildHash string `yaml:"build_hash,omitempty"`
|
||||
DatabaseType string `yaml:"database_type"`
|
||||
DatabaseVersion string `yaml:"database_version"`
|
||||
LdapVendorName string `yaml:"ldap_vendor_name,omitempty"`
|
||||
LdapVendorVersion string `yaml:"ldap_vendor_version,omitempty"`
|
||||
ElasticServerVersion string `yaml:"elastic_server_version,omitempty"`
|
||||
ElasticServerPlugins []string `yaml:"elastic_server_plugins,omitempty"`
|
||||
ServerOS string `yaml:"server_os"`
|
||||
ServerArchitecture string `yaml:"server_architecture"`
|
||||
ServerVersion string `yaml:"server_version"`
|
||||
BuildHash string `yaml:"build_hash,omitempty"`
|
||||
DatabaseType string `yaml:"database_type"`
|
||||
DatabaseVersion string `yaml:"database_version"`
|
||||
LdapVendorName string `yaml:"ldap_vendor_name,omitempty"`
|
||||
LdapVendorVersion string `yaml:"ldap_vendor_version,omitempty"`
|
||||
ElasticServerVersion string `yaml:"elastic_server_version,omitempty"`
|
||||
ElasticServerPlugins []string `yaml:"elastic_server_plugins,omitempty"`
|
||||
ActiveUsers int `yaml:"active_users"`
|
||||
LicenseSupportedUsers int `yaml:"license_supported_users,omitempty"`
|
||||
}
|
||||
|
||||
type FileData struct {
|
||||
|
||||
Ссылка в новой задаче
Block a user