Ver código fonte

Dashboard snapshot: added delete key which can be used to delete snapshots, #1623

Torkel Ödegaard 10 anos atrás
pai
commit
4322f29f34

+ 2 - 0
pkg/api/api.go

@@ -44,7 +44,9 @@ func Register(r *macaron.Macaron) {
 	// dashboard snapshots
 	r.Post("/api/snapshots/", bind(m.CreateDashboardSnapshotCommand{}), CreateDashboardSnapshot)
 	r.Get("/dashboard/snapshots/*", Index)
+
 	r.Get("/api/snapshots/:key", GetDashboardSnapshot)
+	r.Get("/api/snapshots-delete/:key", DeleteDashboardSnapshot)
 
 	// authed api
 	r.Group("/api", func() {

+ 21 - 5
pkg/api/dashboard_snapshot.go

@@ -1,7 +1,6 @@
 package api
 
 import (
-	"strconv"
 	"time"
 
 	"github.com/grafana/grafana/pkg/api/dtos"
@@ -15,12 +14,15 @@ import (
 
 func CreateDashboardSnapshot(c *middleware.Context, cmd m.CreateDashboardSnapshotCommand) {
 	cmd.Key = util.GetRandomString(32)
+	cmd.DeleteKey = util.GetRandomString(32)
 
 	if cmd.External {
 		cmd.OrgId = -1
+		cmd.UserId = -1
 		metrics.M_Api_Dashboard_Snapshot_External.Inc(1)
 	} else {
 		cmd.OrgId = c.OrgId
+		cmd.UserId = c.UserId
 		metrics.M_Api_Dashboard_Snapshot_Create.Inc(1)
 	}
 
@@ -29,7 +31,12 @@ func CreateDashboardSnapshot(c *middleware.Context, cmd m.CreateDashboardSnapsho
 		return
 	}
 
-	c.JSON(200, util.DynMap{"key": cmd.Key, "url": setting.ToAbsUrl("dashboard/snapshot/" + cmd.Key)})
+	c.JSON(200, util.DynMap{
+		"key":       cmd.Key,
+		"deleteKey": cmd.DeleteKey,
+		"url":       setting.ToAbsUrl("dashboard/snapshot/" + cmd.Key),
+		"deleteUrl": setting.ToAbsUrl("api/snapshots-delete/" + cmd.DeleteKey),
+	})
 }
 
 func GetDashboardSnapshot(c *middleware.Context) {
@@ -58,9 +65,18 @@ func GetDashboardSnapshot(c *middleware.Context) {
 
 	metrics.M_Api_Dashboard_Snapshot_Get.Inc(1)
 
-	maxAge := int64(snapshot.Expires.Sub(time.Now()).Seconds())
+	c.Resp.Header().Set("Cache-Control", "public, max-age=3600")
+	c.JSON(200, dto)
+}
 
-	c.Resp.Header().Set("Cache-Control", "public, max-age="+strconv.FormatInt(maxAge, 10))
+func DeleteDashboardSnapshot(c *middleware.Context) {
+	key := c.Params(":key")
+	cmd := &m.DeleteDashboardSnapshotCommand{DeleteKey: key}
 
-	c.JSON(200, dto)
+	if err := bus.Dispatch(cmd); err != nil {
+		c.JsonApiErr(500, "Failed to delete dashboard snapshot", err)
+		return
+	}
+
+	c.JSON(200, util.DynMap{"message": "Snapshot deleted. It might take an hour before it is cleared from a CDN cache."})
 }

+ 20 - 9
pkg/models/dashboard_snapshot.go

@@ -4,10 +4,14 @@ import "time"
 
 // DashboardSnapshot model
 type DashboardSnapshot struct {
-	Id    int64
-	Name  string
-	Key   string
-	OrgId int64
+	Id          int64
+	Name        string
+	Key         string
+	DeleteKey   string
+	OrgId       int64
+	UserId      int64
+	External    bool
+	ExternalUrl string
 
 	Expires time.Time
 	Created time.Time
@@ -20,16 +24,23 @@ type DashboardSnapshot struct {
 // COMMANDS
 
 type CreateDashboardSnapshotCommand struct {
-	Dashboard map[string]interface{} `json:"dashboard" binding:"Required"`
-	External  bool                   `json:"external"`
-	Expires   int64                  `json:"expires"`
+	Dashboard   map[string]interface{} `json:"dashboard" binding:"Required"`
+	External    bool                   `json:"external"`
+	ExternalUrl string                 `json:"externalUrl"`
+	Expires     int64                  `json:"expires"`
 
-	OrgId int64  `json:"-"`
-	Key   string `json:"-"`
+	OrgId     int64  `json:"-"`
+	UserId    int64  `json:"-"`
+	Key       string `json:"-"`
+	DeleteKey string `json:"-"`
 
 	Result *DashboardSnapshot
 }
 
+type DeleteDashboardSnapshotCommand struct {
+	DeleteKey string `json:"-"`
+}
+
 type GetDashboardSnapshotQuery struct {
 	Key string
 

+ 19 - 6
pkg/services/sqlstore/dashboard_snapshot.go

@@ -11,6 +11,7 @@ import (
 func init() {
 	bus.AddHandler("sql", CreateDashboardSnapshot)
 	bus.AddHandler("sql", GetDashboardSnapshot)
+	bus.AddHandler("sql", DeleteDashboardSnapshot)
 }
 
 func CreateDashboardSnapshot(cmd *m.CreateDashboardSnapshotCommand) error {
@@ -23,12 +24,16 @@ func CreateDashboardSnapshot(cmd *m.CreateDashboardSnapshotCommand) error {
 		}
 
 		snapshot := &m.DashboardSnapshot{
-			Key:       cmd.Key,
-			OrgId:     cmd.OrgId,
-			Dashboard: cmd.Dashboard,
-			Expires:   expires,
-			Created:   time.Now(),
-			Updated:   time.Now(),
+			Key:         cmd.Key,
+			DeleteKey:   cmd.DeleteKey,
+			OrgId:       cmd.OrgId,
+			UserId:      cmd.UserId,
+			External:    cmd.External,
+			ExternalUrl: cmd.ExternalUrl,
+			Dashboard:   cmd.Dashboard,
+			Expires:     expires,
+			Created:     time.Now(),
+			Updated:     time.Now(),
 		}
 
 		_, err := sess.Insert(snapshot)
@@ -38,6 +43,14 @@ func CreateDashboardSnapshot(cmd *m.CreateDashboardSnapshotCommand) error {
 	})
 }
 
+func DeleteDashboardSnapshot(cmd *m.DeleteDashboardSnapshotCommand) error {
+	return inTransaction(func(sess *xorm.Session) error {
+		var rawSql = "DELETE FROM dashboard_snapshot WHERE delete_key=?"
+		_, err := sess.Exec(rawSql, cmd.DeleteKey)
+		return err
+	})
+}
+
 func GetDashboardSnapshot(query *m.GetDashboardSnapshotQuery) error {
 	snapshot := m.DashboardSnapshot{Key: query.Key}
 	has, err := x.Get(&snapshot)

+ 29 - 5
pkg/services/sqlstore/migrations/dashboard_snapshot_mig.go

@@ -19,12 +19,36 @@ func addDashboardSnapshotMigrations(mg *Migrator) {
 		},
 	}
 
+	// add v4
 	mg.AddMigration("create dashboard_snapshot table v4", NewAddTableMigration(snapshotV4))
-	addTableIndicesMigrations(mg, "v4", snapshotV4)
 
-	mg.AddMigration("add org_id to dashboard_snapshot", new(AddColumnMigration).
-		Table("dashboard_snapshot").Column(&Column{Name: "org_id", Type: DB_BigInt, Nullable: true}))
+	// drop v4
+	addDropAllIndicesMigrations(mg, "v4", snapshotV4)
+	mg.AddMigration("drop table dashboard_snapshot_v4 #1", NewDropTableMigration("dashboard_snapshot"))
 
-	mg.AddMigration("add index org_id to dashboard_snapshot",
-		NewAddIndexMigration(snapshotV4, &Index{Cols: []string{"org_id"}}))
+	snapshotV5 := Table{
+		Name: "dashboard_snapshot",
+		Columns: []*Column{
+			{Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true},
+			{Name: "name", Type: DB_NVarchar, Length: 255, Nullable: false},
+			{Name: "key", Type: DB_NVarchar, Length: 255, Nullable: false},
+			{Name: "delete_key", Type: DB_NVarchar, Length: 255, Nullable: false},
+			{Name: "org_id", Type: DB_BigInt, Nullable: false},
+			{Name: "user_id", Type: DB_BigInt, Nullable: false},
+			{Name: "external", Type: DB_Bool, Nullable: false},
+			{Name: "external_url", Type: DB_NVarchar, Length: 255, Nullable: false},
+			{Name: "dashboard", Type: DB_Text, Nullable: false},
+			{Name: "expires", Type: DB_DateTime, Nullable: false},
+			{Name: "created", Type: DB_DateTime, Nullable: false},
+			{Name: "updated", Type: DB_DateTime, Nullable: false},
+		},
+		Indices: []*Index{
+			{Cols: []string{"key"}, Type: UniqueIndex},
+			{Cols: []string{"delete_key"}, Type: UniqueIndex},
+			{Cols: []string{"user_id"}},
+		},
+	}
+
+	mg.AddMigration("create dashboard_snapshot table v5 #2", NewAddTableMigration(snapshotV5))
+	addTableIndicesMigrations(mg, "v5", snapshotV5)
 }

+ 3 - 0
src/app/features/dashboard/partials/shareDashboard.html

@@ -110,6 +110,9 @@
 			</button>
 		</div>
 
+		<div class="pull-right" ng-if="step === 2" style="padding: 5px">
+			Did you make a mistake? <a href="{{deleteUrl}}" target="_blank">delete snapshot.</a>
+		</div>
 	</div>
 </div>
 

+ 2 - 0
src/app/features/dashboard/shareSnapshotCtrl.js

@@ -84,10 +84,12 @@ function (angular, _) {
         $scope.loading = false;
 
         if (external) {
+          $scope.deleteUrl = results.deleteUrl;
           $scope.snapshotUrl = results.url;
         } else {
           var baseUrl = $location.absUrl().replace($location.url(), "");
           $scope.snapshotUrl = baseUrl + '/dashboard/snapshot/' + results.key;
+          $scope.deleteUrl = baseUrl + '/api/snapshots-delete/' + results.deleteKey;
         }
 
         $scope.step = 2;