[MM-54288] Support Packet V2 (#29403)
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
091d1bba8b
Коммит
8d4bf4bae0
@@ -5,13 +5,12 @@ package app
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"runtime"
|
||||
"slices"
|
||||
"sync"
|
||||
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"github.com/pkg/errors"
|
||||
"gopkg.in/yaml.v2"
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
"github.com/mattermost/mattermost/server/public/model"
|
||||
"github.com/mattermost/mattermost/server/public/plugin"
|
||||
@@ -19,39 +18,36 @@ import (
|
||||
"github.com/mattermost/mattermost/server/public/shared/request"
|
||||
)
|
||||
|
||||
func (a *App) GenerateSupportPacket(c request.CTX, options *model.SupportPacketOptions) []model.FileData {
|
||||
// A array of the functions that we can iterate through since they all have the same return value
|
||||
func (a *App) GenerateSupportPacket(rctx request.CTX, options *model.SupportPacketOptions) []model.FileData {
|
||||
functions := map[string]func(c request.CTX) (*model.FileData, error){
|
||||
"support packet": a.generateSupportPacketYaml,
|
||||
"plugins": a.createPluginsFile,
|
||||
"config": a.createSanitizedConfigFile,
|
||||
"cpu profile": a.Srv().Platform().CreateCPUProfile,
|
||||
"heap profile": a.Srv().Platform().CreateHeapProfile,
|
||||
"goroutines": a.Srv().Platform().CreateGoroutineProfile,
|
||||
"metadata": a.createSupportPacketMetadata,
|
||||
"metadata": a.getSupportPacketMetadata,
|
||||
"stats": a.getSupportPacketStats,
|
||||
"jobs": a.getSupportPacketJobList,
|
||||
"permissions": a.getSupportPacketPermissionsInfo,
|
||||
"plugins": a.getPluginsFile,
|
||||
}
|
||||
|
||||
if options.IncludeLogs {
|
||||
functions["mattermost log"] = a.Srv().Platform().GetLogFile
|
||||
functions["notification log"] = a.Srv().Platform().GetNotificationLogFile
|
||||
}
|
||||
|
||||
// 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 *multierror.Error
|
||||
// Creating an array of files that we are going to be adding to our zip file
|
||||
var fileDatas []model.FileData
|
||||
var wg sync.WaitGroup
|
||||
var mut sync.Mutex // Protects warnings and fileDatas
|
||||
var (
|
||||
// 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
|
||||
warnings *multierror.Error
|
||||
// Creating an array of files that we are going to be adding to our zip file
|
||||
fileDatas []model.FileData
|
||||
wg sync.WaitGroup
|
||||
mut sync.Mutex // Protects warnings and fileDatas
|
||||
)
|
||||
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
|
||||
for name, fn := range functions {
|
||||
fileData, err := fn(c)
|
||||
fileData, err := fn(rctx)
|
||||
mut.Lock()
|
||||
if err != nil {
|
||||
c.Logger().Error("Failed to generate file for Support Packet", mlog.String("file", name), mlog.Err(err))
|
||||
rctx.Logger().Error("Failed to generate file for Support Packet",
|
||||
mlog.String("file", name),
|
||||
mlog.Err(err),
|
||||
)
|
||||
warnings = multierror.Append(warnings, err)
|
||||
}
|
||||
|
||||
@@ -60,6 +56,17 @@ func (a *App) GenerateSupportPacket(c request.CTX, options *model.SupportPacketO
|
||||
}
|
||||
mut.Unlock()
|
||||
}
|
||||
|
||||
// Generate platform support packet
|
||||
files, err := a.Srv().Platform().GenerateSupportPacket(rctx, options)
|
||||
mut.Lock()
|
||||
if err != nil {
|
||||
warnings = multierror.Append(warnings, err)
|
||||
}
|
||||
if files != nil {
|
||||
fileDatas = append(fileDatas, files...)
|
||||
}
|
||||
mut.Unlock()
|
||||
}()
|
||||
|
||||
// Run the cluster generation in a separate goroutine as CPU profile generation and file upload can take a long time
|
||||
@@ -68,10 +75,10 @@ func (a *App) GenerateSupportPacket(c request.CTX, options *model.SupportPacketO
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
|
||||
files, err := cluster.GenerateSupportPacket(c, options)
|
||||
files, err := cluster.GenerateSupportPacket(rctx, options)
|
||||
mut.Lock()
|
||||
if err != nil {
|
||||
c.Logger().Error("Failed to generate Support Packet from cluster nodes", mlog.Err(err))
|
||||
rctx.Logger().Error("Failed to generate Support Packet from cluster nodes", mlog.Err(err))
|
||||
warnings = multierror.Append(warnings, err)
|
||||
}
|
||||
|
||||
@@ -84,7 +91,7 @@ func (a *App) GenerateSupportPacket(c request.CTX, options *model.SupportPacketO
|
||||
|
||||
wg.Wait()
|
||||
|
||||
pluginContext := pluginContext(c)
|
||||
pluginContext := pluginContext(rctx)
|
||||
a.ch.RunMultiHook(func(hooks plugin.Hooks, manifest *model.Manifest) bool {
|
||||
// If the plugin defined the support_packet prop it means there is a UI element to include it in the support packet.
|
||||
// Check if the plugin is in the list of plugins to include in the Support Packet.
|
||||
@@ -97,7 +104,7 @@ func (a *App) GenerateSupportPacket(c request.CTX, options *model.SupportPacketO
|
||||
// Otherwise, just call the hook as the plugin decided to always include it in the Support Packet.
|
||||
pluginData, err := hooks.GenerateSupportData(pluginContext)
|
||||
if err != nil {
|
||||
c.Logger().Warn("Failed to generate plugin file for Support Packet", mlog.String("plugin", manifest.Id), mlog.Err(err))
|
||||
rctx.Logger().Warn("Failed to generate plugin file for Support Packet", mlog.String("plugin", manifest.Id), mlog.Err(err))
|
||||
warnings = multierror.Append(warnings, err)
|
||||
return true
|
||||
}
|
||||
@@ -120,230 +127,212 @@ func (a *App) GenerateSupportPacket(c request.CTX, options *model.SupportPacketO
|
||||
return fileDatas
|
||||
}
|
||||
|
||||
func (a *App) generateSupportPacketYaml(c request.CTX) (*model.FileData, error) {
|
||||
var rErr *multierror.Error
|
||||
|
||||
/* DB */
|
||||
|
||||
databaseType, databaseSchemaVersion := a.Srv().DatabaseTypeAndSchemaVersion()
|
||||
databaseVersion, err := a.Srv().Store().GetDbVersion(false)
|
||||
if err != nil {
|
||||
rErr = multierror.Append(errors.Wrap(err, "error while getting DB version"))
|
||||
}
|
||||
|
||||
/* Cluster */
|
||||
|
||||
var clusterID string
|
||||
if cluster := a.Cluster(); cluster != nil {
|
||||
clusterID = cluster.GetClusterId()
|
||||
}
|
||||
|
||||
/* File store */
|
||||
|
||||
fileDriver := a.Srv().Platform().FileBackend().DriverName()
|
||||
fileStatus := model.StatusOk
|
||||
err = a.Srv().Platform().FileBackend().TestConnection()
|
||||
if err != nil {
|
||||
fileStatus = model.StatusFail + ": " + err.Error()
|
||||
}
|
||||
|
||||
/* LDAP */
|
||||
|
||||
var vendorName, vendorVersion string
|
||||
if ldap := a.Ldap(); ldap != nil && (*a.Config().LdapSettings.Enable || *a.Config().LdapSettings.EnableSync) {
|
||||
vendorName, vendorVersion, err = ldap.GetVendorNameAndVendorVersion(c)
|
||||
if err != nil {
|
||||
rErr = multierror.Append(errors.Wrap(err, "error while getting LDAP vendor info"))
|
||||
}
|
||||
|
||||
if vendorName == "" {
|
||||
vendorName = "unknown"
|
||||
}
|
||||
if vendorVersion == "" {
|
||||
vendorVersion = "unknown"
|
||||
}
|
||||
}
|
||||
|
||||
/* Elastic Search */
|
||||
|
||||
var elasticServerVersion string
|
||||
var elasticServerPlugins []string
|
||||
if se := a.Srv().Platform().SearchEngine.ElasticsearchEngine; se != nil {
|
||||
elasticServerVersion = se.GetFullVersion()
|
||||
elasticServerPlugins = se.GetPlugins()
|
||||
}
|
||||
|
||||
/* License */
|
||||
|
||||
func (a *App) getSupportPacketStats(rctx request.CTX) (*model.FileData, error) {
|
||||
var (
|
||||
licenseTo string
|
||||
supportedUsers int
|
||||
isTrial bool
|
||||
rErr *multierror.Error
|
||||
err error
|
||||
stats model.SupportPacketStats
|
||||
)
|
||||
if license := a.Srv().License(); license != nil {
|
||||
licenseTo = license.Customer.Company
|
||||
supportedUsers = *license.Features.Users
|
||||
isTrial = license.IsTrial
|
||||
}
|
||||
|
||||
/* Server stats */
|
||||
|
||||
uniqueUserCount, err := a.Srv().Store().User().Count(model.UserCountOptions{})
|
||||
stats.RegisteredUsers, err = a.Srv().Store().User().Count(model.UserCountOptions{IncludeDeleted: true})
|
||||
if err != nil {
|
||||
rErr = multierror.Append(errors.Wrap(err, "error while getting user count"))
|
||||
rErr = multierror.Append(errors.Wrap(err, "failed to get registered user count"))
|
||||
}
|
||||
|
||||
var (
|
||||
totalChannels int
|
||||
totalPosts int
|
||||
totalTeams int
|
||||
websocketConnections int
|
||||
masterDbConnections int
|
||||
replicaDbConnections int
|
||||
dailyActiveUsers int
|
||||
monthlyActiveUsers int
|
||||
inactiveUserCount int
|
||||
)
|
||||
analytics, appErr := a.GetAnalyticsForSupportPacket(c)
|
||||
if appErr != nil {
|
||||
rErr = multierror.Append(errors.Wrap(appErr, "error while getting analytics"))
|
||||
} else {
|
||||
if len(analytics) < 11 {
|
||||
rErr = multierror.Append(errors.New("not enough analytics information found"))
|
||||
} else {
|
||||
totalChannels = int(analytics[0].Value) + int(analytics[1].Value)
|
||||
totalPosts = int(analytics[2].Value)
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
/* Jobs */
|
||||
|
||||
dataRetentionJobs, err := a.Srv().Store().Job().GetAllByTypePage(c, model.JobTypeDataRetention, 0, 2)
|
||||
stats.ActiveUsers, err = a.Srv().Store().User().Count(model.UserCountOptions{})
|
||||
if err != nil {
|
||||
rErr = multierror.Append(errors.Wrap(err, "error while getting data retention jobs"))
|
||||
rErr = multierror.Append(errors.Wrap(err, "failed to get active user count"))
|
||||
}
|
||||
messageExportJobs, err := a.Srv().Store().Job().GetAllByTypePage(c, model.JobTypeMessageExport, 0, 2)
|
||||
|
||||
stats.DailyActiveUsers, err = a.Srv().Store().User().AnalyticsActiveCount(DayMilliseconds, model.UserCountOptions{IncludeBotAccounts: false, IncludeDeleted: false})
|
||||
if err != nil {
|
||||
rErr = multierror.Append(errors.Wrap(err, "error while getting message export jobs"))
|
||||
rErr = multierror.Append(errors.Wrap(err, "failed to get daily active user count"))
|
||||
}
|
||||
elasticPostIndexingJobs, err := a.Srv().Store().Job().GetAllByTypePage(c, model.JobTypeElasticsearchPostIndexing, 0, 2)
|
||||
|
||||
stats.MonthlyActiveUsers, err = a.Srv().Store().User().AnalyticsActiveCount(MonthMilliseconds, model.UserCountOptions{IncludeBotAccounts: false, IncludeDeleted: false})
|
||||
if err != nil {
|
||||
rErr = multierror.Append(errors.Wrap(err, "error while getting ES post indexing jobs"))
|
||||
rErr = multierror.Append(errors.Wrap(err, "failed to get monthly active user count"))
|
||||
}
|
||||
elasticPostAggregationJobs, err := a.Srv().Store().Job().GetAllByTypePage(c, model.JobTypeElasticsearchPostAggregation, 0, 2)
|
||||
|
||||
stats.DeactivatedUsers, err = a.Srv().Store().User().AnalyticsGetInactiveUsersCount()
|
||||
if err != nil {
|
||||
rErr = multierror.Append(errors.Wrap(err, "error while getting ES post aggregation jobs"))
|
||||
rErr = multierror.Append(errors.Wrap(err, "failed to get deactivated user count"))
|
||||
}
|
||||
blevePostIndexingJobs, err := a.Srv().Store().Job().GetAllByTypePage(c, model.JobTypeBlevePostIndexing, 0, 2)
|
||||
|
||||
stats.Guests, err = a.Srv().Store().User().AnalyticsGetGuestCount()
|
||||
if err != nil {
|
||||
rErr = multierror.Append(errors.Wrap(err, "error while getting bleve post indexing jobs"))
|
||||
rErr = multierror.Append(errors.Wrap(err, "failed to get guest count"))
|
||||
}
|
||||
ldapSyncJobs, err := a.Srv().Store().Job().GetAllByTypePage(c, model.JobTypeLdapSync, 0, 2)
|
||||
|
||||
stats.BotAccounts, err = a.Srv().Store().User().Count(model.UserCountOptions{IncludeBotAccounts: true, ExcludeRegularUsers: true})
|
||||
if err != nil {
|
||||
rErr = multierror.Append(errors.Wrap(err, "error while getting LDAP sync jobs"))
|
||||
rErr = multierror.Append(errors.Wrap(err, "failed to get bot acount count"))
|
||||
}
|
||||
migrationJobs, err := a.Srv().Store().Job().GetAllByTypePage(c, model.JobTypeMigrations, 0, 2)
|
||||
|
||||
stats.Posts, err = a.Srv().Store().Post().AnalyticsPostCount(&model.PostCountOptions{})
|
||||
if err != nil {
|
||||
rErr = multierror.Append(errors.Wrap(err, "error while getting migration jobs"))
|
||||
rErr = multierror.Append(errors.Wrap(err, "failed to get post count"))
|
||||
}
|
||||
|
||||
// Creating the struct for Support Packet yaml file
|
||||
supportPacket := model.SupportPacket{
|
||||
/* Build information */
|
||||
ServerOS: runtime.GOOS,
|
||||
ServerArchitecture: runtime.GOARCH,
|
||||
ServerVersion: model.CurrentVersion,
|
||||
BuildHash: model.BuildHash,
|
||||
openChannels, err := a.Srv().Store().Channel().AnalyticsTypeCount("", model.ChannelTypeOpen)
|
||||
if err != nil {
|
||||
rErr = multierror.Append(errors.Wrap(err, "failed to get open channels count"))
|
||||
}
|
||||
privateChannels, err := a.Srv().Store().Channel().AnalyticsTypeCount("", model.ChannelTypePrivate)
|
||||
if err != nil {
|
||||
rErr = multierror.Append(errors.Wrap(err, "failed to get private channels count"))
|
||||
}
|
||||
stats.Channels = openChannels + privateChannels
|
||||
|
||||
/* DB */
|
||||
DatabaseType: databaseType,
|
||||
DatabaseVersion: databaseVersion,
|
||||
DatabaseSchemaVersion: databaseSchemaVersion,
|
||||
WebsocketConnections: websocketConnections,
|
||||
MasterDbConnections: masterDbConnections,
|
||||
ReplicaDbConnections: replicaDbConnections,
|
||||
|
||||
/* Cluster */
|
||||
ClusterID: clusterID,
|
||||
|
||||
/* File store */
|
||||
FileDriver: fileDriver,
|
||||
FileStatus: fileStatus,
|
||||
|
||||
/* LDAP */
|
||||
LdapVendorName: vendorName,
|
||||
LdapVendorVersion: vendorVersion,
|
||||
|
||||
/* Elastic Search */
|
||||
ElasticServerVersion: elasticServerVersion,
|
||||
ElasticServerPlugins: elasticServerPlugins,
|
||||
|
||||
/* License */
|
||||
LicenseTo: licenseTo,
|
||||
LicenseSupportedUsers: supportedUsers,
|
||||
LicenseIsTrial: isTrial,
|
||||
|
||||
/* Server stats */
|
||||
ActiveUsers: int(uniqueUserCount),
|
||||
DailyActiveUsers: dailyActiveUsers,
|
||||
MonthlyActiveUsers: monthlyActiveUsers,
|
||||
InactiveUserCount: inactiveUserCount,
|
||||
TotalPosts: totalPosts,
|
||||
TotalChannels: totalChannels,
|
||||
TotalTeams: totalTeams,
|
||||
|
||||
/* Jobs */
|
||||
DataRetentionJobs: dataRetentionJobs,
|
||||
MessageExportJobs: messageExportJobs,
|
||||
ElasticPostIndexingJobs: elasticPostIndexingJobs,
|
||||
ElasticPostAggregationJobs: elasticPostAggregationJobs,
|
||||
BlevePostIndexingJobs: blevePostIndexingJobs,
|
||||
LdapSyncJobs: ldapSyncJobs,
|
||||
MigrationJobs: migrationJobs,
|
||||
stats.Teams, err = a.Srv().Store().Team().AnalyticsTeamCount(nil)
|
||||
if err != nil {
|
||||
rErr = multierror.Append(errors.Wrap(err, "failed to get team count"))
|
||||
}
|
||||
|
||||
// Marshal to a YAML File
|
||||
supportPacketYaml, err := yaml.Marshal(&supportPacket)
|
||||
stats.SlashCommands, err = a.Srv().Store().Command().AnalyticsCommandCount("")
|
||||
if err != nil {
|
||||
rErr = multierror.Append(errors.Wrap(err, "failed to get command count"))
|
||||
}
|
||||
|
||||
stats.IncomingWebhooks, err = a.Srv().Store().Webhook().AnalyticsIncomingCount("", "")
|
||||
if err != nil {
|
||||
rErr = multierror.Append(errors.Wrap(err, "failed to get incoming webhook count"))
|
||||
}
|
||||
|
||||
stats.OutgoingWebhooks, err = a.Srv().Store().Webhook().AnalyticsOutgoingCount("")
|
||||
if err != nil {
|
||||
rErr = multierror.Append(errors.Wrap(err, "failed to get outgoing webhook count"))
|
||||
}
|
||||
|
||||
b, err := yaml.Marshal(&stats)
|
||||
if err != nil {
|
||||
rErr = multierror.Append(errors.Wrap(err, "failed to marshal Support Packet into yaml"))
|
||||
}
|
||||
|
||||
fileData := &model.FileData{
|
||||
Filename: "support_packet.yaml",
|
||||
Body: supportPacketYaml,
|
||||
Filename: "stats.yaml",
|
||||
Body: b,
|
||||
}
|
||||
return fileData, rErr.ErrorOrNil()
|
||||
}
|
||||
|
||||
func (a *App) createSanitizedConfigFile(_ request.CTX) (*model.FileData, error) {
|
||||
// Getting sanitized config, prettifying it, and then adding it to our file data array
|
||||
sanitizedConfigPrettyJSON, err := json.MarshalIndent(a.GetSanitizedConfig(), "", " ")
|
||||
func (a *App) getSupportPacketJobList(rctx request.CTX) (*model.FileData, error) {
|
||||
const numberOfJobsRuns = 5
|
||||
|
||||
var (
|
||||
rErr *multierror.Error
|
||||
err error
|
||||
jobs model.SupportPacketJobList
|
||||
)
|
||||
|
||||
jobs.LDAPSyncJobs, err = a.Srv().Store().Job().GetAllByTypePage(rctx, model.JobTypeLdapSync, 0, numberOfJobsRuns)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to sanitized config into json")
|
||||
rErr = multierror.Append(errors.Wrap(err, "error while getting LDAP sync jobs"))
|
||||
}
|
||||
jobs.DataRetentionJobs, err = a.Srv().Store().Job().GetAllByTypePage(rctx, model.JobTypeDataRetention, 0, numberOfJobsRuns)
|
||||
if err != nil {
|
||||
rErr = multierror.Append(errors.Wrap(err, "error while getting data retention jobs"))
|
||||
}
|
||||
jobs.MessageExportJobs, err = a.Srv().Store().Job().GetAllByTypePage(rctx, model.JobTypeMessageExport, 0, numberOfJobsRuns)
|
||||
if err != nil {
|
||||
rErr = multierror.Append(errors.Wrap(err, "error while getting message export jobs"))
|
||||
}
|
||||
jobs.ElasticPostIndexingJobs, err = a.Srv().Store().Job().GetAllByTypePage(rctx, model.JobTypeElasticsearchPostIndexing, 0, numberOfJobsRuns)
|
||||
if err != nil {
|
||||
rErr = multierror.Append(errors.Wrap(err, "error while getting ES post indexing jobs"))
|
||||
}
|
||||
jobs.ElasticPostAggregationJobs, err = a.Srv().Store().Job().GetAllByTypePage(rctx, model.JobTypeElasticsearchPostAggregation, 0, numberOfJobsRuns)
|
||||
if err != nil {
|
||||
rErr = multierror.Append(errors.Wrap(err, "error while getting ES post aggregation jobs"))
|
||||
}
|
||||
jobs.BlevePostIndexingJobs, err = a.Srv().Store().Job().GetAllByTypePage(rctx, model.JobTypeBlevePostIndexing, 0, numberOfJobsRuns)
|
||||
if err != nil {
|
||||
rErr = multierror.Append(errors.Wrap(err, "error while getting bleve post indexing jobs"))
|
||||
}
|
||||
jobs.MigrationJobs, err = a.Srv().Store().Job().GetAllByTypePage(rctx, model.JobTypeMigrations, 0, numberOfJobsRuns)
|
||||
if err != nil {
|
||||
rErr = multierror.Append(errors.Wrap(err, "error while getting migration jobs"))
|
||||
}
|
||||
|
||||
b, err := yaml.Marshal(&jobs)
|
||||
if err != nil {
|
||||
rErr = multierror.Append(errors.Wrap(err, "failed to marshal jobs list into yaml"))
|
||||
}
|
||||
|
||||
fileData := &model.FileData{
|
||||
Filename: "sanitized_config.json",
|
||||
Body: sanitizedConfigPrettyJSON,
|
||||
Filename: "jobs.yaml",
|
||||
Body: b,
|
||||
}
|
||||
return fileData, nil
|
||||
return fileData, rErr.ErrorOrNil()
|
||||
}
|
||||
|
||||
func (a *App) createPluginsFile(_ request.CTX) (*model.FileData, error) {
|
||||
func (a *App) getSupportPacketPermissionsInfo(_ request.CTX) (*model.FileData, error) {
|
||||
var (
|
||||
rErr *multierror.Error
|
||||
err error
|
||||
permissions model.SupportPacketPermissionInfo
|
||||
)
|
||||
|
||||
var allSchemes []*model.Scheme
|
||||
perPage := 100
|
||||
page := 0
|
||||
for {
|
||||
schemes, appErr := a.GetSchemesPage("", page, perPage)
|
||||
if appErr != nil {
|
||||
rErr = multierror.Append(errors.Wrap(appErr, "failed to get list of schemes"))
|
||||
break
|
||||
}
|
||||
|
||||
allSchemes = append(allSchemes, schemes...)
|
||||
if len(schemes) < perPage {
|
||||
break
|
||||
}
|
||||
page++
|
||||
}
|
||||
|
||||
for _, s := range allSchemes {
|
||||
s.Sanitize()
|
||||
}
|
||||
permissions.Schemes = allSchemes
|
||||
|
||||
roles, appErr := a.GetAllRoles()
|
||||
if appErr != nil {
|
||||
rErr = multierror.Append(errors.Wrap(appErr, "failed to get list of roles"))
|
||||
}
|
||||
|
||||
for _, r := range roles {
|
||||
r.Sanitize()
|
||||
}
|
||||
permissions.Roles = roles
|
||||
|
||||
b, err := yaml.Marshal(&permissions)
|
||||
if err != nil {
|
||||
rErr = multierror.Append(errors.Wrap(err, "failed to marshal permission info into yaml"))
|
||||
}
|
||||
|
||||
fileData := &model.FileData{
|
||||
Filename: "permissions.yaml",
|
||||
Body: b,
|
||||
}
|
||||
return fileData, rErr.ErrorOrNil()
|
||||
}
|
||||
|
||||
func (a *App) getPluginsFile(_ request.CTX) (*model.FileData, error) {
|
||||
// Getting the plugins installed on the server, prettify it, and then add them to the file data array
|
||||
pluginsResponse, appErr := a.GetPlugins()
|
||||
plugins, appErr := a.GetPlugins()
|
||||
if appErr != nil {
|
||||
return nil, errors.Wrap(appErr, "failed to get plugin list for Support Packet")
|
||||
}
|
||||
|
||||
pluginsPrettyJSON, err := json.MarshalIndent(pluginsResponse, "", " ")
|
||||
var pluginList model.SupportPacketPluginList
|
||||
for _, p := range plugins.Active {
|
||||
pluginList.Enabled = append(pluginList.Enabled, p.Manifest)
|
||||
}
|
||||
for _, p := range plugins.Inactive {
|
||||
pluginList.Disabled = append(pluginList.Disabled, p.Manifest)
|
||||
}
|
||||
|
||||
pluginsPrettyJSON, err := json.MarshalIndent(pluginList, "", " ")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to marshal plugin list into json")
|
||||
}
|
||||
@@ -355,7 +344,7 @@ func (a *App) createPluginsFile(_ request.CTX) (*model.FileData, error) {
|
||||
return fileData, nil
|
||||
}
|
||||
|
||||
func (a *App) createSupportPacketMetadata(_ request.CTX) (*model.FileData, error) {
|
||||
func (a *App) getSupportPacketMetadata(_ request.CTX) (*model.FileData, error) {
|
||||
metadata, err := model.GeneratePacketMetadata(model.SupportPacketType, a.TelemetryId(), a.License(), nil)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to generate Packet metadata")
|
||||
|
||||
Ссылка в новой задаче
Block a user