From 736b285d74075c2d1c333a9ba10319bbb9c28446 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Apr 2024 13:16:55 +0000 Subject: [PATCH 01/20] chore(deps): bump golang.org/x/net from 0.21.0 to 0.23.0 Bumps [golang.org/x/net](https://github.com/golang/net) from 0.21.0 to 0.23.0. - [Commits](https://github.com/golang/net/compare/v0.21.0...v0.23.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-type: indirect ... Signed-off-by: dependabot[bot] --- go.mod | 8 ++++---- go.sum | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index 3b6b5162e..3dfa91f69 100644 --- a/go.mod +++ b/go.mod @@ -205,12 +205,12 @@ require ( github.com/zeebo/xxh3 v1.0.2 // indirect go.opencensus.io v0.24.0 // indirect golang.org/x/arch v0.3.0 // indirect - golang.org/x/crypto v0.19.0 // indirect + golang.org/x/crypto v0.21.0 // indirect golang.org/x/mod v0.13.0 // indirect - golang.org/x/net v0.21.0 // indirect + golang.org/x/net v0.23.0 // indirect golang.org/x/sync v0.6.0 // indirect - golang.org/x/sys v0.17.0 // indirect - golang.org/x/term v0.17.0 // indirect + golang.org/x/sys v0.18.0 // indirect + golang.org/x/term v0.18.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.14.0 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect diff --git a/go.sum b/go.sum index e63016894..2fd5f9afd 100644 --- a/go.sum +++ b/go.sum @@ -538,8 +538,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= @@ -567,8 +567,8 @@ golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= +golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.17.0 h1:6m3ZPmLEFdVxKKWnKq4VqZ60gutO35zm+zrAHVmHyDQ= golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA= @@ -604,12 +604,12 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U= -golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= +golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= From 98c966e49a1460818096ac653cd3a3d2403c1c44 Mon Sep 17 00:00:00 2001 From: AvineshTripathi Date: Fri, 12 Apr 2024 02:14:50 +0530 Subject: [PATCH 02/20] 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 dcf1826e534b21638e5e9ef62ab51ed163da315f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Apr 2024 23:58:02 +0000 Subject: [PATCH 03/20] chore(deps-dev): bump @storybook/addon-interactions in /dashboard Bumps [@storybook/addon-interactions](https://github.com/storybookjs/storybook/tree/HEAD/code/addons/interactions) from 7.6.17 to 8.0.9. - [Release notes](https://github.com/storybookjs/storybook/releases) - [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md) - [Commits](https://github.com/storybookjs/storybook/commits/v8.0.9/code/addons/interactions) --- updated-dependencies: - dependency-name: "@storybook/addon-interactions" dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- dashboard/package-lock.json | 542 +++++++++++++++++++++++++++++++++--- dashboard/package.json | 2 +- 2 files changed, 504 insertions(+), 40 deletions(-) diff --git a/dashboard/package-lock.json b/dashboard/package-lock.json index 5ce42b847..6e08bf573 100644 --- a/dashboard/package-lock.json +++ b/dashboard/package-lock.json @@ -34,7 +34,7 @@ "@commitlint/config-conventional": "^17.2.0", "@jest/globals": "^29.5.0", "@storybook/addon-essentials": "^8.0.5", - "@storybook/addon-interactions": "^7.6.17", + "@storybook/addon-interactions": "^8.0.9", "@storybook/addon-links": "^8.0.4", "@storybook/addons": "^7.4.6", "@storybook/blocks": "^7.6.4", @@ -5936,14 +5936,15 @@ } }, "node_modules/@storybook/addon-interactions": { - "version": "7.6.17", - "resolved": "https://registry.npmjs.org/@storybook/addon-interactions/-/addon-interactions-7.6.17.tgz", - "integrity": "sha512-6zlX+RDQ1PlA6fp7C+hun8t7h2RXfCGs5dGrhEenp2lqnR/rYuUJRC0tmKpkZBb8kZVcbSChzkB/JYkBjBCzpQ==", + "version": "8.0.9", + "resolved": "https://registry.npmjs.org/@storybook/addon-interactions/-/addon-interactions-8.0.9.tgz", + "integrity": "sha512-AMIdNcyM6DDAWvMitBJMqp1iPZND8AXB4QT4VZHGMKG2ngHNKktriEKpTfcRkfKPGTJs9T+71dWfm6/R4tticw==", "dev": true, "dependencies": { "@storybook/global": "^5.0.0", - "@storybook/types": "7.6.17", - "jest-mock": "^27.0.6", + "@storybook/instrumenter": "8.0.9", + "@storybook/test": "8.0.9", + "@storybook/types": "8.0.9", "polished": "^4.2.2", "ts-dedent": "^2.2.0" }, @@ -5952,42 +5953,62 @@ "url": "https://opencollective.com/storybook" } }, - "node_modules/@storybook/addon-interactions/node_modules/@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "node_modules/@storybook/addon-interactions/node_modules/@storybook/channels": { + "version": "8.0.9", + "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-8.0.9.tgz", + "integrity": "sha512-7Lcfyy5CsLWWGhMPO9WG4jZ/Alzp0AjepFhEreYHRPtQrfttp6qMAjE/g1aHgun0qHCYWxwqIG4NLR/hqDNrXQ==", "dev": true, "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" + "@storybook/client-logger": "8.0.9", + "@storybook/core-events": "8.0.9", + "@storybook/global": "^5.0.0", + "telejson": "^7.2.0", + "tiny-invariant": "^1.3.1" }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" } }, - "node_modules/@storybook/addon-interactions/node_modules/@types/yargs": { - "version": "16.0.5", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.5.tgz", - "integrity": "sha512-AxO/ADJOBFJScHbWhq2xAhlWP24rY4aCEG/NFaMvbT3X2MgRsLjhjQwsn0Zi5zn0LG9jUhCCZMeX9Dkuw6k+vQ==", + "node_modules/@storybook/addon-interactions/node_modules/@storybook/client-logger": { + "version": "8.0.9", + "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-8.0.9.tgz", + "integrity": "sha512-LzV/RHkbf07sRc1Jc0ff36RlapKf9Ul7/+9VMvVbI3hshH1CpmrZK4t/tsIdpX/EVOdJ1Gg5cES06PnleOAIPA==", "dev": true, "dependencies": { - "@types/yargs-parser": "*" + "@storybook/global": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" } }, - "node_modules/@storybook/addon-interactions/node_modules/jest-mock": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", - "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", + "node_modules/@storybook/addon-interactions/node_modules/@storybook/core-events": { + "version": "8.0.9", + "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-8.0.9.tgz", + "integrity": "sha512-DxSUx7wG9Qe3OFUBnv3OrYq48J8UWNo2DUR5/JecJCtp3n++L4fAEW3J0IF5FfxpQDMQSp1yTNjZ2PaWCMd2ag==", "dev": true, "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*" + "ts-dedent": "^2.0.0" }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + } + }, + "node_modules/@storybook/addon-interactions/node_modules/@storybook/types": { + "version": "8.0.9", + "resolved": "https://registry.npmjs.org/@storybook/types/-/types-8.0.9.tgz", + "integrity": "sha512-ew0EXzk9k4B557P1qIWYrnvUcgaE0WWA5qQS0AU8l+fRTp5nvl9O3SP/zNIB0SN1qDFO7dXr3idTNTyIikTcEQ==", + "dev": true, + "dependencies": { + "@storybook/channels": "8.0.9", + "@types/express": "^4.7.0", + "file-system-cache": "2.3.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" } }, "node_modules/@storybook/addon-links": { @@ -7912,9 +7933,9 @@ } }, "node_modules/@storybook/csf": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@storybook/csf/-/csf-0.1.2.tgz", - "integrity": "sha512-ePrvE/pS1vsKR9Xr+o+YwdqNgHUyXvg+1Xjx0h9LrVx7Zq4zNe06pd63F5EvzTbCbJsHj7GHr9tkiaqm7U8WRA==", + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@storybook/csf/-/csf-0.1.4.tgz", + "integrity": "sha512-B9UI/lsQMjF+oEfZCI6YXNoeuBcGZoOP5x8yKbe2tIEmsMjSztFKkpPzi5nLCnBk/MBtl6QJeI3ksJnbsWPkOw==", "dev": true, "dependencies": { "type-fest": "^2.19.0" @@ -8196,6 +8217,109 @@ "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/@storybook/instrumenter": { + "version": "8.0.9", + "resolved": "https://registry.npmjs.org/@storybook/instrumenter/-/instrumenter-8.0.9.tgz", + "integrity": "sha512-Gw74dgpTU/2p7FG0s7DuVdqCbJ2MEcSuRJjDo7HcXRYcvWp7I6Ly+C0v7N5VaoS+kbBVerAhLKIHZgG/LZf1og==", + "dev": true, + "dependencies": { + "@storybook/channels": "8.0.9", + "@storybook/client-logger": "8.0.9", + "@storybook/core-events": "8.0.9", + "@storybook/global": "^5.0.0", + "@storybook/preview-api": "8.0.9", + "@vitest/utils": "^1.3.1", + "util": "^0.12.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + } + }, + "node_modules/@storybook/instrumenter/node_modules/@storybook/channels": { + "version": "8.0.9", + "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-8.0.9.tgz", + "integrity": "sha512-7Lcfyy5CsLWWGhMPO9WG4jZ/Alzp0AjepFhEreYHRPtQrfttp6qMAjE/g1aHgun0qHCYWxwqIG4NLR/hqDNrXQ==", + "dev": true, + "dependencies": { + "@storybook/client-logger": "8.0.9", + "@storybook/core-events": "8.0.9", + "@storybook/global": "^5.0.0", + "telejson": "^7.2.0", + "tiny-invariant": "^1.3.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + } + }, + "node_modules/@storybook/instrumenter/node_modules/@storybook/client-logger": { + "version": "8.0.9", + "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-8.0.9.tgz", + "integrity": "sha512-LzV/RHkbf07sRc1Jc0ff36RlapKf9Ul7/+9VMvVbI3hshH1CpmrZK4t/tsIdpX/EVOdJ1Gg5cES06PnleOAIPA==", + "dev": true, + "dependencies": { + "@storybook/global": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + } + }, + "node_modules/@storybook/instrumenter/node_modules/@storybook/core-events": { + "version": "8.0.9", + "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-8.0.9.tgz", + "integrity": "sha512-DxSUx7wG9Qe3OFUBnv3OrYq48J8UWNo2DUR5/JecJCtp3n++L4fAEW3J0IF5FfxpQDMQSp1yTNjZ2PaWCMd2ag==", + "dev": true, + "dependencies": { + "ts-dedent": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + } + }, + "node_modules/@storybook/instrumenter/node_modules/@storybook/preview-api": { + "version": "8.0.9", + "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-8.0.9.tgz", + "integrity": "sha512-zHfX34bkAMzzmE7vbDzaqFwSW6ExiBD0HiO1L/IsHF55f0f7xV7IH8uJyFRrDTvAoW3ReSxZDMvvPpeydFPKGA==", + "dev": true, + "dependencies": { + "@storybook/channels": "8.0.9", + "@storybook/client-logger": "8.0.9", + "@storybook/core-events": "8.0.9", + "@storybook/csf": "^0.1.4", + "@storybook/global": "^5.0.0", + "@storybook/types": "8.0.9", + "@types/qs": "^6.9.5", + "dequal": "^2.0.2", + "lodash": "^4.17.21", + "memoizerific": "^1.11.3", + "qs": "^6.10.0", + "tiny-invariant": "^1.3.1", + "ts-dedent": "^2.0.0", + "util-deprecate": "^1.0.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + } + }, + "node_modules/@storybook/instrumenter/node_modules/@storybook/types": { + "version": "8.0.9", + "resolved": "https://registry.npmjs.org/@storybook/types/-/types-8.0.9.tgz", + "integrity": "sha512-ew0EXzk9k4B557P1qIWYrnvUcgaE0WWA5qQS0AU8l+fRTp5nvl9O3SP/zNIB0SN1qDFO7dXr3idTNTyIikTcEQ==", + "dev": true, + "dependencies": { + "@storybook/channels": "8.0.9", + "@types/express": "^4.7.0", + "file-system-cache": "2.3.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + } + }, "node_modules/@storybook/manager": { "version": "7.4.5", "resolved": "https://registry.npmjs.org/@storybook/manager/-/manager-7.4.5.tgz", @@ -9010,6 +9134,112 @@ "integrity": "sha512-piPoDozdPaX1hNWFJQzzgWqE40gh986VvVx/QO9RU4qYRE55ld7iepDVgZ3ccGUw0R4wge0Oy1dd+3xOQNkkUQ==", "dev": true }, + "node_modules/@storybook/test": { + "version": "8.0.9", + "resolved": "https://registry.npmjs.org/@storybook/test/-/test-8.0.9.tgz", + "integrity": "sha512-bRd5tBJnPzR6UKbDXONWnFWtdkNOY99HMLDUWe5fTRo50GwkrpFBVqPflhdkruEeof0kAbBUbnoN2CIYgtnAFw==", + "dev": true, + "dependencies": { + "@storybook/client-logger": "8.0.9", + "@storybook/core-events": "8.0.9", + "@storybook/instrumenter": "8.0.9", + "@storybook/preview-api": "8.0.9", + "@testing-library/dom": "^9.3.4", + "@testing-library/jest-dom": "^6.4.2", + "@testing-library/user-event": "^14.5.2", + "@vitest/expect": "1.3.1", + "@vitest/spy": "^1.3.1", + "util": "^0.12.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + } + }, + "node_modules/@storybook/test/node_modules/@storybook/channels": { + "version": "8.0.9", + "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-8.0.9.tgz", + "integrity": "sha512-7Lcfyy5CsLWWGhMPO9WG4jZ/Alzp0AjepFhEreYHRPtQrfttp6qMAjE/g1aHgun0qHCYWxwqIG4NLR/hqDNrXQ==", + "dev": true, + "dependencies": { + "@storybook/client-logger": "8.0.9", + "@storybook/core-events": "8.0.9", + "@storybook/global": "^5.0.0", + "telejson": "^7.2.0", + "tiny-invariant": "^1.3.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + } + }, + "node_modules/@storybook/test/node_modules/@storybook/client-logger": { + "version": "8.0.9", + "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-8.0.9.tgz", + "integrity": "sha512-LzV/RHkbf07sRc1Jc0ff36RlapKf9Ul7/+9VMvVbI3hshH1CpmrZK4t/tsIdpX/EVOdJ1Gg5cES06PnleOAIPA==", + "dev": true, + "dependencies": { + "@storybook/global": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + } + }, + "node_modules/@storybook/test/node_modules/@storybook/core-events": { + "version": "8.0.9", + "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-8.0.9.tgz", + "integrity": "sha512-DxSUx7wG9Qe3OFUBnv3OrYq48J8UWNo2DUR5/JecJCtp3n++L4fAEW3J0IF5FfxpQDMQSp1yTNjZ2PaWCMd2ag==", + "dev": true, + "dependencies": { + "ts-dedent": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + } + }, + "node_modules/@storybook/test/node_modules/@storybook/preview-api": { + "version": "8.0.9", + "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-8.0.9.tgz", + "integrity": "sha512-zHfX34bkAMzzmE7vbDzaqFwSW6ExiBD0HiO1L/IsHF55f0f7xV7IH8uJyFRrDTvAoW3ReSxZDMvvPpeydFPKGA==", + "dev": true, + "dependencies": { + "@storybook/channels": "8.0.9", + "@storybook/client-logger": "8.0.9", + "@storybook/core-events": "8.0.9", + "@storybook/csf": "^0.1.4", + "@storybook/global": "^5.0.0", + "@storybook/types": "8.0.9", + "@types/qs": "^6.9.5", + "dequal": "^2.0.2", + "lodash": "^4.17.21", + "memoizerific": "^1.11.3", + "qs": "^6.10.0", + "tiny-invariant": "^1.3.1", + "ts-dedent": "^2.0.0", + "util-deprecate": "^1.0.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + } + }, + "node_modules/@storybook/test/node_modules/@storybook/types": { + "version": "8.0.9", + "resolved": "https://registry.npmjs.org/@storybook/types/-/types-8.0.9.tgz", + "integrity": "sha512-ew0EXzk9k4B557P1qIWYrnvUcgaE0WWA5qQS0AU8l+fRTp5nvl9O3SP/zNIB0SN1qDFO7dXr3idTNTyIikTcEQ==", + "dev": true, + "dependencies": { + "@storybook/channels": "8.0.9", + "@types/express": "^4.7.0", + "file-system-cache": "2.3.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + } + }, "node_modules/@storybook/testing-library": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/@storybook/testing-library/-/testing-library-0.2.2.tgz", @@ -9156,9 +9386,9 @@ } }, "node_modules/@testing-library/dom": { - "version": "9.3.3", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.3.3.tgz", - "integrity": "sha512-fB0R+fa3AUqbLHWyxXa2kGVtf1Fe1ZZFr0Zp6AIbIAzXb2mKbEXl+PCQNUOaq5lbTab5tfctfXRNsWXxa2f7Aw==", + "version": "9.3.4", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.3.4.tgz", + "integrity": "sha512-FlS4ZWlp97iiNWig0Muq8p+3rVDjRiYE+YKGbAqXOu9nwJFFOdL00kFpz42M+4huzYi86vAK1sOOfyOG45muIQ==", "dev": true, "dependencies": { "@babel/code-frame": "^7.10.4", @@ -9257,9 +9487,9 @@ } }, "node_modules/@testing-library/user-event": { - "version": "14.5.1", - "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.5.1.tgz", - "integrity": "sha512-UCcUKrUYGj7ClomOo2SpNVvx4/fkd/2BbIHDCle8A0ax+P3bU7yJwDBDrS6ZwdTMARWTGODX1hEsCcO+7beJjg==", + "version": "14.5.2", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.5.2.tgz", + "integrity": "sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ==", "dev": true, "engines": { "node": ">=12", @@ -10021,6 +10251,138 @@ "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", "dev": true }, + "node_modules/@vitest/expect": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.3.1.tgz", + "integrity": "sha512-xofQFwIzfdmLLlHa6ag0dPV8YsnKOCP1KdAeVVh34vSjN2dcUiXYCD9htu/9eM7t8Xln4v03U9HLxLpPlsXdZw==", + "dev": true, + "dependencies": { + "@vitest/spy": "1.3.1", + "@vitest/utils": "1.3.1", + "chai": "^4.3.10" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/expect/node_modules/@vitest/spy": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.3.1.tgz", + "integrity": "sha512-xAcW+S099ylC9VLU7eZfdT9myV67Nor9w9zhf0mGCYJSO+zM2839tOeROTdikOi/8Qeusffvxb/MyBSOja1Uig==", + "dev": true, + "dependencies": { + "tinyspy": "^2.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/expect/node_modules/@vitest/utils": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.3.1.tgz", + "integrity": "sha512-d3Waie/299qqRyHTm2DjADeTaNdNSVsnwHPWrs20JMpjh6eiVq7ggggweO8rc4arhf6rRkWuHKwvxGvejUXZZQ==", + "dev": true, + "dependencies": { + "diff-sequences": "^29.6.3", + "estree-walker": "^3.0.3", + "loupe": "^2.3.7", + "pretty-format": "^29.7.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/expect/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@vitest/expect/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@vitest/expect/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/@vitest/spy": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.5.0.tgz", + "integrity": "sha512-vu6vi6ew5N5MMHJjD5PoakMRKYdmIrNJmyfkhRpQt5d9Ewhw9nZ5Aqynbi3N61bvk9UvZ5UysMT6ayIrZ8GA9w==", + "dev": true, + "dependencies": { + "tinyspy": "^2.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.5.0.tgz", + "integrity": "sha512-BDU0GNL8MWkRkSRdNFvCUCAVOeHaUlVJ9Tx0TYBZyXaaOTmGtUFObzchCivIBrIwKzvZA7A9sCejVhXM2aY98A==", + "dev": true, + "dependencies": { + "diff-sequences": "^29.6.3", + "estree-walker": "^3.0.3", + "loupe": "^2.3.7", + "pretty-format": "^29.7.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@vitest/utils/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@vitest/utils/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, "node_modules/@webassemblyjs/ast": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", @@ -10727,6 +11089,15 @@ "util": "^0.12.5" } }, + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/ast-types": { "version": "0.14.2", "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.14.2.tgz", @@ -11792,6 +12163,24 @@ "node": ">=4" } }, + "node_modules/chai": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", + "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", + "dev": true, + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", + "pathval": "^1.1.1", + "type-detect": "^4.0.8" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -11828,6 +12217,18 @@ "pnpm": ">=7" } }, + "node_modules/check-error": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.2" + }, + "engines": { + "node": "*" + } + }, "node_modules/chokidar": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", @@ -12929,6 +13330,18 @@ "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", "dev": true }, + "node_modules/deep-eql": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", + "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", + "dev": true, + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/deep-equal": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.2.tgz", @@ -14529,6 +14942,21 @@ "node": ">=8.3.0" } }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/estree-walker/node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", @@ -15323,6 +15751,15 @@ "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/get-intrinsic": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", @@ -18471,6 +18908,15 @@ "loose-envify": "cli.js" } }, + "node_modules/loupe": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.1" + } + }, "node_modules/lower-case": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", @@ -19588,6 +20034,15 @@ "integrity": "sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q==", "dev": true }, + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/pbkdf2": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", @@ -22821,6 +23276,15 @@ "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", "dev": true }, + "node_modules/tinyspy": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz", + "integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==", + "dev": true, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/tippy.js": { "version": "6.3.7", "resolved": "https://registry.npmjs.org/tippy.js/-/tippy.js-6.3.7.tgz", diff --git a/dashboard/package.json b/dashboard/package.json index f7ba31bae..91cae4f6f 100644 --- a/dashboard/package.json +++ b/dashboard/package.json @@ -44,7 +44,7 @@ "@commitlint/config-conventional": "^17.2.0", "@jest/globals": "^29.5.0", "@storybook/addon-essentials": "^8.0.5", - "@storybook/addon-interactions": "^7.6.17", + "@storybook/addon-interactions": "^8.0.9", "@storybook/addon-links": "^8.0.4", "@storybook/addons": "^7.4.6", "@storybook/blocks": "^7.6.4", From a2118efa2730eff01511c185b71bfd47680f244b Mon Sep 17 00:00:00 2001 From: AvineshTripathi Date: Thu, 25 Apr 2024 03:06:02 +0530 Subject: [PATCH 04/20] 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 05/20] 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 06/20] 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 07/20] 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 08/20] 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 09/20] 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 10/20] 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 11/20] 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 12/20] 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 13/20] 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 14/20] 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 15/20] 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 b530817128c23a4753d7e43b51d827ca846b622e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Apr 2024 23:30:35 +0000 Subject: [PATCH 16/20] chore(deps-dev): bump @commitlint/cli in /dashboard Bumps [@commitlint/cli](https://github.com/conventional-changelog/commitlint/tree/HEAD/@commitlint/cli) from 19.2.1 to 19.3.0. - [Release notes](https://github.com/conventional-changelog/commitlint/releases) - [Changelog](https://github.com/conventional-changelog/commitlint/blob/master/@commitlint/cli/CHANGELOG.md) - [Commits](https://github.com/conventional-changelog/commitlint/commits/v19.3.0/@commitlint/cli) --- updated-dependencies: - dependency-name: "@commitlint/cli" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- dashboard/package-lock.json | 32 ++++++++++++++++---------------- dashboard/package.json | 2 +- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/dashboard/package-lock.json b/dashboard/package-lock.json index 6e08bf573..8a63beef6 100644 --- a/dashboard/package-lock.json +++ b/dashboard/package-lock.json @@ -30,7 +30,7 @@ "typescript": "5.2.2" }, "devDependencies": { - "@commitlint/cli": "^19.2.1", + "@commitlint/cli": "^19.3.0", "@commitlint/config-conventional": "^17.2.0", "@jest/globals": "^29.5.0", "@storybook/addon-essentials": "^8.0.5", @@ -2387,13 +2387,13 @@ } }, "node_modules/@commitlint/cli": { - "version": "19.2.1", - "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-19.2.1.tgz", - "integrity": "sha512-cbkYUJsLqRomccNxvoJTyv5yn0bSy05BBizVyIcLACkRbVUqYorC351Diw/XFSWC/GtpwiwT2eOvQgFZa374bg==", + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-19.3.0.tgz", + "integrity": "sha512-LgYWOwuDR7BSTQ9OLZ12m7F/qhNY+NpAyPBgo4YNMkACE7lGuUnuQq1yi9hz1KA4+3VqpOYl8H1rY/LYK43v7g==", "dev": true, "dependencies": { - "@commitlint/format": "^19.0.3", - "@commitlint/lint": "^19.1.0", + "@commitlint/format": "^19.3.0", + "@commitlint/lint": "^19.2.2", "@commitlint/load": "^19.2.0", "@commitlint/read": "^19.2.1", "@commitlint/types": "^19.0.3", @@ -2593,9 +2593,9 @@ } }, "node_modules/@commitlint/format": { - "version": "19.0.3", - "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-19.0.3.tgz", - "integrity": "sha512-QjjyGyoiVWzx1f5xOteKHNLFyhyweVifMgopozSgx1fGNrGV8+wp7k6n1t6StHdJ6maQJ+UUtO2TcEiBFRyR6Q==", + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-19.3.0.tgz", + "integrity": "sha512-luguk5/aF68HiF4H23ACAfk8qS8AHxl4LLN5oxPc24H+2+JRPsNr1OS3Gaea0CrH7PKhArBMKBz5RX9sA5NtTg==", "dev": true, "dependencies": { "@commitlint/types": "^19.0.3", @@ -2618,9 +2618,9 @@ } }, "node_modules/@commitlint/is-ignored": { - "version": "19.0.3", - "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-19.0.3.tgz", - "integrity": "sha512-MqDrxJaRSVSzCbPsV6iOKG/Lt52Y+PVwFVexqImmYYFhe51iVJjK2hRhOG2jUAGiUHk4jpdFr0cZPzcBkSzXDQ==", + "version": "19.2.2", + "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-19.2.2.tgz", + "integrity": "sha512-eNX54oXMVxncORywF4ZPFtJoBm3Tvp111tg1xf4zWXGfhBPKpfKG6R+G3G4v5CPlRROXpAOpQ3HMhA9n1Tck1g==", "dev": true, "dependencies": { "@commitlint/types": "^19.0.3", @@ -2631,12 +2631,12 @@ } }, "node_modules/@commitlint/lint": { - "version": "19.1.0", - "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-19.1.0.tgz", - "integrity": "sha512-ESjaBmL/9cxm+eePyEr6SFlBUIYlYpI80n+Ltm7IA3MAcrmiP05UMhJdAD66sO8jvo8O4xdGn/1Mt2G5VzfZKw==", + "version": "19.2.2", + "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-19.2.2.tgz", + "integrity": "sha512-xrzMmz4JqwGyKQKTpFzlN0dx0TAiT7Ran1fqEBgEmEj+PU98crOFtysJgY+QdeSagx6EDRigQIXJVnfrI0ratA==", "dev": true, "dependencies": { - "@commitlint/is-ignored": "^19.0.3", + "@commitlint/is-ignored": "^19.2.2", "@commitlint/parse": "^19.0.3", "@commitlint/rules": "^19.0.3", "@commitlint/types": "^19.0.3" diff --git a/dashboard/package.json b/dashboard/package.json index 91cae4f6f..1d24fada1 100644 --- a/dashboard/package.json +++ b/dashboard/package.json @@ -40,7 +40,7 @@ "typescript": "5.2.2" }, "devDependencies": { - "@commitlint/cli": "^19.2.1", + "@commitlint/cli": "^19.3.0", "@commitlint/config-conventional": "^17.2.0", "@jest/globals": "^29.5.0", "@storybook/addon-essentials": "^8.0.5", From 76bdb3b733ab55af4ab0f5af539ca70e0fa133f9 Mon Sep 17 00:00:00 2001 From: Azanul Date: Thu, 2 May 2024 11:03:46 +0530 Subject: [PATCH 17/20] 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 18/20] 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 19/20] 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 From d975a5b63d1b15a6a0e0a7fe1059701eb3c7861c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 2 May 2024 13:32:19 +0000 Subject: [PATCH 20/20] chore(deps-dev): bump ejs from 3.1.9 to 3.1.10 in /dashboard Bumps [ejs](https://github.com/mde/ejs) from 3.1.9 to 3.1.10. - [Release notes](https://github.com/mde/ejs/releases) - [Commits](https://github.com/mde/ejs/compare/v3.1.9...v3.1.10) --- updated-dependencies: - dependency-name: ejs dependency-type: indirect ... Signed-off-by: dependabot[bot] --- dashboard/package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dashboard/package-lock.json b/dashboard/package-lock.json index 6e08bf573..e6f03d6c2 100644 --- a/dashboard/package-lock.json +++ b/dashboard/package-lock.json @@ -13859,9 +13859,9 @@ "dev": true }, "node_modules/ejs": { - "version": "3.1.9", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz", - "integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==", + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", "dev": true, "dependencies": { "jake": "^10.8.5"