| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | package api | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2016-03-16 03:29:35 +08:00
										 |  |  | 	"sort" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-05 17:37:13 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/api/dtos" | 
					
						
							|  |  |  | 	"github.com/grafana/grafana/pkg/bus" | 
					
						
							|  |  |  | 	"github.com/grafana/grafana/pkg/middleware" | 
					
						
							|  |  |  | 	m "github.com/grafana/grafana/pkg/models" | 
					
						
							| 
									
										
										
										
											2016-12-07 18:10:42 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/plugins" | 
					
						
							| 
									
										
										
										
											2015-06-01 18:15:49 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/util" | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-08 21:20:07 +08:00
										 |  |  | func GetDataSources(c *middleware.Context) Response { | 
					
						
							| 
									
										
										
										
											2015-02-24 03:07:49 +08:00
										 |  |  | 	query := m.GetDataSourcesQuery{OrgId: c.OrgId} | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-14 17:04:27 +08:00
										 |  |  | 	if err := bus.Dispatch(&query); err != nil { | 
					
						
							| 
									
										
										
										
											2017-02-08 21:20:07 +08:00
										 |  |  | 		return ApiError(500, "Failed to query datasources", err) | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-16 03:29:35 +08:00
										 |  |  | 	result := make(dtos.DataSourceList, 0) | 
					
						
							|  |  |  | 	for _, ds := range query.Result { | 
					
						
							| 
									
										
										
										
											2017-04-25 21:17:49 +08:00
										 |  |  | 		dsItem := dtos.DataSourceListItemDTO{ | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | 			Id:        ds.Id, | 
					
						
							| 
									
										
										
										
											2015-02-24 03:07:49 +08:00
										 |  |  | 			OrgId:     ds.OrgId, | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | 			Name:      ds.Name, | 
					
						
							|  |  |  | 			Url:       ds.Url, | 
					
						
							|  |  |  | 			Type:      ds.Type, | 
					
						
							|  |  |  | 			Access:    ds.Access, | 
					
						
							|  |  |  | 			Password:  ds.Password, | 
					
						
							|  |  |  | 			Database:  ds.Database, | 
					
						
							|  |  |  | 			User:      ds.User, | 
					
						
							|  |  |  | 			BasicAuth: ds.BasicAuth, | 
					
						
							| 
									
										
										
										
											2015-01-09 23:36:23 +08:00
										 |  |  | 			IsDefault: ds.IsDefault, | 
					
						
							| 
									
										
										
										
											2016-09-01 23:21:13 +08:00
										 |  |  | 			JsonData:  ds.JsonData, | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-03-16 03:29:35 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if plugin, exists := plugins.DataSources[ds.Type]; exists { | 
					
						
							|  |  |  | 			dsItem.TypeLogoUrl = plugin.Info.Logos.Small | 
					
						
							|  |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2016-03-23 22:09:48 +08:00
										 |  |  | 			dsItem.TypeLogoUrl = "public/img/icn-datasource.svg" | 
					
						
							| 
									
										
										
										
											2016-03-16 03:29:35 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		result = append(result, dsItem) | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-16 03:29:35 +08:00
										 |  |  | 	sort.Sort(result) | 
					
						
							| 
									
										
										
										
											2017-02-08 21:20:07 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return Json(200, &result) | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-13 16:43:25 +08:00
										 |  |  | func GetDataSourceById(c *middleware.Context) Response { | 
					
						
							| 
									
										
										
										
											2015-02-14 17:04:27 +08:00
										 |  |  | 	query := m.GetDataSourceByIdQuery{ | 
					
						
							| 
									
										
										
										
											2015-02-24 03:07:49 +08:00
										 |  |  | 		Id:    c.ParamsInt64(":id"), | 
					
						
							|  |  |  | 		OrgId: c.OrgId, | 
					
						
							| 
									
										
										
										
											2015-02-14 17:04:27 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if err := bus.Dispatch(&query); err != nil { | 
					
						
							| 
									
										
										
										
											2015-11-13 16:43:25 +08:00
										 |  |  | 		if err == m.ErrDataSourceNotFound { | 
					
						
							|  |  |  | 			return ApiError(404, "Data source not found", nil) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return ApiError(500, "Failed to query datasources", err) | 
					
						
							| 
									
										
										
										
											2015-02-14 17:04:27 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ds := query.Result | 
					
						
							| 
									
										
										
										
											2016-03-08 18:51:03 +08:00
										 |  |  | 	dtos := convertModelToDtos(ds) | 
					
						
							| 
									
										
										
										
											2015-02-14 17:04:27 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-08 18:51:03 +08:00
										 |  |  | 	return Json(200, &dtos) | 
					
						
							| 
									
										
										
										
											2015-02-14 17:04:27 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-10 10:11:36 +08:00
										 |  |  | func DeleteDataSourceById(c *middleware.Context) { | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | 	id := c.ParamsInt64(":id") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if id <= 0 { | 
					
						
							|  |  |  | 		c.JsonApiErr(400, "Missing valid datasource id", nil) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-10 10:11:36 +08:00
										 |  |  | 	cmd := &m.DeleteDataSourceByIdCommand{Id: id, OrgId: c.OrgId} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err := bus.Dispatch(cmd) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		c.JsonApiErr(500, "Failed to delete datasource", err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	c.JsonOK("Data source deleted") | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func DeleteDataSourceByName(c *middleware.Context) { | 
					
						
							|  |  |  | 	name := c.Params(":name") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if name == "" { | 
					
						
							|  |  |  | 		c.JsonApiErr(400, "Missing valid datasource name", nil) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	cmd := &m.DeleteDataSourceByNameCommand{Name: name, OrgId: c.OrgId} | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	err := bus.Dispatch(cmd) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		c.JsonApiErr(500, "Failed to delete datasource", err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	c.JsonOK("Data source deleted") | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-02 16:58:35 +08:00
										 |  |  | func AddDataSource(c *middleware.Context, cmd m.AddDataSourceCommand) { | 
					
						
							| 
									
										
										
										
											2015-02-24 03:07:49 +08:00
										 |  |  | 	cmd.OrgId = c.OrgId | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-09 18:01:37 +08:00
										 |  |  | 	if err := bus.Dispatch(&cmd); err != nil { | 
					
						
							| 
									
										
										
										
											2016-10-01 22:41:27 +08:00
										 |  |  | 		if err == m.ErrDataSourceNameExists { | 
					
						
							|  |  |  | 			c.JsonApiErr(409, err.Error(), err) | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | 		c.JsonApiErr(500, "Failed to add datasource", err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-20 20:02:26 +08:00
										 |  |  | 	c.JSON(200, util.DynMap{"message": "Datasource added", "id": cmd.Result.Id, "name": cmd.Result.Name}) | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-18 23:44:59 +08:00
										 |  |  | func UpdateDataSource(c *middleware.Context, cmd m.UpdateDataSourceCommand) Response { | 
					
						
							| 
									
										
										
										
											2015-02-24 03:07:49 +08:00
										 |  |  | 	cmd.OrgId = c.OrgId | 
					
						
							| 
									
										
										
										
											2015-06-01 18:15:49 +08:00
										 |  |  | 	cmd.Id = c.ParamsInt64(":id") | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-18 23:44:59 +08:00
										 |  |  | 	err := fillWithSecureJsonData(&cmd) | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2016-11-18 23:44:59 +08:00
										 |  |  | 		return ApiError(500, "Failed to update datasource", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err = bus.Dispatch(&cmd) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return ApiError(500, "Failed to update datasource", err) | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-20 20:02:26 +08:00
										 |  |  | 	return Json(200, util.DynMap{"message": "Datasource updated", "id": cmd.Id, "name": cmd.Name}) | 
					
						
							| 
									
										
										
										
											2016-11-18 23:44:59 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func fillWithSecureJsonData(cmd *m.UpdateDataSourceCommand) error { | 
					
						
							|  |  |  | 	if len(cmd.SecureJsonData) == 0 { | 
					
						
							|  |  |  | 		return nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ds, err := getRawDataSourceById(cmd.Id, cmd.OrgId) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-11 16:50:24 +08:00
										 |  |  | 	secureJsonData := ds.SecureJsonData.Decrypt() | 
					
						
							| 
									
										
										
										
											2016-11-18 23:44:59 +08:00
										 |  |  | 	for k, v := range secureJsonData { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if _, ok := cmd.SecureJsonData[k]; !ok { | 
					
						
							|  |  |  | 			cmd.SecureJsonData[k] = v | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-11 16:50:24 +08:00
										 |  |  | 	// set version from db
 | 
					
						
							|  |  |  | 	cmd.Version = ds.Version | 
					
						
							| 
									
										
										
										
											2016-11-18 23:44:59 +08:00
										 |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func getRawDataSourceById(id int64, orgId int64) (*m.DataSource, error) { | 
					
						
							|  |  |  | 	query := m.GetDataSourceByIdQuery{ | 
					
						
							|  |  |  | 		Id:    id, | 
					
						
							|  |  |  | 		OrgId: orgId, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if err := bus.Dispatch(&query); err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return query.Result, nil | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2015-02-28 15:25:13 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-08 04:25:26 +08:00
										 |  |  | // Get /api/datasources/name/:name
 | 
					
						
							|  |  |  | func GetDataSourceByName(c *middleware.Context) Response { | 
					
						
							|  |  |  | 	query := m.GetDataSourceByNameQuery{Name: c.Params(":name"), OrgId: c.OrgId} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if err := bus.Dispatch(&query); err != nil { | 
					
						
							|  |  |  | 		if err == m.ErrDataSourceNotFound { | 
					
						
							|  |  |  | 			return ApiError(404, "Data source not found", nil) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return ApiError(500, "Failed to query datasources", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-06 23:11:46 +08:00
										 |  |  | 	dtos := convertModelToDtos(query.Result) | 
					
						
							| 
									
										
										
										
											2016-03-08 18:51:03 +08:00
										 |  |  | 	return Json(200, &dtos) | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2016-03-08 04:25:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-10 17:31:10 +08:00
										 |  |  | // Get /api/datasources/id/:name
 | 
					
						
							|  |  |  | func GetDataSourceIdByName(c *middleware.Context) Response { | 
					
						
							|  |  |  | 	query := m.GetDataSourceByNameQuery{Name: c.Params(":name"), OrgId: c.OrgId} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if err := bus.Dispatch(&query); err != nil { | 
					
						
							|  |  |  | 		if err == m.ErrDataSourceNotFound { | 
					
						
							|  |  |  | 			return ApiError(404, "Data source not found", nil) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return ApiError(500, "Failed to query datasources", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ds := query.Result | 
					
						
							|  |  |  | 	dtos := dtos.AnyId{ | 
					
						
							|  |  |  | 		Id: ds.Id, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return Json(200, &dtos) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-06 23:11:46 +08:00
										 |  |  | func convertModelToDtos(ds *m.DataSource) dtos.DataSource { | 
					
						
							| 
									
										
										
										
											2016-11-18 23:44:59 +08:00
										 |  |  | 	dto := dtos.DataSource{ | 
					
						
							| 
									
										
										
										
											2016-03-08 04:25:26 +08:00
										 |  |  | 		Id:                ds.Id, | 
					
						
							|  |  |  | 		OrgId:             ds.OrgId, | 
					
						
							|  |  |  | 		Name:              ds.Name, | 
					
						
							|  |  |  | 		Url:               ds.Url, | 
					
						
							|  |  |  | 		Type:              ds.Type, | 
					
						
							|  |  |  | 		Access:            ds.Access, | 
					
						
							|  |  |  | 		Password:          ds.Password, | 
					
						
							|  |  |  | 		Database:          ds.Database, | 
					
						
							|  |  |  | 		User:              ds.User, | 
					
						
							|  |  |  | 		BasicAuth:         ds.BasicAuth, | 
					
						
							|  |  |  | 		BasicAuthUser:     ds.BasicAuthUser, | 
					
						
							|  |  |  | 		BasicAuthPassword: ds.BasicAuthPassword, | 
					
						
							|  |  |  | 		WithCredentials:   ds.WithCredentials, | 
					
						
							|  |  |  | 		IsDefault:         ds.IsDefault, | 
					
						
							|  |  |  | 		JsonData:          ds.JsonData, | 
					
						
							| 
									
										
										
										
											2016-12-15 04:05:12 +08:00
										 |  |  | 		SecureJsonFields:  map[string]bool{}, | 
					
						
							| 
									
										
										
										
											2016-11-18 23:44:59 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-24 23:24:47 +08:00
										 |  |  | 	for k, v := range ds.SecureJsonData { | 
					
						
							|  |  |  | 		if len(v) > 0 { | 
					
						
							| 
									
										
										
										
											2016-12-15 04:05:12 +08:00
										 |  |  | 			dto.SecureJsonFields[k] = true | 
					
						
							| 
									
										
										
										
											2016-11-24 23:24:47 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-18 23:44:59 +08:00
										 |  |  | 	return dto | 
					
						
							| 
									
										
										
										
											2016-03-08 04:25:26 +08:00
										 |  |  | } |