From 98c966e49a1460818096ac653cd3a3d2403c1c44 Mon Sep 17 00:00:00 2001 From: AvineshTripathi Date: Fri, 12 Apr 2024 02:14:50 +0530 Subject: [PATCH 01/16] feat: added db util support to account and alert --- handlers/accounts_handler.go | 24 +++--- handlers/alerts_handler.go | 7 +- handlers/resources_handler.go | 28 +++---- models/execution.go | 134 ++++++++++++++++++++++++++++++++++ models/queries.go | 29 ++++++++ 5 files changed, 195 insertions(+), 27 deletions(-) create mode 100644 models/execution.go create mode 100644 models/queries.go diff --git a/handlers/accounts_handler.go b/handlers/accounts_handler.go index 4e274a799..835945065 100644 --- a/handlers/accounts_handler.go +++ b/handlers/accounts_handler.go @@ -1,7 +1,6 @@ package handlers import ( - "context" "database/sql" "encoding/json" "fmt" @@ -31,14 +30,15 @@ func (handler *ApiHandler) IsOnboardedHandler(c *gin.Context) { Status: "COMPLETE", } - if handler.db == nil { + if handler.dbHandler.Db == nil { output.Status = "PENDING_DATABASE" c.JSON(http.StatusOK, output) return } accounts := make([]models.Account, 0) - err := handler.db.NewRaw("SELECT * FROM accounts").Scan(handler.ctx, &accounts) + + _, err := models.HandleQuery(handler.db, handler.ctx, "LIST", &accounts, nil) if err != nil { log.WithError(err).Error("scan failed") c.JSON(http.StatusInternalServerError, gin.H{"error": "scan failed"}) @@ -62,7 +62,7 @@ func (handler *ApiHandler) ListCloudAccountsHandler(c *gin.Context) { return } - err := handler.db.NewRaw("SELECT * FROM accounts").Scan(handler.ctx, &accounts) + _, err := models.HandleQuery(handler.db, handler.ctx, "LIST", &accounts, nil) if err != nil { log.WithError(err).Error("scan failed") c.JSON(http.StatusInternalServerError, gin.H{"error": "scan failed"}) @@ -73,8 +73,10 @@ func (handler *ApiHandler) ListCloudAccountsHandler(c *gin.Context) { output := struct { Total int `bun:"total" json:"total"` }{} - err = handler.db.NewRaw(fmt.Sprintf("SELECT COUNT(*) as total FROM resources WHERE provider='%s' AND account='%s'", account.Provider, account.Name)).Scan(handler.ctx, &output) + + _, err := models.HandleQuery(handler.db, handler.ctx, "RESOURCE_COUNT", &output, map[string]string{"provider": account.Provider, "account": account.Name}) if err != nil { + fmt.Println(err) c.JSON(http.StatusInternalServerError, gin.H{"error": "scan failed"}) return } @@ -104,12 +106,12 @@ func (handler *ApiHandler) NewCloudAccountHandler(c *gin.Context) { unsavedAccounts = append(unsavedAccounts, account) } else { - result, err := handler.db.NewInsert().Model(&account).Exec(context.Background()) + + result, err := models.HandleQuery(handler.db, handler.ctx, "INSERT", &account, nil) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } - accountId, _ := result.LastInsertId() account.Id = accountId @@ -152,7 +154,8 @@ func (handler *ApiHandler) ReScanAccount(c *gin.Context) { accountId := c.Param("id") account := new(models.Account) - res, err := handler.db.NewUpdate().Model(account).Set("status = ? ", "SCANNING").Where("id = ?", accountId).Where("status = ?", "CONNECTED").Returning("*").Exec(handler.ctx) + account.Status = "SCANNING" + res, err := models.HandleQuery(handler.db, handler.ctx, "RE_SCAN_ACCOUNT", account, map[string]string{"id": accountId, "status": "CONNECTED"}) if err != nil { log.Error("Couldn't set status", err) return @@ -169,11 +172,12 @@ func (handler *ApiHandler) DeleteCloudAccountHandler(c *gin.Context) { accountId := c.Param("id") account := new(models.Account) - _, err := handler.db.NewDelete().Model(account).Where("id = ?", accountId).Exec(handler.ctx) + _, err := models.HandleQuery(handler.db, handler.ctx, "DELETE", account, map[string]string{"id": accountId}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } + c.JSON(http.StatusOK, gin.H{"message": "account has been deleted"}) } @@ -188,7 +192,7 @@ func (handler *ApiHandler) UpdateCloudAccountHandler(c *gin.Context) { return } - _, err = handler.db.NewUpdate().Model(&account).Column("name", "provider", "credentials").Where("id = ?", accountId).Exec(handler.ctx) + _, err = models.HandleQuery(handler.db, handler.ctx, "UPDATE_ACCOUNT", &account, map[string]string{"id": accountId}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return diff --git a/handlers/alerts_handler.go b/handlers/alerts_handler.go index 10fe3692f..4556b6fca 100644 --- a/handlers/alerts_handler.go +++ b/handlers/alerts_handler.go @@ -2,7 +2,6 @@ package handlers import ( "bytes" - "context" "encoding/json" "net/http" "time" @@ -33,7 +32,7 @@ func (handler *ApiHandler) NewAlertHandler(c *gin.Context) { return } - result, err := handler.db.NewInsert().Model(&alert).Exec(context.Background()) + result, err := models.HandleQuery(handler.db, handler.ctx, "INSERT", &alert, nil) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return @@ -62,7 +61,7 @@ func (handler *ApiHandler) UpdateAlertHandler(c *gin.Context) { return } - _, err = handler.db.NewUpdate().Model(&alert).Column("name", "type", "budget", "usage", "endpoint", "secret").Where("id = ?", alertId).Exec(handler.ctx) + _, err = models.HandleQuery(handler.db, handler.ctx, "UPDATE_ALERT",&alert, map[string]string{"id": alertId}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return @@ -75,7 +74,7 @@ func (handler *ApiHandler) DeleteAlertHandler(c *gin.Context) { alertId := c.Param("id") alert := new(models.Alert) - _, err := handler.db.NewDelete().Model(alert).Where("id = ?", alertId).Exec(handler.ctx) + _, err := models.HandleQuery(handler.db,handler.ctx, "DELETE", alert, map[string]string{"id": alertId}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return diff --git a/handlers/resources_handler.go b/handlers/resources_handler.go index da7f894fc..2a0665550 100644 --- a/handlers/resources_handler.go +++ b/handlers/resources_handler.go @@ -18,24 +18,26 @@ import ( ) type ApiHandler struct { - db *bun.DB - ctx context.Context - telemetry bool - cfg models.Config + db *bun.DB + dbHandler DbHandler + ctx context.Context + telemetry bool + cfg models.Config configPath string - analytics utils.Analytics - accounts []models.Account + analytics utils.Analytics + accounts []models.Account } func NewApiHandler(ctx context.Context, telemetry bool, analytics utils.Analytics, db *bun.DB, cfg models.Config, configPath string, accounts []models.Account) *ApiHandler { handler := ApiHandler{ - db: db, - ctx: ctx, - telemetry: telemetry, - cfg: cfg, + db: db, + dbHandler: NewDbHandler(db), + ctx: ctx, + telemetry: telemetry, + cfg: cfg, configPath: configPath, - analytics: analytics, - accounts: accounts, + analytics: analytics, + accounts: accounts, } return &handler } @@ -428,7 +430,7 @@ func (handler *ApiHandler) RelationStatsHandler(c *gin.Context) { Provider: ele.Provider, }) } - + c.JSON(http.StatusOK, out) } diff --git a/models/execution.go b/models/execution.go new file mode 100644 index 000000000..6e749c0f0 --- /dev/null +++ b/models/execution.go @@ -0,0 +1,134 @@ +package models + +import ( + "context" + "database/sql" + "fmt" + + "github.com/uptrace/bun" +) + +type QueryType string + +const ( + RAW QueryType = "RAW" + SELECT QueryType = "SELECT" + INSERT QueryType = "INSERT" + DELETE QueryType = "DELETE" + UPDATE QueryType = "UPDATE" +) + +type DbHandler struct { + Db *bun.DB +} + +func NewDbHandler(db *bun.DB) DbHandler { + return DbHandler{ + Db: db, + } +} + +type Object struct { + Query string `json:"query"` + Type QueryType `json:"type"` + Params []string `json:"params"` +} + +type Data map[string]Object + +func HandleQuery(db *bun.DB, ctx context.Context, queryTitle string, schema interface{}, additionals map[string]string) (sql.Result, error) { + var resp sql.Result + var err error + switch Queries[queryTitle].Type { + case RAW: + err = executeRaw(db, ctx, Queries[queryTitle].Query, schema, additionals) + if err != nil { + return resp, err + } + case SELECT: + err = executeSelect(db, ctx, Queries[queryTitle].Query, schema, additionals) + if err != nil { + return resp, err + } + case INSERT: + resp, err = executeInsert(db, ctx, schema, additionals) + if err != nil { + return resp, err + } + case DELETE: + resp, err = executeDelete(db, ctx, schema, Queries[queryTitle].Query, additionals) + if err != nil { + return resp, err + } + case UPDATE: + resp, err = executeUpdate(db, ctx, schema, Queries[queryTitle].Query, Queries[queryTitle].Params, additionals) + if err != nil { + return resp, err + } + } + return resp, nil +} + +func executeRaw(db *bun.DB, ctx context.Context, query string, schema interface{}, additionals map[string]string) error { + if len(additionals) > 0 { + query = fmt.Sprintf("%s where", query) + } + + for key, value := range additionals { + query = fmt.Sprintf("%s %s = '%s' and", query, key, value) + } + + if len(additionals) > 0 { + query = query[:len(query)-4] + } + + err := db.NewRaw(query).Scan(ctx, schema) + if err != nil { + return err + } + return nil +} + +func executeSelect(db *bun.DB, ctx context.Context, query string, schema interface{}, additionals map[string]string) error { + updatedQuery := db.NewSelect().Model(schema) + for key, value := range additionals { + updatedQuery = updatedQuery.Where(fmt.Sprintf("%s = ?", key), value) + } + + err := updatedQuery.Scan(ctx, schema) + if err != nil { + return err + } + return nil +} + +func executeInsert(db *bun.DB, ctx context.Context, schema interface{}, additionals map[string]string) (sql.Result, error) { + resp, err := db.NewInsert().Model(schema).Exec(ctx) + if err != nil { + return resp, err + } + return resp, nil +} + +func executeDelete(db *bun.DB, ctx context.Context, schema interface{}, query string, additionals map[string]string) (sql.Result, error) { + resp, err := db.NewDelete().Model(schema).Where("id = ?", additionals["id"]).Exec(ctx) + if err != nil { + return resp, err + } + return resp, nil +} + +func executeUpdate(db *bun.DB, ctx context.Context, schema interface{}, query string, columns []string, additionals map[string]string) (sql.Result, error) { + updatedQuery := db.NewUpdate().Model(schema).Column(columns...) + + for key, value := range additionals { + updatedQuery = updatedQuery.Where(fmt.Sprintf("%s = ?", key), value) + } + + updatedQuery = updatedQuery.Returning("*") + resp, err := updatedQuery.Exec(ctx) + if err != nil { + return resp, err + } + return resp, nil +} diff --git a/models/queries.go b/models/queries.go new file mode 100644 index 000000000..29ca9c2fd --- /dev/null +++ b/models/queries.go @@ -0,0 +1,29 @@ +package models + +var Queries = Data{ + "LIST": Object{ + Type: SELECT, + }, + "INSERT": Object{ + Type: INSERT, + }, + "DELETE": Object{ + Type: DELETE, + }, + "UPDATE_ACCOUNT": Object{ + Type: UPDATE, + Params: []string{"name", "provider", "credentials"}, + }, + "UPDATE_ALERT": Object{ + Type: UPDATE, + Params: []string{"name", "type", "budget", "usage", "endpoint", "secret"}, + }, + "RE_SCAN_ACCOUNT": Object{ + Type: UPDATE, + Params: []string{"status"}, + }, + "RESOURCE_COUNT": Object{ + Query: "SELECT COUNT(*) as total FROM resources", + Type: RAW, + }, +} \ No newline at end of file From a2118efa2730eff01511c185b71bfd47680f244b Mon Sep 17 00:00:00 2001 From: AvineshTripathi Date: Thu, 25 Apr 2024 03:06:02 +0530 Subject: [PATCH 02/16] feat: added support to tags --- handlers/tags_handler.go | 17 +++++++---------- models/queries.go | 12 ++++++++++++ 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/handlers/tags_handler.go b/handlers/tags_handler.go index d199edeac..3faa23a54 100644 --- a/handlers/tags_handler.go +++ b/handlers/tags_handler.go @@ -2,10 +2,13 @@ package handlers import ( "encoding/json" + "fmt" "net/http" - "strconv" + + //"strconv" "github.com/gin-gonic/gin" + "github.com/tailwarden/komiser/models" . "github.com/tailwarden/komiser/models" ) @@ -21,7 +24,7 @@ func (handler *ApiHandler) BulkUpdateTagsHandler(c *gin.Context) { resource := Resource{Tags: input.Tags} for _, resourceId := range input.Resources { - _, err = handler.db.NewUpdate().Model(&resource).Column("tags").Where("id = ?", resourceId).Exec(handler.ctx) + _, err = models.HandleQuery(handler.db, handler.ctx, "UPDATE_TAGS", &resource, map[string]string{"id": fmt.Sprintf("%d", resourceId)}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "error while updating tags"}) return @@ -40,13 +43,7 @@ func (handler *ApiHandler) UpdateTagsHandler(c *gin.Context) { resourceId := c.Param("id") - id, err := strconv.Atoi(resourceId) - if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{"error": "resource id should be an integer"}) - return - } - - err = json.NewDecoder(c.Request.Body).Decode(&tags) + err := json.NewDecoder(c.Request.Body).Decode(&tags) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return @@ -54,7 +51,7 @@ func (handler *ApiHandler) UpdateTagsHandler(c *gin.Context) { resource := Resource{Tags: tags} - _, err = handler.db.NewUpdate().Model(&resource).Column("tags").Where("id = ?", id).Exec(handler.ctx) + _, err = models.HandleQuery(handler.db, handler.ctx, "UPDATE_TAGS", &resource, map[string]string{"id": string(resourceId)}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "error while updating tags"}) return diff --git a/models/queries.go b/models/queries.go index 29ca9c2fd..b8fd4196c 100644 --- a/models/queries.go +++ b/models/queries.go @@ -18,6 +18,14 @@ var Queries = Data{ Type: UPDATE, Params: []string{"name", "type", "budget", "usage", "endpoint", "secret"}, }, + "UPDATE_VIEW": Object{ + Type: UPDATE, + Params: []string{"name", "filters", "exclude"}, + }, + "UPDATE_VIEW_EXCLUDE": Object{ + Type: UPDATE, + Params: []string{"exclude"}, + }, "RE_SCAN_ACCOUNT": Object{ Type: UPDATE, Params: []string{"status"}, @@ -26,4 +34,8 @@ var Queries = Data{ Query: "SELECT COUNT(*) as total FROM resources", Type: RAW, }, + "UPDATE_TAGS": Object{ + Type: UPDATE, + Params: []string{"tags"}, + }, } \ No newline at end of file From b4998235898da5955f588f2ea6d4fc505e958cab Mon Sep 17 00:00:00 2001 From: Azanul Date: Wed, 24 Apr 2024 16:16:17 +0530 Subject: [PATCH 03/16] feat: remove dbhandler Signed-off-by: Azanul --- handlers/accounts_handler.go | 3 +-- handlers/resources_handler.go | 2 -- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/handlers/accounts_handler.go b/handlers/accounts_handler.go index 835945065..c96684f15 100644 --- a/handlers/accounts_handler.go +++ b/handlers/accounts_handler.go @@ -30,7 +30,7 @@ func (handler *ApiHandler) IsOnboardedHandler(c *gin.Context) { Status: "COMPLETE", } - if handler.dbHandler.Db == nil { + if handler.db == nil { output.Status = "PENDING_DATABASE" c.JSON(http.StatusOK, output) return @@ -177,7 +177,6 @@ func (handler *ApiHandler) DeleteCloudAccountHandler(c *gin.Context) { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } - c.JSON(http.StatusOK, gin.H{"message": "account has been deleted"}) } diff --git a/handlers/resources_handler.go b/handlers/resources_handler.go index 2a0665550..d610a4866 100644 --- a/handlers/resources_handler.go +++ b/handlers/resources_handler.go @@ -19,7 +19,6 @@ import ( type ApiHandler struct { db *bun.DB - dbHandler DbHandler ctx context.Context telemetry bool cfg models.Config @@ -31,7 +30,6 @@ type ApiHandler struct { func NewApiHandler(ctx context.Context, telemetry bool, analytics utils.Analytics, db *bun.DB, cfg models.Config, configPath string, accounts []models.Account) *ApiHandler { handler := ApiHandler{ db: db, - dbHandler: NewDbHandler(db), ctx: ctx, telemetry: telemetry, cfg: cfg, From 5e73a18c0372615a033f8a489d6a22f84ace7569 Mon Sep 17 00:00:00 2001 From: Azanul Date: Thu, 25 Apr 2024 06:15:34 +0530 Subject: [PATCH 04/16] refac: rebase Signed-off-by: Azanul --- models/execution.go | 18 ------------------ models/queries.go | 26 +++++++++++++++++--------- 2 files changed, 17 insertions(+), 27 deletions(-) diff --git a/models/execution.go b/models/execution.go index 6e749c0f0..bff457121 100644 --- a/models/execution.go +++ b/models/execution.go @@ -18,24 +18,6 @@ const ( UPDATE QueryType = "UPDATE" ) -type DbHandler struct { - Db *bun.DB -} - -func NewDbHandler(db *bun.DB) DbHandler { - return DbHandler{ - Db: db, - } -} - -type Object struct { - Query string `json:"query"` - Type QueryType `json:"type"` - Params []string `json:"params"` -} - -type Data map[string]Object - func HandleQuery(db *bun.DB, ctx context.Context, queryTitle string, schema interface{}, additionals map[string]string) (sql.Result, error) { var resp sql.Result var err error diff --git a/models/queries.go b/models/queries.go index b8fd4196c..e403e4c18 100644 --- a/models/queries.go +++ b/models/queries.go @@ -1,41 +1,49 @@ package models +type Object struct { + Query string `json:"query"` + Type QueryType `json:"type"` + Params []string `json:"params"` +} + +type Data map[string]Object + var Queries = Data{ "LIST": Object{ Type: SELECT, }, "INSERT": Object{ - Type: INSERT, + Type: INSERT, }, "DELETE": Object{ - Type: DELETE, + Type: DELETE, }, "UPDATE_ACCOUNT": Object{ Type: UPDATE, Params: []string{"name", "provider", "credentials"}, }, "UPDATE_ALERT": Object{ - Type: UPDATE, + Type: UPDATE, Params: []string{"name", "type", "budget", "usage", "endpoint", "secret"}, }, "UPDATE_VIEW": Object{ - Type: UPDATE, + Type: UPDATE, Params: []string{"name", "filters", "exclude"}, }, "UPDATE_VIEW_EXCLUDE": Object{ - Type: UPDATE, + Type: UPDATE, Params: []string{"exclude"}, }, "RE_SCAN_ACCOUNT": Object{ - Type: UPDATE, + Type: UPDATE, Params: []string{"status"}, }, "RESOURCE_COUNT": Object{ Query: "SELECT COUNT(*) as total FROM resources", - Type: RAW, + Type: RAW, }, "UPDATE_TAGS": Object{ - Type: UPDATE, + Type: UPDATE, Params: []string{"tags"}, }, -} \ No newline at end of file +} From 5127720e06f693f7edad06a651828bf6f4e77bd2 Mon Sep 17 00:00:00 2001 From: Azanul Date: Wed, 24 Apr 2024 16:34:24 +0530 Subject: [PATCH 05/16] refac: ctx <-> db Signed-off-by: Azanul --- models/execution.go | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/models/execution.go b/models/execution.go index bff457121..467835407 100644 --- a/models/execution.go +++ b/models/execution.go @@ -18,32 +18,32 @@ const ( UPDATE QueryType = "UPDATE" ) -func HandleQuery(db *bun.DB, ctx context.Context, queryTitle string, schema interface{}, additionals map[string]string) (sql.Result, error) { +func HandleQuery(ctx context.Context, db *bun.DB, queryTitle string, schema interface{}, additionals map[string]string) (sql.Result, error) { var resp sql.Result var err error switch Queries[queryTitle].Type { case RAW: - err = executeRaw(db, ctx, Queries[queryTitle].Query, schema, additionals) + err = executeRaw(ctx, db, Queries[queryTitle].Query, schema, additionals) if err != nil { return resp, err } case SELECT: - err = executeSelect(db, ctx, Queries[queryTitle].Query, schema, additionals) + err = executeSelect(ctx, db, Queries[queryTitle].Query, schema, additionals) if err != nil { return resp, err } case INSERT: - resp, err = executeInsert(db, ctx, schema, additionals) + resp, err = executeInsert(ctx, db, schema, additionals) if err != nil { return resp, err } case DELETE: - resp, err = executeDelete(db, ctx, schema, Queries[queryTitle].Query, additionals) + resp, err = executeDelete(ctx, db, schema, Queries[queryTitle].Query, additionals) if err != nil { return resp, err } case UPDATE: - resp, err = executeUpdate(db, ctx, schema, Queries[queryTitle].Query, Queries[queryTitle].Params, additionals) + resp, err = executeUpdate(ctx, db, schema, Queries[queryTitle].Query, Queries[queryTitle].Params, additionals) if err != nil { return resp, err } @@ -51,7 +51,7 @@ func HandleQuery(db *bun.DB, ctx context.Context, queryTitle string, schema inte return resp, nil } -func executeRaw(db *bun.DB, ctx context.Context, query string, schema interface{}, additionals map[string]string) error { +func executeRaw(ctx context.Context, db *bun.DB, query string, schema interface{}, additionals map[string]string) error { if len(additionals) > 0 { query = fmt.Sprintf("%s where", query) } @@ -71,7 +71,7 @@ func executeRaw(db *bun.DB, ctx context.Context, query string, schema interface{ return nil } -func executeSelect(db *bun.DB, ctx context.Context, query string, schema interface{}, additionals map[string]string) error { +func executeSelect(ctx context.Context, db *bun.DB, query string, schema interface{}, additionals map[string]string) error { updatedQuery := db.NewSelect().Model(schema) for key, value := range additionals { updatedQuery = updatedQuery.Where(fmt.Sprintf("%s = ?", key), value) @@ -84,7 +84,7 @@ func executeSelect(db *bun.DB, ctx context.Context, query string, schema interfa return nil } -func executeInsert(db *bun.DB, ctx context.Context, schema interface{}, additionals map[string]string) (sql.Result, error) { +func executeInsert(ctx context.Context, db *bun.DB, schema interface{}, additionals map[string]string) (sql.Result, error) { resp, err := db.NewInsert().Model(schema).Exec(ctx) if err != nil { return resp, err @@ -92,7 +92,7 @@ func executeInsert(db *bun.DB, ctx context.Context, schema interface{}, addition return resp, nil } -func executeDelete(db *bun.DB, ctx context.Context, schema interface{}, query string, additionals map[string]string) (sql.Result, error) { +func executeDelete(ctx context.Context, db *bun.DB, schema interface{}, query string, additionals map[string]string) (sql.Result, error) { resp, err := db.NewDelete().Model(schema).Where("id = ?", additionals["id"]).Exec(ctx) if err != nil { return resp, err @@ -100,7 +100,7 @@ func executeDelete(db *bun.DB, ctx context.Context, schema interface{}, query st return resp, nil } -func executeUpdate(db *bun.DB, ctx context.Context, schema interface{}, query string, columns []string, additionals map[string]string) (sql.Result, error) { +func executeUpdate(ctx context.Context, db *bun.DB, schema interface{}, query string, columns []string, additionals map[string]string) (sql.Result, error) { updatedQuery := db.NewUpdate().Model(schema).Column(columns...) for key, value := range additionals { From 3c25f5cbb2745a40b37c8a7006dfe7993b80765a Mon Sep 17 00:00:00 2001 From: Azanul Date: Thu, 25 Apr 2024 06:19:54 +0530 Subject: [PATCH 06/16] refac: ctx <-> db Signed-off-by: Azanul --- handlers/accounts_handler.go | 14 +++++++------- handlers/alerts_handler.go | 6 +++--- handlers/tags_handler.go | 15 ++++++--------- 3 files changed, 16 insertions(+), 19 deletions(-) diff --git a/handlers/accounts_handler.go b/handlers/accounts_handler.go index c96684f15..7e49e0093 100644 --- a/handlers/accounts_handler.go +++ b/handlers/accounts_handler.go @@ -38,7 +38,7 @@ func (handler *ApiHandler) IsOnboardedHandler(c *gin.Context) { accounts := make([]models.Account, 0) - _, err := models.HandleQuery(handler.db, handler.ctx, "LIST", &accounts, nil) + _, err := models.HandleQuery(handler.ctx, handler.db, "LIST", &accounts, nil) if err != nil { log.WithError(err).Error("scan failed") c.JSON(http.StatusInternalServerError, gin.H{"error": "scan failed"}) @@ -62,7 +62,7 @@ func (handler *ApiHandler) ListCloudAccountsHandler(c *gin.Context) { return } - _, err := models.HandleQuery(handler.db, handler.ctx, "LIST", &accounts, nil) + _, err := models.HandleQuery(handler.ctx, handler.db, "LIST", &accounts, nil) if err != nil { log.WithError(err).Error("scan failed") c.JSON(http.StatusInternalServerError, gin.H{"error": "scan failed"}) @@ -74,7 +74,7 @@ func (handler *ApiHandler) ListCloudAccountsHandler(c *gin.Context) { Total int `bun:"total" json:"total"` }{} - _, err := models.HandleQuery(handler.db, handler.ctx, "RESOURCE_COUNT", &output, map[string]string{"provider": account.Provider, "account": account.Name}) + _, err := models.HandleQuery(handler.ctx, handler.db, "RESOURCE_COUNT", &output, map[string]string{"provider": account.Provider, "account": account.Name}) if err != nil { fmt.Println(err) c.JSON(http.StatusInternalServerError, gin.H{"error": "scan failed"}) @@ -107,7 +107,7 @@ func (handler *ApiHandler) NewCloudAccountHandler(c *gin.Context) { unsavedAccounts = append(unsavedAccounts, account) } else { - result, err := models.HandleQuery(handler.db, handler.ctx, "INSERT", &account, nil) + result, err := models.HandleQuery(handler.ctx, handler.db, "INSERT", &account, nil) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return @@ -155,7 +155,7 @@ func (handler *ApiHandler) ReScanAccount(c *gin.Context) { account := new(models.Account) account.Status = "SCANNING" - res, err := models.HandleQuery(handler.db, handler.ctx, "RE_SCAN_ACCOUNT", account, map[string]string{"id": accountId, "status": "CONNECTED"}) + res, err := models.HandleQuery(handler.ctx, handler.db, "RE_SCAN_ACCOUNT", account, map[string]string{"id": accountId, "status": "CONNECTED"}) if err != nil { log.Error("Couldn't set status", err) return @@ -172,7 +172,7 @@ func (handler *ApiHandler) DeleteCloudAccountHandler(c *gin.Context) { accountId := c.Param("id") account := new(models.Account) - _, err := models.HandleQuery(handler.db, handler.ctx, "DELETE", account, map[string]string{"id": accountId}) + _, err := models.HandleQuery(handler.ctx, handler.db, "DELETE", account, map[string]string{"id": accountId}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return @@ -191,7 +191,7 @@ func (handler *ApiHandler) UpdateCloudAccountHandler(c *gin.Context) { return } - _, err = models.HandleQuery(handler.db, handler.ctx, "UPDATE_ACCOUNT", &account, map[string]string{"id": accountId}) + _, err = models.HandleQuery(handler.ctx, handler.db, "UPDATE_ACCOUNT", &account, map[string]string{"id": accountId}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return diff --git a/handlers/alerts_handler.go b/handlers/alerts_handler.go index 4556b6fca..9891e92ee 100644 --- a/handlers/alerts_handler.go +++ b/handlers/alerts_handler.go @@ -32,7 +32,7 @@ func (handler *ApiHandler) NewAlertHandler(c *gin.Context) { return } - result, err := models.HandleQuery(handler.db, handler.ctx, "INSERT", &alert, nil) + result, err := models.HandleQuery(handler.ctx, handler.db, "INSERT", &alert, nil) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return @@ -61,7 +61,7 @@ func (handler *ApiHandler) UpdateAlertHandler(c *gin.Context) { return } - _, err = models.HandleQuery(handler.db, handler.ctx, "UPDATE_ALERT",&alert, map[string]string{"id": alertId}) + _, err = models.HandleQuery(handler.ctx, handler.db, "UPDATE_ALERT", &alert, map[string]string{"id": alertId}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return @@ -74,7 +74,7 @@ func (handler *ApiHandler) DeleteAlertHandler(c *gin.Context) { alertId := c.Param("id") alert := new(models.Alert) - _, err := models.HandleQuery(handler.db,handler.ctx, "DELETE", alert, map[string]string{"id": alertId}) + _, err := models.HandleQuery(handler.ctx, handler.db, "DELETE", alert, map[string]string{"id": alertId}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return diff --git a/handlers/tags_handler.go b/handlers/tags_handler.go index 3faa23a54..ae61c828f 100644 --- a/handlers/tags_handler.go +++ b/handlers/tags_handler.go @@ -5,15 +5,12 @@ import ( "fmt" "net/http" - //"strconv" - "github.com/gin-gonic/gin" "github.com/tailwarden/komiser/models" - . "github.com/tailwarden/komiser/models" ) func (handler *ApiHandler) BulkUpdateTagsHandler(c *gin.Context) { - var input BulkUpdateTag + var input models.BulkUpdateTag err := json.NewDecoder(c.Request.Body).Decode(&input) if err != nil { @@ -21,10 +18,10 @@ func (handler *ApiHandler) BulkUpdateTagsHandler(c *gin.Context) { return } - resource := Resource{Tags: input.Tags} + resource := models.Resource{Tags: input.Tags} for _, resourceId := range input.Resources { - _, err = models.HandleQuery(handler.db, handler.ctx, "UPDATE_TAGS", &resource, map[string]string{"id": fmt.Sprintf("%d", resourceId)}) + _, err = models.HandleQuery(handler.ctx, handler.db, "UPDATE_TAGS", &resource, map[string]string{"id": fmt.Sprintf("%d", resourceId)}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "error while updating tags"}) return @@ -39,7 +36,7 @@ func (handler *ApiHandler) BulkUpdateTagsHandler(c *gin.Context) { } func (handler *ApiHandler) UpdateTagsHandler(c *gin.Context) { - tags := make([]Tag, 0) + tags := make([]models.Tag, 0) resourceId := c.Param("id") @@ -49,9 +46,9 @@ func (handler *ApiHandler) UpdateTagsHandler(c *gin.Context) { return } - resource := Resource{Tags: tags} + resource := models.Resource{Tags: tags} - _, err = models.HandleQuery(handler.db, handler.ctx, "UPDATE_TAGS", &resource, map[string]string{"id": string(resourceId)}) + _, err = models.HandleQuery(handler.ctx, handler.db, "UPDATE_TAGS", &resource, map[string]string{"id": string(resourceId)}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "error while updating tags"}) return From 5e47837a6fc08d139821eed7e238f5b9687a03ed Mon Sep 17 00:00:00 2001 From: Azanul Date: Thu, 25 Apr 2024 06:30:59 +0530 Subject: [PATCH 07/16] refac: dot imports Signed-off-by: Azanul --- handlers/resources_handler.go | 11 +++++------ handlers/stats_handler.go | 4 ++-- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/handlers/resources_handler.go b/handlers/resources_handler.go index d610a4866..e294d2bfb 100644 --- a/handlers/resources_handler.go +++ b/handlers/resources_handler.go @@ -11,7 +11,6 @@ import ( "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" "github.com/tailwarden/komiser/models" - . "github.com/tailwarden/komiser/models" "github.com/tailwarden/komiser/utils" "github.com/uptrace/bun" "github.com/uptrace/bun/dialect" @@ -41,14 +40,14 @@ func NewApiHandler(ctx context.Context, telemetry bool, analytics utils.Analytic } func (handler *ApiHandler) FilterResourcesHandler(c *gin.Context) { - var filters []Filter + var filters []models.Filter limitRaw := c.Query("limit") skipRaw := c.Query("skip") query := c.Query("query") viewId := c.Query("view") - view := new(View) + view := new(models.View) if viewId != "" { err := handler.db.NewSelect().Model(view).Where("id = ?", viewId).Scan(handler.ctx) if err != nil { @@ -240,7 +239,7 @@ func (handler *ApiHandler) FilterResourcesHandler(c *gin.Context) { whereClause := strings.Join(whereQueries, " AND ") - resources := make([]Resource, 0) + resources := make([]models.Resource, 0) if len(filters) == 0 { if len(query) > 0 { @@ -305,7 +304,7 @@ func (handler *ApiHandler) FilterResourcesHandler(c *gin.Context) { } func (handler *ApiHandler) RelationStatsHandler(c *gin.Context) { - var filters []Filter + var filters []models.Filter err := json.NewDecoder(c.Request.Body).Decode(&filters) if err != nil { @@ -436,7 +435,7 @@ func (handler *ApiHandler) RelationStatsHandler(c *gin.Context) { func (handler *ApiHandler) GetResourceByIdHandler(c *gin.Context) { resourceId := c.Query("resourceId") - var resource Resource + var resource models.Resource err := handler.db.NewSelect().Model(&resource).Where("resource_id = ?", resourceId).Scan(handler.ctx) if err != nil { diff --git a/handlers/stats_handler.go b/handlers/stats_handler.go index 6f4da6853..ddf776b73 100644 --- a/handlers/stats_handler.go +++ b/handlers/stats_handler.go @@ -9,7 +9,7 @@ import ( "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" - . "github.com/tailwarden/komiser/models" + "github.com/tailwarden/komiser/models" "github.com/uptrace/bun/dialect" ) @@ -63,7 +63,7 @@ func (handler *ApiHandler) StatsHandler(c *gin.Context) { } func (handler *ApiHandler) FilterStatsHandler(c *gin.Context) { - var filters []Filter + var filters []models.Filter err := json.NewDecoder(c.Request.Body).Decode(&filters) if err != nil { From 09d3e4d1536fe211ebf8e979ae985dae96ac2c91 Mon Sep 17 00:00:00 2001 From: Azanul Date: Thu, 25 Apr 2024 19:41:36 +0530 Subject: [PATCH 08/16] refac: where builder Signed-off-by: Azanul --- handlers/accounts_handler.go | 8 ++-- handlers/alerts_handler.go | 5 +- handlers/tags_handler.go | 4 +- models/execution.go | 89 +++++++++++++++++------------------- 4 files changed, 52 insertions(+), 54 deletions(-) diff --git a/handlers/accounts_handler.go b/handlers/accounts_handler.go index 7e49e0093..36ce5c9d5 100644 --- a/handlers/accounts_handler.go +++ b/handlers/accounts_handler.go @@ -74,7 +74,7 @@ func (handler *ApiHandler) ListCloudAccountsHandler(c *gin.Context) { Total int `bun:"total" json:"total"` }{} - _, err := models.HandleQuery(handler.ctx, handler.db, "RESOURCE_COUNT", &output, map[string]string{"provider": account.Provider, "account": account.Name}) + _, err := models.HandleQuery(handler.ctx, handler.db, "RESOURCE_COUNT", &output, [][3]string{{"provider", "=", account.Provider}, {"account", "=", account.Name}}) if err != nil { fmt.Println(err) c.JSON(http.StatusInternalServerError, gin.H{"error": "scan failed"}) @@ -155,7 +155,7 @@ func (handler *ApiHandler) ReScanAccount(c *gin.Context) { account := new(models.Account) account.Status = "SCANNING" - res, err := models.HandleQuery(handler.ctx, handler.db, "RE_SCAN_ACCOUNT", account, map[string]string{"id": accountId, "status": "CONNECTED"}) + res, err := models.HandleQuery(handler.ctx, handler.db, "RE_SCAN_ACCOUNT", account, [][3]string{{"id", "=", accountId}, {"status", "=", "CONNECTED"}}) if err != nil { log.Error("Couldn't set status", err) return @@ -172,7 +172,7 @@ func (handler *ApiHandler) DeleteCloudAccountHandler(c *gin.Context) { accountId := c.Param("id") account := new(models.Account) - _, err := models.HandleQuery(handler.ctx, handler.db, "DELETE", account, map[string]string{"id": accountId}) + _, err := models.HandleQuery(handler.ctx, handler.db, "DELETE", account, [][3]string{{"id", "=", accountId}}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return @@ -191,7 +191,7 @@ func (handler *ApiHandler) UpdateCloudAccountHandler(c *gin.Context) { return } - _, err = models.HandleQuery(handler.ctx, handler.db, "UPDATE_ACCOUNT", &account, map[string]string{"id": accountId}) + _, err = models.HandleQuery(handler.ctx, handler.db, "UPDATE_ACCOUNT", &account, [][3]string{{"id", "=", accountId}}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return diff --git a/handlers/alerts_handler.go b/handlers/alerts_handler.go index 9891e92ee..fc8fd497e 100644 --- a/handlers/alerts_handler.go +++ b/handlers/alerts_handler.go @@ -3,6 +3,7 @@ package handlers import ( "bytes" "encoding/json" + "fmt" "net/http" "time" @@ -61,7 +62,7 @@ func (handler *ApiHandler) UpdateAlertHandler(c *gin.Context) { return } - _, err = models.HandleQuery(handler.ctx, handler.db, "UPDATE_ALERT", &alert, map[string]string{"id": alertId}) + _, err = models.HandleQuery(handler.ctx, handler.db, "UPDATE_ALERT", &alert, [][3]string{{"id", "=", fmt.Sprint(alertId)}}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return @@ -74,7 +75,7 @@ func (handler *ApiHandler) DeleteAlertHandler(c *gin.Context) { alertId := c.Param("id") alert := new(models.Alert) - _, err := models.HandleQuery(handler.ctx, handler.db, "DELETE", alert, map[string]string{"id": alertId}) + _, err := models.HandleQuery(handler.ctx, handler.db, "DELETE", alert, [][3]string{{"id", "=", fmt.Sprint(alertId)}}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return diff --git a/handlers/tags_handler.go b/handlers/tags_handler.go index ae61c828f..803fe95e8 100644 --- a/handlers/tags_handler.go +++ b/handlers/tags_handler.go @@ -21,7 +21,7 @@ func (handler *ApiHandler) BulkUpdateTagsHandler(c *gin.Context) { resource := models.Resource{Tags: input.Tags} for _, resourceId := range input.Resources { - _, err = models.HandleQuery(handler.ctx, handler.db, "UPDATE_TAGS", &resource, map[string]string{"id": fmt.Sprintf("%d", resourceId)}) + _, err = models.HandleQuery(handler.ctx, handler.db, "UPDATE_TAGS", &resource, [][3]string{{"id", "=", fmt.Sprint(resourceId)}}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "error while updating tags"}) return @@ -48,7 +48,7 @@ func (handler *ApiHandler) UpdateTagsHandler(c *gin.Context) { resource := models.Resource{Tags: tags} - _, err = models.HandleQuery(handler.ctx, handler.db, "UPDATE_TAGS", &resource, map[string]string{"id": string(resourceId)}) + _, err = models.HandleQuery(handler.ctx, handler.db, "UPDATE_TAGS", &resource, [][3]string{{"id", "=", fmt.Sprint(resourceId)}}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "error while updating tags"}) return diff --git a/models/execution.go b/models/execution.go index 467835407..f9ea55ff4 100644 --- a/models/execution.go +++ b/models/execution.go @@ -18,46 +18,37 @@ const ( UPDATE QueryType = "UPDATE" ) -func HandleQuery(ctx context.Context, db *bun.DB, queryTitle string, schema interface{}, additionals map[string]string) (sql.Result, error) { +func HandleQuery(ctx context.Context, db *bun.DB, queryTitle string, schema interface{}, conditions [][3]string) (sql.Result, error) { var resp sql.Result var err error - switch Queries[queryTitle].Type { + query := Queries[queryTitle] + switch query.Type { case RAW: - err = executeRaw(ctx, db, Queries[queryTitle].Query, schema, additionals) - if err != nil { - return resp, err - } + err = executeRaw(ctx, db, query.Query, schema, conditions) + case SELECT: - err = executeSelect(ctx, db, Queries[queryTitle].Query, schema, additionals) - if err != nil { - return resp, err - } + err = executeSelect(ctx, db, query.Query, schema, conditions) + case INSERT: - resp, err = executeInsert(ctx, db, schema, additionals) - if err != nil { - return resp, err - } + resp, err = executeInsert(ctx, db, schema, conditions) + case DELETE: - resp, err = executeDelete(ctx, db, schema, Queries[queryTitle].Query, additionals) - if err != nil { - return resp, err - } + resp, err = executeDelete(ctx, db, schema, query.Query, conditions) + case UPDATE: - resp, err = executeUpdate(ctx, db, schema, Queries[queryTitle].Query, Queries[queryTitle].Params, additionals) - if err != nil { - return resp, err - } + resp, err = executeUpdate(ctx, db, schema, query.Params, conditions) } - return resp, nil + return resp, err } -func executeRaw(ctx context.Context, db *bun.DB, query string, schema interface{}, additionals map[string]string) error { +func executeRaw(ctx context.Context, db *bun.DB, query string, schema interface{}, additionals [][3]string) error { if len(additionals) > 0 { query = fmt.Sprintf("%s where", query) } - for key, value := range additionals { - query = fmt.Sprintf("%s %s = '%s' and", query, key, value) + for _, triplet := range additionals { + key, op, value := triplet[0], triplet[1], triplet[2] + query = fmt.Sprintf("%s %s %s '%s' and", query, key, op, value) } if len(additionals) > 0 { @@ -71,20 +62,15 @@ func executeRaw(ctx context.Context, db *bun.DB, query string, schema interface{ return nil } -func executeSelect(ctx context.Context, db *bun.DB, query string, schema interface{}, additionals map[string]string) error { - updatedQuery := db.NewSelect().Model(schema) - for key, value := range additionals { - updatedQuery = updatedQuery.Where(fmt.Sprintf("%s = ?", key), value) - } +func executeSelect(ctx context.Context, db *bun.DB, query string, schema interface{}, conditions [][3]string) error { + q := db.NewSelect().Model(schema) - err := updatedQuery.Scan(ctx, schema) - if err != nil { - return err - } - return nil + q = addWhereClause(q.QueryBuilder(), conditions).Unwrap().(*bun.SelectQuery) + + return q.Scan(ctx, schema) } -func executeInsert(ctx context.Context, db *bun.DB, schema interface{}, additionals map[string]string) (sql.Result, error) { +func executeInsert(ctx context.Context, db *bun.DB, schema interface{}, conditions [][3]string) (sql.Result, error) { resp, err := db.NewInsert().Model(schema).Exec(ctx) if err != nil { return resp, err @@ -92,25 +78,36 @@ func executeInsert(ctx context.Context, db *bun.DB, schema interface{}, addition return resp, nil } -func executeDelete(ctx context.Context, db *bun.DB, schema interface{}, query string, additionals map[string]string) (sql.Result, error) { - resp, err := db.NewDelete().Model(schema).Where("id = ?", additionals["id"]).Exec(ctx) +func executeDelete(ctx context.Context, db *bun.DB, schema interface{}, query string, conditions [][3]string) (sql.Result, error) { + q := db.NewDelete().Model(schema) + + q = addWhereClause(q.QueryBuilder(), conditions).Unwrap().(*bun.DeleteQuery) + + resp, err := q.Exec(ctx) if err != nil { return resp, err } return resp, nil } -func executeUpdate(ctx context.Context, db *bun.DB, schema interface{}, query string, columns []string, additionals map[string]string) (sql.Result, error) { - updatedQuery := db.NewUpdate().Model(schema).Column(columns...) +func executeUpdate(ctx context.Context, db *bun.DB, schema interface{}, columns []string, conditions [][3]string) (sql.Result, error) { + q := db.NewUpdate().Model(schema).Column(columns...) - for key, value := range additionals { - updatedQuery = updatedQuery.Where(fmt.Sprintf("%s = ?", key), value) - } + q = addWhereClause(q.QueryBuilder(), conditions).Unwrap().(*bun.UpdateQuery) - updatedQuery = updatedQuery.Returning("*") - resp, err := updatedQuery.Exec(ctx) + q = q.Returning("*") + + resp, err := q.Exec(ctx) if err != nil { return resp, err } return resp, nil } + +func addWhereClause(query bun.QueryBuilder, conditions [][3]string) bun.QueryBuilder { + for _, triplet := range conditions { + key, op, value := triplet[0], triplet[1], triplet[2] + query = query.Where(fmt.Sprintf("%s %s ?", key, op), value) + } + return query +} From fdbf22a2cc60324cf5d216ce0f8e31550e18399a Mon Sep 17 00:00:00 2001 From: Azanul Date: Fri, 26 Apr 2024 12:21:32 +0530 Subject: [PATCH 09/16] refac: repository Signed-off-by: Azanul --- handlers/accounts_handler.go | 15 +++---- handlers/alerts_handler.go | 7 ++-- handlers/tags_handler.go | 5 ++- models/queries.go | 49 ----------------------- models/execution.go => repository/sql.go | 50 +++++++++++++++++++++++- 5 files changed, 64 insertions(+), 62 deletions(-) delete mode 100644 models/queries.go rename models/execution.go => repository/sql.go (74%) diff --git a/handlers/accounts_handler.go b/handlers/accounts_handler.go index 36ce5c9d5..b5b0d5828 100644 --- a/handlers/accounts_handler.go +++ b/handlers/accounts_handler.go @@ -11,6 +11,7 @@ import ( "github.com/go-co-op/gocron" log "github.com/sirupsen/logrus" "github.com/tailwarden/komiser/models" + "github.com/tailwarden/komiser/repository" "github.com/tailwarden/komiser/utils" "github.com/uptrace/bun" "github.com/uptrace/bun/dialect/pgdialect" @@ -38,7 +39,7 @@ func (handler *ApiHandler) IsOnboardedHandler(c *gin.Context) { accounts := make([]models.Account, 0) - _, err := models.HandleQuery(handler.ctx, handler.db, "LIST", &accounts, nil) + _, err := repository.HandleQuery(handler.ctx, handler.db, "LIST", &accounts, nil) if err != nil { log.WithError(err).Error("scan failed") c.JSON(http.StatusInternalServerError, gin.H{"error": "scan failed"}) @@ -62,7 +63,7 @@ func (handler *ApiHandler) ListCloudAccountsHandler(c *gin.Context) { return } - _, err := models.HandleQuery(handler.ctx, handler.db, "LIST", &accounts, nil) + _, err := repository.HandleQuery(handler.ctx, handler.db, "LIST", &accounts, nil) if err != nil { log.WithError(err).Error("scan failed") c.JSON(http.StatusInternalServerError, gin.H{"error": "scan failed"}) @@ -74,7 +75,7 @@ func (handler *ApiHandler) ListCloudAccountsHandler(c *gin.Context) { Total int `bun:"total" json:"total"` }{} - _, err := models.HandleQuery(handler.ctx, handler.db, "RESOURCE_COUNT", &output, [][3]string{{"provider", "=", account.Provider}, {"account", "=", account.Name}}) + _, err := repository.HandleQuery(handler.ctx, handler.db, "RESOURCE_COUNT", &output, [][3]string{{"provider", "=", account.Provider}, {"account", "=", account.Name}}) if err != nil { fmt.Println(err) c.JSON(http.StatusInternalServerError, gin.H{"error": "scan failed"}) @@ -107,7 +108,7 @@ func (handler *ApiHandler) NewCloudAccountHandler(c *gin.Context) { unsavedAccounts = append(unsavedAccounts, account) } else { - result, err := models.HandleQuery(handler.ctx, handler.db, "INSERT", &account, nil) + result, err := repository.HandleQuery(handler.ctx, handler.db, "INSERT", &account, nil) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return @@ -155,7 +156,7 @@ func (handler *ApiHandler) ReScanAccount(c *gin.Context) { account := new(models.Account) account.Status = "SCANNING" - res, err := models.HandleQuery(handler.ctx, handler.db, "RE_SCAN_ACCOUNT", account, [][3]string{{"id", "=", accountId}, {"status", "=", "CONNECTED"}}) + res, err := repository.HandleQuery(handler.ctx, handler.db, "RE_SCAN_ACCOUNT", account, [][3]string{{"id", "=", accountId}, {"status", "=", "CONNECTED"}}) if err != nil { log.Error("Couldn't set status", err) return @@ -172,7 +173,7 @@ func (handler *ApiHandler) DeleteCloudAccountHandler(c *gin.Context) { accountId := c.Param("id") account := new(models.Account) - _, err := models.HandleQuery(handler.ctx, handler.db, "DELETE", account, [][3]string{{"id", "=", accountId}}) + _, err := repository.HandleQuery(handler.ctx, handler.db, "DELETE", account, [][3]string{{"id", "=", accountId}}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return @@ -191,7 +192,7 @@ func (handler *ApiHandler) UpdateCloudAccountHandler(c *gin.Context) { return } - _, err = models.HandleQuery(handler.ctx, handler.db, "UPDATE_ACCOUNT", &account, [][3]string{{"id", "=", accountId}}) + _, err = repository.HandleQuery(handler.ctx, handler.db, "UPDATE_ACCOUNT", &account, [][3]string{{"id", "=", accountId}}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return diff --git a/handlers/alerts_handler.go b/handlers/alerts_handler.go index fc8fd497e..e22e86682 100644 --- a/handlers/alerts_handler.go +++ b/handlers/alerts_handler.go @@ -9,6 +9,7 @@ import ( "github.com/gin-gonic/gin" "github.com/tailwarden/komiser/models" + "github.com/tailwarden/komiser/repository" ) func (handler *ApiHandler) IsSlackEnabledHandler(c *gin.Context) { @@ -33,7 +34,7 @@ func (handler *ApiHandler) NewAlertHandler(c *gin.Context) { return } - result, err := models.HandleQuery(handler.ctx, handler.db, "INSERT", &alert, nil) + result, err := repository.HandleQuery(handler.ctx, handler.db, "INSERT", &alert, nil) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return @@ -62,7 +63,7 @@ func (handler *ApiHandler) UpdateAlertHandler(c *gin.Context) { return } - _, err = models.HandleQuery(handler.ctx, handler.db, "UPDATE_ALERT", &alert, [][3]string{{"id", "=", fmt.Sprint(alertId)}}) + _, err = repository.HandleQuery(handler.ctx, handler.db, "UPDATE_ALERT", &alert, [][3]string{{"id", "=", fmt.Sprint(alertId)}}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return @@ -75,7 +76,7 @@ func (handler *ApiHandler) DeleteAlertHandler(c *gin.Context) { alertId := c.Param("id") alert := new(models.Alert) - _, err := models.HandleQuery(handler.ctx, handler.db, "DELETE", alert, [][3]string{{"id", "=", fmt.Sprint(alertId)}}) + _, err := repository.HandleQuery(handler.ctx, handler.db, "DELETE", alert, [][3]string{{"id", "=", fmt.Sprint(alertId)}}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return diff --git a/handlers/tags_handler.go b/handlers/tags_handler.go index 803fe95e8..1feec49a2 100644 --- a/handlers/tags_handler.go +++ b/handlers/tags_handler.go @@ -7,6 +7,7 @@ import ( "github.com/gin-gonic/gin" "github.com/tailwarden/komiser/models" + "github.com/tailwarden/komiser/repository" ) func (handler *ApiHandler) BulkUpdateTagsHandler(c *gin.Context) { @@ -21,7 +22,7 @@ func (handler *ApiHandler) BulkUpdateTagsHandler(c *gin.Context) { resource := models.Resource{Tags: input.Tags} for _, resourceId := range input.Resources { - _, err = models.HandleQuery(handler.ctx, handler.db, "UPDATE_TAGS", &resource, [][3]string{{"id", "=", fmt.Sprint(resourceId)}}) + _, err = repository.HandleQuery(handler.ctx, handler.db, "UPDATE_TAGS", &resource, [][3]string{{"id", "=", fmt.Sprint(resourceId)}}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "error while updating tags"}) return @@ -48,7 +49,7 @@ func (handler *ApiHandler) UpdateTagsHandler(c *gin.Context) { resource := models.Resource{Tags: tags} - _, err = models.HandleQuery(handler.ctx, handler.db, "UPDATE_TAGS", &resource, [][3]string{{"id", "=", fmt.Sprint(resourceId)}}) + _, err = repository.HandleQuery(handler.ctx, handler.db, "UPDATE_TAGS", &resource, [][3]string{{"id", "=", fmt.Sprint(resourceId)}}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "error while updating tags"}) return diff --git a/models/queries.go b/models/queries.go deleted file mode 100644 index e403e4c18..000000000 --- a/models/queries.go +++ /dev/null @@ -1,49 +0,0 @@ -package models - -type Object struct { - Query string `json:"query"` - Type QueryType `json:"type"` - Params []string `json:"params"` -} - -type Data map[string]Object - -var Queries = Data{ - "LIST": Object{ - Type: SELECT, - }, - "INSERT": Object{ - Type: INSERT, - }, - "DELETE": Object{ - Type: DELETE, - }, - "UPDATE_ACCOUNT": Object{ - Type: UPDATE, - Params: []string{"name", "provider", "credentials"}, - }, - "UPDATE_ALERT": Object{ - Type: UPDATE, - Params: []string{"name", "type", "budget", "usage", "endpoint", "secret"}, - }, - "UPDATE_VIEW": Object{ - Type: UPDATE, - Params: []string{"name", "filters", "exclude"}, - }, - "UPDATE_VIEW_EXCLUDE": Object{ - Type: UPDATE, - Params: []string{"exclude"}, - }, - "RE_SCAN_ACCOUNT": Object{ - Type: UPDATE, - Params: []string{"status"}, - }, - "RESOURCE_COUNT": Object{ - Query: "SELECT COUNT(*) as total FROM resources", - Type: RAW, - }, - "UPDATE_TAGS": Object{ - Type: UPDATE, - Params: []string{"tags"}, - }, -} diff --git a/models/execution.go b/repository/sql.go similarity index 74% rename from models/execution.go rename to repository/sql.go index f9ea55ff4..dbe6582d3 100644 --- a/models/execution.go +++ b/repository/sql.go @@ -1,4 +1,4 @@ -package models +package repository import ( "context" @@ -18,6 +18,54 @@ const ( UPDATE QueryType = "UPDATE" ) +type Object struct { + Query string `json:"query"` + Type QueryType `json:"type"` + Params []string `json:"params"` +} + +type Data map[string]Object + +var Queries = Data{ + "LIST": Object{ + Type: SELECT, + }, + "INSERT": Object{ + Type: INSERT, + }, + "DELETE": Object{ + Type: DELETE, + }, + "UPDATE_ACCOUNT": Object{ + Type: UPDATE, + Params: []string{"name", "provider", "credentials"}, + }, + "UPDATE_ALERT": Object{ + Type: UPDATE, + Params: []string{"name", "type", "budget", "usage", "endpoint", "secret"}, + }, + "UPDATE_VIEW": Object{ + Type: UPDATE, + Params: []string{"name", "filters", "exclude"}, + }, + "UPDATE_VIEW_EXCLUDE": Object{ + Type: UPDATE, + Params: []string{"exclude"}, + }, + "RE_SCAN_ACCOUNT": Object{ + Type: UPDATE, + Params: []string{"status"}, + }, + "RESOURCE_COUNT": Object{ + Query: "SELECT COUNT(*) as total FROM resources", + Type: RAW, + }, + "UPDATE_TAGS": Object{ + Type: UPDATE, + Params: []string{"tags"}, + }, +} + func HandleQuery(ctx context.Context, db *bun.DB, queryTitle string, schema interface{}, conditions [][3]string) (sql.Result, error) { var resp sql.Result var err error From d96e606c127ab64771f850f01e9e02f477b11d4c Mon Sep 17 00:00:00 2001 From: AvineshTripathi Date: Sun, 28 Apr 2024 19:51:58 +0530 Subject: [PATCH 10/16] feat: added support to more tables --- handlers/csv_handler.go | 5 +++-- handlers/dashboard_handler.go | 18 +++++++++--------- handlers/views_handler.go | 24 +++++++++++------------- repository/sql.go | 20 ++++++++++++++++++++ 4 files changed, 43 insertions(+), 24 deletions(-) diff --git a/handlers/csv_handler.go b/handlers/csv_handler.go index b85a22c79..e5f2e36e7 100644 --- a/handlers/csv_handler.go +++ b/handlers/csv_handler.go @@ -14,12 +14,13 @@ import ( "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" "github.com/tailwarden/komiser/models" + "github.com/tailwarden/komiser/repository" "github.com/uptrace/bun/dialect" ) func (handler *ApiHandler) DownloadInventoryCSV(c *gin.Context) { resources := make([]models.Resource, 0) - err := handler.db.NewSelect().Table("resources").Scan(handler.ctx, &resources) + _, err := repository.HandleQuery(handler.ctx, handler.db, "LIST", &resources, [][3]string{}) if err != nil { logrus.WithError(err).Error("Could not read from DB") c.JSON(http.StatusInternalServerError, gin.H{"error": "cloud not read from DB"}) @@ -37,7 +38,7 @@ func (handler *ApiHandler) DownloadInventoryCSVForView(c *gin.Context) { viewId := c.Param("viewId") view := new(models.View) - err := handler.db.NewSelect().Model(view).Where("id = ?", viewId).Scan(handler.ctx) + _, err := repository.HandleQuery(handler.ctx, handler.db, "LIST", view, [][3]string{{"id", "=", fmt.Sprint(viewId)}}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return diff --git a/handlers/dashboard_handler.go b/handlers/dashboard_handler.go index b2a6b92c8..0fc63b4f3 100644 --- a/handlers/dashboard_handler.go +++ b/handlers/dashboard_handler.go @@ -11,6 +11,7 @@ import ( "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" "github.com/tailwarden/komiser/models" + "github.com/tailwarden/komiser/repository" "github.com/tailwarden/komiser/utils" "github.com/uptrace/bun" ) @@ -31,17 +32,17 @@ func (handler *ApiHandler) DashboardStatsHandler(c *gin.Context) { regions := struct { Count int `bun:"count" json:"total"` }{} - - err := handler.db.NewRaw("SELECT COUNT(*) as count FROM (SELECT DISTINCT region FROM resources) AS temp").Scan(handler.ctx, ®ions) + + _, err := repository.HandleQuery(handler.ctx, handler.db, "REGION_RESOURCE_COUNT", ®ions, [][3]string{}) if err != nil { logrus.WithError(err).Error("scan failed") } resources := struct { - Count int `bun:"count" json:"total"` + Count int `bun:"total" json:"total"` }{} - - err = handler.db.NewRaw("SELECT COUNT(*) as count FROM resources").Scan(handler.ctx, &resources) + + _, err = repository.HandleQuery(handler.ctx, handler.db, "RESOURCE_COUNT", &resources, [][3]string{}) if err != nil { logrus.WithError(err).Error("scan failed") } @@ -50,7 +51,7 @@ func (handler *ApiHandler) DashboardStatsHandler(c *gin.Context) { Sum float64 `bun:"sum" json:"total"` }{} - err = handler.db.NewRaw("SELECT SUM(cost) as sum FROM resources").Scan(handler.ctx, &cost) + _, err = repository.HandleQuery(handler.ctx, handler.db, "RESOURCE_COST_SUM", &cost, [][3]string{}) if err != nil { logrus.WithError(err).Error("scan failed") } @@ -59,7 +60,7 @@ func (handler *ApiHandler) DashboardStatsHandler(c *gin.Context) { Count int `bun:"count" json:"total"` }{} - err = handler.db.NewRaw("SELECT COUNT(*) as count FROM (SELECT DISTINCT account FROM resources) AS temp").Scan(handler.ctx, &accounts) + _, err = repository.HandleQuery(handler.ctx, handler.db, "REGION_RESOURCE_COUNT", ®ions, [][3]string{}) if err != nil { logrus.WithError(err).Error("scan failed") } @@ -143,8 +144,7 @@ func (handler *ApiHandler) LocationBreakdownStatsHandler(c *gin.Context) { c.JSON(http.StatusInternalServerError, []models.OutputLocations{}) return } - - err := handler.db.NewRaw("SELECT region as label, COUNT(*) as total FROM resources GROUP BY region ORDER by total desc;").Scan(handler.ctx, &groups) + _, err := repository.HandleQuery(handler.ctx, handler.db, "LOCATION_BREAKDOWN_STAT", &groups, [][3]string{}) if err != nil { logrus.WithError(err).Error("scan failed") } diff --git a/handlers/views_handler.go b/handlers/views_handler.go index 416b800ee..31c240c48 100644 --- a/handlers/views_handler.go +++ b/handlers/views_handler.go @@ -1,7 +1,6 @@ package handlers import ( - "context" "encoding/json" "fmt" "net/http" @@ -10,6 +9,7 @@ import ( "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" "github.com/tailwarden/komiser/models" + "github.com/tailwarden/komiser/repository" ) func (handler *ApiHandler) NewViewHandler(c *gin.Context) { @@ -20,8 +20,7 @@ func (handler *ApiHandler) NewViewHandler(c *gin.Context) { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } - - result, err := handler.db.NewInsert().Model(&view).Exec(context.Background()) + result, err := repository.HandleQuery(handler.ctx, handler.db, "INSERT", &view, [][3]string{}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return @@ -40,7 +39,7 @@ func (handler *ApiHandler) NewViewHandler(c *gin.Context) { func (handler *ApiHandler) ListViewsHandler(c *gin.Context) { views := make([]models.View, 0) - err := handler.db.NewRaw("SELECT * FROM views").Scan(handler.ctx, &views) + _, err := repository.HandleQuery(handler.ctx, handler.db, "LIST", &views, [][3]string{}) if err != nil { logrus.WithError(err).Error("scan failed") c.JSON(http.StatusInternalServerError, gin.H{"error": "scan failed"}) @@ -60,7 +59,7 @@ func (handler *ApiHandler) UpdateViewHandler(c *gin.Context) { return } - _, err = handler.db.NewUpdate().Model(&view).Column("name", "filters", "exclude").Where("id = ?", viewId).Exec(handler.ctx) + _, err = repository.HandleQuery(handler.ctx, handler.db, "UPDATE_VIEW", &view, [][3]string{{"id", "=", fmt.Sprint(viewId)}}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return @@ -73,7 +72,7 @@ func (handler *ApiHandler) DeleteViewHandler(c *gin.Context) { viewId := c.Param("id") view := new(models.View) - _, err := handler.db.NewDelete().Model(view).Where("id = ?", viewId).Exec(handler.ctx) + _, err := repository.HandleQuery(handler.ctx, handler.db, "DELETE", view, [][3]string{{"id", "=", fmt.Sprint(viewId)}}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return @@ -91,8 +90,7 @@ func (handler *ApiHandler) HideResourcesFromViewHandler(c *gin.Context) { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } - - _, err = handler.db.NewUpdate().Model(&view).Column("exclude").Where("id = ?", viewId).Exec(handler.ctx) + _, err = repository.HandleQuery(handler.ctx, handler.db, "UPDATE_VIEW_EXCLUDE", &view, [][3]string{{"id", "=", fmt.Sprint(viewId)}}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return @@ -110,8 +108,7 @@ func (handler *ApiHandler) UnhideResourcesFromViewHandler(c *gin.Context) { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } - - _, err = handler.db.NewUpdate().Model(&view).Column("exclude").Where("id = ?", viewId).Exec(handler.ctx) + _, err = repository.HandleQuery(handler.ctx, handler.db, "UPDATE_VIEW_EXCLUDE", &view, [][3]string{{"id", "=", fmt.Sprint(viewId)}}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return @@ -124,7 +121,7 @@ func (handler *ApiHandler) ListHiddenResourcesHandler(c *gin.Context) { viewId := c.Param("id") view := new(models.View) - err := handler.db.NewSelect().Model(view).Where("id = ?", viewId).Scan(handler.ctx) + _, err := repository.HandleQuery(handler.ctx, handler.db, "LIST", &view, [][3]string{{"id", "=", fmt.Sprint(viewId)}}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return @@ -134,7 +131,8 @@ func (handler *ApiHandler) ListHiddenResourcesHandler(c *gin.Context) { if len(view.Exclude) > 0 { s, _ := json.Marshal(view.Exclude) - err = handler.db.NewRaw(fmt.Sprintf("SELECT * FROM resources WHERE id IN (%s)", strings.Trim(string(s), "[]"))).Scan(handler.ctx, &resources) + + _, err = repository.HandleQuery(handler.ctx, handler.db, "LIST", &resources, [][3]string{{"id", "IN", strings.Trim(string(s), "[]")}}) if err != nil { logrus.WithError(err).Error("scan failed") } @@ -149,7 +147,7 @@ func (handler *ApiHandler) ListViewAlertsHandler(c *gin.Context) { alerts := make([]models.Alert, 0) - err := handler.db.NewRaw(fmt.Sprintf("SELECT * FROM alerts WHERE view_id = %s", viewId)).Scan(handler.ctx, &alerts) + _, err := repository.HandleQuery(handler.ctx, handler.db, "LIST", &alerts, [][3]string{{"view_id", "=", fmt.Sprint(viewId)}}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return diff --git a/repository/sql.go b/repository/sql.go index dbe6582d3..c379d9643 100644 --- a/repository/sql.go +++ b/repository/sql.go @@ -60,6 +60,26 @@ var Queries = Data{ Query: "SELECT COUNT(*) as total FROM resources", Type: RAW, }, + "RESOURCE_COST_SUM": Object{ + Query: "SELECT SUM(cost) as sum FROM resources", + Type: RAW, + }, + "ACCOUNTS_RESOURCE_COUNT": Object{ + Query: "SELECT COUNT(*) as count FROM (SELECT DISTINCT account FROM resources) AS temp", + Type: RAW, + }, + "REGION_RESOURCE_COUNT": Object{ + Query: "SELECT COUNT(*) as count FROM (SELECT DISTINCT region FROM resources) AS temp", + Type: RAW, + }, + "FILTER_RESOURCE_COUNT": Object{ + Query: "SELECT filters as label, COUNT(*) as total FROM resources", + Type: RAW, + }, + "LOCATION_BREAKDOWN_STAT": Object{ + Query: "SELECT region as label, COUNT(*) as total FROM resources GROUP BY region ORDER by total desc;", + Type: RAW, + }, "UPDATE_TAGS": Object{ Type: UPDATE, Params: []string{"tags"}, From 1da2fa691098a8bbaa3dfd29b97d175312d6a5c1 Mon Sep 17 00:00:00 2001 From: Azanul Date: Mon, 29 Apr 2024 15:53:14 +0530 Subject: [PATCH 11/16] refac: unused params Signed-off-by: Azanul --- repository/sql.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/repository/sql.go b/repository/sql.go index c379d9643..663ee94f0 100644 --- a/repository/sql.go +++ b/repository/sql.go @@ -95,13 +95,13 @@ func HandleQuery(ctx context.Context, db *bun.DB, queryTitle string, schema inte err = executeRaw(ctx, db, query.Query, schema, conditions) case SELECT: - err = executeSelect(ctx, db, query.Query, schema, conditions) + err = executeSelect(ctx, db, schema, conditions) case INSERT: - resp, err = executeInsert(ctx, db, schema, conditions) + resp, err = executeInsert(ctx, db, schema) case DELETE: - resp, err = executeDelete(ctx, db, schema, query.Query, conditions) + resp, err = executeDelete(ctx, db, schema, conditions) case UPDATE: resp, err = executeUpdate(ctx, db, schema, query.Params, conditions) @@ -130,7 +130,7 @@ func executeRaw(ctx context.Context, db *bun.DB, query string, schema interface{ return nil } -func executeSelect(ctx context.Context, db *bun.DB, query string, schema interface{}, conditions [][3]string) error { +func executeSelect(ctx context.Context, db *bun.DB, schema interface{}, conditions [][3]string) error { q := db.NewSelect().Model(schema) q = addWhereClause(q.QueryBuilder(), conditions).Unwrap().(*bun.SelectQuery) @@ -138,7 +138,7 @@ func executeSelect(ctx context.Context, db *bun.DB, query string, schema interfa return q.Scan(ctx, schema) } -func executeInsert(ctx context.Context, db *bun.DB, schema interface{}, conditions [][3]string) (sql.Result, error) { +func executeInsert(ctx context.Context, db *bun.DB, schema interface{}) (sql.Result, error) { resp, err := db.NewInsert().Model(schema).Exec(ctx) if err != nil { return resp, err @@ -146,7 +146,7 @@ func executeInsert(ctx context.Context, db *bun.DB, schema interface{}, conditio return resp, nil } -func executeDelete(ctx context.Context, db *bun.DB, schema interface{}, query string, conditions [][3]string) (sql.Result, error) { +func executeDelete(ctx context.Context, db *bun.DB, schema interface{}, conditions [][3]string) (sql.Result, error) { q := db.NewDelete().Model(schema) q = addWhereClause(q.QueryBuilder(), conditions).Unwrap().(*bun.DeleteQuery) From 750802f7200c3ba25b36c8f162623b90170e568d Mon Sep 17 00:00:00 2001 From: Azanul Date: Mon, 29 Apr 2024 19:28:36 +0530 Subject: [PATCH 12/16] refac: avoid writing strings for title Signed-off-by: Azanul --- repository/sql.go | 50 +++++++++++++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/repository/sql.go b/repository/sql.go index 663ee94f0..fb42475f1 100644 --- a/repository/sql.go +++ b/repository/sql.go @@ -24,63 +24,79 @@ type Object struct { Params []string `json:"params"` } -type Data map[string]Object +const ( + ListKey = "LIST" + InsertKey = "INSERT" + DeleteKey = "DELETE" + UpdateAccountKey = "UPDATE_ACCOUNT" + UpdateAlertKey = "UPDATE_ALERT" + UpdateViewKey = "UPDATE_VIEW" + UpdateViewExcludeKey = "UPDATE_VIEW_EXCLUDE" + ReScanAccountKey = "RE_SCAN_ACCOUNT" + ResourceCountKey = "RESOURCE_COUNT" + ResourceCostSumKey = "RESOURCE_COST_SUM" + AccountsResourceCountKey = "ACCOUNTS_RESOURCE_COUNT" + RegionResourceCountKey = "REGION_RESOURCE_COUNT" + FilterResourceCountKey = "FILTER_RESOURCE_COUNT" + LocationBreakdownStatKey = "LOCATION_BREAKDOWN_STAT" + UpdateTagsKey = "UPDATE_TAGS" +) -var Queries = Data{ - "LIST": Object{ +var Queries = map[string]Object{ + ListKey: { Type: SELECT, }, - "INSERT": Object{ + InsertKey: { Type: INSERT, }, - "DELETE": Object{ + DeleteKey: { Type: DELETE, }, - "UPDATE_ACCOUNT": Object{ + UpdateAccountKey: { Type: UPDATE, Params: []string{"name", "provider", "credentials"}, }, - "UPDATE_ALERT": Object{ + UpdateAlertKey: { Type: UPDATE, Params: []string{"name", "type", "budget", "usage", "endpoint", "secret"}, }, - "UPDATE_VIEW": Object{ + UpdateViewKey: { Type: UPDATE, Params: []string{"name", "filters", "exclude"}, }, - "UPDATE_VIEW_EXCLUDE": Object{ + UpdateViewExcludeKey: { Type: UPDATE, Params: []string{"exclude"}, }, - "RE_SCAN_ACCOUNT": Object{ + ReScanAccountKey: { Type: UPDATE, Params: []string{"status"}, }, - "RESOURCE_COUNT": Object{ + ResourceCountKey: { Query: "SELECT COUNT(*) as total FROM resources", Type: RAW, }, - "RESOURCE_COST_SUM": Object{ + ResourceCostSumKey: { Query: "SELECT SUM(cost) as sum FROM resources", Type: RAW, }, - "ACCOUNTS_RESOURCE_COUNT": Object{ + AccountsResourceCountKey: { Query: "SELECT COUNT(*) as count FROM (SELECT DISTINCT account FROM resources) AS temp", Type: RAW, }, - "REGION_RESOURCE_COUNT": Object{ + RegionResourceCountKey: { Query: "SELECT COUNT(*) as count FROM (SELECT DISTINCT region FROM resources) AS temp", Type: RAW, }, - "FILTER_RESOURCE_COUNT": Object{ + FilterResourceCountKey: { Query: "SELECT filters as label, COUNT(*) as total FROM resources", Type: RAW, }, - "LOCATION_BREAKDOWN_STAT": Object{ + LocationBreakdownStatKey: { Query: "SELECT region as label, COUNT(*) as total FROM resources GROUP BY region ORDER by total desc;", Type: RAW, }, - "UPDATE_TAGS": Object{ + UpdateTagsKey: { Type: UPDATE, Params: []string{"tags"}, }, From 0fda795b96af060abfa3cce2c5f29c91caad40b2 Mon Sep 17 00:00:00 2001 From: Azanul Date: Mon, 29 Apr 2024 19:57:31 +0530 Subject: [PATCH 13/16] refac: handle stats queries Signed-off-by: Azanul --- handlers/stats_handler.go | 24 +++++++++--------------- repository/sql.go | 20 ++++++++++++++++++++ 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/handlers/stats_handler.go b/handlers/stats_handler.go index ddf776b73..50d0b70fe 100644 --- a/handlers/stats_handler.go +++ b/handlers/stats_handler.go @@ -10,6 +10,7 @@ import ( "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" "github.com/tailwarden/komiser/models" + "github.com/tailwarden/komiser/repository" "github.com/uptrace/bun/dialect" ) @@ -17,17 +18,15 @@ func (handler *ApiHandler) StatsHandler(c *gin.Context) { regions := struct { Count int `bun:"count" json:"total"` }{} - - err := handler.db.NewRaw("SELECT COUNT(*) as count FROM (SELECT DISTINCT region FROM resources) AS temp").Scan(handler.ctx, ®ions) + _, err := repository.HandleQuery(c, handler.db, repository.RegionResourceCountKey, ®ions, nil) if err != nil { logrus.WithError(err).Error("scan failed") } resources := struct { - Count int `bun:"count" json:"total"` + Count int `bun:"total" json:"total"` }{} - - err = handler.db.NewRaw("SELECT COUNT(*) as count FROM resources").Scan(handler.ctx, &resources) + _, err = repository.HandleQuery(c, handler.db, repository.ResourceCountKey, &resources, nil) if err != nil { logrus.WithError(err).Error("scan failed") } @@ -35,8 +34,7 @@ func (handler *ApiHandler) StatsHandler(c *gin.Context) { cost := struct { Sum float64 `bun:"sum" json:"total"` }{} - - err = handler.db.NewRaw("SELECT SUM(cost) as sum FROM resources").Scan(handler.ctx, &cost) + _, err = repository.HandleQuery(c, handler.db, repository.ResourceCostSumKey, &cost, nil) if err != nil { logrus.WithError(err).Error("scan failed") } @@ -321,8 +319,7 @@ func (handler *ApiHandler) ListRegionsHandler(c *gin.Context) { } outputs := make([]Output, 0) - - err := handler.db.NewRaw("SELECT DISTINCT(region) FROM resources").Scan(handler.ctx, &outputs) + _, err := repository.HandleQuery(c, handler.db, repository.ListRegionsKey, &outputs, nil) if err != nil { logrus.WithError(err).Error("scan failed") } @@ -347,8 +344,7 @@ func (handler *ApiHandler) ListProvidersHandler(c *gin.Context) { } outputs := make([]Output, 0) - - err := handler.db.NewRaw("SELECT DISTINCT(provider) FROM resources").Scan(handler.ctx, &outputs) + _, err := repository.HandleQuery(c, handler.db, repository.ListProvidersKey, &outputs, nil) if err != nil { logrus.WithError(err).Error("scan failed") } @@ -368,8 +364,7 @@ func (handler *ApiHandler) ListServicesHandler(c *gin.Context) { } outputs := make([]Output, 0) - - err := handler.db.NewRaw("SELECT DISTINCT(service) FROM resources").Scan(handler.ctx, &outputs) + _, err := repository.HandleQuery(c, handler.db, repository.ListServicesKey, &outputs, nil) if err != nil { logrus.WithError(err).Error("scan failed") } @@ -394,8 +389,7 @@ func (handler *ApiHandler) ListAccountsHandler(c *gin.Context) { } outputs := make([]Output, 0) - - err := handler.db.NewRaw("SELECT DISTINCT(account) FROM resources").Scan(handler.ctx, &outputs) + _, err := repository.HandleQuery(c, handler.db, repository.ListAccountsKey, &outputs, nil) if err != nil { logrus.WithError(err).Error("scan failed") } diff --git a/repository/sql.go b/repository/sql.go index fb42475f1..65fe55ba5 100644 --- a/repository/sql.go +++ b/repository/sql.go @@ -40,6 +40,10 @@ const ( FilterResourceCountKey = "FILTER_RESOURCE_COUNT" LocationBreakdownStatKey = "LOCATION_BREAKDOWN_STAT" UpdateTagsKey = "UPDATE_TAGS" + ListRegionsKey = "LISST_REGIONS" + ListProvidersKey = "LIST_PROVIDERS" + ListServicesKey = "LIST_SERVICES" + ListAccountsKey = "LIST_ACCOUNTS" ) var Queries = map[string]Object{ @@ -100,6 +104,22 @@ var Queries = map[string]Object{ Type: UPDATE, Params: []string{"tags"}, }, + ListRegionsKey: { + Type: RAW, + Query: "SELECT DISTINCT(region) FROM resources", + }, + ListProvidersKey: { + Type: RAW, + Query: "SELECT DISTINCT(provider) FROM resources", + }, + ListServicesKey: { + Type: RAW, + Query: "SELECT DISTINCT(service) FROM resources", + }, + ListAccountsKey: { + Type: RAW, + Query: "SELECT DISTINCT(account) FROM resources", + }, } func HandleQuery(ctx context.Context, db *bun.DB, queryTitle string, schema interface{}, conditions [][3]string) (sql.Result, error) { From 76bdb3b733ab55af4ab0f5af539ca70e0fa133f9 Mon Sep 17 00:00:00 2001 From: Azanul Date: Thu, 2 May 2024 11:03:46 +0530 Subject: [PATCH 14/16] refac: handle resource query Signed-off-by: Azanul --- handlers/resources_handler.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/handlers/resources_handler.go b/handlers/resources_handler.go index e294d2bfb..1107cecc5 100644 --- a/handlers/resources_handler.go +++ b/handlers/resources_handler.go @@ -11,6 +11,7 @@ import ( "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" "github.com/tailwarden/komiser/models" + "github.com/tailwarden/komiser/repository" "github.com/tailwarden/komiser/utils" "github.com/uptrace/bun" "github.com/uptrace/bun/dialect" @@ -437,7 +438,7 @@ func (handler *ApiHandler) GetResourceByIdHandler(c *gin.Context) { var resource models.Resource - err := handler.db.NewSelect().Model(&resource).Where("resource_id = ?", resourceId).Scan(handler.ctx) + _, err := repository.HandleQuery(handler.ctx, handler.db, "SELECT", &resource, [][3]string{{"resource_id", "=", resourceId}}) if err != nil { c.JSON(http.StatusNotFound, gin.H{"error": "Resource not found"}) } From 57cf6be663ae43647be34cdf8e6015a17fccf959 Mon Sep 17 00:00:00 2001 From: Azanul Date: Thu, 2 May 2024 13:39:27 +0530 Subject: [PATCH 15/16] refac: repo interface Signed-off-by: Azanul --- handlers/accounts_handler.go | 15 ++--- handlers/alerts_handler.go | 7 +- handlers/csv_handler.go | 5 +- handlers/dashboard_handler.go | 15 ++--- handlers/resources_handler.go | 8 ++- handlers/stats_handler.go | 14 ++-- handlers/tags_handler.go | 5 +- handlers/views_handler.go | 21 +++--- repository/{sql.go => core.go} | 109 ++---------------------------- repository/error.go | 5 ++ repository/sql/sql.go | 119 ++++++++++++++++++++++++++++++++ repository/sqlite/sqlite.go | 120 +++++++++++++++++++++++++++++++++ 12 files changed, 294 insertions(+), 149 deletions(-) rename repository/{sql.go => core.go} (51%) create mode 100644 repository/error.go create mode 100644 repository/sql/sql.go create mode 100644 repository/sqlite/sqlite.go diff --git a/handlers/accounts_handler.go b/handlers/accounts_handler.go index b5b0d5828..187f56746 100644 --- a/handlers/accounts_handler.go +++ b/handlers/accounts_handler.go @@ -11,7 +11,6 @@ import ( "github.com/go-co-op/gocron" log "github.com/sirupsen/logrus" "github.com/tailwarden/komiser/models" - "github.com/tailwarden/komiser/repository" "github.com/tailwarden/komiser/utils" "github.com/uptrace/bun" "github.com/uptrace/bun/dialect/pgdialect" @@ -39,7 +38,7 @@ func (handler *ApiHandler) IsOnboardedHandler(c *gin.Context) { accounts := make([]models.Account, 0) - _, err := repository.HandleQuery(handler.ctx, handler.db, "LIST", &accounts, nil) + _, err := handler.repo.HandleQuery(c, "LIST", &accounts, nil) if err != nil { log.WithError(err).Error("scan failed") c.JSON(http.StatusInternalServerError, gin.H{"error": "scan failed"}) @@ -63,7 +62,7 @@ func (handler *ApiHandler) ListCloudAccountsHandler(c *gin.Context) { return } - _, err := repository.HandleQuery(handler.ctx, handler.db, "LIST", &accounts, nil) + _, err := handler.repo.HandleQuery(c, "LIST", &accounts, nil) if err != nil { log.WithError(err).Error("scan failed") c.JSON(http.StatusInternalServerError, gin.H{"error": "scan failed"}) @@ -75,7 +74,7 @@ func (handler *ApiHandler) ListCloudAccountsHandler(c *gin.Context) { Total int `bun:"total" json:"total"` }{} - _, err := repository.HandleQuery(handler.ctx, handler.db, "RESOURCE_COUNT", &output, [][3]string{{"provider", "=", account.Provider}, {"account", "=", account.Name}}) + _, err := handler.repo.HandleQuery(c, "RESOURCE_COUNT", &output, [][3]string{{"provider", "=", account.Provider}, {"account", "=", account.Name}}) if err != nil { fmt.Println(err) c.JSON(http.StatusInternalServerError, gin.H{"error": "scan failed"}) @@ -108,7 +107,7 @@ func (handler *ApiHandler) NewCloudAccountHandler(c *gin.Context) { unsavedAccounts = append(unsavedAccounts, account) } else { - result, err := repository.HandleQuery(handler.ctx, handler.db, "INSERT", &account, nil) + result, err := handler.repo.HandleQuery(c, "INSERT", &account, nil) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return @@ -156,7 +155,7 @@ func (handler *ApiHandler) ReScanAccount(c *gin.Context) { account := new(models.Account) account.Status = "SCANNING" - res, err := repository.HandleQuery(handler.ctx, handler.db, "RE_SCAN_ACCOUNT", account, [][3]string{{"id", "=", accountId}, {"status", "=", "CONNECTED"}}) + res, err := handler.repo.HandleQuery(c, "RE_SCAN_ACCOUNT", account, [][3]string{{"id", "=", accountId}, {"status", "=", "CONNECTED"}}) if err != nil { log.Error("Couldn't set status", err) return @@ -173,7 +172,7 @@ func (handler *ApiHandler) DeleteCloudAccountHandler(c *gin.Context) { accountId := c.Param("id") account := new(models.Account) - _, err := repository.HandleQuery(handler.ctx, handler.db, "DELETE", account, [][3]string{{"id", "=", accountId}}) + _, err := handler.repo.HandleQuery(c, "DELETE", account, [][3]string{{"id", "=", accountId}}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return @@ -192,7 +191,7 @@ func (handler *ApiHandler) UpdateCloudAccountHandler(c *gin.Context) { return } - _, err = repository.HandleQuery(handler.ctx, handler.db, "UPDATE_ACCOUNT", &account, [][3]string{{"id", "=", accountId}}) + _, err = handler.repo.HandleQuery(c, "UPDATE_ACCOUNT", &account, [][3]string{{"id", "=", accountId}}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return diff --git a/handlers/alerts_handler.go b/handlers/alerts_handler.go index e22e86682..7f69196f0 100644 --- a/handlers/alerts_handler.go +++ b/handlers/alerts_handler.go @@ -9,7 +9,6 @@ import ( "github.com/gin-gonic/gin" "github.com/tailwarden/komiser/models" - "github.com/tailwarden/komiser/repository" ) func (handler *ApiHandler) IsSlackEnabledHandler(c *gin.Context) { @@ -34,7 +33,7 @@ func (handler *ApiHandler) NewAlertHandler(c *gin.Context) { return } - result, err := repository.HandleQuery(handler.ctx, handler.db, "INSERT", &alert, nil) + result, err := handler.repo.HandleQuery(c, "INSERT", &alert, nil) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return @@ -63,7 +62,7 @@ func (handler *ApiHandler) UpdateAlertHandler(c *gin.Context) { return } - _, err = repository.HandleQuery(handler.ctx, handler.db, "UPDATE_ALERT", &alert, [][3]string{{"id", "=", fmt.Sprint(alertId)}}) + _, err = handler.repo.HandleQuery(c, "UPDATE_ALERT", &alert, [][3]string{{"id", "=", fmt.Sprint(alertId)}}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return @@ -76,7 +75,7 @@ func (handler *ApiHandler) DeleteAlertHandler(c *gin.Context) { alertId := c.Param("id") alert := new(models.Alert) - _, err := repository.HandleQuery(handler.ctx, handler.db, "DELETE", alert, [][3]string{{"id", "=", fmt.Sprint(alertId)}}) + _, err := handler.repo.HandleQuery(c, "DELETE", alert, [][3]string{{"id", "=", fmt.Sprint(alertId)}}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return diff --git a/handlers/csv_handler.go b/handlers/csv_handler.go index e5f2e36e7..4b845dad4 100644 --- a/handlers/csv_handler.go +++ b/handlers/csv_handler.go @@ -14,13 +14,12 @@ import ( "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" "github.com/tailwarden/komiser/models" - "github.com/tailwarden/komiser/repository" "github.com/uptrace/bun/dialect" ) func (handler *ApiHandler) DownloadInventoryCSV(c *gin.Context) { resources := make([]models.Resource, 0) - _, err := repository.HandleQuery(handler.ctx, handler.db, "LIST", &resources, [][3]string{}) + _, err := handler.repo.HandleQuery(c, "LIST", &resources, [][3]string{}) if err != nil { logrus.WithError(err).Error("Could not read from DB") c.JSON(http.StatusInternalServerError, gin.H{"error": "cloud not read from DB"}) @@ -38,7 +37,7 @@ func (handler *ApiHandler) DownloadInventoryCSVForView(c *gin.Context) { viewId := c.Param("viewId") view := new(models.View) - _, err := repository.HandleQuery(handler.ctx, handler.db, "LIST", view, [][3]string{{"id", "=", fmt.Sprint(viewId)}}) + _, err := handler.repo.HandleQuery(c, "LIST", view, [][3]string{{"id", "=", fmt.Sprint(viewId)}}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return diff --git a/handlers/dashboard_handler.go b/handlers/dashboard_handler.go index 0fc63b4f3..34165ed3b 100644 --- a/handlers/dashboard_handler.go +++ b/handlers/dashboard_handler.go @@ -11,7 +11,6 @@ import ( "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" "github.com/tailwarden/komiser/models" - "github.com/tailwarden/komiser/repository" "github.com/tailwarden/komiser/utils" "github.com/uptrace/bun" ) @@ -32,8 +31,8 @@ func (handler *ApiHandler) DashboardStatsHandler(c *gin.Context) { regions := struct { Count int `bun:"count" json:"total"` }{} - - _, err := repository.HandleQuery(handler.ctx, handler.db, "REGION_RESOURCE_COUNT", ®ions, [][3]string{}) + + _, err := handler.repo.HandleQuery(c, "REGION_RESOURCE_COUNT", ®ions, [][3]string{}) if err != nil { logrus.WithError(err).Error("scan failed") } @@ -41,8 +40,8 @@ func (handler *ApiHandler) DashboardStatsHandler(c *gin.Context) { resources := struct { Count int `bun:"total" json:"total"` }{} - - _, err = repository.HandleQuery(handler.ctx, handler.db, "RESOURCE_COUNT", &resources, [][3]string{}) + + _, err = handler.repo.HandleQuery(c, "RESOURCE_COUNT", &resources, [][3]string{}) if err != nil { logrus.WithError(err).Error("scan failed") } @@ -51,7 +50,7 @@ func (handler *ApiHandler) DashboardStatsHandler(c *gin.Context) { Sum float64 `bun:"sum" json:"total"` }{} - _, err = repository.HandleQuery(handler.ctx, handler.db, "RESOURCE_COST_SUM", &cost, [][3]string{}) + _, err = handler.repo.HandleQuery(c, "RESOURCE_COST_SUM", &cost, [][3]string{}) if err != nil { logrus.WithError(err).Error("scan failed") } @@ -60,7 +59,7 @@ func (handler *ApiHandler) DashboardStatsHandler(c *gin.Context) { Count int `bun:"count" json:"total"` }{} - _, err = repository.HandleQuery(handler.ctx, handler.db, "REGION_RESOURCE_COUNT", ®ions, [][3]string{}) + _, err = handler.repo.HandleQuery(c, "REGION_RESOURCE_COUNT", ®ions, [][3]string{}) if err != nil { logrus.WithError(err).Error("scan failed") } @@ -144,7 +143,7 @@ func (handler *ApiHandler) LocationBreakdownStatsHandler(c *gin.Context) { c.JSON(http.StatusInternalServerError, []models.OutputLocations{}) return } - _, err := repository.HandleQuery(handler.ctx, handler.db, "LOCATION_BREAKDOWN_STAT", &groups, [][3]string{}) + _, err := handler.repo.HandleQuery(c, "LOCATION_BREAKDOWN_STAT", &groups, [][3]string{}) if err != nil { logrus.WithError(err).Error("scan failed") } diff --git a/handlers/resources_handler.go b/handlers/resources_handler.go index 1107cecc5..070b8136d 100644 --- a/handlers/resources_handler.go +++ b/handlers/resources_handler.go @@ -2,6 +2,7 @@ package handlers import ( "context" + "database/sql" "encoding/json" "fmt" "net/http" @@ -19,6 +20,7 @@ import ( type ApiHandler struct { db *bun.DB + repo Repository ctx context.Context telemetry bool cfg models.Config @@ -27,6 +29,10 @@ type ApiHandler struct { accounts []models.Account } +type Repository interface { + HandleQuery(context.Context, repository.QueryType, interface{}, [][3]string) (sql.Result, error) +} + func NewApiHandler(ctx context.Context, telemetry bool, analytics utils.Analytics, db *bun.DB, cfg models.Config, configPath string, accounts []models.Account) *ApiHandler { handler := ApiHandler{ db: db, @@ -438,7 +444,7 @@ func (handler *ApiHandler) GetResourceByIdHandler(c *gin.Context) { var resource models.Resource - _, err := repository.HandleQuery(handler.ctx, handler.db, "SELECT", &resource, [][3]string{{"resource_id", "=", resourceId}}) + _, err := handler.repo.HandleQuery(c, repository.SELECT, &resource, [][3]string{{"resource_id", "=", resourceId}}) if err != nil { c.JSON(http.StatusNotFound, gin.H{"error": "Resource not found"}) } diff --git a/handlers/stats_handler.go b/handlers/stats_handler.go index 50d0b70fe..fe2fd2d63 100644 --- a/handlers/stats_handler.go +++ b/handlers/stats_handler.go @@ -18,7 +18,7 @@ func (handler *ApiHandler) StatsHandler(c *gin.Context) { regions := struct { Count int `bun:"count" json:"total"` }{} - _, err := repository.HandleQuery(c, handler.db, repository.RegionResourceCountKey, ®ions, nil) + _, err := handler.repo.HandleQuery(c, repository.RegionResourceCountKey, ®ions, nil) if err != nil { logrus.WithError(err).Error("scan failed") } @@ -26,7 +26,7 @@ func (handler *ApiHandler) StatsHandler(c *gin.Context) { resources := struct { Count int `bun:"total" json:"total"` }{} - _, err = repository.HandleQuery(c, handler.db, repository.ResourceCountKey, &resources, nil) + _, err = handler.repo.HandleQuery(c, repository.ResourceCountKey, &resources, nil) if err != nil { logrus.WithError(err).Error("scan failed") } @@ -34,7 +34,7 @@ func (handler *ApiHandler) StatsHandler(c *gin.Context) { cost := struct { Sum float64 `bun:"sum" json:"total"` }{} - _, err = repository.HandleQuery(c, handler.db, repository.ResourceCostSumKey, &cost, nil) + _, err = handler.repo.HandleQuery(c, repository.ResourceCostSumKey, &cost, nil) if err != nil { logrus.WithError(err).Error("scan failed") } @@ -319,7 +319,7 @@ func (handler *ApiHandler) ListRegionsHandler(c *gin.Context) { } outputs := make([]Output, 0) - _, err := repository.HandleQuery(c, handler.db, repository.ListRegionsKey, &outputs, nil) + _, err := handler.repo.HandleQuery(c, repository.ListRegionsKey, &outputs, nil) if err != nil { logrus.WithError(err).Error("scan failed") } @@ -344,7 +344,7 @@ func (handler *ApiHandler) ListProvidersHandler(c *gin.Context) { } outputs := make([]Output, 0) - _, err := repository.HandleQuery(c, handler.db, repository.ListProvidersKey, &outputs, nil) + _, err := handler.repo.HandleQuery(c, repository.ListProvidersKey, &outputs, nil) if err != nil { logrus.WithError(err).Error("scan failed") } @@ -364,7 +364,7 @@ func (handler *ApiHandler) ListServicesHandler(c *gin.Context) { } outputs := make([]Output, 0) - _, err := repository.HandleQuery(c, handler.db, repository.ListServicesKey, &outputs, nil) + _, err := handler.repo.HandleQuery(c, repository.ListServicesKey, &outputs, nil) if err != nil { logrus.WithError(err).Error("scan failed") } @@ -389,7 +389,7 @@ func (handler *ApiHandler) ListAccountsHandler(c *gin.Context) { } outputs := make([]Output, 0) - _, err := repository.HandleQuery(c, handler.db, repository.ListAccountsKey, &outputs, nil) + _, err := handler.repo.HandleQuery(c, repository.ListAccountsKey, &outputs, nil) if err != nil { logrus.WithError(err).Error("scan failed") } diff --git a/handlers/tags_handler.go b/handlers/tags_handler.go index 1feec49a2..1585032f7 100644 --- a/handlers/tags_handler.go +++ b/handlers/tags_handler.go @@ -7,7 +7,6 @@ import ( "github.com/gin-gonic/gin" "github.com/tailwarden/komiser/models" - "github.com/tailwarden/komiser/repository" ) func (handler *ApiHandler) BulkUpdateTagsHandler(c *gin.Context) { @@ -22,7 +21,7 @@ func (handler *ApiHandler) BulkUpdateTagsHandler(c *gin.Context) { resource := models.Resource{Tags: input.Tags} for _, resourceId := range input.Resources { - _, err = repository.HandleQuery(handler.ctx, handler.db, "UPDATE_TAGS", &resource, [][3]string{{"id", "=", fmt.Sprint(resourceId)}}) + _, err = handler.repo.HandleQuery(c, "UPDATE_TAGS", &resource, [][3]string{{"id", "=", fmt.Sprint(resourceId)}}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "error while updating tags"}) return @@ -49,7 +48,7 @@ func (handler *ApiHandler) UpdateTagsHandler(c *gin.Context) { resource := models.Resource{Tags: tags} - _, err = repository.HandleQuery(handler.ctx, handler.db, "UPDATE_TAGS", &resource, [][3]string{{"id", "=", fmt.Sprint(resourceId)}}) + _, err = handler.repo.HandleQuery(c, "UPDATE_TAGS", &resource, [][3]string{{"id", "=", fmt.Sprint(resourceId)}}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "error while updating tags"}) return diff --git a/handlers/views_handler.go b/handlers/views_handler.go index 31c240c48..8b656a0bd 100644 --- a/handlers/views_handler.go +++ b/handlers/views_handler.go @@ -9,7 +9,6 @@ import ( "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" "github.com/tailwarden/komiser/models" - "github.com/tailwarden/komiser/repository" ) func (handler *ApiHandler) NewViewHandler(c *gin.Context) { @@ -20,7 +19,7 @@ func (handler *ApiHandler) NewViewHandler(c *gin.Context) { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } - result, err := repository.HandleQuery(handler.ctx, handler.db, "INSERT", &view, [][3]string{}) + result, err := handler.repo.HandleQuery(c, "INSERT", &view, [][3]string{}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return @@ -39,7 +38,7 @@ func (handler *ApiHandler) NewViewHandler(c *gin.Context) { func (handler *ApiHandler) ListViewsHandler(c *gin.Context) { views := make([]models.View, 0) - _, err := repository.HandleQuery(handler.ctx, handler.db, "LIST", &views, [][3]string{}) + _, err := handler.repo.HandleQuery(c, "LIST", &views, [][3]string{}) if err != nil { logrus.WithError(err).Error("scan failed") c.JSON(http.StatusInternalServerError, gin.H{"error": "scan failed"}) @@ -59,7 +58,7 @@ func (handler *ApiHandler) UpdateViewHandler(c *gin.Context) { return } - _, err = repository.HandleQuery(handler.ctx, handler.db, "UPDATE_VIEW", &view, [][3]string{{"id", "=", fmt.Sprint(viewId)}}) + _, err = handler.repo.HandleQuery(c, "UPDATE_VIEW", &view, [][3]string{{"id", "=", fmt.Sprint(viewId)}}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return @@ -72,7 +71,7 @@ func (handler *ApiHandler) DeleteViewHandler(c *gin.Context) { viewId := c.Param("id") view := new(models.View) - _, err := repository.HandleQuery(handler.ctx, handler.db, "DELETE", view, [][3]string{{"id", "=", fmt.Sprint(viewId)}}) + _, err := handler.repo.HandleQuery(c, "DELETE", view, [][3]string{{"id", "=", fmt.Sprint(viewId)}}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return @@ -90,7 +89,7 @@ func (handler *ApiHandler) HideResourcesFromViewHandler(c *gin.Context) { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } - _, err = repository.HandleQuery(handler.ctx, handler.db, "UPDATE_VIEW_EXCLUDE", &view, [][3]string{{"id", "=", fmt.Sprint(viewId)}}) + _, err = handler.repo.HandleQuery(c, "UPDATE_VIEW_EXCLUDE", &view, [][3]string{{"id", "=", fmt.Sprint(viewId)}}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return @@ -108,7 +107,7 @@ func (handler *ApiHandler) UnhideResourcesFromViewHandler(c *gin.Context) { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } - _, err = repository.HandleQuery(handler.ctx, handler.db, "UPDATE_VIEW_EXCLUDE", &view, [][3]string{{"id", "=", fmt.Sprint(viewId)}}) + _, err = handler.repo.HandleQuery(c, "UPDATE_VIEW_EXCLUDE", &view, [][3]string{{"id", "=", fmt.Sprint(viewId)}}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return @@ -121,7 +120,7 @@ func (handler *ApiHandler) ListHiddenResourcesHandler(c *gin.Context) { viewId := c.Param("id") view := new(models.View) - _, err := repository.HandleQuery(handler.ctx, handler.db, "LIST", &view, [][3]string{{"id", "=", fmt.Sprint(viewId)}}) + _, err := handler.repo.HandleQuery(c, "LIST", &view, [][3]string{{"id", "=", fmt.Sprint(viewId)}}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return @@ -132,7 +131,7 @@ func (handler *ApiHandler) ListHiddenResourcesHandler(c *gin.Context) { if len(view.Exclude) > 0 { s, _ := json.Marshal(view.Exclude) - _, err = repository.HandleQuery(handler.ctx, handler.db, "LIST", &resources, [][3]string{{"id", "IN", strings.Trim(string(s), "[]")}}) + _, err = handler.repo.HandleQuery(c, "LIST", &resources, [][3]string{{"id", "IN", strings.Trim(string(s), "[]")}}) if err != nil { logrus.WithError(err).Error("scan failed") } @@ -147,11 +146,11 @@ func (handler *ApiHandler) ListViewAlertsHandler(c *gin.Context) { alerts := make([]models.Alert, 0) - _, err := repository.HandleQuery(handler.ctx, handler.db, "LIST", &alerts, [][3]string{{"view_id", "=", fmt.Sprint(viewId)}}) + _, err := handler.repo.HandleQuery(c, "LIST", &alerts, [][3]string{{"view_id", "=", fmt.Sprint(viewId)}}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, alerts) -} \ No newline at end of file +} diff --git a/repository/sql.go b/repository/core.go similarity index 51% rename from repository/sql.go rename to repository/core.go index 65fe55ba5..20d517a4f 100644 --- a/repository/sql.go +++ b/repository/core.go @@ -46,106 +46,7 @@ const ( ListAccountsKey = "LIST_ACCOUNTS" ) -var Queries = map[string]Object{ - ListKey: { - Type: SELECT, - }, - InsertKey: { - Type: INSERT, - }, - DeleteKey: { - Type: DELETE, - }, - UpdateAccountKey: { - Type: UPDATE, - Params: []string{"name", "provider", "credentials"}, - }, - UpdateAlertKey: { - Type: UPDATE, - Params: []string{"name", "type", "budget", "usage", "endpoint", "secret"}, - }, - UpdateViewKey: { - Type: UPDATE, - Params: []string{"name", "filters", "exclude"}, - }, - UpdateViewExcludeKey: { - Type: UPDATE, - Params: []string{"exclude"}, - }, - ReScanAccountKey: { - Type: UPDATE, - Params: []string{"status"}, - }, - ResourceCountKey: { - Query: "SELECT COUNT(*) as total FROM resources", - Type: RAW, - }, - ResourceCostSumKey: { - Query: "SELECT SUM(cost) as sum FROM resources", - Type: RAW, - }, - AccountsResourceCountKey: { - Query: "SELECT COUNT(*) as count FROM (SELECT DISTINCT account FROM resources) AS temp", - Type: RAW, - }, - RegionResourceCountKey: { - Query: "SELECT COUNT(*) as count FROM (SELECT DISTINCT region FROM resources) AS temp", - Type: RAW, - }, - FilterResourceCountKey: { - Query: "SELECT filters as label, COUNT(*) as total FROM resources", - Type: RAW, - }, - LocationBreakdownStatKey: { - Query: "SELECT region as label, COUNT(*) as total FROM resources GROUP BY region ORDER by total desc;", - Type: RAW, - }, - UpdateTagsKey: { - Type: UPDATE, - Params: []string{"tags"}, - }, - ListRegionsKey: { - Type: RAW, - Query: "SELECT DISTINCT(region) FROM resources", - }, - ListProvidersKey: { - Type: RAW, - Query: "SELECT DISTINCT(provider) FROM resources", - }, - ListServicesKey: { - Type: RAW, - Query: "SELECT DISTINCT(service) FROM resources", - }, - ListAccountsKey: { - Type: RAW, - Query: "SELECT DISTINCT(account) FROM resources", - }, -} - -func HandleQuery(ctx context.Context, db *bun.DB, queryTitle string, schema interface{}, conditions [][3]string) (sql.Result, error) { - var resp sql.Result - var err error - query := Queries[queryTitle] - switch query.Type { - case RAW: - err = executeRaw(ctx, db, query.Query, schema, conditions) - - case SELECT: - err = executeSelect(ctx, db, schema, conditions) - - case INSERT: - resp, err = executeInsert(ctx, db, schema) - - case DELETE: - resp, err = executeDelete(ctx, db, schema, conditions) - - case UPDATE: - resp, err = executeUpdate(ctx, db, schema, query.Params, conditions) - } - return resp, err -} - -func executeRaw(ctx context.Context, db *bun.DB, query string, schema interface{}, additionals [][3]string) error { +func ExecuteRaw(ctx context.Context, db *bun.DB, query string, schema interface{}, additionals [][3]string) error { if len(additionals) > 0 { query = fmt.Sprintf("%s where", query) } @@ -166,7 +67,7 @@ func executeRaw(ctx context.Context, db *bun.DB, query string, schema interface{ return nil } -func executeSelect(ctx context.Context, db *bun.DB, schema interface{}, conditions [][3]string) error { +func ExecuteSelect(ctx context.Context, db *bun.DB, schema interface{}, conditions [][3]string) error { q := db.NewSelect().Model(schema) q = addWhereClause(q.QueryBuilder(), conditions).Unwrap().(*bun.SelectQuery) @@ -174,7 +75,7 @@ func executeSelect(ctx context.Context, db *bun.DB, schema interface{}, conditio return q.Scan(ctx, schema) } -func executeInsert(ctx context.Context, db *bun.DB, schema interface{}) (sql.Result, error) { +func ExecuteInsert(ctx context.Context, db *bun.DB, schema interface{}) (sql.Result, error) { resp, err := db.NewInsert().Model(schema).Exec(ctx) if err != nil { return resp, err @@ -182,7 +83,7 @@ func executeInsert(ctx context.Context, db *bun.DB, schema interface{}) (sql.Res return resp, nil } -func executeDelete(ctx context.Context, db *bun.DB, schema interface{}, conditions [][3]string) (sql.Result, error) { +func ExecuteDelete(ctx context.Context, db *bun.DB, schema interface{}, conditions [][3]string) (sql.Result, error) { q := db.NewDelete().Model(schema) q = addWhereClause(q.QueryBuilder(), conditions).Unwrap().(*bun.DeleteQuery) @@ -194,7 +95,7 @@ func executeDelete(ctx context.Context, db *bun.DB, schema interface{}, conditio return resp, nil } -func executeUpdate(ctx context.Context, db *bun.DB, schema interface{}, columns []string, conditions [][3]string) (sql.Result, error) { +func ExecuteUpdate(ctx context.Context, db *bun.DB, schema interface{}, columns []string, conditions [][3]string) (sql.Result, error) { q := db.NewUpdate().Model(schema).Column(columns...) q = addWhereClause(q.QueryBuilder(), conditions).Unwrap().(*bun.UpdateQuery) diff --git a/repository/error.go b/repository/error.go new file mode 100644 index 000000000..605d82150 --- /dev/null +++ b/repository/error.go @@ -0,0 +1,5 @@ +package repository + +import "errors" + +var ErrQueryNotFound = errors.New("query not found") diff --git a/repository/sql/sql.go b/repository/sql/sql.go new file mode 100644 index 000000000..e5aaed810 --- /dev/null +++ b/repository/sql/sql.go @@ -0,0 +1,119 @@ +package sql + +import ( + "context" + "database/sql" + + "github.com/tailwarden/komiser/repository" + "github.com/uptrace/bun" +) + +type Repository struct { + db *bun.DB +} + +func NewRepository(db *bun.DB) *Repository { + return &Repository{db: db} +} + +var Queries = map[string]repository.Object{ + repository.ListKey: { + Type: repository.SELECT, + }, + repository.InsertKey: { + Type: repository.INSERT, + }, + repository.DeleteKey: { + Type: repository.DELETE, + }, + repository.UpdateAccountKey: { + Type: repository.UPDATE, + Params: []string{"name", "provider", "credentials"}, + }, + repository.UpdateAlertKey: { + Type: repository.UPDATE, + Params: []string{"name", "type", "budget", "usage", "endpoint", "secret"}, + }, + repository.UpdateViewKey: { + Type: repository.UPDATE, + Params: []string{"name", "filters", "exclude"}, + }, + repository.UpdateViewExcludeKey: { + Type: repository.UPDATE, + Params: []string{"exclude"}, + }, + repository.ReScanAccountKey: { + Type: repository.UPDATE, + Params: []string{"status"}, + }, + repository.ResourceCountKey: { + Query: "SELECT COUNT(*) as total FROM resources", + Type: repository.RAW, + }, + repository.ResourceCostSumKey: { + Query: "SELECT SUM(cost) as sum FROM resources", + Type: repository.RAW, + }, + repository.AccountsResourceCountKey: { + Query: "SELECT COUNT(*) as count FROM (SELECT DISTINCT account FROM resources) AS temp", + Type: repository.RAW, + }, + repository.RegionResourceCountKey: { + Query: "SELECT COUNT(*) as count FROM (SELECT DISTINCT region FROM resources) AS temp", + Type: repository.RAW, + }, + repository.FilterResourceCountKey: { + Query: "SELECT filters as label, COUNT(*) as total FROM resources", + Type: repository.RAW, + }, + repository.LocationBreakdownStatKey: { + Query: "SELECT region as label, COUNT(*) as total FROM resources GROUP BY region ORDER by total desc;", + Type: repository.RAW, + }, + repository.UpdateTagsKey: { + Type: repository.UPDATE, + Params: []string{"tags"}, + }, + repository.ListRegionsKey: { + Type: repository.RAW, + Query: "SELECT DISTINCT(region) FROM resources", + }, + repository.ListProvidersKey: { + Type: repository.RAW, + Query: "SELECT DISTINCT(provider) FROM resources", + }, + repository.ListServicesKey: { + Type: repository.RAW, + Query: "SELECT DISTINCT(service) FROM resources", + }, + repository.ListAccountsKey: { + Type: repository.RAW, + Query: "SELECT DISTINCT(account) FROM resources", + }, +} + +func (repo *Repository) HandleQuery(ctx context.Context, queryTitle string, schema interface{}, conditions [][3]string) (sql.Result, error) { + var resp sql.Result + var err error + query, ok := Queries[queryTitle] + if !ok { + return nil, repository.ErrQueryNotFound + } + switch query.Type { + case repository.RAW: + err = repository.ExecuteRaw(ctx, repo.db, query.Query, schema, conditions) + + case repository.SELECT: + err = repository.ExecuteSelect(ctx, repo.db, schema, conditions) + + case repository.INSERT: + resp, err = repository.ExecuteInsert(ctx, repo.db, schema) + + case repository.DELETE: + resp, err = repository.ExecuteDelete(ctx, repo.db, schema, conditions) + + case repository.UPDATE: + resp, err = repository.ExecuteUpdate(ctx, repo.db, schema, query.Params, conditions) + } + return resp, err +} diff --git a/repository/sqlite/sqlite.go b/repository/sqlite/sqlite.go new file mode 100644 index 000000000..b175900dc --- /dev/null +++ b/repository/sqlite/sqlite.go @@ -0,0 +1,120 @@ +package sql + +import ( + "context" + "database/sql" + + "github.com/tailwarden/komiser/repository" + "github.com/uptrace/bun" +) + +type Repository struct { + db *bun.DB + queries map[string]repository.Object +} + +func NewRepository(db *bun.DB) *Repository { + return &Repository{db: db, queries: Queries} +} + +var Queries = map[string]repository.Object{ + repository.ListKey: { + Type: repository.SELECT, + }, + repository.InsertKey: { + Type: repository.INSERT, + }, + repository.DeleteKey: { + Type: repository.DELETE, + }, + repository.UpdateAccountKey: { + Type: repository.UPDATE, + Params: []string{"name", "provider", "credentials"}, + }, + repository.UpdateAlertKey: { + Type: repository.UPDATE, + Params: []string{"name", "type", "budget", "usage", "endpoint", "secret"}, + }, + repository.UpdateViewKey: { + Type: repository.UPDATE, + Params: []string{"name", "filters", "exclude"}, + }, + repository.UpdateViewExcludeKey: { + Type: repository.UPDATE, + Params: []string{"exclude"}, + }, + repository.ReScanAccountKey: { + Type: repository.UPDATE, + Params: []string{"status"}, + }, + repository.ResourceCountKey: { + Query: "SELECT COUNT(*) as total FROM resources", + Type: repository.RAW, + }, + repository.ResourceCostSumKey: { + Query: "SELECT SUM(cost) as sum FROM resources", + Type: repository.RAW, + }, + repository.AccountsResourceCountKey: { + Query: "SELECT COUNT(*) as count FROM (SELECT DISTINCT account FROM resources) AS temp", + Type: repository.RAW, + }, + repository.RegionResourceCountKey: { + Query: "SELECT COUNT(*) as count FROM (SELECT DISTINCT region FROM resources) AS temp", + Type: repository.RAW, + }, + repository.FilterResourceCountKey: { + Query: "SELECT filters as label, COUNT(*) as total FROM resources", + Type: repository.RAW, + }, + repository.LocationBreakdownStatKey: { + Query: "SELECT region as label, COUNT(*) as total FROM resources GROUP BY region ORDER by total desc;", + Type: repository.RAW, + }, + repository.UpdateTagsKey: { + Type: repository.UPDATE, + Params: []string{"tags"}, + }, + repository.ListRegionsKey: { + Type: repository.RAW, + Query: "SELECT DISTINCT(region) FROM resources", + }, + repository.ListProvidersKey: { + Type: repository.RAW, + Query: "SELECT DISTINCT(provider) FROM resources", + }, + repository.ListServicesKey: { + Type: repository.RAW, + Query: "SELECT DISTINCT(service) FROM resources", + }, + repository.ListAccountsKey: { + Type: repository.RAW, + Query: "SELECT DISTINCT(account) FROM resources", + }, +} + +func (repo *Repository) HandleQuery(ctx context.Context, queryTitle string, schema interface{}, conditions [][3]string) (sql.Result, error) { + var resp sql.Result + var err error + query, ok := Queries[queryTitle] + if !ok { + return nil, repository.ErrQueryNotFound + } + switch query.Type { + case repository.RAW: + err = repository.ExecuteRaw(ctx, repo.db, query.Query, schema, conditions) + + case repository.SELECT: + err = repository.ExecuteSelect(ctx, repo.db, schema, conditions) + + case repository.INSERT: + resp, err = repository.ExecuteInsert(ctx, repo.db, schema) + + case repository.DELETE: + resp, err = repository.ExecuteDelete(ctx, repo.db, schema, conditions) + + case repository.UPDATE: + resp, err = repository.ExecuteUpdate(ctx, repo.db, schema, query.Params, conditions) + } + return resp, err +} From 4fef5d3d2c72e67e73705a0ba642f8e21c296a83 Mon Sep 17 00:00:00 2001 From: Azanul Date: Thu, 2 May 2024 14:04:29 +0530 Subject: [PATCH 16/16] refac: remove hardcoded strings Signed-off-by: Azanul --- handlers/accounts_handler.go | 15 ++++++++------- handlers/alerts_handler.go | 7 ++++--- handlers/csv_handler.go | 5 +++-- handlers/dashboard_handler.go | 11 ++++++----- handlers/resources_handler.go | 2 +- handlers/tags_handler.go | 5 +++-- handlers/views_handler.go | 19 ++++++++++--------- 7 files changed, 35 insertions(+), 29 deletions(-) diff --git a/handlers/accounts_handler.go b/handlers/accounts_handler.go index 187f56746..038d8844d 100644 --- a/handlers/accounts_handler.go +++ b/handlers/accounts_handler.go @@ -11,6 +11,7 @@ import ( "github.com/go-co-op/gocron" log "github.com/sirupsen/logrus" "github.com/tailwarden/komiser/models" + "github.com/tailwarden/komiser/repository" "github.com/tailwarden/komiser/utils" "github.com/uptrace/bun" "github.com/uptrace/bun/dialect/pgdialect" @@ -38,7 +39,7 @@ func (handler *ApiHandler) IsOnboardedHandler(c *gin.Context) { accounts := make([]models.Account, 0) - _, err := handler.repo.HandleQuery(c, "LIST", &accounts, nil) + _, err := handler.repo.HandleQuery(c, repository.ListKey, &accounts, nil) if err != nil { log.WithError(err).Error("scan failed") c.JSON(http.StatusInternalServerError, gin.H{"error": "scan failed"}) @@ -62,7 +63,7 @@ func (handler *ApiHandler) ListCloudAccountsHandler(c *gin.Context) { return } - _, err := handler.repo.HandleQuery(c, "LIST", &accounts, nil) + _, err := handler.repo.HandleQuery(c, repository.ListKey, &accounts, nil) if err != nil { log.WithError(err).Error("scan failed") c.JSON(http.StatusInternalServerError, gin.H{"error": "scan failed"}) @@ -74,7 +75,7 @@ func (handler *ApiHandler) ListCloudAccountsHandler(c *gin.Context) { Total int `bun:"total" json:"total"` }{} - _, err := handler.repo.HandleQuery(c, "RESOURCE_COUNT", &output, [][3]string{{"provider", "=", account.Provider}, {"account", "=", account.Name}}) + _, err := handler.repo.HandleQuery(c, repository.ResourceCountKey, &output, [][3]string{{"provider", "=", account.Provider}, {"account", "=", account.Name}}) if err != nil { fmt.Println(err) c.JSON(http.StatusInternalServerError, gin.H{"error": "scan failed"}) @@ -107,7 +108,7 @@ func (handler *ApiHandler) NewCloudAccountHandler(c *gin.Context) { unsavedAccounts = append(unsavedAccounts, account) } else { - result, err := handler.repo.HandleQuery(c, "INSERT", &account, nil) + result, err := handler.repo.HandleQuery(c, repository.InsertKey, &account, nil) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return @@ -155,7 +156,7 @@ func (handler *ApiHandler) ReScanAccount(c *gin.Context) { account := new(models.Account) account.Status = "SCANNING" - res, err := handler.repo.HandleQuery(c, "RE_SCAN_ACCOUNT", account, [][3]string{{"id", "=", accountId}, {"status", "=", "CONNECTED"}}) + res, err := handler.repo.HandleQuery(c, repository.ReScanAccountKey, account, [][3]string{{"id", "=", accountId}, {"status", "=", "CONNECTED"}}) if err != nil { log.Error("Couldn't set status", err) return @@ -172,7 +173,7 @@ func (handler *ApiHandler) DeleteCloudAccountHandler(c *gin.Context) { accountId := c.Param("id") account := new(models.Account) - _, err := handler.repo.HandleQuery(c, "DELETE", account, [][3]string{{"id", "=", accountId}}) + _, err := handler.repo.HandleQuery(c, repository.DeleteKey, account, [][3]string{{"id", "=", accountId}}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return @@ -191,7 +192,7 @@ func (handler *ApiHandler) UpdateCloudAccountHandler(c *gin.Context) { return } - _, err = handler.repo.HandleQuery(c, "UPDATE_ACCOUNT", &account, [][3]string{{"id", "=", accountId}}) + _, err = handler.repo.HandleQuery(c, repository.UpdateAccountKey, &account, [][3]string{{"id", "=", accountId}}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return diff --git a/handlers/alerts_handler.go b/handlers/alerts_handler.go index 7f69196f0..b7a401096 100644 --- a/handlers/alerts_handler.go +++ b/handlers/alerts_handler.go @@ -9,6 +9,7 @@ import ( "github.com/gin-gonic/gin" "github.com/tailwarden/komiser/models" + "github.com/tailwarden/komiser/repository" ) func (handler *ApiHandler) IsSlackEnabledHandler(c *gin.Context) { @@ -33,7 +34,7 @@ func (handler *ApiHandler) NewAlertHandler(c *gin.Context) { return } - result, err := handler.repo.HandleQuery(c, "INSERT", &alert, nil) + result, err := handler.repo.HandleQuery(c, repository.InsertKey, &alert, nil) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return @@ -62,7 +63,7 @@ func (handler *ApiHandler) UpdateAlertHandler(c *gin.Context) { return } - _, err = handler.repo.HandleQuery(c, "UPDATE_ALERT", &alert, [][3]string{{"id", "=", fmt.Sprint(alertId)}}) + _, err = handler.repo.HandleQuery(c, repository.UpdateAlertKey, &alert, [][3]string{{"id", "=", fmt.Sprint(alertId)}}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return @@ -75,7 +76,7 @@ func (handler *ApiHandler) DeleteAlertHandler(c *gin.Context) { alertId := c.Param("id") alert := new(models.Alert) - _, err := handler.repo.HandleQuery(c, "DELETE", alert, [][3]string{{"id", "=", fmt.Sprint(alertId)}}) + _, err := handler.repo.HandleQuery(c, repository.DeleteKey, alert, [][3]string{{"id", "=", fmt.Sprint(alertId)}}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return diff --git a/handlers/csv_handler.go b/handlers/csv_handler.go index 4b845dad4..afcb24b25 100644 --- a/handlers/csv_handler.go +++ b/handlers/csv_handler.go @@ -14,12 +14,13 @@ import ( "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" "github.com/tailwarden/komiser/models" + "github.com/tailwarden/komiser/repository" "github.com/uptrace/bun/dialect" ) func (handler *ApiHandler) DownloadInventoryCSV(c *gin.Context) { resources := make([]models.Resource, 0) - _, err := handler.repo.HandleQuery(c, "LIST", &resources, [][3]string{}) + _, err := handler.repo.HandleQuery(c, repository.ListKey, &resources, [][3]string{}) if err != nil { logrus.WithError(err).Error("Could not read from DB") c.JSON(http.StatusInternalServerError, gin.H{"error": "cloud not read from DB"}) @@ -37,7 +38,7 @@ func (handler *ApiHandler) DownloadInventoryCSVForView(c *gin.Context) { viewId := c.Param("viewId") view := new(models.View) - _, err := handler.repo.HandleQuery(c, "LIST", view, [][3]string{{"id", "=", fmt.Sprint(viewId)}}) + _, err := handler.repo.HandleQuery(c, repository.ListKey, view, [][3]string{{"id", "=", fmt.Sprint(viewId)}}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return diff --git a/handlers/dashboard_handler.go b/handlers/dashboard_handler.go index 34165ed3b..8400c718b 100644 --- a/handlers/dashboard_handler.go +++ b/handlers/dashboard_handler.go @@ -11,6 +11,7 @@ import ( "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" "github.com/tailwarden/komiser/models" + "github.com/tailwarden/komiser/repository" "github.com/tailwarden/komiser/utils" "github.com/uptrace/bun" ) @@ -32,7 +33,7 @@ func (handler *ApiHandler) DashboardStatsHandler(c *gin.Context) { Count int `bun:"count" json:"total"` }{} - _, err := handler.repo.HandleQuery(c, "REGION_RESOURCE_COUNT", ®ions, [][3]string{}) + _, err := handler.repo.HandleQuery(c, repository.RegionResourceCountKey, ®ions, [][3]string{}) if err != nil { logrus.WithError(err).Error("scan failed") } @@ -41,7 +42,7 @@ func (handler *ApiHandler) DashboardStatsHandler(c *gin.Context) { Count int `bun:"total" json:"total"` }{} - _, err = handler.repo.HandleQuery(c, "RESOURCE_COUNT", &resources, [][3]string{}) + _, err = handler.repo.HandleQuery(c, repository.ResourceCountKey, &resources, [][3]string{}) if err != nil { logrus.WithError(err).Error("scan failed") } @@ -50,7 +51,7 @@ func (handler *ApiHandler) DashboardStatsHandler(c *gin.Context) { Sum float64 `bun:"sum" json:"total"` }{} - _, err = handler.repo.HandleQuery(c, "RESOURCE_COST_SUM", &cost, [][3]string{}) + _, err = handler.repo.HandleQuery(c, repository.ResourceCostSumKey, &cost, [][3]string{}) if err != nil { logrus.WithError(err).Error("scan failed") } @@ -59,7 +60,7 @@ func (handler *ApiHandler) DashboardStatsHandler(c *gin.Context) { Count int `bun:"count" json:"total"` }{} - _, err = handler.repo.HandleQuery(c, "REGION_RESOURCE_COUNT", ®ions, [][3]string{}) + _, err = handler.repo.HandleQuery(c, repository.RegionResourceCountKey, ®ions, [][3]string{}) if err != nil { logrus.WithError(err).Error("scan failed") } @@ -143,7 +144,7 @@ func (handler *ApiHandler) LocationBreakdownStatsHandler(c *gin.Context) { c.JSON(http.StatusInternalServerError, []models.OutputLocations{}) return } - _, err := handler.repo.HandleQuery(c, "LOCATION_BREAKDOWN_STAT", &groups, [][3]string{}) + _, err := handler.repo.HandleQuery(c, repository.LocationBreakdownStatKey, &groups, [][3]string{}) if err != nil { logrus.WithError(err).Error("scan failed") } diff --git a/handlers/resources_handler.go b/handlers/resources_handler.go index 070b8136d..e3b0ac6f5 100644 --- a/handlers/resources_handler.go +++ b/handlers/resources_handler.go @@ -444,7 +444,7 @@ func (handler *ApiHandler) GetResourceByIdHandler(c *gin.Context) { var resource models.Resource - _, err := handler.repo.HandleQuery(c, repository.SELECT, &resource, [][3]string{{"resource_id", "=", resourceId}}) + _, err := handler.repo.HandleQuery(c, repository.ListKey, &resource, [][3]string{{"resource_id", "=", resourceId}}) if err != nil { c.JSON(http.StatusNotFound, gin.H{"error": "Resource not found"}) } diff --git a/handlers/tags_handler.go b/handlers/tags_handler.go index 1585032f7..c69412ed9 100644 --- a/handlers/tags_handler.go +++ b/handlers/tags_handler.go @@ -7,6 +7,7 @@ import ( "github.com/gin-gonic/gin" "github.com/tailwarden/komiser/models" + "github.com/tailwarden/komiser/repository" ) func (handler *ApiHandler) BulkUpdateTagsHandler(c *gin.Context) { @@ -21,7 +22,7 @@ func (handler *ApiHandler) BulkUpdateTagsHandler(c *gin.Context) { resource := models.Resource{Tags: input.Tags} for _, resourceId := range input.Resources { - _, err = handler.repo.HandleQuery(c, "UPDATE_TAGS", &resource, [][3]string{{"id", "=", fmt.Sprint(resourceId)}}) + _, err = handler.repo.HandleQuery(c, repository.UpdateTagsKey, &resource, [][3]string{{"id", "=", fmt.Sprint(resourceId)}}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "error while updating tags"}) return @@ -48,7 +49,7 @@ func (handler *ApiHandler) UpdateTagsHandler(c *gin.Context) { resource := models.Resource{Tags: tags} - _, err = handler.repo.HandleQuery(c, "UPDATE_TAGS", &resource, [][3]string{{"id", "=", fmt.Sprint(resourceId)}}) + _, err = handler.repo.HandleQuery(c, repository.UpdateTagsKey, &resource, [][3]string{{"id", "=", fmt.Sprint(resourceId)}}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "error while updating tags"}) return diff --git a/handlers/views_handler.go b/handlers/views_handler.go index 8b656a0bd..7a77faad1 100644 --- a/handlers/views_handler.go +++ b/handlers/views_handler.go @@ -9,6 +9,7 @@ import ( "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" "github.com/tailwarden/komiser/models" + "github.com/tailwarden/komiser/repository" ) func (handler *ApiHandler) NewViewHandler(c *gin.Context) { @@ -19,7 +20,7 @@ func (handler *ApiHandler) NewViewHandler(c *gin.Context) { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } - result, err := handler.repo.HandleQuery(c, "INSERT", &view, [][3]string{}) + result, err := handler.repo.HandleQuery(c, repository.InsertKey, &view, [][3]string{}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return @@ -38,7 +39,7 @@ func (handler *ApiHandler) NewViewHandler(c *gin.Context) { func (handler *ApiHandler) ListViewsHandler(c *gin.Context) { views := make([]models.View, 0) - _, err := handler.repo.HandleQuery(c, "LIST", &views, [][3]string{}) + _, err := handler.repo.HandleQuery(c, repository.ListKey, &views, [][3]string{}) if err != nil { logrus.WithError(err).Error("scan failed") c.JSON(http.StatusInternalServerError, gin.H{"error": "scan failed"}) @@ -58,7 +59,7 @@ func (handler *ApiHandler) UpdateViewHandler(c *gin.Context) { return } - _, err = handler.repo.HandleQuery(c, "UPDATE_VIEW", &view, [][3]string{{"id", "=", fmt.Sprint(viewId)}}) + _, err = handler.repo.HandleQuery(c, repository.UpdateViewKey, &view, [][3]string{{"id", "=", fmt.Sprint(viewId)}}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return @@ -71,7 +72,7 @@ func (handler *ApiHandler) DeleteViewHandler(c *gin.Context) { viewId := c.Param("id") view := new(models.View) - _, err := handler.repo.HandleQuery(c, "DELETE", view, [][3]string{{"id", "=", fmt.Sprint(viewId)}}) + _, err := handler.repo.HandleQuery(c, repository.DeleteKey, view, [][3]string{{"id", "=", fmt.Sprint(viewId)}}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return @@ -89,7 +90,7 @@ func (handler *ApiHandler) HideResourcesFromViewHandler(c *gin.Context) { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } - _, err = handler.repo.HandleQuery(c, "UPDATE_VIEW_EXCLUDE", &view, [][3]string{{"id", "=", fmt.Sprint(viewId)}}) + _, err = handler.repo.HandleQuery(c, repository.UpdateViewExcludeKey, &view, [][3]string{{"id", "=", fmt.Sprint(viewId)}}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return @@ -107,7 +108,7 @@ func (handler *ApiHandler) UnhideResourcesFromViewHandler(c *gin.Context) { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } - _, err = handler.repo.HandleQuery(c, "UPDATE_VIEW_EXCLUDE", &view, [][3]string{{"id", "=", fmt.Sprint(viewId)}}) + _, err = handler.repo.HandleQuery(c, repository.UpdateViewExcludeKey, &view, [][3]string{{"id", "=", fmt.Sprint(viewId)}}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return @@ -120,7 +121,7 @@ func (handler *ApiHandler) ListHiddenResourcesHandler(c *gin.Context) { viewId := c.Param("id") view := new(models.View) - _, err := handler.repo.HandleQuery(c, "LIST", &view, [][3]string{{"id", "=", fmt.Sprint(viewId)}}) + _, err := handler.repo.HandleQuery(c, repository.ListKey, &view, [][3]string{{"id", "=", fmt.Sprint(viewId)}}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return @@ -131,7 +132,7 @@ func (handler *ApiHandler) ListHiddenResourcesHandler(c *gin.Context) { if len(view.Exclude) > 0 { s, _ := json.Marshal(view.Exclude) - _, err = handler.repo.HandleQuery(c, "LIST", &resources, [][3]string{{"id", "IN", strings.Trim(string(s), "[]")}}) + _, err = handler.repo.HandleQuery(c, repository.ListKey, &resources, [][3]string{{"id", "IN", strings.Trim(string(s), "[]")}}) if err != nil { logrus.WithError(err).Error("scan failed") } @@ -146,7 +147,7 @@ func (handler *ApiHandler) ListViewAlertsHandler(c *gin.Context) { alerts := make([]models.Alert, 0) - _, err := handler.repo.HandleQuery(c, "LIST", &alerts, [][3]string{{"view_id", "=", fmt.Sprint(viewId)}}) + _, err := handler.repo.HandleQuery(c, repository.ListKey, &alerts, [][3]string{{"view_id", "=", fmt.Sprint(viewId)}}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return