Alerting: Remove legacy alerting (#83671)

Removes legacy alerting, so long and thanks for all the fish! 🐟

---------

Co-authored-by: Matthew Jacobson <matthew.jacobson@grafana.com>
Co-authored-by: Sonia Aguilar <soniaAguilarPeiron@users.noreply.github.com>
Co-authored-by: Armand Grillet <armandgrillet@users.noreply.github.com>
Co-authored-by: William Wernert <rwwiv@users.noreply.github.com>
Co-authored-by: Yuri Tseretyan <yuriy.tseretyan@grafana.com>
This commit is contained in:
Gilles De Mey
2024-03-14 15:36:35 +01:00
committed by GitHub
co-authored by Matthew Jacobson Sonia Aguilar Armand Grillet William Wernert Yuri Tseretyan
parent f26344e176
commit 8765c48389
298 changed files with 540 additions and 45125 deletions
-23
View File
@@ -78,29 +78,6 @@ func (hs *HTTPServer) AdminProvisioningReloadPlugins(c *contextmodel.ReqContext)
return response.Success("Plugins config reloaded")
}
// swagger:route POST /admin/provisioning/notifications/reload admin_provisioning adminProvisioningReloadNotifications
//
// Reload legacy alert notifier provisioning configurations.
//
// Reloads the provisioning config files for legacy alert notifiers again. It won’t return until the new provisioned entities are already stored in the database. In case of dashboards, it will stop polling for changes in dashboard files and then restart it with new configurations after returning.
// If you are running Grafana Enterprise and have Fine-grained access control enabled, you need to have a permission with action `provisioning:reload` and scope `provisioners:notifications`.
//
// Security:
// - basic:
//
// Responses:
// 200: okResponse
// 401: unauthorisedError
// 403: forbiddenError
// 500: internalServerError
func (hs *HTTPServer) AdminProvisioningReloadNotifications(c *contextmodel.ReqContext) response.Response {
err := hs.ProvisioningService.ProvisionNotifications(c.Req.Context())
if err != nil {
return response.Error(http.StatusInternalServerError, "", err)
}
return response.Success("Notifications config reloaded")
}
func (hs *HTTPServer) AdminProvisioningReloadAlerting(c *contextmodel.ReqContext) response.Response {
err := hs.ProvisioningService.ProvisionAlerting(c.Req.Context())
if err != nil {
-20
View File
@@ -71,26 +71,6 @@ func TestAPI_AdminProvisioningReload_AccessControl(t *testing.T) {
expectedCode: http.StatusForbidden,
url: "/api/admin/provisioning/dashboards/reload",
},
{
desc: "should work for notifications with specific scope",
expectedCode: http.StatusOK,
expectedBody: `{"message":"Notifications config reloaded"}`,
permissions: []accesscontrol.Permission{
{
Action: ActionProvisioningReload,
Scope: ScopeProvisionersNotifications,
},
},
url: "/api/admin/provisioning/notifications/reload",
checkCall: func(mock provisioning.ProvisioningServiceMock) {
assert.Len(t, mock.Calls.ProvisionNotifications, 1)
},
},
{
desc: "should fail for notifications with no permission",
expectedCode: http.StatusForbidden,
url: "/api/admin/provisioning/notifications/reload",
},
{
desc: "should work for datasources with specific scope",
expectedCode: http.StatusOK,
-1035
View File
File diff suppressed because it is too large Load Diff
-33
View File
@@ -55,7 +55,6 @@ func (hs *HTTPServer) registerRoutes() {
reqNotSignedIn := middleware.ReqNotSignedIn
reqSignedInNoAnonymous := middleware.ReqSignedInNoAnonymous
reqGrafanaAdmin := middleware.ReqGrafanaAdmin
reqEditorRole := middleware.ReqEditorRole
reqOrgAdmin := middleware.ReqOrgAdmin
reqRoleForAppRoute := middleware.RoleAppPluginAuth(hs.AccessControl, hs.pluginStore, hs.Features, hs.log)
reqSnapshotPublicModeOrSignedIn := middleware.SnapshotPublicModeOrSignedIn(hs.Cfg)
@@ -509,41 +508,11 @@ func (hs *HTTPServer) registerRoutes() {
// DataSource w/ expressions
apiRoute.Post("/ds/query", requestmeta.SetSLOGroup(requestmeta.SLOGroupHighSlow), authorize(ac.EvalPermission(datasources.ActionQuery)), hs.getDSQueryEndpoint())
apiRoute.Group("/alerts", func(alertsRoute routing.RouteRegister) {
alertsRoute.Post("/test", routing.Wrap(hs.AlertTest))
alertsRoute.Post("/:alertId/pause", reqEditorRole, routing.Wrap(hs.PauseAlert(hs.Cfg.AlertingEnabled)))
alertsRoute.Get("/:alertId", hs.ValidateOrgAlert, routing.Wrap(hs.GetAlert))
alertsRoute.Get("/", routing.Wrap(hs.GetAlerts))
alertsRoute.Get("/states-for-dashboard", routing.Wrap(hs.GetAlertStatesForDashboard))
}, requestmeta.SetOwner(requestmeta.TeamAlerting))
// Unified Alerting
apiRoute.Get("/alert-notifiers", reqSignedIn, requestmeta.SetOwner(requestmeta.TeamAlerting), routing.Wrap(
hs.GetAlertNotifiers()),
)
// Legacy
apiRoute.Get("/alert-notifiers-legacy", reqEditorRole, requestmeta.SetOwner(requestmeta.TeamAlerting), routing.Wrap(
hs.GetLegacyAlertNotifiers()),
)
apiRoute.Group("/alert-notifications", func(alertNotifications routing.RouteRegister) {
alertNotifications.Get("/", routing.Wrap(hs.GetAlertNotifications))
alertNotifications.Post("/test", routing.Wrap(hs.NotificationTest))
alertNotifications.Post("/", routing.Wrap(hs.CreateAlertNotification))
alertNotifications.Put("/:notificationId", routing.Wrap(hs.UpdateAlertNotification))
alertNotifications.Get("/:notificationId", routing.Wrap(hs.GetAlertNotificationByID))
alertNotifications.Delete("/:notificationId", routing.Wrap(hs.DeleteAlertNotification))
alertNotifications.Get("/uid/:uid", routing.Wrap(hs.GetAlertNotificationByUID))
alertNotifications.Put("/uid/:uid", routing.Wrap(hs.UpdateAlertNotificationByUID))
alertNotifications.Delete("/uid/:uid", routing.Wrap(hs.DeleteAlertNotificationByUID))
}, reqEditorRole, requestmeta.SetOwner(requestmeta.TeamAlerting))
// alert notifications without requirement of user to be org editor
apiRoute.Group("/alert-notifications", func(orgRoute routing.RouteRegister) {
orgRoute.Get("/lookup", routing.Wrap(hs.GetAlertNotificationLookup))
}, requestmeta.SetOwner(requestmeta.TeamAlerting))
apiRoute.Get("/annotations", authorize(ac.EvalPermission(ac.ActionAnnotationsRead)), routing.Wrap(hs.GetAnnotations))
apiRoute.Post("/annotations/mass-delete", authorize(ac.EvalPermission(ac.ActionAnnotationsDelete)), routing.Wrap(hs.MassDeleteAnnotations))
@@ -583,7 +552,6 @@ func (hs *HTTPServer) registerRoutes() {
adminRoute.Get("/settings", authorize(ac.EvalPermission(ac.ActionSettingsRead)), routing.Wrap(hs.AdminGetSettings))
adminRoute.Get("/settings-verbose", authorize(ac.EvalPermission(ac.ActionSettingsRead)), routing.Wrap(hs.AdminGetVerboseSettings))
adminRoute.Get("/stats", authorize(ac.EvalPermission(ac.ActionServerStatsRead)), routing.Wrap(hs.AdminGetStats))
adminRoute.Post("/pause-all-alerts", reqGrafanaAdmin, routing.Wrap(hs.PauseAllAlerts(hs.Cfg.AlertingEnabled)))
adminRoute.Post("/encryption/rotate-data-keys", reqGrafanaAdmin, routing.Wrap(hs.AdminRotateDataEncryptionKeys))
adminRoute.Post("/encryption/reencrypt-data-keys", reqGrafanaAdmin, routing.Wrap(hs.AdminReEncryptEncryptionKeys))
@@ -596,7 +564,6 @@ func (hs *HTTPServer) registerRoutes() {
adminRoute.Post("/provisioning/dashboards/reload", authorize(ac.EvalPermission(ActionProvisioningReload, ScopeProvisionersDashboards)), routing.Wrap(hs.AdminProvisioningReloadDashboards))
adminRoute.Post("/provisioning/plugins/reload", authorize(ac.EvalPermission(ActionProvisioningReload, ScopeProvisionersPlugins)), routing.Wrap(hs.AdminProvisioningReloadPlugins))
adminRoute.Post("/provisioning/datasources/reload", authorize(ac.EvalPermission(ActionProvisioningReload, ScopeProvisionersDatasources)), routing.Wrap(hs.AdminProvisioningReloadDatasources))
adminRoute.Post("/provisioning/notifications/reload", authorize(ac.EvalPermission(ActionProvisioningReload, ScopeProvisionersNotifications)), routing.Wrap(hs.AdminProvisioningReloadNotifications))
adminRoute.Post("/provisioning/alerting/reload", authorize(ac.EvalPermission(ActionProvisioningReload, ScopeProvisionersAlertRules)), routing.Wrap(hs.AdminProvisioningReloadAlerting))
}, reqSignedIn)
-6
View File
@@ -7,7 +7,6 @@ import (
"net/http"
"github.com/grafana/grafana/pkg/api/response"
"github.com/grafana/grafana/pkg/services/alerting"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
"github.com/grafana/grafana/pkg/util"
@@ -30,11 +29,6 @@ func ToDashboardErrorResponse(ctx context.Context, pluginStore pluginstore.Store
return response.Error(http.StatusBadRequest, err.Error(), nil)
}
var validationErr alerting.ValidationError
if ok := errors.As(err, &validationErr); ok {
return response.Error(http.StatusUnprocessableEntity, validationErr.Error(), err)
}
var pluginErr dashboards.UpdatePluginDashboardError
if ok := errors.As(err, &pluginErr); ok {
message := fmt.Sprintf("The dashboard belongs to plugin %s.", pluginErr.PluginId)
+1 -2
View File
@@ -19,7 +19,6 @@ import (
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/infra/metrics"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/alerting"
"github.com/grafana/grafana/pkg/services/auth/identity"
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
"github.com/grafana/grafana/pkg/services/dashboards"
@@ -441,7 +440,7 @@ func (hs *HTTPServer) postDashboard(c *contextmodel.ReqContext, cmd dashboards.S
Overwrite: cmd.Overwrite,
}
dashboard, err := hs.DashboardService.SaveDashboard(alerting.WithUAEnabled(ctx, hs.Cfg.UnifiedAlerting.IsEnabled()), dashItem, allowUiUpdate)
dashboard, err := hs.DashboardService.SaveDashboard(ctx, dashItem, allowUiUpdate)
if hs.Live != nil {
// Tell everyone listening that the dashboard changed
+2 -4
View File
@@ -28,7 +28,6 @@ import (
"github.com/grafana/grafana/pkg/services/accesscontrol/acimpl"
"github.com/grafana/grafana/pkg/services/accesscontrol/actest"
accesscontrolmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock"
"github.com/grafana/grafana/pkg/services/alerting"
"github.com/grafana/grafana/pkg/services/annotations/annotationstest"
"github.com/grafana/grafana/pkg/services/auth/identity"
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
@@ -479,7 +478,6 @@ func TestDashboardAPIEndpoint(t *testing.T) {
{SaveError: dashboards.ErrDashboardVersionMismatch, ExpectedStatusCode: http.StatusPreconditionFailed},
{SaveError: dashboards.ErrDashboardTitleEmpty, ExpectedStatusCode: http.StatusBadRequest},
{SaveError: dashboards.ErrDashboardFolderCannotHaveParent, ExpectedStatusCode: http.StatusBadRequest},
{SaveError: alerting.ValidationError{Reason: "Mu"}, ExpectedStatusCode: http.StatusUnprocessableEntity},
{SaveError: dashboards.ErrDashboardTypeMismatch, ExpectedStatusCode: http.StatusBadRequest},
{SaveError: dashboards.ErrDashboardFolderWithSameNameAsDashboard, ExpectedStatusCode: http.StatusBadRequest},
{SaveError: dashboards.ErrDashboardWithSameNameAsFolder, ExpectedStatusCode: http.StatusBadRequest},
@@ -834,14 +832,14 @@ func getDashboardShouldReturn200WithConfig(t *testing.T, sc *scenarioContext, pr
if dashboardService == nil {
dashboardService, err = service.ProvideDashboardServiceImpl(
cfg, dashboardStore, folderStore, nil, features, folderPermissions, dashboardPermissions,
cfg, dashboardStore, folderStore, features, folderPermissions, dashboardPermissions,
ac, folderSvc, nil,
)
require.NoError(t, err)
}
dashboardProvisioningService, err := service.ProvideDashboardServiceImpl(
cfg, dashboardStore, folderStore, nil, features, folderPermissions, dashboardPermissions,
cfg, dashboardStore, folderStore, features, folderPermissions, dashboardPermissions,
ac, folderSvc, nil,
)
require.NoError(t, err)
-137
View File
@@ -1,137 +0,0 @@
package dtos
import (
"fmt"
"time"
"github.com/grafana/grafana/pkg/components/null"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/services/alerting/models"
)
func formatShort(interval time.Duration) string {
var result string
hours := interval / time.Hour
if hours > 0 {
result += fmt.Sprintf("%dh", hours)
}
remaining := interval - (hours * time.Hour)
mins := remaining / time.Minute
if mins > 0 {
result += fmt.Sprintf("%dm", mins)
}
remaining -= (mins * time.Minute)
seconds := remaining / time.Second
if seconds > 0 {
result += fmt.Sprintf("%ds", seconds)
}
return result
}
func NewAlertNotification(notification *models.AlertNotification) *AlertNotification {
dto := &AlertNotification{
Id: notification.ID,
Uid: notification.UID,
Name: notification.Name,
Type: notification.Type,
IsDefault: notification.IsDefault,
Created: notification.Created,
Updated: notification.Updated,
Frequency: formatShort(notification.Frequency),
SendReminder: notification.SendReminder,
DisableResolveMessage: notification.DisableResolveMessage,
Settings: notification.Settings,
SecureFields: map[string]bool{},
}
if notification.SecureSettings != nil {
for k := range notification.SecureSettings {
dto.SecureFields[k] = true
}
}
return dto
}
type AlertNotification struct {
Id int64 `json:"id"`
Uid string `json:"uid"`
Name string `json:"name"`
Type string `json:"type"`
IsDefault bool `json:"isDefault"`
SendReminder bool `json:"sendReminder"`
DisableResolveMessage bool `json:"disableResolveMessage"`
Frequency string `json:"frequency"`
Created time.Time `json:"created"`
Updated time.Time `json:"updated"`
Settings *simplejson.Json `json:"settings"`
SecureFields map[string]bool `json:"secureFields"`
}
func NewAlertNotificationLookup(notification *models.AlertNotification) *AlertNotificationLookup {
return &AlertNotificationLookup{
Id: notification.ID,
Uid: notification.UID,
Name: notification.Name,
Type: notification.Type,
IsDefault: notification.IsDefault,
}
}
type AlertNotificationLookup struct {
Id int64 `json:"id"`
Uid string `json:"uid"`
Name string `json:"name"`
Type string `json:"type"`
IsDefault bool `json:"isDefault"`
}
type AlertTestCommand struct {
Dashboard *simplejson.Json `json:"dashboard" binding:"Required"`
PanelId int64 `json:"panelId" binding:"Required"`
}
type AlertTestResult struct {
Firing bool `json:"firing"`
State models.AlertStateType `json:"state"`
ConditionEvals string `json:"conditionEvals"`
TimeMs string `json:"timeMs"`
Error string `json:"error,omitempty"`
EvalMatches []*EvalMatch `json:"matches,omitempty"`
Logs []*AlertTestResultLog `json:"logs,omitempty"`
}
type AlertTestResultLog struct {
Message string `json:"message"`
Data any `json:"data"`
}
type EvalMatch struct {
Tags map[string]string `json:"tags,omitempty"`
Metric string `json:"metric"`
Value null.Float `json:"value"`
}
type NotificationTestCommand struct {
ID int64 `json:"id,omitempty"`
Name string `json:"name"`
Type string `json:"type"`
SendReminder bool `json:"sendReminder"`
DisableResolveMessage bool `json:"disableResolveMessage"`
Frequency string `json:"frequency"`
Settings *simplejson.Json `json:"settings"`
SecureSettings map[string]string `json:"secureSettings"`
}
type PauseAlertCommand struct {
AlertId int64 `json:"alertId"`
Paused bool `json:"paused"`
}
type PauseAllAlertsCommand struct {
Paused bool `json:"paused"`
}
-35
View File
@@ -1,35 +0,0 @@
package dtos
import (
"testing"
"time"
)
func TestFormatShort(t *testing.T) {
tcs := []struct {
interval time.Duration
expected string
}{
{interval: time.Hour, expected: "1h"},
{interval: time.Hour + time.Minute, expected: "1h1m"},
{interval: (time.Hour * 10) + time.Minute, expected: "10h1m"},
{interval: (time.Hour * 10) + (time.Minute * 10) + time.Second, expected: "10h10m1s"},
{interval: time.Minute * 10, expected: "10m"},
}
for _, tc := range tcs {
got := formatShort(tc.interval)
if got != tc.expected {
t.Errorf("expected %s got %s interval: %v", tc.expected, got, tc.interval)
}
parsed, err := time.ParseDuration(tc.expected)
if err != nil {
t.Fatalf("could not parse expected duration")
}
if parsed != tc.interval {
t.Errorf("expects the parsed duration to equal the interval. Got %v expected: %v", parsed, tc.interval)
}
}
}
+14 -18
View File
@@ -141,24 +141,20 @@ type FrontendSettingsSqlConnectionLimitsDTO struct {
}
type FrontendSettingsDTO struct {
DefaultDatasource string `json:"defaultDatasource"`
Datasources map[string]plugins.DataSourceDTO `json:"datasources"`
MinRefreshInterval string `json:"minRefreshInterval"`
Panels map[string]plugins.PanelDTO `json:"panels"`
Apps map[string]*plugins.AppDTO `json:"apps"`
AppUrl string `json:"appUrl"`
AppSubUrl string `json:"appSubUrl"`
AllowOrgCreate bool `json:"allowOrgCreate"`
AuthProxyEnabled bool `json:"authProxyEnabled"`
LdapEnabled bool `json:"ldapEnabled"`
JwtHeaderName string `json:"jwtHeaderName"`
JwtUrlLogin bool `json:"jwtUrlLogin"`
AlertingEnabled bool `json:"alertingEnabled"`
AlertingErrorOrTimeout string `json:"alertingErrorOrTimeout"`
AlertingNoDataOrNullValues string `json:"alertingNoDataOrNullValues"`
AlertingMinInterval int64 `json:"alertingMinInterval"`
LiveEnabled bool `json:"liveEnabled"`
AutoAssignOrg bool `json:"autoAssignOrg"`
DefaultDatasource string `json:"defaultDatasource"`
Datasources map[string]plugins.DataSourceDTO `json:"datasources"`
MinRefreshInterval string `json:"minRefreshInterval"`
Panels map[string]plugins.PanelDTO `json:"panels"`
Apps map[string]*plugins.AppDTO `json:"apps"`
AppUrl string `json:"appUrl"`
AppSubUrl string `json:"appSubUrl"`
AllowOrgCreate bool `json:"allowOrgCreate"`
AuthProxyEnabled bool `json:"authProxyEnabled"`
LdapEnabled bool `json:"ldapEnabled"`
JwtHeaderName string `json:"jwtHeaderName"`
JwtUrlLogin bool `json:"jwtUrlLogin"`
LiveEnabled bool `json:"liveEnabled"`
AutoAssignOrg bool `json:"autoAssignOrg"`
VerifyEmailEnabled bool `json:"verifyEmailEnabled"`
SigV4AuthEnabled bool `json:"sigV4AuthEnabled"`
+1 -1
View File
@@ -465,7 +465,7 @@ func setupServer(b testing.TB, sc benchScenario, features featuremgmt.FeatureTog
require.NoError(b, err)
dashboardSvc, err := dashboardservice.ProvideDashboardServiceImpl(
sc.cfg, dashStore, folderStore, nil,
sc.cfg, dashStore, folderStore,
features, folderPermissions, dashboardPermissions, ac,
folderServiceWithFlagOn, nil,
)
-7
View File
@@ -178,9 +178,6 @@ func (hs *HTTPServer) getFrontendSettings(c *contextmodel.ReqContext) (*dtos.Fro
LdapEnabled: hs.Cfg.LDAPAuthEnabled,
JwtHeaderName: hs.Cfg.JWTAuth.HeaderName,
JwtUrlLogin: hs.Cfg.JWTAuth.URLLogin,
AlertingErrorOrTimeout: hs.Cfg.AlertingErrorOrTimeout,
AlertingNoDataOrNullValues: hs.Cfg.AlertingNoDataOrNullValues,
AlertingMinInterval: hs.Cfg.AlertingMinInterval,
LiveEnabled: hs.Cfg.LiveMaxConnections != 0,
AutoAssignOrg: hs.Cfg.AutoAssignOrg,
VerifyEmailEnabled: hs.Cfg.VerifyEmailEnabled,
@@ -312,10 +309,6 @@ func (hs *HTTPServer) getFrontendSettings(c *contextmodel.ReqContext) (*dtos.Fro
frontendSettings.UnifiedAlertingEnabled = *hs.Cfg.UnifiedAlerting.Enabled
}
if hs.Cfg.AlertingEnabled != nil {
frontendSettings.AlertingEnabled = *(hs.Cfg.AlertingEnabled)
}
// It returns false if the provider is not enabled or the skip org role sync is false.
parseSkipOrgRoleSyncEnabled := func(info *social.OAuthInfo) bool {
if info == nil {
+2 -7
View File
@@ -47,7 +47,6 @@ import (
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/plugins/pluginscdn"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/alerting"
"github.com/grafana/grafana/pkg/services/annotations"
"github.com/grafana/grafana/pkg/services/apikey"
"github.com/grafana/grafana/pkg/services/auth"
@@ -158,7 +157,6 @@ type HTTPServer struct {
ContextHandler *contexthandler.ContextHandler
LoggerMiddleware loggermw.Logger
SQLStore db.DB
AlertEngine *alerting.AlertEngine
AlertNG *ngalert.AlertNG
LibraryPanelService librarypanels.Service
LibraryElementService libraryelements.Service
@@ -184,7 +182,6 @@ type HTTPServer struct {
dashboardProvisioningService dashboards.DashboardProvisioningService
folderService folder.Service
dsGuardian guardian.DatasourceGuardianProvider
AlertNotificationService *alerting.AlertNotificationService
dashboardsnapshotsService dashboardsnapshots.Service
PluginSettings pluginSettings.Service
AvatarCacheServer *avatar.AvatarCacheServer
@@ -226,7 +223,7 @@ type ServerOptions struct {
func ProvideHTTPServer(opts ServerOptions, cfg *setting.Cfg, routeRegister routing.RouteRegister, bus bus.Bus,
renderService rendering.Service, licensing licensing.Licensing, hooksService *hooks.HooksService,
cacheService *localcache.CacheService, sqlStore *sqlstore.SQLStore, alertEngine *alerting.AlertEngine,
cacheService *localcache.CacheService, sqlStore *sqlstore.SQLStore,
pluginRequestValidator validations.PluginRequestValidator, pluginStaticRouteResolver plugins.StaticRouteResolver,
pluginDashboardService plugindashboards.Service, pluginStore pluginstore.Store, pluginClient plugins.Client,
pluginErrorResolver plugins.ErrorResolver, pluginInstaller plugins.Installer, settingsProvider setting.Provider,
@@ -245,7 +242,7 @@ func ProvideHTTPServer(opts ServerOptions, cfg *setting.Cfg, routeRegister routi
authInfoService login.AuthInfoService, storageService store.StorageService,
notificationService notifications.Service, dashboardService dashboards.DashboardService,
dashboardProvisioningService dashboards.DashboardProvisioningService, folderService folder.Service,
dsGuardian guardian.DatasourceGuardianProvider, alertNotificationService *alerting.AlertNotificationService,
dsGuardian guardian.DatasourceGuardianProvider,
dashboardsnapshotsService dashboardsnapshots.Service, pluginSettings pluginSettings.Service,
avatarCacheServer *avatar.AvatarCacheServer, preferenceService pref.Service,
folderPermissionsService accesscontrol.FolderPermissionsService,
@@ -274,7 +271,6 @@ func ProvideHTTPServer(opts ServerOptions, cfg *setting.Cfg, routeRegister routi
HooksService: hooksService,
CacheService: cacheService,
SQLStore: sqlStore,
AlertEngine: alertEngine,
PluginRequestValidator: pluginRequestValidator,
pluginInstaller: pluginInstaller,
pluginClient: pluginClient,
@@ -330,7 +326,6 @@ func ProvideHTTPServer(opts ServerOptions, cfg *setting.Cfg, routeRegister routi
dashboardProvisioningService: dashboardProvisioningService,
folderService: folderService,
dsGuardian: dsGuardian,
AlertNotificationService: alertNotificationService,
dashboardsnapshotsService: dashboardsnapshotsService,
PluginSettings: pluginSettings,
AvatarCacheServer: avatarCacheServer,
+3
View File
@@ -350,6 +350,9 @@ func (hs *HTTPServer) applyUserInvite(ctx context.Context, usr *user.User, invit
return true, nil
}
// swagger:response SMTPNotEnabledError
type SMTPNotEnabledError PreconditionFailedError
// swagger:parameters addOrgInvite
type AddInviteParams struct {
// in:body