func NewReverseProxy(ds *m.DataSource, proxyPath string) *httputil.ReverseProxy { target, _ := url.Parse(ds.Url) director := func(req *http.Request) { req.URL.Scheme = target.Scheme req.URL.Host = target.Host req.Host = target.Host reqQueryVals := req.URL.Query() if ds.Type == m.DS_INFLUXDB_08 { req.URL.Path = util.JoinUrlFragments(target.Path, "db/"+ds.Database+"/"+proxyPath) reqQueryVals.Add("u", ds.User) reqQueryVals.Add("p", ds.Password) req.URL.RawQuery = reqQueryVals.Encode() } else if ds.Type == m.DS_INFLUXDB { req.URL.Path = util.JoinUrlFragments(target.Path, proxyPath) reqQueryVals.Add("db", ds.Database) req.URL.RawQuery = reqQueryVals.Encode() if !ds.BasicAuth { req.Header.Add("Authorization", util.GetBasicAuthHeader(ds.User, ds.Password)) } } else { req.URL.Path = util.JoinUrlFragments(target.Path, proxyPath) } if ds.BasicAuth { req.Header.Add("Authorization", util.GetBasicAuthHeader(ds.BasicAuthUser, ds.BasicAuthPassword)) } } return &httputil.ReverseProxy{Director: director} }
func sendWebRequestSync(ctx context.Context, webhook *Webhook) error { webhookLog.Debug("Sending webhook", "url", webhook.Url) client := &http.Client{ Timeout: time.Duration(10 * time.Second), } request, err := http.NewRequest(http.MethodPost, webhook.Url, bytes.NewReader([]byte(webhook.Body))) if webhook.User != "" && webhook.Password != "" { request.Header.Add("Authorization", util.GetBasicAuthHeader(webhook.User, webhook.Password)) } if err != nil { return err } resp, err := ctxhttp.Do(ctx, client, request) if err != nil { return err } if resp.StatusCode/100 == 2 { return nil } body, err := ioutil.ReadAll(resp.Body) if err != nil { return err } defer resp.Body.Close() webhookLog.Debug("Webhook failed", "statuscode", resp.Status, "body", string(body)) return fmt.Errorf("Webhook response status %v", resp.Status) }
func sendWebRequest(webhook *Webhook) error { webhookLog.Debug("Sending webhook", "url", webhook.Url) client := http.Client{ Timeout: time.Duration(10 * time.Second), } request, err := http.NewRequest("POST", webhook.Url, bytes.NewReader([]byte(webhook.Body))) if webhook.User != "" && webhook.Password != "" { request.Header.Add("Authorization", util.GetBasicAuthHeader(webhook.User, webhook.Password)) } if err != nil { return err } resp, err := client.Do(request) if err != nil { return err } _, err = ioutil.ReadAll(resp.Body) if err != nil { return err } if resp.StatusCode != 200 { return fmt.Errorf("Webhook response code %v", resp.StatusCode) } defer resp.Body.Close() return nil }
func NewReverseProxy(ds *m.DataSource, proxyPath string, targetUrl *url.URL) *httputil.ReverseProxy { director := func(req *http.Request) { req.URL.Scheme = targetUrl.Scheme req.URL.Host = targetUrl.Host req.Host = targetUrl.Host reqQueryVals := req.URL.Query() if ds.Type == m.DS_INFLUXDB_08 { req.URL.Path = util.JoinUrlFragments(targetUrl.Path, "db/"+ds.Database+"/"+proxyPath) reqQueryVals.Add("u", ds.User) reqQueryVals.Add("p", ds.Password) req.URL.RawQuery = reqQueryVals.Encode() } else if ds.Type == m.DS_INFLUXDB { req.URL.Path = util.JoinUrlFragments(targetUrl.Path, proxyPath) req.URL.RawQuery = reqQueryVals.Encode() if !ds.BasicAuth { req.Header.Del("Authorization") req.Header.Add("Authorization", util.GetBasicAuthHeader(ds.User, ds.Password)) } } else { req.URL.Path = util.JoinUrlFragments(targetUrl.Path, proxyPath) } if ds.BasicAuth { req.Header.Del("Authorization") req.Header.Add("Authorization", util.GetBasicAuthHeader(ds.BasicAuthUser, ds.BasicAuthPassword)) } dsAuth := req.Header.Get("X-DS-Authorization") if len(dsAuth) > 0 { req.Header.Del("X-DS-Authorization") req.Header.Del("Authorization") req.Header.Add("Authorization", dsAuth) } time.Sleep(time.Second * 5) // clear cookie headers req.Header.Del("Cookie") req.Header.Del("Set-Cookie") } return &httputil.ReverseProxy{Director: director, FlushInterval: time.Millisecond * 200} }
/** * @function: func NewReverseProxy(ds *m.DataSource, proxyPath string) *httputil.ReverseProxy * @description: This function initializes a reverse proxy. * @related issues: OWL-028, OWL-017, OWL-002 * @param: *m.DataSource ds * @param: string proxyPath * @return: *httputil.ReverseProxy * @author: Don Hsieh * @since: 07/17/2015 * @last modified: 08/04/2015 * @called by: func ProxyDataSourceRequest(c *middleware.Context) * in pkg/api/dataproxy.go */ func NewReverseProxy(ds *m.DataSource, proxyPath string) *httputil.ReverseProxy { target, _ := url.Parse(ds.Url) director := func(req *http.Request) { req.URL.Scheme = target.Scheme req.URL.Host = target.Host req.Host = target.Host reqQueryVals := req.URL.Query() if ds.Type == m.DS_INFLUXDB_08 { req.URL.Path = util.JoinUrlFragments(target.Path, "db/"+ds.Database+"/"+proxyPath) reqQueryVals.Add("u", ds.User) reqQueryVals.Add("p", ds.Password) req.URL.RawQuery = reqQueryVals.Encode() } else if ds.Type == m.DS_INFLUXDB { req.URL.Path = util.JoinUrlFragments(target.Path, proxyPath) reqQueryVals.Add("db", ds.Database) reqQueryVals.Add("u", ds.User) reqQueryVals.Add("p", ds.Password) req.URL.RawQuery = reqQueryVals.Encode() } else if ds.Type == "openfalcon" { // fmt.Printf("Welcome to %v!\n", ds.Type) // fmt.Printf("NewReverseProxy req.URL = %v\n", req.URL) reqQueryVals.Add("target", ds.Url) req.URL.RawQuery = reqQueryVals.Encode() ds.Url = "http://localhost" var port = "4001" ds.Url += ":" + port // fmt.Printf("NewReverseProxy ds.Url = %v\n", ds.Url) proxyPath = "/" target, _ := url.Parse(ds.Url) req.URL.Scheme = target.Scheme req.URL.Host = target.Host req.Host = target.Host req.URL.Path = util.JoinUrlFragments(target.Path, proxyPath) } else { req.URL.Path = util.JoinUrlFragments(target.Path, proxyPath) } if ds.BasicAuth { req.Header.Add("Authorization", util.GetBasicAuthHeader(ds.BasicAuthUser, ds.BasicAuthPassword)) } } return &httputil.ReverseProxy{Director: director} }
func sendWebRequestSync(ctx context.Context, webhook *Webhook) error { webhookLog.Debug("Sending webhook", "url", webhook.Url, "http method", webhook.HttpMethod) if webhook.HttpMethod == "" { webhook.HttpMethod = http.MethodPost } request, err := http.NewRequest(webhook.HttpMethod, webhook.Url, bytes.NewReader([]byte(webhook.Body))) if err != nil { return err } request.Header.Add("Content-Type", "application/json") request.Header.Add("User-Agent", "Grafana") if webhook.User != "" && webhook.Password != "" { request.Header.Add("Authorization", util.GetBasicAuthHeader(webhook.User, webhook.Password)) } for k, v := range webhook.HttpHeader { request.Header.Set(k, v) } resp, err := ctxhttp.Do(ctx, http.DefaultClient, request) if err != nil { return err } if resp.StatusCode/100 == 2 { return nil } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { return err } webhookLog.Debug("Webhook failed", "statuscode", resp.Status, "body", string(body)) return fmt.Errorf("Webhook response status %v", resp.Status) }
func getFrontendSettingsMap(c *middleware.Context) (map[string]interface{}, error) { orgDataSources := make([]*m.DataSource, 0) if c.OrgId != 0 { query := m.GetDataSourcesQuery{OrgId: c.OrgId} err := bus.Dispatch(&query) if err != nil { return nil, err } orgDataSources = query.Result } datasources := make(map[string]interface{}) var defaultDatasource string enabledPlugins, err := plugins.GetEnabledPlugins(c.OrgId) if err != nil { return nil, err } for _, ds := range orgDataSources { url := ds.Url if ds.Access == m.DS_ACCESS_PROXY { url = "/api/datasources/proxy/" + strconv.FormatInt(ds.Id, 10) } var dsMap = map[string]interface{}{ "type": ds.Type, "name": ds.Name, "url": url, } meta, exists := enabledPlugins.DataSources[ds.Type] if !exists { log.Error(3, "Could not find plugin definition for data source: %v", ds.Type) continue } dsMap["meta"] = meta if ds.IsDefault { defaultDatasource = ds.Name } if ds.JsonData != nil { dsMap["jsonData"] = ds.JsonData } if ds.Access == m.DS_ACCESS_DIRECT { if ds.BasicAuth { dsMap["basicAuth"] = util.GetBasicAuthHeader(ds.BasicAuthUser, ds.BasicAuthPassword) } if ds.WithCredentials { dsMap["withCredentials"] = ds.WithCredentials } if ds.Type == m.DS_INFLUXDB_08 { dsMap["username"] = ds.User dsMap["password"] = ds.Password dsMap["url"] = url + "/db/" + ds.Database } if ds.Type == m.DS_INFLUXDB { dsMap["username"] = ds.User dsMap["password"] = ds.Password dsMap["database"] = ds.Database dsMap["url"] = url } } if ds.Type == m.DS_ES { dsMap["index"] = ds.Database } if ds.Type == m.DS_INFLUXDB { dsMap["database"] = ds.Database } if ds.Type == m.DS_PROMETHEUS { // add unproxied server URL for link to Prometheus web UI dsMap["directUrl"] = ds.Url } datasources[ds.Name] = dsMap } // add grafana backend data source grafanaDatasourceMeta, _ := plugins.DataSources["grafana"] datasources["-- Grafana --"] = map[string]interface{}{ "type": "grafana", "name": "-- Grafana --", "meta": grafanaDatasourceMeta, } // add mixed backend data source datasources["-- Mixed --"] = map[string]interface{}{ "type": "mixed", "meta": plugins.DataSources["mixed"], } if defaultDatasource == "" { defaultDatasource = "-- Grafana --" } panels := map[string]interface{}{} for _, panel := range enabledPlugins.Panels { panels[panel.Id] = map[string]interface{}{ "module": panel.Module, "baseUrl": panel.BaseUrl, "name": panel.Name, "id": panel.Id, "info": panel.Info, "hideFromList": panel.HideFromList, "sort": getPanelSort(panel.Id), } } jsonObj := map[string]interface{}{ "defaultDatasource": defaultDatasource, "datasources": datasources, "panels": panels, "appSubUrl": setting.AppSubUrl, "allowOrgCreate": (setting.AllowUserOrgCreate && c.IsSignedIn) || c.IsGrafanaAdmin, "authProxyEnabled": setting.AuthProxyEnabled, "ldapEnabled": setting.LdapEnabled, "buildInfo": map[string]interface{}{ "version": setting.BuildVersion, "commit": setting.BuildCommit, "buildstamp": setting.BuildStamp, "latestVersion": plugins.GrafanaLatestVersion, "hasUpdate": plugins.GrafanaHasUpdate, "env": setting.Env, }, } return jsonObj, nil }
func TestMiddlewareContext(t *testing.T) { Convey("Given the grafana middleware", t, func() { middlewareScenario("middleware should add context to injector", func(sc *scenarioContext) { sc.fakeReq("GET", "/").exec() So(sc.context, ShouldNotBeNil) }) middlewareScenario("Default middleware should allow get request", func(sc *scenarioContext) { sc.fakeReq("GET", "/").exec() So(sc.resp.Code, ShouldEqual, 200) }) middlewareScenario("Non api request should init session", func(sc *scenarioContext) { sc.fakeReq("GET", "/").exec() So(sc.resp.Header().Get("Set-Cookie"), ShouldContainSubstring, "grafana_sess") }) middlewareScenario("Invalid api key", func(sc *scenarioContext) { sc.apiKey = "invalid_key_test" sc.fakeReq("GET", "/").exec() Convey("Should not init session", func() { So(sc.resp.Header().Get("Set-Cookie"), ShouldBeEmpty) }) Convey("Should return 401", func() { So(sc.resp.Code, ShouldEqual, 401) So(sc.respJson["message"], ShouldEqual, "Invalid API key") }) }) middlewareScenario("Using basic auth", func(sc *scenarioContext) { bus.AddHandler("test", func(query *m.GetUserByLoginQuery) error { query.Result = &m.User{ Password: util.EncodePassword("myPass", "salt"), Salt: "salt", } return nil }) bus.AddHandler("test", func(loginUserQuery *l.LoginUserQuery) error { return nil }) bus.AddHandler("test", func(query *m.GetSignedInUserQuery) error { query.Result = &m.SignedInUser{OrgId: 2, UserId: 12} return nil }) setting.BasicAuthEnabled = true authHeader := util.GetBasicAuthHeader("myUser", "myPass") sc.fakeReq("GET", "/").withAuthoriziationHeader(authHeader).exec() Convey("Should init middleware context with user", func() { So(sc.context.IsSignedIn, ShouldEqual, true) So(sc.context.OrgId, ShouldEqual, 2) So(sc.context.UserId, ShouldEqual, 12) }) }) middlewareScenario("Valid api key", func(sc *scenarioContext) { keyhash := util.EncodePassword("v5nAwpMafFP6znaS4urhdWDLS5511M42", "asd") bus.AddHandler("test", func(query *m.GetApiKeyByNameQuery) error { query.Result = &m.ApiKey{OrgId: 12, Role: m.ROLE_EDITOR, Key: keyhash} return nil }) sc.fakeReq("GET", "/").withValidApiKey().exec() Convey("Should return 200", func() { So(sc.resp.Code, ShouldEqual, 200) }) Convey("Should init middleware context", func() { So(sc.context.IsSignedIn, ShouldEqual, true) So(sc.context.OrgId, ShouldEqual, 12) So(sc.context.OrgRole, ShouldEqual, m.ROLE_EDITOR) }) }) middlewareScenario("Valid api key, but does not match db hash", func(sc *scenarioContext) { keyhash := "something_not_matching" bus.AddHandler("test", func(query *m.GetApiKeyByNameQuery) error { query.Result = &m.ApiKey{OrgId: 12, Role: m.ROLE_EDITOR, Key: keyhash} return nil }) sc.fakeReq("GET", "/").withValidApiKey().exec() Convey("Should return api key invalid", func() { So(sc.resp.Code, ShouldEqual, 401) So(sc.respJson["message"], ShouldEqual, "Invalid API key") }) }) middlewareScenario("UserId in session", func(sc *scenarioContext) { sc.fakeReq("GET", "/").handler(func(c *Context) { c.Session.Set(SESS_KEY_USERID, int64(12)) }).exec() bus.AddHandler("test", func(query *m.GetSignedInUserQuery) error { query.Result = &m.SignedInUser{OrgId: 2, UserId: 12} return nil }) sc.fakeReq("GET", "/").exec() Convey("should init context with user info", func() { So(sc.context.IsSignedIn, ShouldBeTrue) So(sc.context.UserId, ShouldEqual, 12) }) }) middlewareScenario("When anonymous access is enabled", func(sc *scenarioContext) { setting.AnonymousEnabled = true setting.AnonymousOrgName = "test" setting.AnonymousOrgRole = string(m.ROLE_EDITOR) bus.AddHandler("test", func(query *m.GetOrgByNameQuery) error { So(query.Name, ShouldEqual, "test") query.Result = &m.Org{Id: 2, Name: "test"} return nil }) sc.fakeReq("GET", "/").exec() Convey("should init context with org info", func() { So(sc.context.UserId, ShouldEqual, 0) So(sc.context.OrgId, ShouldEqual, 2) So(sc.context.OrgRole, ShouldEqual, m.ROLE_EDITOR) }) Convey("context signed in should be false", func() { So(sc.context.IsSignedIn, ShouldBeFalse) }) }) middlewareScenario("When auth_proxy is enabled enabled and user exists", func(sc *scenarioContext) { setting.AuthProxyEnabled = true setting.AuthProxyHeaderName = "X-WEBAUTH-USER" setting.AuthProxyHeaderProperty = "username" bus.AddHandler("test", func(query *m.GetSignedInUserQuery) error { query.Result = &m.SignedInUser{OrgId: 2, UserId: 12} return nil }) sc.fakeReq("GET", "/") sc.req.Header.Add("X-WEBAUTH-USER", "torkelo") sc.exec() Convey("should init context with user info", func() { So(sc.context.IsSignedIn, ShouldBeTrue) So(sc.context.UserId, ShouldEqual, 12) So(sc.context.OrgId, ShouldEqual, 2) }) }) middlewareScenario("When auth_proxy is enabled enabled and user does not exists", func(sc *scenarioContext) { setting.AuthProxyEnabled = true setting.AuthProxyHeaderName = "X-WEBAUTH-USER" setting.AuthProxyHeaderProperty = "username" setting.AuthProxyAutoSignUp = true bus.AddHandler("test", func(query *m.GetSignedInUserQuery) error { if query.UserId > 0 { query.Result = &m.SignedInUser{OrgId: 4, UserId: 33} return nil } else { return m.ErrUserNotFound } }) bus.AddHandler("test", func(cmd *m.CreateUserCommand) error { cmd.Result = m.User{Id: 33} return nil }) sc.fakeReq("GET", "/") sc.req.Header.Add("X-WEBAUTH-USER", "torkelo") sc.exec() Convey("Should create user if auto sign up is enabled", func() { So(sc.context.IsSignedIn, ShouldBeTrue) So(sc.context.UserId, ShouldEqual, 33) So(sc.context.OrgId, ShouldEqual, 4) }) }) middlewareScenario("When auth_proxy is enabled and request RemoteAddr is not trusted", func(sc *scenarioContext) { setting.AuthProxyEnabled = true setting.AuthProxyHeaderName = "X-WEBAUTH-USER" setting.AuthProxyHeaderProperty = "username" setting.AuthProxyWhitelist = "192.168.1.1, 192.168.2.1" sc.fakeReq("GET", "/") sc.req.Header.Add("X-WEBAUTH-USER", "torkelo") sc.req.RemoteAddr = "192.168.3.1:12345" sc.exec() Convey("should return 407 status code", func() { So(sc.resp.Code, ShouldEqual, 407) }) }) middlewareScenario("When auth_proxy is enabled and request RemoteAddr is trusted", func(sc *scenarioContext) { setting.AuthProxyEnabled = true setting.AuthProxyHeaderName = "X-WEBAUTH-USER" setting.AuthProxyHeaderProperty = "username" setting.AuthProxyWhitelist = "192.168.1.1, 192.168.2.1" bus.AddHandler("test", func(query *m.GetSignedInUserQuery) error { query.Result = &m.SignedInUser{OrgId: 4, UserId: 33} return nil }) sc.fakeReq("GET", "/") sc.req.Header.Add("X-WEBAUTH-USER", "torkelo") sc.req.RemoteAddr = "192.168.2.1:12345" sc.exec() Convey("Should init context with user info", func() { So(sc.context.IsSignedIn, ShouldBeTrue) So(sc.context.UserId, ShouldEqual, 33) So(sc.context.OrgId, ShouldEqual, 4) }) }) middlewareScenario("When session exists for previous user, create a new session", func(sc *scenarioContext) { setting.AuthProxyEnabled = true setting.AuthProxyHeaderName = "X-WEBAUTH-USER" setting.AuthProxyHeaderProperty = "username" setting.AuthProxyWhitelist = "" bus.AddHandler("test", func(query *m.GetSignedInUserQuery) error { query.Result = &m.SignedInUser{OrgId: 4, UserId: 32} return nil }) // create session sc.fakeReq("GET", "/").handler(func(c *Context) { c.Session.Set(SESS_KEY_USERID, int64(33)) }).exec() oldSessionID := sc.context.Session.ID() sc.req.Header.Add("X-WEBAUTH-USER", "torkelo") sc.exec() newSessionID := sc.context.Session.ID() Convey("Should not share session with other user", func() { So(oldSessionID, ShouldNotEqual, newSessionID) }) }) middlewareScenario("When auth_proxy and ldap enabled call sync with ldap user", func(sc *scenarioContext) { setting.AuthProxyEnabled = true setting.AuthProxyHeaderName = "X-WEBAUTH-USER" setting.AuthProxyHeaderProperty = "username" setting.AuthProxyWhitelist = "" setting.LdapEnabled = true called := false syncGrafanaUserWithLdapUser = func(ctx *Context, query *m.GetSignedInUserQuery) error { called = true return nil } bus.AddHandler("test", func(query *m.GetSignedInUserQuery) error { query.Result = &m.SignedInUser{OrgId: 4, UserId: 32} return nil }) sc.fakeReq("GET", "/") sc.req.Header.Add("X-WEBAUTH-USER", "torkelo") sc.exec() Convey("Should call syncGrafanaUserWithLdapUser", func() { So(called, ShouldBeTrue) }) }) }) }
func getFrontendSettingsMap(c *middleware.Context) (map[string]interface{}, error) { orgDataSources := make([]*m.DataSource, 0) if c.OrgId != 0 { query := m.GetDataSourcesQuery{OrgId: c.OrgId} err := bus.Dispatch(&query) if err != nil { return nil, err } orgDataSources = query.Result } datasources := make(map[string]interface{}) var defaultDatasource string for _, ds := range orgDataSources { url := ds.Url if ds.Access == m.DS_ACCESS_PROXY { url = setting.AppSubUrl + "/api/datasources/proxy/" + strconv.FormatInt(ds.Id, 10) } var dsMap = map[string]interface{}{ "type": ds.Type, "name": ds.Name, "url": url, } meta, exists := plugins.DataSources[ds.Type] if !exists { log.Error(3, "Could not find plugin definition for data source: %v", ds.Type) continue } dsMap["meta"] = meta if ds.IsDefault { defaultDatasource = ds.Name } if len(ds.JsonData) > 0 { dsMap["jsonData"] = ds.JsonData } if ds.Access == m.DS_ACCESS_DIRECT { if ds.BasicAuth { dsMap["basicAuth"] = util.GetBasicAuthHeader(ds.BasicAuthUser, ds.BasicAuthPassword) } if ds.Type == m.DS_INFLUXDB_08 { dsMap["username"] = ds.User dsMap["password"] = ds.Password dsMap["url"] = url + "/db/" + ds.Database } if ds.Type == m.DS_INFLUXDB { dsMap["username"] = ds.User dsMap["password"] = ds.Password dsMap["database"] = ds.Database dsMap["url"] = url } } if ds.Type == m.DS_ES { dsMap["index"] = ds.Database } datasources[ds.Name] = dsMap } // add grafana backend data source grafanaDatasourceMeta, _ := plugins.DataSources["grafana"] datasources["-- Grafana --"] = map[string]interface{}{ "type": "grafana", "meta": grafanaDatasourceMeta, } // add mixed backend data source datasources["-- Mixed --"] = map[string]interface{}{ "type": "mixed", "meta": plugins.DataSources["mixed"], } if defaultDatasource == "" { defaultDatasource = "-- Grafana --" } jsonObj := map[string]interface{}{ "defaultDatasource": defaultDatasource, "datasources": datasources, "appSubUrl": setting.AppSubUrl, "allowOrgCreate": (setting.AllowUserOrgCreate && c.IsSignedIn) || c.IsGrafanaAdmin, "buildInfo": map[string]interface{}{ "version": setting.BuildVersion, "commit": setting.BuildCommit, "buildstamp": setting.BuildStamp, }, } return jsonObj, nil }
func getFrontendSettingsMap(c *middleware.Context) (map[string]interface{}, error) { orgDataSources := make([]*m.DataSource, 0) if c.OrgId != 0 { query := m.GetDataSourcesQuery{OrgId: c.OrgId} err := bus.Dispatch(&query) if err != nil { return nil, err } orgDataSources = query.Result } datasources := make(map[string]interface{}) var defaultDatasource string for _, ds := range orgDataSources { url := ds.Url if ds.Access == m.DS_ACCESS_PROXY { url = setting.AppSubUrl + "/api/datasources/proxy/" + strconv.FormatInt(ds.Id, 10) } var dsMap = map[string]interface{}{ "type": ds.Type, "name": ds.Name, "url": url, } meta, exists := plugins.DataSources[ds.Type] if !exists { log.Error(3, "Could not find plugin definition for data source: %v", ds.Type) continue } dsMap["meta"] = meta if ds.IsDefault { defaultDatasource = ds.Name } if len(ds.JsonData) > 0 { dsMap["jsonData"] = ds.JsonData } if ds.Access == m.DS_ACCESS_DIRECT { if ds.BasicAuth { dsMap["basicAuth"] = util.GetBasicAuthHeader(ds.BasicAuthUser, ds.BasicAuthPassword) } if ds.Type == m.DS_INFLUXDB_08 { dsMap["username"] = ds.User dsMap["password"] = ds.Password dsMap["url"] = url + "/db/" + ds.Database } if ds.Type == m.DS_INFLUXDB { dsMap["username"] = ds.User dsMap["password"] = ds.Password dsMap["database"] = ds.Database dsMap["url"] = url } } if ds.Type == m.DS_ES { dsMap["index"] = ds.Database } datasources[ds.Name] = dsMap } // add grafana backend data source grafanaDatasourceMeta, _ := plugins.DataSources["grafana"] datasources["grafana"] = map[string]interface{}{ "type": "grafana", "meta": grafanaDatasourceMeta, } if defaultDatasource == "" { defaultDatasource = "raintank" } // add raintank backend. graphiteMeta, _ := plugins.DataSources["graphite"] datasources["raintank"] = map[string]interface{}{ "type": "graphite", "meta": graphiteMeta, "url": "/api/graphite", } jsonObj := map[string]interface{}{ "defaultDatasource": defaultDatasource, "datasources": datasources, "appSubUrl": setting.AppSubUrl, "allowOrgCreate": setting.AllowUserOrgCreate || c.IsGrafanaAdmin, "buildInfo": map[string]interface{}{ "version": setting.BuildVersion, "commit": setting.BuildCommit, "buildstamp": setting.BuildStamp, }, //TODO: this should loaded from the config file. "plugins": map[string]interface{}{ "dependencies": []string{"raintank/all"}, "panels": map[string]interface{}{ "raintankMonitorDescription": map[string]string{"path": "../plugins/raintank/panels/raintankMonitorDescription", "name": "Raintank Monitor Description"}, "raintankEventsPanel": map[string]string{"path": "../plugins/raintank/panels/raintankEventsPanel", "name": "Raintank Events"}, }, }, } return jsonObj, nil }