diff --git a/grafana b/grafana index 0e970307160..ad91093902b 160000 --- a/grafana +++ b/grafana @@ -1 +1 @@ -Subproject commit 0e970307160dfed9b09f6d1bf06dd49ff38035b7 +Subproject commit ad91093902bdfc0d2a87bb362a76a9057aef4361 diff --git a/pkg/api/api.go b/pkg/api/api.go index b4bbb7dbc1c..5987168f85b 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -28,7 +28,9 @@ func Register(m *macaron.Macaron) { // datasources m.Get("/admin/datasources/", auth, Index) m.Get("/api/admin/datasources/list", auth, GetDataSources) - m.Post("/api/admin/datasources/add", auth, AddDataSource) + m.Put("/api/admin/datasources", auth, AddDataSource) + m.Post("/api/admin/datasources", auth, UpdateDataSource) + m.Delete("/api/admin/datasources/:id", auth, DeleteDataSource) // user register m.Get("/register/*_", Index) diff --git a/pkg/api/api_datasources.go b/pkg/api/api_datasources.go index 1819da86e83..ed97b41738e 100644 --- a/pkg/api/api_datasources.go +++ b/pkg/api/api_datasources.go @@ -16,9 +16,9 @@ func GetDataSources(c *middleware.Context) { return } - result := make([]*dtos.DataSource, len(query.Resp)) - for _, ds := range query.Resp { - result = append(result, &dtos.DataSource{ + result := make([]*dtos.DataSource, len(query.Result)) + for i, ds := range query.Result { + result[i] = &dtos.DataSource{ Id: ds.Id, AccountId: ds.AccountId, Name: ds.Name, @@ -28,12 +28,31 @@ func GetDataSources(c *middleware.Context) { Password: ds.Password, User: ds.User, BasicAuth: ds.BasicAuth, - }) + } } c.JSON(200, result) } +func DeleteDataSource(c *middleware.Context) { + id := c.ParamsInt64(":id") + + if id <= 0 { + c.JsonApiErr(400, "Missing valid datasource id", nil) + return + } + + cmd := &m.DeleteDataSourceCommand{Id: id, AccountId: c.UserAccount.Id} + + err := bus.Dispatch(cmd) + if err != nil { + c.JsonApiErr(500, "Failed to delete datasource", err) + return + } + + c.JsonOK("Data source deleted") +} + func AddDataSource(c *middleware.Context) { cmd := m.AddDataSourceCommand{} @@ -52,3 +71,22 @@ func AddDataSource(c *middleware.Context) { c.JsonOK("Datasource added") } + +func UpdateDataSource(c *middleware.Context) { + cmd := m.UpdateDataSourceCommand{} + + if !c.JsonBody(&cmd) { + c.JsonApiErr(400, "Validation failed", nil) + return + } + + cmd.AccountId = c.Account.Id + + err := bus.Dispatch(&cmd) + if err != nil { + c.JsonApiErr(500, "Failed to update datasource", err) + return + } + + c.JsonOK("Datasource updated") +} diff --git a/pkg/api/dtos/models.go b/pkg/api/dtos/models.go index f39c00e6aef..7b340d06d4b 100644 --- a/pkg/api/dtos/models.go +++ b/pkg/api/dtos/models.go @@ -39,9 +39,8 @@ type Collaborator struct { } type DataSource struct { - Id int64 `json:"id"` - AccountId int64 `json:"accountId"` - + Id int64 `json:"id"` + AccountId int64 `json:"accountId"` Name string `json:"name"` Type models.DsType `json:"type"` Access models.DsAccess `json:"access"` diff --git a/pkg/models/datasource.go b/pkg/models/datasource.go index 0c03eb3c4bb..25ca8d66bd8 100644 --- a/pkg/models/datasource.go +++ b/pkg/models/datasource.go @@ -31,7 +31,7 @@ type DataSource struct { type GetDataSourcesQuery struct { AccountId int64 - Resp []*DataSource + Result []*DataSource } type AddDataSourceCommand struct { @@ -43,3 +43,19 @@ type AddDataSourceCommand struct { Password string User string } + +type UpdateDataSourceCommand struct { + Id int64 + AccountId int64 + Name string + Type DsType + Access DsAccess + Url string + Password string + User string +} + +type DeleteDataSourceCommand struct { + Id int64 + AccountId int64 +} diff --git a/pkg/stores/sqlstore/sqlstore_datasource.go b/pkg/stores/sqlstore/sqlstore_datasource.go index d644b05ad09..cd8be560ac9 100644 --- a/pkg/stores/sqlstore/sqlstore_datasource.go +++ b/pkg/stores/sqlstore/sqlstore_datasource.go @@ -12,13 +12,23 @@ import ( func init() { bus.AddHandler("sql", GetDataSources) bus.AddHandler("sql", AddDataSource) + bus.AddHandler("sql", DeleteDataSource) + bus.AddHandler("sql", UpdateDataSource) } func GetDataSources(query *m.GetDataSourcesQuery) error { sess := x.Limit(100, 0).Where("account_id=?", query.AccountId) - query.Resp = make([]*m.DataSource, 0) - return sess.Find(&query.Resp) + query.Result = make([]*m.DataSource, 0) + return sess.Find(&query.Result) +} + +func DeleteDataSource(cmd *m.DeleteDataSourceCommand) error { + return inTransaction(func(sess *xorm.Session) error { + var rawSql = "DELETE FROM data_source WHERE id=? and account_id=?" + _, err := sess.Exec(rawSql, cmd.Id, cmd.AccountId) + return err + }) } func AddDataSource(cmd *m.AddDataSourceCommand) error { @@ -36,12 +46,28 @@ func AddDataSource(cmd *m.AddDataSourceCommand) error { Updated: time.Now(), } - if ds.Id == 0 { - _, err = sess.Insert(ds) - } else { - _, err = sess.Id(ds.Id).Update(ds) - } + _, err = sess.Insert(ds) return err }) } + +func UpdateDataSource(cmd *m.UpdateDataSourceCommand) error { + + return inTransaction(func(sess *xorm.Session) error { + var err error + + ds := m.DataSource{ + Id: cmd.Id, + AccountId: cmd.AccountId, + Name: cmd.Name, + Type: cmd.Type, + Access: cmd.Access, + Url: cmd.Url, + Updated: time.Now(), + } + + _, err = sess.Where("id=? and account_id=?", ds.Id, ds.AccountId).Update(&ds) + return err + }) +} diff --git a/pkg/stores/sqlstore/sqlstore_test.go b/pkg/stores/sqlstore/sqlstore_test.go index cc1f5b8bbf5..27bb4c4bec4 100644 --- a/pkg/stores/sqlstore/sqlstore_test.go +++ b/pkg/stores/sqlstore/sqlstore_test.go @@ -45,13 +45,44 @@ func TestDataAccess(t *testing.T) { err = GetDataSources(&query) So(err, ShouldBeNil) - So(len(query.Resp), ShouldEqual, 1) + So(len(query.Result), ShouldEqual, 1) - ds := query.Resp[0] + ds := query.Result[0] So(ds.AccountId, ShouldEqual, 10) }) + Convey("Given a datasource", func() { + + AddDataSource(&m.AddDataSourceCommand{ + AccountId: 10, + Type: m.DS_GRAPHITE, + Access: m.DS_ACCESS_DIRECT, + Url: "http://test", + }) + + query := m.GetDataSourcesQuery{AccountId: 10} + GetDataSources(&query) + ds := query.Result[0] + + Convey("Can delete datasource", func() { + err := DeleteDataSource(&m.DeleteDataSourceCommand{Id: ds.Id, AccountId: ds.AccountId}) + So(err, ShouldBeNil) + + GetDataSources(&query) + So(len(query.Result), ShouldEqual, 0) + }) + + Convey("Can not delete datasource with wrong accountId", func() { + err := DeleteDataSource(&m.DeleteDataSourceCommand{Id: ds.Id, AccountId: 123123}) + So(err, ShouldBeNil) + + GetDataSources(&query) + So(len(query.Result), ShouldEqual, 1) + }) + + }) + }) }