"Fossies" - the Fresh Open Source Software Archive

Member "mattermost-server-7.9.1/app/admin.go" (16 Mar 2023, 8300 Bytes) of package /linux/www/mattermost-server-7.9.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Go source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the last Fossies "Diffs" side-by-side code changes report for "admin.go": 7.8.1_vs_7.9.0.

    1 // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
    2 // See LICENSE.txt for license information.
    3 
    4 package app
    5 
    6 import (
    7     "encoding/json"
    8     "fmt"
    9     "io"
   10     "net/http"
   11     "time"
   12 
   13     "github.com/mattermost/mattermost-server/v6/model"
   14     "github.com/mattermost/mattermost-server/v6/services/cache"
   15     "github.com/mattermost/mattermost-server/v6/shared/i18n"
   16     "github.com/mattermost/mattermost-server/v6/shared/mail"
   17     "github.com/mattermost/mattermost-server/v6/shared/mlog"
   18 )
   19 
   20 var latestVersionCache = cache.NewLRU(cache.LRUOptions{
   21     Size: 1,
   22 })
   23 
   24 func (s *Server) GetLogs(page, perPage int) ([]string, *model.AppError) {
   25     var lines []string
   26 
   27     license := s.License()
   28     if license != nil && *license.Features.Cluster && s.platform.Cluster() != nil && *s.platform.Config().ClusterSettings.Enable {
   29         if info := s.platform.Cluster().GetMyClusterInfo(); info != nil {
   30             lines = append(lines, "-----------------------------------------------------------------------------------------------------------")
   31             lines = append(lines, "-----------------------------------------------------------------------------------------------------------")
   32             lines = append(lines, info.Hostname)
   33             lines = append(lines, "-----------------------------------------------------------------------------------------------------------")
   34             lines = append(lines, "-----------------------------------------------------------------------------------------------------------")
   35         } else {
   36             mlog.Error("Could not get cluster info")
   37         }
   38     }
   39 
   40     melines, err := s.GetLogsSkipSend(page, perPage, &model.LogFilter{})
   41     if err != nil {
   42         return nil, err
   43     }
   44 
   45     lines = append(lines, melines...)
   46 
   47     if s.platform.Cluster() != nil && *s.platform.Config().ClusterSettings.Enable {
   48         clines, err := s.platform.Cluster().GetLogs(page, perPage)
   49         if err != nil {
   50             return nil, err
   51         }
   52 
   53         lines = append(lines, clines...)
   54     }
   55 
   56     return lines, nil
   57 }
   58 
   59 func (s *Server) QueryLogs(page, perPage int, logFilter *model.LogFilter) (map[string][]string, *model.AppError) {
   60     logData := make(map[string][]string)
   61 
   62     serverName := "default"
   63 
   64     license := s.License()
   65     if license != nil && *license.Features.Cluster && s.platform.Cluster() != nil && *s.platform.Config().ClusterSettings.Enable {
   66         if info := s.platform.Cluster().GetMyClusterInfo(); info != nil {
   67             serverName = info.Hostname
   68         } else {
   69             mlog.Error("Could not get cluster info")
   70         }
   71     }
   72 
   73     serverNames := logFilter.ServerNames
   74     if len(serverNames) > 0 {
   75         for _, nodeName := range serverNames {
   76             if nodeName == "default" {
   77                 AddLocalLogs(logData, s, page, perPage, nodeName, logFilter)
   78             }
   79         }
   80     } else {
   81         AddLocalLogs(logData, s, page, perPage, serverName, logFilter)
   82     }
   83 
   84     if s.platform.Cluster() != nil && *s.Config().ClusterSettings.Enable {
   85         clusterLogs, err := s.platform.Cluster().QueryLogs(page, perPage)
   86         if err != nil {
   87             return nil, err
   88         }
   89 
   90         if clusterLogs != nil && len(serverNames) > 0 {
   91             for _, filteredNodeName := range serverNames {
   92                 logData[filteredNodeName] = clusterLogs[filteredNodeName]
   93             }
   94         } else {
   95             for nodeName, logs := range clusterLogs {
   96                 logData[nodeName] = logs
   97             }
   98         }
   99     }
  100 
  101     return logData, nil
  102 }
  103 
  104 func AddLocalLogs(logData map[string][]string, s *Server, page, perPage int, serverName string, logFilter *model.LogFilter) *model.AppError {
  105     currentServerLogs, err := s.GetLogsSkipSend(page, perPage, logFilter)
  106     if err != nil {
  107         return err
  108     }
  109 
  110     logData[serverName] = currentServerLogs
  111     return nil
  112 }
  113 
  114 func (a *App) QueryLogs(page, perPage int, logFilter *model.LogFilter) (map[string][]string, *model.AppError) {
  115     return a.Srv().QueryLogs(page, perPage, logFilter)
  116 }
  117 
  118 func (a *App) GetLogs(page, perPage int) ([]string, *model.AppError) {
  119     return a.Srv().GetLogs(page, perPage)
  120 }
  121 
  122 func (s *Server) GetLogsSkipSend(page, perPage int, logFilter *model.LogFilter) ([]string, *model.AppError) {
  123     return s.platform.GetLogsSkipSend(page, perPage, logFilter)
  124 }
  125 
  126 func (a *App) GetLogsSkipSend(page, perPage int, logFilter *model.LogFilter) ([]string, *model.AppError) {
  127     return a.Srv().GetLogsSkipSend(page, perPage, logFilter)
  128 }
  129 
  130 func (a *App) GetClusterStatus() []*model.ClusterInfo {
  131     infos := make([]*model.ClusterInfo, 0)
  132 
  133     if a.Cluster() != nil {
  134         infos = a.Cluster().GetClusterInfos()
  135     }
  136 
  137     return infos
  138 }
  139 
  140 func (s *Server) InvalidateAllCaches() *model.AppError {
  141     return s.platform.InvalidateAllCaches()
  142 }
  143 
  144 func (s *Server) InvalidateAllCachesSkipSend() {
  145     s.platform.InvalidateAllCachesSkipSend()
  146 
  147 }
  148 
  149 func (a *App) RecycleDatabaseConnection() {
  150     mlog.Info("Attempting to recycle database connections.")
  151 
  152     // This works by setting 10 seconds as the max conn lifetime for all DB connections.
  153     // This allows in gradually closing connections as they expire. In future, we can think
  154     // of exposing this as a param from the REST api.
  155     a.Srv().Store().RecycleDBConnections(10 * time.Second)
  156 
  157     mlog.Info("Finished recycling database connections.")
  158 }
  159 
  160 func (a *App) TestSiteURL(siteURL string) *model.AppError {
  161     url := fmt.Sprintf("%s/api/v4/system/ping", siteURL)
  162     res, err := http.Get(url)
  163     if err != nil || res.StatusCode != 200 {
  164         return model.NewAppError("testSiteURL", "app.admin.test_site_url.failure", nil, "", http.StatusBadRequest)
  165     }
  166     defer func() {
  167         _, _ = io.Copy(io.Discard, res.Body)
  168         _ = res.Body.Close()
  169     }()
  170 
  171     return nil
  172 }
  173 
  174 func (a *App) TestEmail(userID string, cfg *model.Config) *model.AppError {
  175     if *cfg.EmailSettings.SMTPServer == "" {
  176         return model.NewAppError("testEmail", "api.admin.test_email.missing_server", nil, i18n.T("api.context.invalid_param.app_error", map[string]any{"Name": "SMTPServer"}), http.StatusBadRequest)
  177     }
  178 
  179     // if the user hasn't changed their email settings, fill in the actual SMTP password so that
  180     // the user can verify an existing SMTP connection
  181     if *cfg.EmailSettings.SMTPPassword == model.FakeSetting {
  182         if *cfg.EmailSettings.SMTPServer == *a.Config().EmailSettings.SMTPServer &&
  183             *cfg.EmailSettings.SMTPPort == *a.Config().EmailSettings.SMTPPort &&
  184             *cfg.EmailSettings.SMTPUsername == *a.Config().EmailSettings.SMTPUsername {
  185             *cfg.EmailSettings.SMTPPassword = *a.Config().EmailSettings.SMTPPassword
  186         } else {
  187             return model.NewAppError("testEmail", "api.admin.test_email.reenter_password", nil, "", http.StatusBadRequest)
  188         }
  189     }
  190     user, err := a.GetUser(userID)
  191     if err != nil {
  192         return err
  193     }
  194 
  195     T := i18n.GetUserTranslations(user.Locale)
  196     license := a.Srv().License()
  197     mailConfig := a.Srv().MailServiceConfig()
  198     if err := mail.SendMailUsingConfig(user.Email, T("api.admin.test_email.subject"), T("api.admin.test_email.body"), mailConfig, license != nil && *license.Features.Compliance, "", "", "", "", ""); err != nil {
  199         return model.NewAppError("testEmail", "app.admin.test_email.failure", map[string]any{"Error": err.Error()}, "", http.StatusInternalServerError)
  200     }
  201 
  202     return nil
  203 }
  204 
  205 func (a *App) GetLatestVersion(latestVersionUrl string) (*model.GithubReleaseInfo, *model.AppError) {
  206     var cachedLatestVersion *model.GithubReleaseInfo
  207     if cacheErr := latestVersionCache.Get("latest_version_cache", &cachedLatestVersion); cacheErr == nil {
  208         return cachedLatestVersion, nil
  209     }
  210 
  211     res, err := http.Get(latestVersionUrl)
  212     if err != nil {
  213         return nil, model.NewAppError("GetLatestVersion", model.NoTranslation, nil, "", http.StatusInternalServerError).Wrap(err)
  214     }
  215 
  216     defer res.Body.Close()
  217 
  218     responseData, err := io.ReadAll(res.Body)
  219     if err != nil {
  220         return nil, model.NewAppError("GetLatestVersion", model.NoTranslation, nil, "", http.StatusInternalServerError).Wrap(err)
  221     }
  222 
  223     var releaseInfoResponse *model.GithubReleaseInfo
  224     err = json.Unmarshal(responseData, &releaseInfoResponse)
  225     if err != nil {
  226         return nil, model.NewAppError("GetLatestVersion", model.NoTranslation, nil, "", http.StatusInternalServerError).Wrap(err)
  227     }
  228 
  229     if validErr := releaseInfoResponse.IsValid(); validErr != nil {
  230         return nil, model.NewAppError("GetLatestVersion", model.NoTranslation, nil, "", http.StatusInternalServerError).Wrap(validErr)
  231     }
  232 
  233     err = latestVersionCache.Set("latest_version_cache", releaseInfoResponse)
  234     if err != nil {
  235         return nil, model.NewAppError("GetLatestVersion", model.NoTranslation, nil, "", http.StatusInternalServerError).Wrap(err)
  236     }
  237 
  238     return releaseInfoResponse, nil
  239 }
  240 
  241 func (a *App) ClearLatestVersionCache() {
  242     latestVersionCache.Remove("latest_version_cache")
  243 }