grafana/pkg/api/index.go

323 lines
10 KiB
Go
Raw Normal View History

package api
import (
"fmt"
"strings"
2015-02-05 03:37:13 -06:00
"github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/bus"
m "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/plugins"
2015-02-05 03:37:13 -06:00
"github.com/grafana/grafana/pkg/setting"
)
2018-03-07 10:54:50 -06:00
func setIndexViewData(c *m.ReqContext) (*dtos.IndexViewData, error) {
settings, err := getFrontendSettingsMap(c)
if err != nil {
return nil, err
}
prefsQuery := m.GetPreferencesWithDefaultsQuery{OrgId: c.OrgId, UserId: c.UserId}
if err := bus.Dispatch(&prefsQuery); err != nil {
return nil, err
}
prefs := prefsQuery.Result
// Read locale from acccept-language
acceptLang := c.Req.Header.Get("Accept-Language")
locale := "en-US"
if len(acceptLang) > 0 {
parts := strings.Split(acceptLang, ",")
locale = parts[0]
}
appUrl := setting.AppUrl
appSubUrl := setting.AppSubUrl
// special case when doing localhost call from phantomjs
if c.IsRenderCall {
appUrl = fmt.Sprintf("%s://localhost:%s", setting.Protocol, setting.HttpPort)
appSubUrl = ""
settings["appSubUrl"] = ""
}
var data = dtos.IndexViewData{
User: &dtos.CurrentUser{
Id: c.UserId,
IsSignedIn: c.IsSignedIn,
Login: c.Login,
Email: c.Email,
Name: c.Name,
OrgCount: c.OrgCount,
OrgId: c.OrgId,
OrgName: c.OrgName,
OrgRole: c.OrgRole,
GravatarUrl: dtos.GetGravatarUrl(c.Email),
IsGrafanaAdmin: c.IsGrafanaAdmin,
LightTheme: prefs.Theme == "light",
Timezone: prefs.Timezone,
Locale: locale,
HelpFlags1: c.HelpFlags1,
},
Settings: settings,
2017-10-11 14:36:03 -05:00
Theme: prefs.Theme,
AppUrl: appUrl,
AppSubUrl: appSubUrl,
GoogleAnalyticsId: setting.GoogleAnalyticsId,
GoogleTagManagerId: setting.GoogleTagManagerId,
BuildVersion: setting.BuildVersion,
BuildCommit: setting.BuildCommit,
NewGrafanaVersion: plugins.GrafanaLatestVersion,
NewGrafanaVersionExists: plugins.GrafanaHasUpdate,
}
if setting.DisableGravatar {
data.User.GravatarUrl = setting.AppSubUrl + "/public/img/user_profile.png"
}
if len(data.User.Name) == 0 {
data.User.Name = data.User.Login
2015-02-03 03:46:52 -06:00
}
themeUrlParam := c.Query("theme")
if themeUrlParam == "light" {
data.User.LightTheme = true
2017-10-18 02:48:37 -05:00
data.Theme = "light"
}
2017-06-22 17:41:39 -05:00
if c.OrgRole == m.ROLE_ADMIN || c.OrgRole == m.ROLE_EDITOR {
2017-08-15 10:52:52 -05:00
data.NavTree = append(data.NavTree, &dtos.NavLink{
Text: "Create",
Id: "create",
2017-06-22 17:41:39 -05:00
Icon: "fa fa-fw fa-plus",
2017-12-15 08:17:05 -06:00
Url: setting.AppSubUrl + "/dashboard/new",
2017-06-22 17:41:39 -05:00
Children: []*dtos.NavLink{
2017-10-14 14:17:16 -05:00
{Text: "Dashboard", Icon: "gicon gicon-dashboard-new", Url: setting.AppSubUrl + "/dashboard/new"},
{Text: "Folder", SubTitle: "Create a new folder to organize your dashboards", Id: "folder", Icon: "gicon gicon-folder-new", Url: setting.AppSubUrl + "/dashboards/folder/new"},
2017-12-05 05:19:01 -06:00
{Text: "Import", SubTitle: "Import dashboard from file or Grafana.com", Id: "import", Icon: "gicon gicon-dashboard-import", Url: setting.AppSubUrl + "/dashboard/import"},
2017-06-22 17:41:39 -05:00
},
})
}
2017-06-22 17:41:39 -05:00
dashboardChildNavs := []*dtos.NavLink{
{Text: "Home", Id: "home", Url: setting.AppSubUrl + "/", Icon: "gicon gicon-home", HideFromTabs: true},
{Text: "Divider", Divider: true, Id: "divider", HideFromTabs: true},
2017-12-13 16:48:44 -06:00
{Text: "Manage", Id: "manage-dashboards", Url: setting.AppSubUrl + "/dashboards", Icon: "gicon gicon-manage"},
{Text: "Playlists", Id: "playlists", Url: setting.AppSubUrl + "/playlists", Icon: "gicon gicon-playlists"},
{Text: "Snapshots", Id: "snapshots", Url: setting.AppSubUrl + "/dashboard/snapshots", Icon: "gicon gicon-snapshots"},
}
2017-08-15 10:52:52 -05:00
data.NavTree = append(data.NavTree, &dtos.NavLink{
Text: "Dashboards",
2017-08-15 13:24:16 -05:00
Id: "dashboards",
SubTitle: "Manage dashboards & folders",
2017-10-14 14:17:16 -05:00
Icon: "gicon gicon-dashboard",
Url: setting.AppSubUrl + "/",
Children: dashboardChildNavs,
})
2017-08-15 13:24:16 -05:00
if c.IsSignedIn {
profileNode := &dtos.NavLink{
Text: c.SignedInUser.NameOrFallback(),
SubTitle: c.SignedInUser.Login,
2017-08-15 16:17:34 -05:00
Id: "profile",
Img: data.User.GravatarUrl,
Url: setting.AppSubUrl + "/profile",
HideFromMenu: true,
2017-08-15 13:24:16 -05:00
Children: []*dtos.NavLink{
2017-12-13 16:48:44 -06:00
{Text: "Preferences", Id: "profile-settings", Url: setting.AppSubUrl + "/profile", Icon: "gicon gicon-preferences"},
2017-08-15 13:24:16 -05:00
{Text: "Change Password", Id: "change-password", Url: setting.AppSubUrl + "/profile/password", Icon: "fa fa-fw fa-lock", HideFromMenu: true},
},
}
if !setting.DisableSignoutMenu {
// add sign out first
2017-11-30 10:28:24 -06:00
profileNode.Children = append(profileNode.Children, &dtos.NavLink{
Text: "Sign out", Id: "sign-out", Url: setting.AppSubUrl + "/logout", Icon: "fa fa-fw fa-sign-out", Target: "_self",
})
}
data.NavTree = append(data.NavTree, profileNode)
2017-08-15 13:24:16 -05:00
}
if setting.AlertingEnabled && (c.OrgRole == m.ROLE_ADMIN || c.OrgRole == m.ROLE_EDITOR) {
alertChildNavs := []*dtos.NavLink{
2017-12-13 16:48:44 -06:00
{Text: "Alert Rules", Id: "alert-list", Url: setting.AppSubUrl + "/alerting/list", Icon: "gicon gicon-alert-rules"},
2017-11-30 04:31:38 -06:00
{Text: "Notification channels", Id: "channels", Url: setting.AppSubUrl + "/alerting/notifications", Icon: "gicon gicon-alert-notification-channel"},
}
2017-08-15 10:52:52 -05:00
data.NavTree = append(data.NavTree, &dtos.NavLink{
Text: "Alerting",
2017-11-30 08:37:03 -06:00
SubTitle: "Alert rules & notifications",
2017-08-15 13:24:16 -05:00
Id: "alerting",
2017-10-14 14:17:16 -05:00
Icon: "gicon gicon-alert",
Url: setting.AppSubUrl + "/alerting/list",
Children: alertChildNavs,
})
}
enabledPlugins, err := plugins.GetEnabledPlugins(c.OrgId)
if err != nil {
return nil, err
}
2015-12-21 16:09:27 -06:00
for _, plugin := range enabledPlugins.Apps {
2016-01-11 11:03:08 -06:00
if plugin.Pinned {
appLink := &dtos.NavLink{
2016-01-11 11:03:08 -06:00
Text: plugin.Name,
2017-08-15 13:24:16 -05:00
Id: "plugin-page-" + plugin.Id,
Url: plugin.DefaultNavUrl,
2016-01-11 11:03:08 -06:00
Img: plugin.Info.Logos.Small,
}
for _, include := range plugin.Includes {
if !c.HasUserRole(include.Role) {
continue
}
if include.Type == "page" && include.AddToNav {
link := &dtos.NavLink{
Url: setting.AppSubUrl + "/plugins/" + plugin.Id + "/page/" + include.Slug,
Text: include.Name,
}
appLink.Children = append(appLink.Children, link)
}
if include.Type == "dashboard" && include.AddToNav {
link := &dtos.NavLink{
Url: setting.AppSubUrl + "/dashboard/db/" + include.Slug,
Text: include.Name,
}
appLink.Children = append(appLink.Children, link)
}
}
2016-09-27 07:39:51 -05:00
if len(appLink.Children) > 0 && c.OrgRole == m.ROLE_ADMIN {
appLink.Children = append(appLink.Children, &dtos.NavLink{Divider: true})
2017-12-13 16:48:44 -06:00
appLink.Children = append(appLink.Children, &dtos.NavLink{Text: "Plugin Config", Icon: "gicon gicon-cog", Url: setting.AppSubUrl + "/plugins/" + plugin.Id + "/edit"})
}
if len(appLink.Children) > 0 {
2017-08-15 10:52:52 -05:00
data.NavTree = append(data.NavTree, appLink)
}
}
}
2017-08-15 07:49:12 -05:00
if c.OrgRole == m.ROLE_ADMIN {
cfgNode := &dtos.NavLink{
2017-11-30 08:37:03 -06:00
Id: "cfg",
Text: "Configuration",
SubTitle: "Organization: " + c.OrgName,
2017-12-13 16:48:44 -06:00
Icon: "gicon gicon-cog",
2017-11-30 08:37:03 -06:00
Url: setting.AppSubUrl + "/datasources",
Children: []*dtos.NavLink{
2017-08-15 07:49:12 -05:00
{
2017-08-15 10:52:52 -05:00
Text: "Data Sources",
2017-10-27 01:33:04 -05:00
Icon: "gicon gicon-datasources",
2017-08-15 10:52:52 -05:00
Description: "Add and configure data sources",
Id: "datasources",
Url: setting.AppSubUrl + "/datasources",
2017-08-15 07:49:12 -05:00
},
2017-08-15 10:52:52 -05:00
{
2017-12-13 04:21:33 -06:00
Text: "Users",
2017-08-15 10:52:52 -05:00
Id: "users",
2017-08-18 07:49:04 -05:00
Description: "Manage org members",
2017-12-13 16:48:44 -06:00
Icon: "gicon gicon-user",
2017-08-15 10:52:52 -05:00
Url: setting.AppSubUrl + "/org/users",
},
2017-08-18 07:49:04 -05:00
{
2017-11-30 08:37:03 -06:00
Text: "Teams",
2017-12-01 03:47:21 -06:00
Id: "teams",
2017-08-18 07:49:04 -05:00
Description: "Manage org groups",
2017-12-08 09:25:45 -06:00
Icon: "gicon gicon-team",
Url: setting.AppSubUrl + "/org/teams",
2017-08-18 07:49:04 -05:00
},
2017-11-30 08:37:03 -06:00
{
Text: "Plugins",
Id: "plugins",
Description: "View and configure plugins",
2017-12-13 16:48:44 -06:00
Icon: "gicon gicon-plugins",
2017-11-30 08:37:03 -06:00
Url: setting.AppSubUrl + "/plugins",
},
{
Text: "Preferences",
Id: "org-settings",
Description: "Organization preferences",
2017-12-13 16:48:44 -06:00
Icon: "gicon gicon-preferences",
2017-11-30 08:37:03 -06:00
Url: setting.AppSubUrl + "/org",
},
2017-08-15 10:52:52 -05:00
{
Text: "API Keys",
2017-08-15 13:24:16 -05:00
Id: "apikeys",
2017-08-15 10:52:52 -05:00
Description: "Create & manage API keys",
2017-12-13 16:48:44 -06:00
Icon: "gicon gicon-apikeys",
2017-08-15 10:52:52 -05:00
Url: setting.AppSubUrl + "/org/apikeys",
},
},
2017-08-15 07:49:12 -05:00
}
if c.IsGrafanaAdmin {
cfgNode.Children = append(cfgNode.Children, &dtos.NavLink{
2018-01-18 11:17:58 -06:00
Divider: true, HideFromTabs: true, Id: "admin-divider", Text: "Text",
})
cfgNode.Children = append(cfgNode.Children, &dtos.NavLink{
2017-12-01 06:49:15 -06:00
Text: "Server Admin",
HideFromTabs: true,
SubTitle: "Manage all users & orgs",
Id: "admin",
2017-12-13 16:48:44 -06:00
Icon: "gicon gicon-shield",
2017-12-01 06:49:15 -06:00
Url: setting.AppSubUrl + "/admin/users",
Children: []*dtos.NavLink{
2017-12-13 16:48:44 -06:00
{Text: "Users", Id: "global-users", Url: setting.AppSubUrl + "/admin/users", Icon: "gicon gicon-user"},
2017-12-01 06:49:15 -06:00
{Text: "Orgs", Id: "global-orgs", Url: setting.AppSubUrl + "/admin/orgs", Icon: "gicon gicon-org"},
2017-12-13 16:48:44 -06:00
{Text: "Settings", Id: "server-settings", Url: setting.AppSubUrl + "/admin/settings", Icon: "gicon gicon-preferences"},
2017-12-01 06:49:15 -06:00
{Text: "Stats", Id: "server-stats", Url: setting.AppSubUrl + "/admin/stats", Icon: "fa fa-fw fa-bar-chart"},
{Text: "Style Guide", Id: "styleguide", Url: setting.AppSubUrl + "/styleguide", Icon: "fa fa-fw fa-eyedropper"},
},
})
}
2017-08-15 07:49:12 -05:00
2017-08-15 10:52:52 -05:00
data.NavTree = append(data.NavTree, cfgNode)
2016-02-14 10:37:05 -06:00
}
data.NavTree = append(data.NavTree, &dtos.NavLink{
Text: "Help",
Id: "help",
Url: "#",
2017-12-13 16:48:44 -06:00
Icon: "gicon gicon-question",
HideFromMenu: true,
Children: []*dtos.NavLink{
{Text: "Keyboard shortcuts", Url: "/shortcuts", Icon: "fa fa-fw fa-keyboard-o", Target: "_self"},
{Text: "Community site", Url: "http://community.grafana.com", Icon: "fa fa-fw fa-comment", Target: "_blank"},
{Text: "Documentation", Url: "http://docs.grafana.org", Icon: "fa fa-fw fa-file", Target: "_blank"},
},
})
return &data, nil
}
2018-03-07 10:54:50 -06:00
func Index(c *m.ReqContext) {
if data, err := setIndexViewData(c); err != nil {
c.Handle(500, "Failed to get settings", err)
return
} else {
c.HTML(200, "index", data)
}
}
2018-03-07 10:54:50 -06:00
func NotFoundHandler(c *m.ReqContext) {
if c.IsApiRequest() {
2015-03-22 14:14:00 -05:00
c.JsonApiErr(404, "Not found", nil)
return
}
if data, err := setIndexViewData(c); err != nil {
c.Handle(500, "Failed to get settings", err)
return
} else {
c.HTML(404, "index", data)
}
}