diff --git a/kubewatch/env_gen.json b/kubewatch/env_gen.json index 7e6863b42..045a01b12 100644 --- a/kubewatch/env_gen.json +++ b/kubewatch/env_gen.json @@ -1 +1 @@ -[{"Category":"ARGOCD_INFORMER","Fields":[{"Env":"ACD_INFORMER","EnvType":"bool","EnvValue":"true","EnvDescription":"Used to determine whether ArgoCD informer is enabled or not","Example":"","Deprecated":"false"},{"Env":"ACD_NAMESPACE","EnvType":"string","EnvValue":"devtroncd","EnvDescription":"Namespace where all the ArgoCD application objects are published. For multi-cluster mode, it will be set to v1.NamespaceAll","Example":"","Deprecated":"false"}]},{"Category":"CD_ARGO_WORKFLOW","Fields":[{"Env":"CD_DEFAULT_NAMESPACE","EnvType":"string","EnvValue":"devtron-cd","EnvDescription":"Namespace where all CD workflows objects are scheduled. For multi-cluster mode, it will be set to v1.NamespaceAll","Example":"","Deprecated":"false"},{"Env":"CD_INFORMER","EnvType":"bool","EnvValue":"true","EnvDescription":"Used to determine whether CD informer is enabled or not","Example":"","Deprecated":"false"}]},{"Category":"CI_ARGO_WORKFLOW","Fields":[{"Env":"CI_INFORMER","EnvType":"bool","EnvValue":"true","EnvDescription":"Used to determine whether CI informer is enabled or not","Example":"","Deprecated":"false"},{"Env":"DEFAULT_NAMESPACE","EnvType":"string","EnvValue":"devtron-ci","EnvDescription":"Namespace where all CI workflows objects are scheduled. For multi-cluster mode, it will be set to v1.NamespaceAll","Example":"","Deprecated":"false"}]},{"Category":"CLUSTER_MODE","Fields":[{"Env":"CLUSTER_ARGO_CD_TYPE","EnvType":"string","EnvValue":"IN_CLUSTER","EnvDescription":"Determines cluster mode for ArgoCD informer; for multiple cluster mode, it will be set to ALL_CLUSTER; for single cluster mode, it will be set to IN_CLUSTER","Example":"","Deprecated":"false"},{"Env":"CLUSTER_CD_ARGO_WF_TYPE","EnvType":"string","EnvValue":"IN_CLUSTER","EnvDescription":"Determines cluster mode for CD ArgoWorkflow informer; for multiple cluster mode, it will be set to ALL_CLUSTER; for single cluster mode, it will be set to IN_CLUSTER","Example":"","Deprecated":"false"},{"Env":"CLUSTER_CI_ARGO_WF_TYPE","EnvType":"string","EnvValue":"IN_CLUSTER","EnvDescription":"Determines cluster mode for CI ArgoWorkflow informer; for multiple cluster mode, it will be set to ALL_CLUSTER; for single cluster mode, it will be set to IN_CLUSTER","Example":"","Deprecated":"false"},{"Env":"CLUSTER_TYPE","EnvType":"string","EnvValue":"IN_CLUSTER","EnvDescription":"Determines cluster mode for System Executor informer; for multiple cluster mode, it will be set to ALL_CLUSTER; for single cluster mode, it will be set to IN_CLUSTER","Example":"","Deprecated":"false"}]},{"Category":"DEVTRON","Fields":[{"Env":"APP","EnvType":"string","EnvValue":"kubewatch","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"CONSUMER_CONFIG_JSON","EnvType":"string","EnvValue":"","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"DEFAULT_LOG_TIME_LIMIT","EnvType":"int64","EnvValue":"1","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"ENABLE_STATSVIZ","EnvType":"bool","EnvValue":"false","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"K8s_CLIENT_MAX_IDLE_CONNS_PER_HOST","EnvType":"int","EnvValue":"25","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"K8s_TCP_IDLE_CONN_TIMEOUT","EnvType":"int","EnvValue":"300","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"K8s_TCP_KEEPALIVE","EnvType":"int","EnvValue":"30","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"K8s_TCP_TIMEOUT","EnvType":"int","EnvValue":"30","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"K8s_TLS_HANDSHAKE_TIMEOUT","EnvType":"int","EnvValue":"10","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"LOG_LEVEL","EnvType":"int","EnvValue":"-1","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"NATS_MSG_ACK_WAIT_IN_SECS","EnvType":"int","EnvValue":"120","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"NATS_MSG_BUFFER_SIZE","EnvType":"int","EnvValue":"-1","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"NATS_MSG_MAX_AGE","EnvType":"int","EnvValue":"86400","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"NATS_MSG_PROCESSING_BATCH_SIZE","EnvType":"int","EnvValue":"1","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"NATS_MSG_REPLICAS","EnvType":"int","EnvValue":"0","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"NATS_SERVER_HOST","EnvType":"string","EnvValue":"nats://devtron-nats.devtroncd:4222","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_ADDR","EnvType":"string","EnvValue":"127.0.0.1","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_DATABASE","EnvType":"string","EnvValue":"orchestrator","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_EXPORT_PROM_METRICS","EnvType":"bool","EnvValue":"true","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_LOG_ALL_FAILURE_QUERIES","EnvType":"bool","EnvValue":"true","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_LOG_ALL_QUERY","EnvType":"bool","EnvValue":"false","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_LOG_SLOW_QUERY","EnvType":"bool","EnvValue":"true","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_PASSWORD","EnvType":"string","EnvValue":"","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_PORT","EnvType":"string","EnvValue":"5432","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_QUERY_DUR_THRESHOLD","EnvType":"int64","EnvValue":"5000","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_USER","EnvType":"string","EnvValue":"","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"RUNTIME_CONFIG_LOCAL_DEV","EnvType":"LocalDevMode","EnvValue":"false","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"STREAM_CONFIG_JSON","EnvType":"string","EnvValue":"","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"USE_CUSTOM_HTTP_TRANSPORT","EnvType":"bool","EnvValue":"false","EnvDescription":"","Example":"","Deprecated":"false"}]},{"Category":"EXTERNAL_KUBEWATCH","Fields":[{"Env":"CD_EXTERNAL_LISTENER_URL","EnvType":"string","EnvValue":"http://devtroncd-orchestrator-service-prod.devtroncd:80","EnvDescription":"URL of the orchestrator","Example":"","Deprecated":"false"},{"Env":"CD_EXTERNAL_NAMESPACE","EnvType":"string","EnvValue":"","EnvDescription":"Namespace where the external kubewatch is set up","Example":"","Deprecated":"false"},{"Env":"CD_EXTERNAL_ORCHESTRATOR_TOKEN","EnvType":"string","EnvValue":"","EnvDescription":"Token used to authenticate with the orchestrator","Example":"","Deprecated":"false"},{"Env":"CD_EXTERNAL_REST_LISTENER","EnvType":"bool","EnvValue":"false","EnvDescription":"Used to determine whether it's an external kubewatch or internal kubewatch","Example":"","Deprecated":"false"}]},{"Category":"GRACEFUL_SHUTDOWN","Fields":[{"Env":"SLEEP_TIMEOUT","EnvType":"int","EnvValue":"5","EnvDescription":"Graceful shutdown timeout in seconds","Example":"","Deprecated":"false"}]}] \ No newline at end of file +[{"Category":"ARGOCD_INFORMER","Fields":[{"Env":"ACD_INFORMER","EnvType":"bool","EnvValue":"true","EnvDescription":"Used to determine whether ArgoCD informer is enabled or not","Example":"","Deprecated":"false"},{"Env":"ACD_NAMESPACE","EnvType":"string","EnvValue":"devtroncd","EnvDescription":"Namespace where all the ArgoCD application objects are published. For multi-cluster mode, it will be set to v1.NamespaceAll","Example":"","Deprecated":"false"}]},{"Category":"CD_ARGO_WORKFLOW","Fields":[{"Env":"CD_DEFAULT_NAMESPACE","EnvType":"string","EnvValue":"devtron-cd","EnvDescription":"Namespace where all CD workflows objects are scheduled. For multi-cluster mode, it will be set to v1.NamespaceAll","Example":"","Deprecated":"false"},{"Env":"CD_INFORMER","EnvType":"bool","EnvValue":"true","EnvDescription":"Used to determine whether CD informer is enabled or not","Example":"","Deprecated":"false"}]},{"Category":"CI_ARGO_WORKFLOW","Fields":[{"Env":"CI_INFORMER","EnvType":"bool","EnvValue":"true","EnvDescription":"Used to determine whether CI informer is enabled or not","Example":"","Deprecated":"false"},{"Env":"DEFAULT_NAMESPACE","EnvType":"string","EnvValue":"devtron-ci","EnvDescription":"Namespace where all CI workflows objects are scheduled. For multi-cluster mode, it will be set to v1.NamespaceAll","Example":"","Deprecated":"false"}]},{"Category":"CLUSTER_MODE","Fields":[{"Env":"CLUSTER_ARGO_CD_TYPE","EnvType":"string","EnvValue":"IN_CLUSTER","EnvDescription":"Determines cluster mode for ArgoCD informer; for multiple cluster mode, it will be set to ALL_CLUSTER; for single cluster mode, it will be set to IN_CLUSTER","Example":"","Deprecated":"false"},{"Env":"CLUSTER_CD_ARGO_WF_TYPE","EnvType":"string","EnvValue":"IN_CLUSTER","EnvDescription":"Determines cluster mode for CD ArgoWorkflow informer; for multiple cluster mode, it will be set to ALL_CLUSTER; for single cluster mode, it will be set to IN_CLUSTER","Example":"","Deprecated":"false"},{"Env":"CLUSTER_CI_ARGO_WF_TYPE","EnvType":"string","EnvValue":"IN_CLUSTER","EnvDescription":"Determines cluster mode for CI ArgoWorkflow informer; for multiple cluster mode, it will be set to ALL_CLUSTER; for single cluster mode, it will be set to IN_CLUSTER","Example":"","Deprecated":"false"},{"Env":"CLUSTER_TYPE","EnvType":"string","EnvValue":"IN_CLUSTER","EnvDescription":"Determines cluster mode for System Executor informer; for multiple cluster mode, it will be set to ALL_CLUSTER; for single cluster mode, it will be set to IN_CLUSTER","Example":"","Deprecated":"false"}]},{"Category":"DEVTRON","Fields":[{"Env":"APP","EnvType":"string","EnvValue":"kubewatch","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"CONSUMER_CONFIG_JSON","EnvType":"string","EnvValue":"","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"DEFAULT_LOG_TIME_LIMIT","EnvType":"int64","EnvValue":"1","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"ENABLE_STATSVIZ","EnvType":"bool","EnvValue":"false","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"K8s_CLIENT_MAX_IDLE_CONNS_PER_HOST","EnvType":"int","EnvValue":"25","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"K8s_TCP_IDLE_CONN_TIMEOUT","EnvType":"int","EnvValue":"300","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"K8s_TCP_KEEPALIVE","EnvType":"int","EnvValue":"30","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"K8s_TCP_TIMEOUT","EnvType":"int","EnvValue":"30","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"K8s_TLS_HANDSHAKE_TIMEOUT","EnvType":"int","EnvValue":"10","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"LOG_LEVEL","EnvType":"int","EnvValue":"-1","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"NATS_MSG_ACK_WAIT_IN_SECS","EnvType":"int","EnvValue":"120","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"NATS_MSG_BUFFER_SIZE","EnvType":"int","EnvValue":"-1","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"NATS_MSG_MAX_AGE","EnvType":"int","EnvValue":"86400","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"NATS_MSG_PROCESSING_BATCH_SIZE","EnvType":"int","EnvValue":"1","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"NATS_MSG_REPLICAS","EnvType":"int","EnvValue":"0","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"NATS_SERVER_HOST","EnvType":"string","EnvValue":"nats://devtron-nats.devtroncd:4222","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_ADDR","EnvType":"string","EnvValue":"127.0.0.1","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_DATABASE","EnvType":"string","EnvValue":"orchestrator","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_EXPORT_PROM_METRICS","EnvType":"bool","EnvValue":"true","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_LOG_ALL_FAILURE_QUERIES","EnvType":"bool","EnvValue":"true","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_LOG_ALL_QUERY","EnvType":"bool","EnvValue":"false","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_LOG_SLOW_QUERY","EnvType":"bool","EnvValue":"true","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_PASSWORD","EnvType":"string","EnvValue":"","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_PORT","EnvType":"string","EnvValue":"5432","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_QUERY_DUR_THRESHOLD","EnvType":"int64","EnvValue":"5000","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_USER","EnvType":"string","EnvValue":"","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"RUNTIME_CONFIG_LOCAL_DEV","EnvType":"bool","EnvValue":"false","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"STREAM_CONFIG_JSON","EnvType":"string","EnvValue":"","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"USE_CUSTOM_HTTP_TRANSPORT","EnvType":"bool","EnvValue":"false","EnvDescription":"","Example":"","Deprecated":"false"}]},{"Category":"EXTERNAL_KUBEWATCH","Fields":[{"Env":"CD_EXTERNAL_LISTENER_URL","EnvType":"string","EnvValue":"http://devtroncd-orchestrator-service-prod.devtroncd:80","EnvDescription":"URL of the orchestrator","Example":"","Deprecated":"false"},{"Env":"CD_EXTERNAL_NAMESPACE","EnvType":"string","EnvValue":"","EnvDescription":"Namespace where the external kubewatch is set up","Example":"","Deprecated":"false"},{"Env":"CD_EXTERNAL_ORCHESTRATOR_TOKEN","EnvType":"string","EnvValue":"","EnvDescription":"Token used to authenticate with the orchestrator","Example":"","Deprecated":"false"},{"Env":"CD_EXTERNAL_REST_LISTENER","EnvType":"bool","EnvValue":"false","EnvDescription":"Used to determine whether it's an external kubewatch or internal kubewatch","Example":"","Deprecated":"false"}]},{"Category":"GRACEFUL_SHUTDOWN","Fields":[{"Env":"SLEEP_TIMEOUT","EnvType":"int","EnvValue":"5","EnvDescription":"Graceful shutdown timeout in seconds","Example":"","Deprecated":"false"}]},{"Category":"POSTGRES","Fields":[{"Env":"CASBIN_DATABASE","EnvType":"string","EnvValue":"casbin","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_READ_TIMEOUT","EnvType":"int64","EnvValue":"30","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_WRITE_TIMEOUT","EnvType":"int64","EnvValue":"30","EnvDescription":"","Example":"","Deprecated":"false"}]}] \ No newline at end of file diff --git a/kubewatch/env_gen.md b/kubewatch/env_gen.md index d766b2e9e..babb43804 100644 --- a/kubewatch/env_gen.md +++ b/kubewatch/env_gen.md @@ -59,7 +59,7 @@ | PG_PORT | string |5432 | | | false | | PG_QUERY_DUR_THRESHOLD | int64 |5000 | | | false | | PG_USER | string | | | | false | - | RUNTIME_CONFIG_LOCAL_DEV | LocalDevMode |false | | | false | + | RUNTIME_CONFIG_LOCAL_DEV | bool |false | | | false | | STREAM_CONFIG_JSON | string | | | | false | | USE_CUSTOM_HTTP_TRANSPORT | bool |false | | | false | @@ -78,3 +78,11 @@ |-------|----------|-------------------|-------------------|-----------------------|------------------| | SLEEP_TIMEOUT | int |5 | Graceful shutdown timeout in seconds | | false | + +## POSTGRES Related Environment Variables +| Key | Type | Default Value | Description | Example | Deprecated | +|-------|----------|-------------------|-------------------|-----------------------|------------------| + | CASBIN_DATABASE | string |casbin | | | false | + | PG_READ_TIMEOUT | int64 |30 | | | false | + | PG_WRITE_TIMEOUT | int64 |30 | | | false | + diff --git a/kubewatch/main.go b/kubewatch/main.go index fdb48bfb5..d4f25cabe 100644 --- a/kubewatch/main.go +++ b/kubewatch/main.go @@ -17,6 +17,7 @@ package main import ( + "github.com/devtron-labs/common-lib/securestore" "log" "os" "os/signal" @@ -25,6 +26,10 @@ import ( ) func main() { + err := securestore.SetEncryptionKey() + if err != nil { + log.Println("error in setting encryption key", "err", err) + } app, err := InitializeApp() if err != nil { log.Panic(err) diff --git a/kubewatch/pkg/cluster/ClusterRepository.go b/kubewatch/pkg/cluster/ClusterRepository.go index 187407293..fee210477 100644 --- a/kubewatch/pkg/cluster/ClusterRepository.go +++ b/kubewatch/pkg/cluster/ClusterRepository.go @@ -17,6 +17,7 @@ package repository import ( + "github.com/devtron-labs/common-lib/securestore" "github.com/devtron-labs/common-lib/utils/k8s/commonBean" "github.com/devtron-labs/kubewatch/pkg/sql" "github.com/go-pg/pg" @@ -25,23 +26,23 @@ import ( ) type Cluster struct { - tableName struct{} `sql:"cluster" pg:",discard_unknown_columns"` - Id int `sql:"id,pk"` - ClusterName string `sql:"cluster_name"` - ServerUrl string `sql:"server_url"` - PrometheusEndpoint string `sql:"prometheus_endpoint"` - Active bool `sql:"active,notnull"` - CdArgoSetup bool `sql:"cd_argo_setup,notnull"` - Config map[string]string `sql:"config"` - PUserName string `sql:"p_username"` - PPassword string `sql:"p_password"` - PTlsClientCert string `sql:"p_tls_client_cert"` - PTlsClientKey string `sql:"p_tls_client_key"` - AgentInstallationStage int `sql:"agent_installation_stage"` - K8sVersion string `sql:"k8s_version"` - ErrorInConnecting string `sql:"error_in_connecting"` - InsecureSkipTlsVerify bool `sql:"insecure_skip_tls_verify"` - IsVirtualCluster bool `sql:"is_virtual_cluster"` + tableName struct{} `sql:"cluster" pg:",discard_unknown_columns"` + Id int `sql:"id,pk"` + ClusterName string `sql:"cluster_name"` + ServerUrl string `sql:"server_url"` + PrometheusEndpoint string `sql:"prometheus_endpoint"` + Active bool `sql:"active,notnull"` + CdArgoSetup bool `sql:"cd_argo_setup,notnull"` + Config securestore.EncryptedMap `sql:"config"` + PUserName string `sql:"p_username"` + PPassword string `sql:"p_password"` + PTlsClientCert string `sql:"p_tls_client_cert"` + PTlsClientKey string `sql:"p_tls_client_key"` + AgentInstallationStage int `sql:"agent_installation_stage"` + K8sVersion string `sql:"k8s_version"` + ErrorInConnecting string `sql:"error_in_connecting"` + InsecureSkipTlsVerify bool `sql:"insecure_skip_tls_verify"` + IsVirtualCluster bool `sql:"is_virtual_cluster"` sql.AuditLog } diff --git a/kubewatch/vendor/github.com/devtron-labs/common-lib/securestore/AttributesRepoDBConnection.go b/kubewatch/vendor/github.com/devtron-labs/common-lib/securestore/AttributesRepoDBConnection.go new file mode 100644 index 000000000..907d202bd --- /dev/null +++ b/kubewatch/vendor/github.com/devtron-labs/common-lib/securestore/AttributesRepoDBConnection.go @@ -0,0 +1,75 @@ +package securestore + +import ( + "github.com/caarlos0/env" + "github.com/devtron-labs/common-lib/utils" + "github.com/devtron-labs/common-lib/utils/bean" + "github.com/go-pg/pg" + "log" +) + +func NewAttributesRepositoryImplForDatabase(databaseName string) (*AttributesRepositoryImpl, error) { + dbConn, err := newDbConnection(databaseName) + if err != nil { + return nil, err + } + return NewAttributesRepositoryImpl(dbConn), nil +} + +type config struct { + Addr string `env:"PG_ADDR" envDefault:"127.0.0.1"` + Port string `env:"PG_PORT" envDefault:"5432"` + User string `env:"PG_USER" envDefault:""` + Password string `env:"PG_PASSWORD" envDefault:"" secretData:"-"` + Database string `env:"PG_DATABASE" envDefault:"orchestrator"` + ApplicationName string `env:"APP" envDefault:"orchestrator"` + bean.PgQueryMonitoringConfig + LocalDev bool `env:"RUNTIME_CONFIG_LOCAL_DEV" envDefault:"false"` +} + +func getDbConfig(databaseName string) (*config, error) { + cfg := &config{} + err := env.Parse(cfg) + if err != nil { + return cfg, err + } + monitoringCfg, err := bean.GetPgQueryMonitoringConfig(cfg.ApplicationName) + if err != nil { + return cfg, err + } + cfg.PgQueryMonitoringConfig = monitoringCfg + if !cfg.LocalDev { + cfg.Database = databaseName //overriding database + } + return cfg, err +} + +func newDbConnection(databaseName string) (*pg.DB, error) { + cfg, err := getDbConfig(databaseName) + if err != nil { + return nil, err + } + options := pg.Options{ + Addr: cfg.Addr + ":" + cfg.Port, + User: cfg.User, + Password: cfg.Password, + Database: cfg.Database, + ApplicationName: cfg.ApplicationName, + } + dbConnection := pg.Connect(&options) + //check db connection + var test string + _, err = dbConnection.QueryOne(&test, `SELECT 1`) + + if err != nil { + log.Println("error in connecting orchestrator db ", "err", err) + return nil, err + } else { + log.Println("connected with orchestrator db") + } + //-------------- + if cfg.LogSlowQuery { + dbConnection.OnQueryProcessed(utils.GetPGPostQueryProcessor(cfg.PgQueryMonitoringConfig)) + } + return dbConnection, err +} diff --git a/kubewatch/vendor/github.com/devtron-labs/common-lib/securestore/AttributesRepository.go b/kubewatch/vendor/github.com/devtron-labs/common-lib/securestore/AttributesRepository.go new file mode 100644 index 000000000..eadf7a8f4 --- /dev/null +++ b/kubewatch/vendor/github.com/devtron-labs/common-lib/securestore/AttributesRepository.go @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2020-2024. Devtron Inc. + */ + +package securestore + +import ( + sql2 "github.com/devtron-labs/common-lib/utils/sql" + "github.com/go-pg/pg" + "time" +) + +const ENCRYPTION_KEY string = "encryptionKey" // AES-256 encryption key for sensitive data + +type Attributes struct { + tableName struct{} `sql:"attributes" pg:",discard_unknown_columns"` + Id int `sql:"id,pk"` + Key string `sql:"key,notnull"` + Value string `sql:"value,notnull"` + Active bool `sql:"active, notnull"` + sql2.AuditLog +} + +type AttributesRepository interface { + Save(model *Attributes, tx *pg.Tx) (*Attributes, error) + Update(model *Attributes, tx *pg.Tx) error + FindByKey(key string) (*Attributes, error) + GetConnection() (dbConnection *pg.DB) + SaveEncryptionKeyIfNotExists(value string) error + GetEncryptionKey() (string, error) +} + +type AttributesRepositoryImpl struct { + dbConnection *pg.DB +} + +func NewAttributesRepositoryImpl(dbConnection *pg.DB) *AttributesRepositoryImpl { + return &AttributesRepositoryImpl{dbConnection: dbConnection} +} + +func (impl *AttributesRepositoryImpl) GetConnection() (dbConnection *pg.DB) { + return impl.dbConnection +} + +func (repo AttributesRepositoryImpl) Save(model *Attributes, tx *pg.Tx) (*Attributes, error) { + err := tx.Insert(model) + if err != nil { + return model, err + } + return model, nil +} + +func (repo AttributesRepositoryImpl) Update(model *Attributes, tx *pg.Tx) error { + err := tx.Update(model) + if err != nil { + return err + } + return nil +} + +func (repo AttributesRepositoryImpl) FindByKey(key string) (*Attributes, error) { + model := &Attributes{} + err := repo.dbConnection. + Model(model). + Where("key = ?", key). + Where("active = ?", true). + Select() + if err != nil { + return model, err + } + return model, nil +} + +// SaveEncryptionKeyIfNotExists saves an encryption key in the attributes table if not exists +func (repo AttributesRepositoryImpl) SaveEncryptionKeyIfNotExists(value string) error { + dbConnection := repo.GetConnection() + tx, err := dbConnection.Begin() + if err != nil { + return err + } + defer tx.Rollback() + + //deleting all keys if exists for safe side + _, err = tx.Model(&Attributes{}).Where("key = ?", ENCRYPTION_KEY).Delete() + // Create new encryption key entry + model := &Attributes{ + Key: ENCRYPTION_KEY, + Value: value, + Active: true, + AuditLog: sql2.AuditLog{ + CreatedBy: 1, + UpdatedBy: 1, + CreatedOn: time.Now(), + UpdatedOn: time.Now(), + }, + } + _, err = repo.Save(model, tx) + if err != nil { + return err + } + return tx.Commit() +} + +// GetEncryptionKey retrieves the active encryption key from the attributes table +func (repo AttributesRepositoryImpl) GetEncryptionKey() (string, error) { + model, err := repo.FindByKey(ENCRYPTION_KEY) + if err != nil { + return "", err + } + return model.Value, nil +} diff --git a/kubewatch/vendor/github.com/devtron-labs/common-lib/securestore/EncryptionKeyService.go b/kubewatch/vendor/github.com/devtron-labs/common-lib/securestore/EncryptionKeyService.go new file mode 100644 index 000000000..f8a37acec --- /dev/null +++ b/kubewatch/vendor/github.com/devtron-labs/common-lib/securestore/EncryptionKeyService.go @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2024. Devtron Inc. + */ + +package securestore + +import ( + "crypto/rand" + "encoding/hex" + "fmt" + "github.com/go-pg/pg" + log "github.com/sirupsen/logrus" +) + +func SetEncryptionKey() error { + repo, err := NewAttributesRepositoryImplForDatabase("orchestrator") //hardcoded for orchestrator as need to pick a common key for every service + if err != nil { + log.Println("error in creating attributes repository", "err", err) + return err + } + encryptionService := NewEncryptionKeyServiceImpl(repo) + err = encryptionService.CreateAndStoreEncryptionKey() + if err != nil { + log.Println("error in creating and storing encryption key", "err", err) + return err + } + return nil +} + +type EncryptionKeyService interface { + // CreateAndStoreEncryptionKey generates a new AES-256 encryption key and stores it in the attributes repository + CreateAndStoreEncryptionKey() error + + // RotateEncryptionKey generates a new encryption key and stores it (deactivating the old one) + RotateEncryptionKey(userId int32) (string, error) + + // GenerateEncryptionKey generates a new AES-256 encryption key (32 bytes) + GenerateEncryptionKey() (string, error) + + GetEncryptionKey() (string, error) +} + +type EncryptionKeyServiceImpl struct { + attributesRepository AttributesRepository +} + +func NewEncryptionKeyServiceImpl(attributesRepository AttributesRepository) *EncryptionKeyServiceImpl { + impl := &EncryptionKeyServiceImpl{ + attributesRepository: attributesRepository, + } + return impl +} + +// GenerateEncryptionKey generates a new AES-256 encryption key (32 bytes = 256 bits) +func (impl *EncryptionKeyServiceImpl) GenerateEncryptionKey() (string, error) { + // Generate 32 random bytes for AES-256 + key := make([]byte, 32) + _, err := rand.Read(key) + if err != nil { + log.Error("error generating random encryption key", "err", err) + return "", fmt.Errorf("failed to generate encryption key: %w", err) + } + // Encode to hex string for storage + keyHex := hex.EncodeToString(key) + return keyHex, nil +} + +// CreateAndStoreEncryptionKey generates a new AES-256 encryption key and stores it in the attributes repository +func (impl *EncryptionKeyServiceImpl) CreateAndStoreEncryptionKey() error { + // Check if encryption key already exists + encryptionKeyModel, err := impl.attributesRepository.FindByKey(ENCRYPTION_KEY) + if err != nil && err != pg.ErrNoRows { + log.Error("error checking for existing encryption key", "err", err) + return err + } + var encryptionKeyEncoded string + if encryptionKeyModel != nil && encryptionKeyModel.Id > 0 && len(encryptionKeyModel.Value) > 0 { + encryptionKeyEncoded = encryptionKeyModel.Value + log.Println("encryption key already exists", "keyId", encryptionKeyModel.Id) + } else { + // Generate new encryption key + encryptionKeyNew, err := impl.GenerateEncryptionKey() + if err != nil { + return err + } + // Store in repository + err = impl.attributesRepository.SaveEncryptionKeyIfNotExists(encryptionKeyNew) + if err != nil { + log.Error("error storing encryption key", "err", err) + return fmt.Errorf("failed to store encryption key: %w", err) + } + encryptionKeyEncoded = encryptionKeyNew + log.Println("Successfully created and stored encryption key") + } + + encryptionKey, err = hex.DecodeString(encryptionKeyEncoded) + if err != nil || len(encryptionKey) != 32 { + return fmt.Errorf("encryptionKey is incorrect : %v", err) + } + return nil +} + +// RotateEncryptionKey generates a new encryption key and stores it (deactivating the old one) +func (impl *EncryptionKeyServiceImpl) RotateEncryptionKey(userId int32) (string, error) { + log.Println("Rotating encryption key", "userId", userId) + + // Generate new encryption key + newEncryptionKey, err := impl.GenerateEncryptionKey() + if err != nil { + return "", err + } + + // Store in repository (this will deactivate the old key) + err = impl.attributesRepository.SaveEncryptionKeyIfNotExists(newEncryptionKey) + if err != nil { + log.Error("error rotating encryption key", "err", err) + return "", fmt.Errorf("failed to rotate encryption key: %w", err) + } + //TODO: also need to rotate encryption's already done + log.Println("Successfully rotated encryption key", "userId", userId) + return newEncryptionKey, nil +} + +// GetEncryptionKey retrieves the active encryption key from the repository +func (impl *EncryptionKeyServiceImpl) GetEncryptionKey() (string, error) { + key, err := impl.attributesRepository.GetEncryptionKey() + if err != nil { + if err == pg.ErrNoRows { + log.Error("encryption key not found in repository") + return "", fmt.Errorf("encryption key not found, please create one first") + } + log.Error("error retrieving encryption key", "err", err) + return "", err + } + return key, nil +} diff --git a/kubewatch/vendor/github.com/devtron-labs/common-lib/securestore/common.go b/kubewatch/vendor/github.com/devtron-labs/common-lib/securestore/common.go new file mode 100644 index 000000000..4444765e3 --- /dev/null +++ b/kubewatch/vendor/github.com/devtron-labs/common-lib/securestore/common.go @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2024. Devtron Inc. + */ + +package securestore + +import ( + "crypto/aes" + "crypto/cipher" + "crypto/rand" + "encoding/base64" + "encoding/json" + "errors" + "fmt" + "github.com/go-pg/pg/types" + "io" +) + +var decryptionFailErr = fmt.Errorf("Decryption failed") + +func DidDecryptionFail(err error) bool { + return errors.Is(err, decryptionFailErr) +} + +var encryptionKey []byte + +func encrypt(data []byte) (string, error) { + if len(data) == 0 { + return "", nil + } + block, err := aes.NewCipher(encryptionKey) + if err != nil { + return "", err + } + aesGCM, err := cipher.NewGCM(block) + if err != nil { + return "", err + } + nonce := make([]byte, aesGCM.NonceSize()) + if _, err := io.ReadFull(rand.Reader, nonce); err != nil { + return "", err + } + ciphertext := aesGCM.Seal(nonce, nonce, data, nil) + return base64.StdEncoding.EncodeToString(ciphertext), nil +} + +func decrypt(cipherBase64 string) (string, error) { + // Try decrypting (normal encrypted flow) + cipherData, err := base64.StdEncoding.DecodeString(cipherBase64) + if err == nil { + block, err := aes.NewCipher(encryptionKey) + if err != nil { + return "", err + } + aesGCM, err := cipher.NewGCM(block) + if err != nil { + return "", err + } + nonceSize := aesGCM.NonceSize() + if len(cipherData) >= nonceSize { + nonce, ciphertext := cipherData[:nonceSize], cipherData[nonceSize:] + plainText, err := aesGCM.Open(nil, nonce, ciphertext, nil) + if err == nil { + return string(plainText), nil // Successfully decrypted + } + } + } + return cipherBase64, decryptionFailErr +} + +// AppendValue : can be used for auto encryption of fields but is only supported in go-pg/v10. Not being used anywhere as of now, to be tested when start using. +func (e EncryptedMap) AppendValue(b []byte, quote int) ([]byte, error) { + jsonBytes, err := json.Marshal(e) + if err != nil { + return nil, err + } + + encryptedString, err := encrypt(jsonBytes) + if err != nil { + return nil, err + } + + return types.AppendString(b, encryptedString, quote), nil +} diff --git a/kubewatch/vendor/github.com/devtron-labs/common-lib/securestore/map.go b/kubewatch/vendor/github.com/devtron-labs/common-lib/securestore/map.go new file mode 100644 index 000000000..dd9c25846 --- /dev/null +++ b/kubewatch/vendor/github.com/devtron-labs/common-lib/securestore/map.go @@ -0,0 +1,73 @@ +package securestore + +import ( + "encoding/json" + "fmt" +) + +type EncryptedMap map[string]string + +const ( + ENCRYPTED_KEY = "encrypted_data" +) + +func EncryptMap(m EncryptedMap) (map[string]string, error) { + bytesM, err := json.Marshal(m) + if err != nil { + return nil, err + } + encryptedData, err := encrypt(bytesM) + if err != nil { + return nil, err + } + return EncryptedMap{ENCRYPTED_KEY: encryptedData}, nil +} + +func decryptMap(mCipher []byte) (map[string]string, error) { + var m map[string]string + err := json.Unmarshal(mCipher, &m) + if err != nil { + return nil, err + } + if len(m[ENCRYPTED_KEY]) > 0 { + decryptedMapBytes, err := decrypt(m[ENCRYPTED_KEY]) + if err != nil && !DidDecryptionFail(err) { + return nil, err + } + if err == nil { + var decryptedMap map[string]string + err = json.Unmarshal([]byte(decryptedMapBytes), &decryptedMap) + if err != nil { + return nil, err + } + return decryptedMap, nil + } + } else { + // Fallback: maybe it's just raw JSON + // Validate that it's a valid JSON map[string]string + // Neither decrypted nor valid plaintext JSON + return m, nil + } + return nil, fmt.Errorf("decryption failed and data is not valid plaintext JSON") +} + +func (e *EncryptedMap) Scan(value interface{}) error { + if value == nil { + return nil + } + var encrypted []byte + switch v := value.(type) { + case string: + encrypted = []byte(v) + case []byte: + encrypted = v + default: + return fmt.Errorf("unsupported type: %T", v) + } + var err error + *e, err = decryptMap(encrypted) + if err != nil { + return err + } + return nil +} diff --git a/kubewatch/vendor/github.com/devtron-labs/common-lib/securestore/strings.go b/kubewatch/vendor/github.com/devtron-labs/common-lib/securestore/strings.go new file mode 100644 index 000000000..e7c5128b2 --- /dev/null +++ b/kubewatch/vendor/github.com/devtron-labs/common-lib/securestore/strings.go @@ -0,0 +1,60 @@ +package securestore + +import ( + "fmt" +) + +type EncryptedString string + +func (e *EncryptedString) String() string { + return string(*e) +} + +func ToEncryptedString(s string) EncryptedString { + return EncryptedString(s) +} + +func EncryptString(data string) (EncryptedString, error) { + encryptedStr, err := encrypt([]byte(data)) + if err != nil { + return "", err + } + return EncryptedString(encryptedStr), nil +} + +func decryptString(cipherBase64 string) (string, error) { + decryptedBytes, err := decrypt(cipherBase64) + if err != nil && !DidDecryptionFail(err) { + return "", err + } + // Fallback: decrypting failed, considering it as just normal string + if DidDecryptionFail(err) { + return cipherBase64, nil + } else { + return decryptedBytes, nil + } +} + +func (e *EncryptedString) Scan(value interface{}) error { + if value == nil { + return nil + } + var encrypted []byte + switch v := value.(type) { + case string: + encrypted = []byte(v) + case []byte: + encrypted = v + default: + return fmt.Errorf("unsupported type: %T", v) + } + decryptedBytes, err := decryptString(string(encrypted)) + if err != nil { + return err + } + if decryptedBytes == "" { + return nil + } + *e = EncryptedString(decryptedBytes) + return nil +} diff --git a/kubewatch/vendor/github.com/devtron-labs/common-lib/utils/sql/AuditLog.go b/kubewatch/vendor/github.com/devtron-labs/common-lib/utils/sql/AuditLog.go new file mode 100644 index 000000000..fb3a38e79 --- /dev/null +++ b/kubewatch/vendor/github.com/devtron-labs/common-lib/utils/sql/AuditLog.go @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2020-2024. Devtron Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sql + +import ( + "time" +) + +type AuditLog struct { + CreatedOn time.Time `sql:"created_on,type:timestamptz"` + CreatedBy int32 `sql:"created_by,type:integer"` + UpdatedOn time.Time `sql:"updated_on,type:timestamptz"` + UpdatedBy int32 `sql:"updated_by,type:integer"` +} + +func NewDefaultAuditLog(userId int32) AuditLog { + return AuditLog{ + CreatedOn: time.Now(), + CreatedBy: userId, + UpdatedOn: time.Now(), + UpdatedBy: userId, + } +} + +// CreateAuditLog can be used by any repository to create AuditLog for insert operation +func (model *AuditLog) CreateAuditLog(userId int32) { + model.CreatedOn = time.Now() + model.UpdatedOn = time.Now() + model.CreatedBy = userId + model.UpdatedBy = userId +} + +// UpdateAuditLog can be used by any repository to update AuditLog for update operation +func (model *AuditLog) UpdateAuditLog(userId int32) { + model.UpdatedOn = time.Now() + model.UpdatedBy = userId +} diff --git a/kubewatch/vendor/github.com/devtron-labs/common-lib/utils/sql/TransactionWrapper.go b/kubewatch/vendor/github.com/devtron-labs/common-lib/utils/sql/TransactionWrapper.go new file mode 100644 index 000000000..3c797e1e1 --- /dev/null +++ b/kubewatch/vendor/github.com/devtron-labs/common-lib/utils/sql/TransactionWrapper.go @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2024. Devtron Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sql + +import "github.com/go-pg/pg" + +type TransactionWrapper interface { + StartTx() (*pg.Tx, error) + RollbackTx(tx *pg.Tx) error + CommitTx(tx *pg.Tx) error +} + +type TransactionUtilImpl struct { + dbConnection *pg.DB +} + +func NewTransactionUtilImpl(db *pg.DB) *TransactionUtilImpl { + return &TransactionUtilImpl{ + dbConnection: db, + } +} +func (impl *TransactionUtilImpl) RollbackTx(tx *pg.Tx) error { + return tx.Rollback() +} +func (impl *TransactionUtilImpl) CommitTx(tx *pg.Tx) error { + return tx.Commit() +} +func (impl *TransactionUtilImpl) StartTx() (*pg.Tx, error) { + return impl.dbConnection.Begin() +} diff --git a/kubewatch/vendor/github.com/devtron-labs/common-lib/utils/sql/connection.go b/kubewatch/vendor/github.com/devtron-labs/common-lib/utils/sql/connection.go new file mode 100644 index 000000000..fa6858e5d --- /dev/null +++ b/kubewatch/vendor/github.com/devtron-labs/common-lib/utils/sql/connection.go @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2020-2024. Devtron Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sql + +import ( + "github.com/devtron-labs/common-lib/utils" + "github.com/devtron-labs/common-lib/utils/bean" + "go.uber.org/zap" + "reflect" + "time" + + "github.com/caarlos0/env" + "github.com/go-pg/pg" +) + +// CATEGORY=POSTGRES +type Config struct { + Addr string `env:"PG_ADDR" envDefault:"127.0.0.1" description:"address of postgres service" example:"postgresql-postgresql.devtroncd" deprecated:"false"` + Port string `env:"PG_PORT" envDefault:"5432" description:"port of postgresql service" example:"5432"` + User string `env:"PG_USER" envDefault:"" description:"user for postgres" example:"postgres"` + Password string `env:"PG_PASSWORD" envDefault:"" secretData:"-" description:"password for postgres, associated with PG_USER" example:"confidential ;)"` + Database string `env:"PG_DATABASE" envDefault:"orchestrator" description:"postgres database to be made connection with" example:"orchestrator, casbin, git_sensor, lens"` + CasbinDatabase string `env:"CASBIN_DATABASE" envDefault:"casbin""` + ApplicationName string `env:"APP" envDefault:"orchestrator" description:"Application name"` + ReadTimeout int64 `env:"PG_READ_TIMEOUT" envDefault:"30"` + WriteTimeout int64 `env:"PG_WRITE_TIMEOUT" envDefault:"30"` + bean.PgQueryMonitoringConfig +} + +func GetConfig() (*Config, error) { + cfg := &Config{} + err := env.Parse(cfg) + if err != nil { + return cfg, err + } + monitoringCfg, err := bean.GetPgQueryMonitoringConfig(cfg.ApplicationName) + if err != nil { + return cfg, err + } + cfg.PgQueryMonitoringConfig = monitoringCfg + return cfg, err +} + +func NewDbConnection(cfg *Config, logger *zap.SugaredLogger) (*pg.DB, error) { + options := pg.Options{ + Addr: cfg.Addr + ":" + cfg.Port, + User: cfg.User, + Password: cfg.Password, + Database: cfg.Database, + ApplicationName: cfg.ApplicationName, + ReadTimeout: time.Duration(cfg.ReadTimeout) * time.Second, + WriteTimeout: time.Duration(cfg.WriteTimeout) * time.Second, + } + dbConnection := pg.Connect(&options) + // check db connection + var test string + _, err := dbConnection.QueryOne(&test, `SELECT 1`) + + if err != nil { + logger.Errorw("error in connecting db ", "db", obfuscateSecretTags(cfg), "err", err) + return nil, err + } else { + logger.Infow("connected with db", "db", obfuscateSecretTags(cfg)) + } + + // -------------- + dbConnection.OnQueryProcessed(utils.GetPGPostQueryProcessor(cfg.PgQueryMonitoringConfig)) + return dbConnection, err +} + +func obfuscateSecretTags(cfg interface{}) interface{} { + + cfgDpl := reflect.New(reflect.ValueOf(cfg).Elem().Type()).Interface() + cfgDplElm := reflect.ValueOf(cfgDpl).Elem() + t := cfgDplElm.Type() + for i := 0; i < t.NumField(); i++ { + if _, ok := t.Field(i).Tag.Lookup("secretData"); ok { + cfgDplElm.Field(i).SetString("********") + } else { + cfgDplElm.Field(i).Set(reflect.ValueOf(cfg).Elem().Field(i)) + } + } + return cfgDpl +} + +/*type DbConnectionHolder struct { + connection *pg.DB +} + +func (holder *DbConnectionHolder) CloseConnection() error { + return holder.connection.Close() +}*/ diff --git a/kubewatch/vendor/github.com/devtron-labs/common-lib/utils/sql/wire_sql.go b/kubewatch/vendor/github.com/devtron-labs/common-lib/utils/sql/wire_sql.go new file mode 100644 index 000000000..32aee8f5b --- /dev/null +++ b/kubewatch/vendor/github.com/devtron-labs/common-lib/utils/sql/wire_sql.go @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2024. Devtron Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sql + +import ( + "github.com/google/wire" +) + +var PgSqlWireSet = wire.NewSet( + GetConfig, + NewDbConnection, +) diff --git a/kubewatch/vendor/modules.txt b/kubewatch/vendor/modules.txt index 3bdaf3309..ca31a87a3 100644 --- a/kubewatch/vendor/modules.txt +++ b/kubewatch/vendor/modules.txt @@ -264,6 +264,7 @@ github.com/devtron-labs/common-lib/monitoring/statsViz github.com/devtron-labs/common-lib/pubsub-lib github.com/devtron-labs/common-lib/pubsub-lib/metrics github.com/devtron-labs/common-lib/pubsub-lib/model +github.com/devtron-labs/common-lib/securestore github.com/devtron-labs/common-lib/utils github.com/devtron-labs/common-lib/utils/bean github.com/devtron-labs/common-lib/utils/http @@ -274,6 +275,7 @@ github.com/devtron-labs/common-lib/utils/k8s/health github.com/devtron-labs/common-lib/utils/k8sObjectsUtil github.com/devtron-labs/common-lib/utils/remoteConnection/bean github.com/devtron-labs/common-lib/utils/runTime +github.com/devtron-labs/common-lib/utils/sql github.com/devtron-labs/common-lib/utils/yaml # github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f ## explicit