mirror of https://github.com/grafana/grafana
inital backend suport for quotas. issue #321
Conflicts: conf/defaults.ini main.go pkg/services/sqlstore/migrations/migrations.gopull/2720/head
parent
96af2debfc
commit
9023171940
@ -0,0 +1,26 @@ |
||||
package api |
||||
|
||||
import ( |
||||
"github.com/grafana/grafana/pkg/bus" |
||||
"github.com/grafana/grafana/pkg/middleware" |
||||
m "github.com/grafana/grafana/pkg/models" |
||||
) |
||||
|
||||
func GetOrgQuotas(c *middleware.Context) Response { |
||||
query := m.GetQuotasQuery{OrgId: c.ParamsInt64(":orgId")} |
||||
|
||||
if err := bus.Dispatch(&query); err != nil { |
||||
return ApiError(500, "Failed to get org quotas", err) |
||||
} |
||||
|
||||
return Json(200, query.Result) |
||||
} |
||||
|
||||
func UpdateOrgQuota(c *middleware.Context, cmd m.UpdateQuotaCmd) Response { |
||||
cmd.OrgId = c.ParamsInt64(":orgId") |
||||
cmd.Target = m.QuotaTarget(c.Params(":target")) |
||||
if err := bus.Dispatch(&cmd); err != nil { |
||||
return ApiError(500, "Failed to update org quotas", err) |
||||
} |
||||
return ApiSuccess("Organization quota updated") |
||||
} |
||||
@ -0,0 +1,63 @@ |
||||
package models |
||||
|
||||
import ( |
||||
"github.com/grafana/grafana/pkg/setting" |
||||
"time" |
||||
) |
||||
|
||||
type QuotaTarget string |
||||
|
||||
const ( |
||||
QUOTA_USER QuotaTarget = "user" //SQL table to query. ie. "select count(*) from user where org_id=?"
|
||||
QUOTA_DATASOURCE QuotaTarget = "data_source" |
||||
QUOTA_DASHBOARD QuotaTarget = "dashboard" |
||||
QUOTA_ENDPOINT QuotaTarget = "endpoint" |
||||
QUOTA_COLLECTOR QuotaTarget = "collector" |
||||
) |
||||
|
||||
// defaults are set from settings package.
|
||||
var DefaultQuotas map[QuotaTarget]int64 |
||||
|
||||
func InitQuotaDefaults() { |
||||
// set global defaults.
|
||||
DefaultQuotas = make(map[QuotaTarget]int64) |
||||
quota := setting.Cfg.Section("quota") |
||||
DefaultQuotas[QUOTA_USER] = quota.Key("user").MustInt64(10) |
||||
DefaultQuotas[QUOTA_DATASOURCE] = quota.Key("data_source").MustInt64(10) |
||||
DefaultQuotas[QUOTA_DASHBOARD] = quota.Key("dashboard").MustInt64(10) |
||||
DefaultQuotas[QUOTA_ENDPOINT] = quota.Key("endpoint").MustInt64(10) |
||||
DefaultQuotas[QUOTA_COLLECTOR] = quota.Key("collector").MustInt64(10) |
||||
} |
||||
|
||||
type Quota struct { |
||||
Id int64 |
||||
OrgId int64 |
||||
Target QuotaTarget |
||||
Limit int64 |
||||
Created time.Time |
||||
Updated time.Time |
||||
} |
||||
|
||||
type QuotaDTO struct { |
||||
OrgId int64 `json:"org_id"` |
||||
Target QuotaTarget `json:"target"` |
||||
Limit int64 `json:"limit"` |
||||
Used int64 `json:"used"` |
||||
} |
||||
|
||||
type GetQuotaByTargetQuery struct { |
||||
Target QuotaTarget |
||||
OrgId int64 |
||||
Result *QuotaDTO |
||||
} |
||||
|
||||
type GetQuotasQuery struct { |
||||
OrgId int64 |
||||
Result []*QuotaDTO |
||||
} |
||||
|
||||
type UpdateQuotaCmd struct { |
||||
Target QuotaTarget `json:"target"` |
||||
Limit int64 `json:"limit"` |
||||
OrgId int64 `json:"-"` |
||||
} |
||||
@ -0,0 +1,27 @@ |
||||
package migrations |
||||
|
||||
import ( |
||||
. "github.com/grafana/grafana/pkg/services/sqlstore/migrator" |
||||
) |
||||
|
||||
func addQuotaMigration(mg *Migrator) { |
||||
|
||||
var quotaV1 = Table{ |
||||
Name: "quota", |
||||
Columns: []*Column{ |
||||
{Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true}, |
||||
{Name: "org_id", Type: DB_BigInt, Nullable: false}, |
||||
{Name: "target", Type: DB_NVarchar, Length: 255, Nullable: false}, |
||||
{Name: "limit", Type: DB_BigInt, Nullable: false}, |
||||
{Name: "created", Type: DB_DateTime, Nullable: false}, |
||||
{Name: "updated", Type: DB_DateTime, Nullable: false}, |
||||
}, |
||||
Indices: []*Index{ |
||||
{Cols: []string{"org_id", "target"}, Type: UniqueIndex}, |
||||
}, |
||||
} |
||||
mg.AddMigration("create quota table v1", NewAddTableMigration(quotaV1)) |
||||
|
||||
//------- indexes ------------------
|
||||
addTableIndicesMigrations(mg, "v1", quotaV1) |
||||
} |
||||
@ -0,0 +1,90 @@ |
||||
package sqlstore |
||||
|
||||
import ( |
||||
"fmt" |
||||
"github.com/grafana/grafana/pkg/bus" |
||||
m "github.com/grafana/grafana/pkg/models" |
||||
) |
||||
|
||||
func init() { |
||||
bus.AddHandler("sql", GetQuotaByTarget) |
||||
bus.AddHandler("sql", GetQuotas) |
||||
bus.AddHandler("sql", UpdateQuota) |
||||
} |
||||
|
||||
type targetCount struct { |
||||
Count int64 |
||||
} |
||||
|
||||
func GetQuotaByTarget(query *m.GetQuotaByTargetQuery) error { |
||||
quota := m.Quota{ |
||||
Target: query.Target, |
||||
OrgId: query.OrgId, |
||||
} |
||||
has, err := x.Get(quota) |
||||
if err != nil { |
||||
return err |
||||
} else if has == false { |
||||
quota.Limit = m.DefaultQuotas[query.Target] |
||||
} |
||||
|
||||
//get quota used.
|
||||
rawSql := fmt.Sprintf("SELECT COUNT(*) as count from %s where org_id=?", string(query.Target)) |
||||
resp := make([]*targetCount, 0) |
||||
if err := x.Sql(rawSql, query.OrgId).Find(&resp); err != nil { |
||||
return err |
||||
} |
||||
|
||||
query.Result = &m.QuotaDTO{ |
||||
Target: query.Target, |
||||
Limit: quota.Limit, |
||||
OrgId: query.OrgId, |
||||
Used: resp[0].Count, |
||||
} |
||||
|
||||
return nil |
||||
} |
||||
|
||||
func GetQuotas(query *m.GetQuotasQuery) error { |
||||
quotas := make([]*m.Quota, 0) |
||||
sess := x.Table("quota") |
||||
if err := sess.Where("org_id=?", query.OrgId).Find("as); err != nil { |
||||
return err |
||||
} |
||||
|
||||
seenTargets := make(map[m.QuotaTarget]bool) |
||||
for _, q := range quotas { |
||||
seenTargets[q.Target] = true |
||||
} |
||||
|
||||
for t, v := range m.DefaultQuotas { |
||||
if _, ok := seenTargets[t]; !ok { |
||||
quotas = append(quotas, &m.Quota{ |
||||
OrgId: query.OrgId, |
||||
Target: t, |
||||
Limit: v, |
||||
}) |
||||
} |
||||
} |
||||
result := make([]*m.QuotaDTO, len(quotas)) |
||||
for i, q := range quotas { |
||||
//get quota used.
|
||||
rawSql := fmt.Sprintf("SELECT COUNT(*) as count from %s where org_id=?", string(q.Target)) |
||||
resp := make([]*targetCount, 0) |
||||
if err := x.Sql(rawSql, q.OrgId).Find(&resp); err != nil { |
||||
return err |
||||
} |
||||
result[i] = &m.QuotaDTO{ |
||||
Target: q.Target, |
||||
Limit: q.Limit, |
||||
OrgId: q.OrgId, |
||||
Used: resp[0].Count, |
||||
} |
||||
} |
||||
query.Result = result |
||||
return nil |
||||
} |
||||
|
||||
func UpdateQuota(cmd *m.UpdateQuotaCmd) error { |
||||
return nil |
||||
} |
||||
Loading…
Reference in new issue