diff --git a/chart-sync/App.go b/chart-sync/App.go index 312939866..668fcf2ab 100644 --- a/chart-sync/App.go +++ b/chart-sync/App.go @@ -3,6 +3,7 @@ package main import ( "github.com/devtron-labs/chart-sync/internals" "github.com/devtron-labs/chart-sync/pkg" + "github.com/devtron-labs/common-lib/securestore" "github.com/go-pg/pg" "github.com/prometheus/client_golang/prometheus/promhttp" "go.uber.org/zap" @@ -22,12 +23,17 @@ func NewApp(Logger *zap.SugaredLogger, db *pg.DB, syncService pkg.SyncService, configuration *internals.Configuration) *App { + err := securestore.SetEncryptionKey() + if err != nil { + Logger.Errorw("error in setting encryption key", "err", err) + } return &App{ Logger: Logger, db: db, syncService: syncService, configuration: configuration, } + } func (app *App) Start() { diff --git a/chart-sync/env_gen.json b/chart-sync/env_gen.json index d09dd9336..f27709593 100644 --- a/chart-sync/env_gen.json +++ b/chart-sync/env_gen.json @@ -1 +1 @@ -[{"Category":"DEVTRON","Fields":[{"Env":"APP","EnvType":"string","EnvValue":"chart-sync","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"APP_STORE_APPLICATION_VERSIONS_SAVE_CHUNK_SIZE","EnvType":"int","EnvValue":"20","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"APP_SYNC_SHUTDOWN_WAIT_DURATION","EnvType":"int","EnvValue":"120","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"CHART_PROVIDER_ID","EnvType":"string","EnvValue":"*","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"IS_OCI_REGISTRY","EnvType":"bool","EnvValue":"true","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"LOG_LEVEL","EnvType":"int","EnvValue":"0","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PARALLELISM_LIMIT_FOR_TAG_PROCESSING","EnvType":"int","EnvValue":"0","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":"password","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":"user","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PROMETHEUS_MATRIX_PORT","EnvType":"int","EnvValue":"8080","EnvDescription":"","Example":"","Deprecated":"false"}]}] \ No newline at end of file +[{"Category":"DEVTRON","Fields":[{"Env":"APP","EnvType":"string","EnvValue":"chart-sync","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"APP_STORE_APPLICATION_VERSIONS_SAVE_CHUNK_SIZE","EnvType":"int","EnvValue":"20","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"APP_SYNC_SHUTDOWN_WAIT_DURATION","EnvType":"int","EnvValue":"120","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"CHART_PROVIDER_ID","EnvType":"string","EnvValue":"*","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"IS_OCI_REGISTRY","EnvType":"bool","EnvValue":"true","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"LOG_LEVEL","EnvType":"int","EnvValue":"0","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PARALLELISM_LIMIT_FOR_TAG_PROCESSING","EnvType":"int","EnvValue":"0","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":"password","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":"user","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PROMETHEUS_MATRIX_PORT","EnvType":"int","EnvValue":"8080","EnvDescription":"","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/chart-sync/env_gen.md b/chart-sync/env_gen.md index bc983e60a..b7296c54f 100644 --- a/chart-sync/env_gen.md +++ b/chart-sync/env_gen.md @@ -22,3 +22,11 @@ | PG_USER | string |user | | | false | | PROMETHEUS_MATRIX_PORT | int |8080 | | | 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/chart-sync/go.mod b/chart-sync/go.mod index 3f70584cf..f7db255bf 100644 --- a/chart-sync/go.mod +++ b/chart-sync/go.mod @@ -4,7 +4,7 @@ go 1.24.0 toolchain go1.24.3 -replace github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3 +replace github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20251013041509-9d1c5175da2d require ( github.com/caarlos0/env v3.5.0+incompatible diff --git a/chart-sync/go.sum b/chart-sync/go.sum index 50f0fe981..e45277c8f 100644 --- a/chart-sync/go.sum +++ b/chart-sync/go.sum @@ -43,8 +43,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3 h1:jCxpB8+6KD29jenB4SLTimCYzsmazBAPKv6637xRT5M= -github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3/go.mod h1:/Ciy9tD9OxZOWBDPIasM448H7uvSo4+ZJiExpfwBZpA= +github.com/devtron-labs/devtron-services/common-lib v0.0.0-20251013041509-9d1c5175da2d h1:EAGZ+sei6Hl98Hp09HgNcnOIWgI43jcx1q0Mb6V5HdQ= +github.com/devtron-labs/devtron-services/common-lib v0.0.0-20251013041509-9d1c5175da2d/go.mod h1:/Ciy9tD9OxZOWBDPIasM448H7uvSo4+ZJiExpfwBZpA= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/distribution/distribution/v3 v3.0.0 h1:q4R8wemdRQDClzoNNStftB2ZAfqOiN6UX90KJc4HjyM= diff --git a/chart-sync/internals/sql/DockerArtifactStoreRepository.go b/chart-sync/internals/sql/DockerArtifactStoreRepository.go index 5094af2b4..b875ea27c 100644 --- a/chart-sync/internals/sql/DockerArtifactStoreRepository.go +++ b/chart-sync/internals/sql/DockerArtifactStoreRepository.go @@ -18,6 +18,7 @@ package sql import ( + "github.com/devtron-labs/common-lib/securestore" "github.com/go-pg/pg" "github.com/go-pg/pg/orm" ) @@ -41,23 +42,23 @@ type RegistryType string var OCI_REGISRTY_REPO_TYPE_LIST = []string{OCI_REGISRTY_REPO_TYPE_CONTAINER, OCI_REGISRTY_REPO_TYPE_CHART} type DockerArtifactStore struct { - tableName struct{} `sql:"docker_artifact_store" json:",omitempty" pg:",discard_unknown_columns"` - Id string `sql:"id,pk" json:"id,,omitempty"` - PluginId string `sql:"plugin_id,notnull" json:"pluginId,omitempty"` - RegistryURL string `sql:"registry_url" json:"registryUrl,omitempty"` - RegistryType RegistryType `sql:"registry_type,notnull" json:"registryType,omitempty"` - IsOCICompliantRegistry bool `sql:"is_oci_compliant_registry,notnull" json:"isOCICompliantRegistry,omitempty"` - AWSAccessKeyId string `sql:"aws_accesskey_id" json:"awsAccessKeyId,omitempty" ` - AWSSecretAccessKey string `sql:"aws_secret_accesskey" json:"awsSecretAccessKey,omitempty"` - AWSRegion string `sql:"aws_region" json:"awsRegion,omitempty"` - Username string `sql:"username" json:"username,omitempty"` - Password string `sql:"password" json:"password,omitempty"` - IsDefault bool `sql:"is_default,notnull" json:"isDefault"` - Connection string `sql:"connection" json:"connection,omitempty"` - Cert string `sql:"cert" json:"cert,omitempty"` - Active bool `sql:"active,notnull" json:"active"` - RemoteConnectionConfigId int `sql:"remote_connection_config_id"` - CredentialsType string `sql:"credentials_type,notnull"` + tableName struct{} `sql:"docker_artifact_store" json:",omitempty" pg:",discard_unknown_columns"` + Id string `sql:"id,pk" json:"id,,omitempty"` + PluginId string `sql:"plugin_id,notnull" json:"pluginId,omitempty"` + RegistryURL string `sql:"registry_url" json:"registryUrl,omitempty"` + RegistryType RegistryType `sql:"registry_type,notnull" json:"registryType,omitempty"` + IsOCICompliantRegistry bool `sql:"is_oci_compliant_registry,notnull" json:"isOCICompliantRegistry,omitempty"` + AWSAccessKeyId string `sql:"aws_accesskey_id" json:"awsAccessKeyId,omitempty" ` + AWSSecretAccessKey securestore.EncryptedString `sql:"aws_secret_accesskey" json:"awsSecretAccessKey,omitempty"` + AWSRegion string `sql:"aws_region" json:"awsRegion,omitempty"` + Username string `sql:"username" json:"username,omitempty"` + Password securestore.EncryptedString `sql:"password" json:"password,omitempty"` + IsDefault bool `sql:"is_default,notnull" json:"isDefault"` + Connection string `sql:"connection" json:"connection,omitempty"` + Cert string `sql:"cert" json:"cert,omitempty"` + Active bool `sql:"active,notnull" json:"active"` + RemoteConnectionConfigId int `sql:"remote_connection_config_id"` + CredentialsType string `sql:"credentials_type,notnull"` OCIRegistryConfig []*OCIRegistryConfig RemoteConnectionConfig *RemoteConnectionConfig AuditLog diff --git a/chart-sync/internals/sql/remoteConnectionConfigRepository.go b/chart-sync/internals/sql/remoteConnectionConfigRepository.go index d93302e7b..28c9ed525 100644 --- a/chart-sync/internals/sql/remoteConnectionConfigRepository.go +++ b/chart-sync/internals/sql/remoteConnectionConfigRepository.go @@ -1,20 +1,21 @@ package sql import ( + "github.com/devtron-labs/common-lib/securestore" "github.com/go-pg/pg" "go.uber.org/zap" ) type RemoteConnectionConfig struct { - tableName struct{} `sql:"remote_connection_config" pg:",discard_unknown_columns"` - Id int `sql:"id,pk"` - ConnectionMethod string `sql:"connection_method"` - ProxyUrl string `sql:"proxy_url"` - SSHServerAddress string `sql:"ssh_server_address"` - SSHUsername string `sql:"ssh_username"` - SSHPassword string `sql:"ssh_password"` - SSHAuthKey string `sql:"ssh_auth_key"` - Deleted bool `sql:"deleted,notnull"` + tableName struct{} `sql:"remote_connection_config" pg:",discard_unknown_columns"` + Id int `sql:"id,pk"` + ConnectionMethod string `sql:"connection_method"` + ProxyUrl string `sql:"proxy_url"` + SSHServerAddress string `sql:"ssh_server_address"` + SSHUsername string `sql:"ssh_username"` + SSHPassword securestore.EncryptedString `sql:"ssh_password"` + SSHAuthKey securestore.EncryptedString `sql:"ssh_auth_key"` + Deleted bool `sql:"deleted,notnull"` AuditLog } diff --git a/chart-sync/pkg/registry/adapter.go b/chart-sync/pkg/registry/adapter.go index b81419cb4..5c7adcb24 100644 --- a/chart-sync/pkg/registry/adapter.go +++ b/chart-sync/pkg/registry/adapter.go @@ -19,8 +19,8 @@ func NewToRegistryConfig(store *sql.DockerArtifactStore) (*registry.Configuratio remoteConnectionConfig.SSHTunnelConfig = &bean.SSHTunnelConfig{ SSHServerAddress: store.RemoteConnectionConfig.SSHServerAddress, SSHUsername: store.RemoteConnectionConfig.SSHUsername, - SSHPassword: store.RemoteConnectionConfig.SSHPassword, - SSHAuthKey: store.RemoteConnectionConfig.SSHAuthKey, + SSHPassword: store.RemoteConnectionConfig.SSHPassword.String(), + SSHAuthKey: store.RemoteConnectionConfig.SSHAuthKey.String(), } } } @@ -36,9 +36,9 @@ func NewToRegistryConfig(store *sql.DockerArtifactStore) (*registry.Configuratio RegistryId: store.Id, RegistryUrl: store.RegistryURL, Username: store.Username, - Password: store.Password, + Password: store.Password.String(), AwsAccessKey: store.AWSAccessKeyId, - AwsSecretKey: store.AWSSecretAccessKey, + AwsSecretKey: store.AWSSecretAccessKey.String(), AwsRegion: store.AWSRegion, RegistryConnectionType: store.Connection, RegistryCertificateString: store.Cert, diff --git a/chart-sync/vendor/github.com/devtron-labs/common-lib/securestore/AttributesRepoDBConnection.go b/chart-sync/vendor/github.com/devtron-labs/common-lib/securestore/AttributesRepoDBConnection.go new file mode 100644 index 000000000..907d202bd --- /dev/null +++ b/chart-sync/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/chart-sync/vendor/github.com/devtron-labs/common-lib/securestore/AttributesRepository.go b/chart-sync/vendor/github.com/devtron-labs/common-lib/securestore/AttributesRepository.go new file mode 100644 index 000000000..eadf7a8f4 --- /dev/null +++ b/chart-sync/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/chart-sync/vendor/github.com/devtron-labs/common-lib/securestore/EncryptionKeyService.go b/chart-sync/vendor/github.com/devtron-labs/common-lib/securestore/EncryptionKeyService.go new file mode 100644 index 000000000..f8a37acec --- /dev/null +++ b/chart-sync/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/chart-sync/vendor/github.com/devtron-labs/common-lib/securestore/common.go b/chart-sync/vendor/github.com/devtron-labs/common-lib/securestore/common.go new file mode 100644 index 000000000..4444765e3 --- /dev/null +++ b/chart-sync/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/chart-sync/vendor/github.com/devtron-labs/common-lib/securestore/map.go b/chart-sync/vendor/github.com/devtron-labs/common-lib/securestore/map.go new file mode 100644 index 000000000..dd9c25846 --- /dev/null +++ b/chart-sync/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/chart-sync/vendor/github.com/devtron-labs/common-lib/securestore/strings.go b/chart-sync/vendor/github.com/devtron-labs/common-lib/securestore/strings.go new file mode 100644 index 000000000..e7c5128b2 --- /dev/null +++ b/chart-sync/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/chart-sync/vendor/github.com/devtron-labs/common-lib/utils/sql/AuditLog.go b/chart-sync/vendor/github.com/devtron-labs/common-lib/utils/sql/AuditLog.go new file mode 100644 index 000000000..fb3a38e79 --- /dev/null +++ b/chart-sync/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/chart-sync/vendor/github.com/devtron-labs/common-lib/utils/sql/TransactionWrapper.go b/chart-sync/vendor/github.com/devtron-labs/common-lib/utils/sql/TransactionWrapper.go new file mode 100644 index 000000000..3c797e1e1 --- /dev/null +++ b/chart-sync/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/chart-sync/vendor/github.com/devtron-labs/common-lib/utils/sql/connection.go b/chart-sync/vendor/github.com/devtron-labs/common-lib/utils/sql/connection.go new file mode 100644 index 000000000..fa6858e5d --- /dev/null +++ b/chart-sync/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/chart-sync/vendor/github.com/devtron-labs/common-lib/utils/sql/wire_sql.go b/chart-sync/vendor/github.com/devtron-labs/common-lib/utils/sql/wire_sql.go new file mode 100644 index 000000000..32aee8f5b --- /dev/null +++ b/chart-sync/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/chart-sync/vendor/modules.txt b/chart-sync/vendor/modules.txt index a41fd5861..289298626 100644 --- a/chart-sync/vendor/modules.txt +++ b/chart-sync/vendor/modules.txt @@ -95,16 +95,18 @@ github.com/containerd/platforms # github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc ## explicit github.com/davecgh/go-spew/spew -# github.com/devtron-labs/common-lib v0.19.1 => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3 +# github.com/devtron-labs/common-lib v0.19.1 => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20251013041509-9d1c5175da2d ## explicit; go 1.24.0 github.com/devtron-labs/common-lib/constants github.com/devtron-labs/common-lib/fetchAllEnv github.com/devtron-labs/common-lib/git-manager/util github.com/devtron-labs/common-lib/helmLib/registry +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 github.com/devtron-labs/common-lib/utils/remoteConnection/bean +github.com/devtron-labs/common-lib/utils/sql # github.com/docker/cli v28.1.1+incompatible ## explicit github.com/docker/cli/cli/config/types @@ -967,4 +969,4 @@ sigs.k8s.io/structured-merge-diff/v4/value sigs.k8s.io/yaml sigs.k8s.io/yaml/goyaml.v2 sigs.k8s.io/yaml/goyaml.v3 -# github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3 +# github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20251013041509-9d1c5175da2d diff --git a/chart-sync/wire_gen.go b/chart-sync/wire_gen.go index 874f69de6..0022efdf4 100644 --- a/chart-sync/wire_gen.go +++ b/chart-sync/wire_gen.go @@ -1,6 +1,6 @@ // Code generated by Wire. DO NOT EDIT. -//go:generate go run github.com/google/wire/cmd/wire +//go:generate go run -mod=mod github.com/google/wire/cmd/wire //go:build !wireinject // +build !wireinject diff --git a/ci-runner/go.mod b/ci-runner/go.mod index a47038b06..1ba4eb04e 100644 --- a/ci-runner/go.mod +++ b/ci-runner/go.mod @@ -4,7 +4,7 @@ go 1.24.0 toolchain go1.24.3 -replace github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3 +replace github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20251013041509-9d1c5175da2d require ( github.com/Knetic/govaluate v3.0.0+incompatible diff --git a/ci-runner/go.sum b/ci-runner/go.sum index 989602349..6c6eaf1eb 100644 --- a/ci-runner/go.sum +++ b/ci-runner/go.sum @@ -114,8 +114,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3 h1:jCxpB8+6KD29jenB4SLTimCYzsmazBAPKv6637xRT5M= -github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3/go.mod h1:/Ciy9tD9OxZOWBDPIasM448H7uvSo4+ZJiExpfwBZpA= +github.com/devtron-labs/devtron-services/common-lib v0.0.0-20251013041509-9d1c5175da2d h1:EAGZ+sei6Hl98Hp09HgNcnOIWgI43jcx1q0Mb6V5HdQ= +github.com/devtron-labs/devtron-services/common-lib v0.0.0-20251013041509-9d1c5175da2d/go.mod h1:/Ciy9tD9OxZOWBDPIasM448H7uvSo4+ZJiExpfwBZpA= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/docker/cli v28.1.1+incompatible h1:eyUemzeI45DY7eDPuwUcmDyDj1pM98oD5MdSpiItp8k= diff --git a/ci-runner/vendor/modules.txt b/ci-runner/vendor/modules.txt index adcc96a6d..81b865a92 100644 --- a/ci-runner/vendor/modules.txt +++ b/ci-runner/vendor/modules.txt @@ -298,7 +298,7 @@ github.com/cncf/xds/go/xds/type/v3 # github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc ## explicit github.com/davecgh/go-spew/spew -# github.com/devtron-labs/common-lib v0.19.1 => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3 +# github.com/devtron-labs/common-lib v0.19.1 => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20251013041509-9d1c5175da2d ## explicit; go 1.24.0 github.com/devtron-labs/common-lib/blob-storage github.com/devtron-labs/common-lib/constants @@ -1198,4 +1198,4 @@ sigs.k8s.io/structured-merge-diff/v4/value ## explicit; go 1.12 sigs.k8s.io/yaml sigs.k8s.io/yaml/goyaml.v2 -# github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3 +# github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20251013041509-9d1c5175da2d diff --git a/common-lib/securestore/AttributesRepoDBConnection.go b/common-lib/securestore/AttributesRepoDBConnection.go new file mode 100644 index 000000000..907d202bd --- /dev/null +++ b/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/common-lib/securestore/AttributesRepository.go b/common-lib/securestore/AttributesRepository.go new file mode 100644 index 000000000..eadf7a8f4 --- /dev/null +++ b/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/common-lib/securestore/EncryptionKeyService.go b/common-lib/securestore/EncryptionKeyService.go new file mode 100644 index 000000000..f8a37acec --- /dev/null +++ b/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/common-lib/securestore/common.go b/common-lib/securestore/common.go new file mode 100644 index 000000000..4444765e3 --- /dev/null +++ b/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/common-lib/securestore/map.go b/common-lib/securestore/map.go new file mode 100644 index 000000000..dd9c25846 --- /dev/null +++ b/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/common-lib/securestore/strings.go b/common-lib/securestore/strings.go new file mode 100644 index 000000000..e7c5128b2 --- /dev/null +++ b/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/git-sensor/api/GrpcHandler.go b/git-sensor/api/GrpcHandler.go index 454714331..1a6e249b8 100644 --- a/git-sensor/api/GrpcHandler.go +++ b/git-sensor/api/GrpcHandler.go @@ -18,6 +18,7 @@ package api import ( "context" + "github.com/devtron-labs/common-lib/securestore" "github.com/devtron-labs/git-sensor/internals/sql" "github.com/devtron-labs/git-sensor/pkg" "github.com/devtron-labs/git-sensor/pkg/git" @@ -77,9 +78,9 @@ func (impl *GrpcHandlerImpl) SaveGitProvider(ctx context.Context, req *pb.GitPro Name: req.Name, Url: req.Url, UserName: req.UserName, - Password: req.Password, - AccessToken: req.AccessToken, - SshPrivateKey: req.SshPrivateKey, + Password: securestore.ToEncryptedString(req.Password), + AccessToken: securestore.ToEncryptedString(req.AccessToken), + SshPrivateKey: securestore.ToEncryptedString(req.SshPrivateKey), AuthMode: sql.AuthMode(req.AuthMode), Active: req.Active, CaCert: req.CaCert, diff --git a/git-sensor/app/App.go b/git-sensor/app/App.go index 636a224e9..94146279f 100644 --- a/git-sensor/app/App.go +++ b/git-sensor/app/App.go @@ -24,6 +24,7 @@ import ( constants "github.com/devtron-labs/common-lib/constants" pubsub "github.com/devtron-labs/common-lib/pubsub-lib" "github.com/devtron-labs/common-lib/pubsub-lib/metrics" + "github.com/devtron-labs/common-lib/securestore" "github.com/devtron-labs/git-sensor/api" "github.com/devtron-labs/git-sensor/bean" "github.com/devtron-labs/git-sensor/internals/middleware" @@ -59,6 +60,10 @@ type App struct { } func NewApp(MuxRouter *api.MuxRouter, Logger *zap.SugaredLogger, impl *git.GitWatcherImpl, db *pg.DB, pubSubClient *pubsub.PubSubClientServiceImpl, GrpcControllerImpl *api.GrpcHandlerImpl) *App { + err := securestore.SetEncryptionKey() + if err != nil { + Logger.Errorw("error in setting encryption key", "err", err) + } return &App{ MuxRouter: MuxRouter, Logger: Logger, diff --git a/git-sensor/env_gen.json b/git-sensor/env_gen.json index 2a7cbdb4f..95f60cc11 100644 --- a/git-sensor/env_gen.json +++ b/git-sensor/env_gen.json @@ -1 +1 @@ -[{"Category":"DEVTRON","Fields":[{"Env":"ANALYTICS_DEBUG","EnvType":"bool","EnvValue":"false","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"APP","EnvType":"string","EnvValue":"git-sensor","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"CLI_CMD_TIMEOUT_GLOBAL_SECONDS","EnvType":"int","EnvValue":"900","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"CLI_CMD_TIMEOUT_JSON","EnvType":"string","EnvValue":"","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"COMMIT_STATS_TIMEOUT_IN_SEC","EnvType":"int","EnvValue":"2","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_FILE_STATS","EnvType":"bool","EnvValue":"false","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"ENABLE_STATSVIZ","EnvType":"bool","EnvValue":"false","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"GIT_HISTORY_COUNT","EnvType":"int","EnvValue":"15","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"GOGIT_TIMEOUT_SECONDS","EnvType":"int","EnvValue":"10","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"LOG_LEVEL","EnvType":"int","EnvValue":"0","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"MIN_LIMIT_FOR_PVC","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":"git_sensor","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":"POLL_DURATION","EnvType":"int","EnvValue":"2","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"POLL_WORKER","EnvType":"int","EnvValue":"5","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"SERVER_GRPC_PORT","EnvType":"int","EnvValue":"8081","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"SERVER_REST_PORT","EnvType":"int","EnvValue":"8080","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"STREAM_CONFIG_JSON","EnvType":"string","EnvValue":"","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"USE_GIT_CLI","EnvType":"bool","EnvValue":"false","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"USE_GIT_CLI_ANALYTICS","EnvType":"bool","EnvValue":"false","EnvDescription":"","Example":"","Deprecated":"false"}]}] \ No newline at end of file +[{"Category":"DEVTRON","Fields":[{"Env":"ANALYTICS_DEBUG","EnvType":"bool","EnvValue":"false","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"APP","EnvType":"string","EnvValue":"git-sensor","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"CLI_CMD_TIMEOUT_GLOBAL_SECONDS","EnvType":"int","EnvValue":"900","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"CLI_CMD_TIMEOUT_JSON","EnvType":"string","EnvValue":"","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"COMMIT_STATS_TIMEOUT_IN_SEC","EnvType":"int","EnvValue":"2","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_FILE_STATS","EnvType":"bool","EnvValue":"false","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"ENABLE_STATSVIZ","EnvType":"bool","EnvValue":"false","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"GIT_HISTORY_COUNT","EnvType":"int","EnvValue":"15","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"GOGIT_TIMEOUT_SECONDS","EnvType":"int","EnvValue":"10","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"LOG_LEVEL","EnvType":"int","EnvValue":"0","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"MIN_LIMIT_FOR_PVC","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":"git_sensor","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":"POLL_DURATION","EnvType":"int","EnvValue":"2","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"POLL_WORKER","EnvType":"int","EnvValue":"5","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"SERVER_GRPC_PORT","EnvType":"int","EnvValue":"8081","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"SERVER_REST_PORT","EnvType":"int","EnvValue":"8080","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"STREAM_CONFIG_JSON","EnvType":"string","EnvValue":"","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"USE_GIT_CLI","EnvType":"bool","EnvValue":"false","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"USE_GIT_CLI_ANALYTICS","EnvType":"bool","EnvValue":"false","EnvDescription":"","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/git-sensor/env_gen.md b/git-sensor/env_gen.md index b43f8137d..61987d549 100644 --- a/git-sensor/env_gen.md +++ b/git-sensor/env_gen.md @@ -40,3 +40,11 @@ | USE_GIT_CLI | bool |false | | | false | | USE_GIT_CLI_ANALYTICS | bool |false | | | 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/git-sensor/go.mod b/git-sensor/go.mod index d77b1cbc7..1e66f54e8 100644 --- a/git-sensor/go.mod +++ b/git-sensor/go.mod @@ -4,26 +4,26 @@ go 1.24.0 toolchain go1.24.3 -replace github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3 +replace github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20251013041509-9d1c5175da2d require ( github.com/caarlos0/env v3.5.0+incompatible - github.com/devtron-labs/common-lib v0.19.1 + github.com/devtron-labs/common-lib v0.0.0 github.com/devtron-labs/protos v0.0.3-0.20250323220609-ecf8a0f7305e github.com/gammazero/workerpool v1.1.3 - github.com/go-git/go-git/v5 v5.16.0 + github.com/go-git/go-git/v5 v5.13.2 github.com/go-pg/pg v6.15.1+incompatible github.com/google/uuid v1.6.0 github.com/google/wire v0.6.0 - github.com/gorilla/handlers v1.5.2 + github.com/gorilla/handlers v1.4.2 github.com/gorilla/mux v1.8.1 github.com/gorilla/schema v1.4.1 - github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2 + github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.1 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 github.com/prometheus/client_golang v1.22.0 github.com/robfig/cron/v3 v3.0.1 github.com/stretchr/testify v1.10.0 - github.com/tidwall/gjson v1.18.0 + github.com/tidwall/gjson v1.9.3 go.uber.org/zap v1.27.0 golang.org/x/sys v0.33.0 google.golang.org/grpc v1.72.2 @@ -32,22 +32,21 @@ require ( ) require ( - dario.cat/mergo v1.0.2 // indirect + dario.cat/mergo v1.0.0 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect - github.com/ProtonMail/go-crypto v1.3.0 // indirect + github.com/ProtonMail/go-crypto v1.1.5 // indirect github.com/arl/statsviz v0.6.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/cloudflare/circl v1.6.1 // indirect - github.com/cyphar/filepath-securejoin v0.4.1 // indirect + github.com/cloudflare/circl v1.3.7 // indirect + github.com/cyphar/filepath-securejoin v0.3.6 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/docker/cli v28.1.1+incompatible // indirect github.com/emirpasic/gods v1.18.1 // indirect - github.com/felixge/httpsnoop v1.0.4 // indirect github.com/gammazero/deque v1.0.0 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect github.com/go-git/go-billy/v5 v5.6.2 // indirect - github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect @@ -66,10 +65,10 @@ require ( github.com/prometheus/procfs v0.16.1 // indirect github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect github.com/sirupsen/logrus v1.9.3 // indirect - github.com/skeema/knownhosts v1.3.1 // indirect + github.com/skeema/knownhosts v1.3.0 // indirect github.com/stretchr/objx v0.5.2 // indirect github.com/tidwall/match v1.1.1 // indirect - github.com/tidwall/pretty v1.2.1 // indirect + github.com/tidwall/pretty v1.2.0 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect go.uber.org/multierr v1.11.0 // indirect golang.org/x/crypto v0.38.0 // indirect diff --git a/git-sensor/go.sum b/git-sensor/go.sum index 163eedaf1..6d1cc2c47 100644 --- a/git-sensor/go.sum +++ b/git-sensor/go.sum @@ -1,10 +1,10 @@ -dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8= -dario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMIE34DRGLWqDy0g5FuKDhCb31ngxA= +dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= +dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= -github.com/ProtonMail/go-crypto v1.3.0 h1:ILq8+Sf5If5DCpHQp4PbZdS1J7HDFRXz/+xKBiRGFrw= -github.com/ProtonMail/go-crypto v1.3.0/go.mod h1:9whxjD8Rbs29b4XWbB8irEcE8KHMqaR2e7GWU1R+/PE= +github.com/ProtonMail/go-crypto v1.1.5 h1:eoAQfK2dwL+tFSFpr7TbOaPNUbPiJj4fLYwwGE1FQO4= +github.com/ProtonMail/go-crypto v1.1.5/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/arl/statsviz v0.6.0 h1:jbW1QJkEYQkufd//4NDYRSNBpwJNrdzPahF7ZmoGdyE= @@ -17,27 +17,25 @@ github.com/caarlos0/env v3.5.0+incompatible h1:Yy0UN8o9Wtr/jGHZDpCBLpNrzcFLLM2yi github.com/caarlos0/env v3.5.0+incompatible/go.mod h1:tdCsowwCzMLdkqRYDlHpZCp2UooDD3MspDBjZ2AD02Y= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0= -github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= +github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= +github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= -github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s= -github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= +github.com/cyphar/filepath-securejoin v0.3.6 h1:4d9N5ykBnSp5Xn2JkhocYDkOpURL/18CYMpo6xB9uWM= +github.com/cyphar/filepath-securejoin v0.3.6/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3 h1:jCxpB8+6KD29jenB4SLTimCYzsmazBAPKv6637xRT5M= -github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3/go.mod h1:/Ciy9tD9OxZOWBDPIasM448H7uvSo4+ZJiExpfwBZpA= +github.com/devtron-labs/devtron-services/common-lib v0.0.0-20251013041509-9d1c5175da2d h1:EAGZ+sei6Hl98Hp09HgNcnOIWgI43jcx1q0Mb6V5HdQ= +github.com/devtron-labs/devtron-services/common-lib v0.0.0-20251013041509-9d1c5175da2d/go.mod h1:/Ciy9tD9OxZOWBDPIasM448H7uvSo4+ZJiExpfwBZpA= github.com/devtron-labs/protos v0.0.3-0.20250323220609-ecf8a0f7305e h1:U6UdYbW8a7xn5IzFPd8cywjVVPfutGJCudjePAfL/Hs= github.com/devtron-labs/protos v0.0.3-0.20250323220609-ecf8a0f7305e/go.mod h1:1TqULGlTey+VNhAu/ag7NJuUvByJemkqodsc9L5PHJk= github.com/docker/cli v28.1.1+incompatible h1:eyUemzeI45DY7eDPuwUcmDyDj1pM98oD5MdSpiItp8k= github.com/docker/cli v28.1.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/elazarl/goproxy v1.7.2 h1:Y2o6urb7Eule09PjlhQRGNsqRfPmYI3KKQLFpCAV3+o= -github.com/elazarl/goproxy v1.7.2/go.mod h1:82vkLNir0ALaW14Rc399OTTjyNREgmdL2cVoIbS6XaE= +github.com/elazarl/goproxy v1.4.0 h1:4GyuSbFa+s26+3rmYNSuUVsx+HgPrV1bk1jXI0l9wjM= +github.com/elazarl/goproxy v1.4.0/go.mod h1:X/5W/t+gzDyLfHW4DrMdpjqYjpXsURlBt9lpBDxZZZQ= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= -github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= -github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= @@ -53,16 +51,16 @@ github.com/go-git/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UN github.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= -github.com/go-git/go-git/v5 v5.16.0 h1:k3kuOEpkc0DeY7xlL6NaaNg39xdgQbtH5mwCafHO9AQ= -github.com/go-git/go-git/v5 v5.16.0/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8= +github.com/go-git/go-git/v5 v5.13.2 h1:7O7xvsK7K+rZPKW6AQR1YyNhfywkv7B8/FsP3ki6Zv0= +github.com/go-git/go-git/v5 v5.13.2/go.mod h1:hWdW5P4YZRjmpGHwRH2v3zkWcNl6HeXaXQEMGb3NJ9A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-pg/pg v6.15.1+incompatible h1:vO4P9WoCi+i4qomgcBXWlKgDk4GcHAqDAOIfkEpi7B4= github.com/go-pg/pg v6.15.1+incompatible/go.mod h1:a2oXow+aFOrvwcKs3eIA0lNFmMilrxK2sOkB5NWe0vA= -github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ= -github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -73,16 +71,16 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/wire v0.6.0 h1:HBkoIh4BdSxoyo9PveV8giw7ZsaBOvzWKfcg/6MrVwI= github.com/google/wire v0.6.0/go.mod h1:F4QhpQ9EDIdJ1Mbop/NZBRB+5yrR6qg3BnctaoUk6NA= -github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE= -github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w= +github.com/gorilla/handlers v1.4.2 h1:0QniY0USkHQ1RGCLfKxeNHK9bkDHGRYGNDFBCS+YARg= +github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= github.com/gorilla/schema v1.4.1 h1:jUg5hUjCSDZpNGLuXQOgIWGdlgrIdYvgQ0wZtdK1M3E= github.com/gorilla/schema v1.4.1/go.mod h1:Dg5SSm5PV60mhF2NFaTV1xuYYj8tV8NOPRo4FggUMnM= github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo= github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA= -github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2 h1:sGm2vDRFUrQJO/Veii4h4zG2vvqG6uWNkBHSTqXOZk0= -github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2/go.mod h1:wd1YpapPLivG6nQgbf7ZkG1hhSOXDhhn4MLTknx2aAc= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.1 h1:HcUWd006luQPljE73d5sk+/VgYPGUReEVz2y1/qylwY= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.1/go.mod h1:w9Y7gY31krpLmrVU5ZPG9H7l9fZuRu5/3R3S3FMtVQ4= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= @@ -134,15 +132,15 @@ github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzM github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= -github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= -github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/skeema/knownhosts v1.3.1 h1:X2osQ+RAjK76shCbvhHHHVl3ZlgDm8apHEHFqRjnBY8= -github.com/skeema/knownhosts v1.3.1/go.mod h1:r7KTdC8l4uxWRyK2TpQZ/1o5HaSzh06ePQNxPwTcfiY= +github.com/skeema/knownhosts v1.3.0 h1:AM+y0rI04VksttfwjkSTNQorvGqmwATnvnAHpSgc0LY= +github.com/skeema/knownhosts v1.3.0/go.mod h1:sPINvnADmT/qYH1kfv+ePMmOBTH6Tbl7b5LvTDjFK7M= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= @@ -151,13 +149,12 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= -github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/gjson v1.9.3 h1:hqzS9wAHMO+KVBBkLxYdkEeeFHuqr95GfClRLKlgK0E= +github.com/tidwall/gjson v1.9.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= -github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= -github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= diff --git a/git-sensor/internals/sql/GitProviderRepository.go b/git-sensor/internals/sql/GitProviderRepository.go index d16aaa7e9..f1e493455 100644 --- a/git-sensor/internals/sql/GitProviderRepository.go +++ b/git-sensor/internals/sql/GitProviderRepository.go @@ -16,7 +16,10 @@ package sql -import "github.com/go-pg/pg" +import ( + "github.com/devtron-labs/common-lib/securestore" + "github.com/go-pg/pg" +) type AuthMode string @@ -28,20 +31,20 @@ const ( ) type GitProvider struct { - tableName struct{} `sql:"git_provider"` - Id int `sql:"id,pk"` - Name string `sql:"name,notnull"` - Url string `sql:"url,notnull"` - UserName string `sql:"user_name"` - Password string `sql:"password"` - SshPrivateKey string `sql:"ssh_private_key"` - AccessToken string `sql:"access_token"` - AuthMode AuthMode `sql:"auth_mode,notnull"` - Active bool `sql:"active,notnull"` - TlsCert string `sql:"tls_cert"` - TlsKey string `sql:"tls_key"` - CaCert string `sql:"ca_cert"` - EnableTLSVerification bool `sql:"enable_tls_verification"` + tableName struct{} `sql:"git_provider"` + Id int `sql:"id,pk"` + Name string `sql:"name,notnull"` + Url string `sql:"url,notnull"` + UserName string `sql:"user_name"` + Password securestore.EncryptedString `sql:"password"` + SshPrivateKey securestore.EncryptedString `sql:"ssh_private_key"` + AccessToken securestore.EncryptedString `sql:"access_token"` + AuthMode AuthMode `sql:"auth_mode,notnull"` + Active bool `sql:"active,notnull"` + TlsCert string `sql:"tls_cert"` + TlsKey string `sql:"tls_key"` + CaCert string `sql:"ca_cert"` + EnableTLSVerification bool `sql:"enable_tls_verification"` //models.AuditLog } @@ -61,11 +64,13 @@ func NewGitProviderRepositoryImpl(dbConnection *pg.DB) *GitProviderRepositoryImp } func (impl GitProviderRepositoryImpl) Save(provider *GitProvider) error { + //not doing encryption here as fields are already encrypted in orch and send as it is here _, err := impl.dbConnection.Model(provider).Insert() return err } func (impl GitProviderRepositoryImpl) Update(provider *GitProvider) error { + //not doing encryption here as fields are already encrypted in orch and send as it is here _, err := impl.dbConnection.Model(provider).WherePK().Update() return err } diff --git a/git-sensor/pkg/RepoManages.go b/git-sensor/pkg/RepoManages.go index 90a448727..67e65e43f 100644 --- a/git-sensor/pkg/RepoManages.go +++ b/git-sensor/pkg/RepoManages.go @@ -182,7 +182,7 @@ func (impl RepoManagerImpl) InactivateWebhookDataMappingForPipelineMaterials(old func (impl RepoManagerImpl) updateCommitsInPipelineMaterial(gitCtx git.GitContext, material *sql.GitMaterial, pipelineMaterial *sql.CiPipelineMaterial) *sql.CiPipelineMaterial { - gitCtx = gitCtx.WithCredentials(material.GitProvider.UserName, material.GitProvider.Password). + gitCtx = gitCtx.WithCredentials(material.GitProvider.UserName, material.GitProvider.Password.String()). WithTLSData(material.GitProvider.CaCert, material.GitProvider.TlsKey, material.GitProvider.TlsCert, material.GitProvider.EnableTLSVerification) fetchCount := impl.configuration.GitHistoryCount @@ -248,7 +248,7 @@ func (impl RepoManagerImpl) SaveGitProvider(provider *sql.GitProvider) (*sql.Git } if (err == nil) && (provider.AuthMode == sql.AUTH_MODE_SSH) { - err = git.CreateOrUpdateSshPrivateKeyOnDisk(provider.Id, provider.SshPrivateKey) + err = git.CreateOrUpdateSshPrivateKeyOnDisk(provider.Id, provider.SshPrivateKey.String()) if err != nil { impl.logger.Errorw("error in creating/updating ssh private key ", "err", err) } @@ -393,7 +393,7 @@ func (impl RepoManagerImpl) checkoutMaterial(gitCtx git.GitContext, material *sq checkoutLocationForFetching := impl.repositoryManager.GetCheckoutLocation(gitCtx, material, gitProvider.Url, checkoutPath) - errMsg, err := impl.repositoryManager.Add(gitCtx, material.GitProviderId, checkoutPath, material.Url, gitProvider.AuthMode, gitProvider.SshPrivateKey) + errMsg, err := impl.repositoryManager.Add(gitCtx, material.GitProviderId, checkoutPath, material.Url, gitProvider.AuthMode, gitProvider.SshPrivateKey.String()) if err != nil { impl.logger.Errorw("error encountered in adding git repo", "materialId", material.Id, "err", err, "errMsg", errMsg) material.CheckoutStatus = false @@ -800,7 +800,7 @@ func (impl RepoManagerImpl) GetCommitMetadataForPipelineMaterial(gitCtx git.GitC return nil, err } - gitCtx = gitCtx.WithCredentials(gitMaterial.GitProvider.UserName, gitMaterial.GitProvider.Password). + gitCtx = gitCtx.WithCredentials(gitMaterial.GitProvider.UserName, gitMaterial.GitProvider.Password.String()). WithTLSData(gitMaterial.GitProvider.CaCert, gitMaterial.GitProvider.TlsKey, gitMaterial.GitProvider.TlsCert, gitMaterial.GitProvider.EnableTLSVerification) // validate checkout status of gitMaterial if !gitMaterial.CheckoutStatus { impl.logger.Errorw("checkout not success", "gitMaterialId", gitMaterialId) @@ -859,7 +859,7 @@ func (impl RepoManagerImpl) GetReleaseChanges(gitCtx git.GitContext, request *Re impl.locker.ReturnLocker(gitMaterial.Id) }() - gitCtx = gitCtx.WithCredentials(gitMaterial.GitProvider.UserName, gitMaterial.GitProvider.Password). + gitCtx = gitCtx.WithCredentials(gitMaterial.GitProvider.UserName, gitMaterial.GitProvider.Password.String()). WithTLSData(gitMaterial.GitProvider.CaCert, gitMaterial.GitProvider.TlsKey, gitMaterial.GitProvider.TlsCert, gitMaterial.GitProvider.EnableTLSVerification) gitChanges, err := impl.repositoryManagerAnalytics.ChangesSinceByRepositoryForAnalytics(gitCtx, gitMaterial.CheckoutLocation, request.OldCommit, request.NewCommit) diff --git a/git-sensor/pkg/git/Util.go b/git-sensor/pkg/git/Util.go index 2b96e6eee..d067b1bac 100644 --- a/git-sensor/pkg/git/Util.go +++ b/git-sensor/pkg/git/Util.go @@ -72,10 +72,10 @@ func GetCheckoutPath(url string, cloneLocation string) string { func GetUserNamePassword(gitProvider *sql.GitProvider) (userName, password string, err error) { switch gitProvider.AuthMode { case sql.AUTH_MODE_USERNAME_PASSWORD: - return gitProvider.UserName, gitProvider.Password, nil + return gitProvider.UserName, gitProvider.Password.String(), nil case sql.AUTH_MODE_ACCESS_TOKEN: - return gitProvider.UserName, gitProvider.AccessToken, nil + return gitProvider.UserName, gitProvider.AccessToken.String(), nil case sql.AUTH_MODE_ANONYMOUS: return "", "", nil case sql.AUTH_MODE_SSH: diff --git a/git-sensor/pkg/git/Watcher.go b/git-sensor/pkg/git/Watcher.go index c0ff1d51a..19f811263 100644 --- a/git-sensor/pkg/git/Watcher.go +++ b/git-sensor/pkg/git/Watcher.go @@ -201,7 +201,7 @@ func (impl *GitWatcherImpl) handleSshKeyCreationAndRetry(gitCtx GitContext, mate return false, nil, errMsg, err } } - _, errMsg, err = impl.repositoryManager.CreateSshFileIfNotExistsAndConfigureSshCommand(gitCtx, location, gitProvider.Id, gitProvider.SshPrivateKey) + _, errMsg, err = impl.repositoryManager.CreateSshFileIfNotExistsAndConfigureSshCommand(gitCtx, location, gitProvider.Id, gitProvider.SshPrivateKey.String()) if err != nil { impl.logger.Errorw("error in creating/configuring ssh private key on disk ", "repo", material.Url, "gitProviderId", gitProvider.Id, "errMsg", errMsg, "err", err) return false, nil, errMsg, err diff --git a/git-sensor/vendor/dario.cat/mergo/.gitignore b/git-sensor/vendor/dario.cat/mergo/.gitignore index 45ad0f1ae..529c3412b 100644 --- a/git-sensor/vendor/dario.cat/mergo/.gitignore +++ b/git-sensor/vendor/dario.cat/mergo/.gitignore @@ -13,9 +13,6 @@ # Output of the go coverage tool, specifically when used with LiteIDE *.out -# Golang/Intellij -.idea - # Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 .glide/ diff --git a/git-sensor/vendor/dario.cat/mergo/FUNDING.json b/git-sensor/vendor/dario.cat/mergo/FUNDING.json deleted file mode 100644 index 0585e1fe1..000000000 --- a/git-sensor/vendor/dario.cat/mergo/FUNDING.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "drips": { - "ethereum": { - "ownedBy": "0x6160020e7102237aC41bdb156e94401692D76930" - } - } -} diff --git a/git-sensor/vendor/dario.cat/mergo/README.md b/git-sensor/vendor/dario.cat/mergo/README.md index 0e4a59afd..7d0cf9f32 100644 --- a/git-sensor/vendor/dario.cat/mergo/README.md +++ b/git-sensor/vendor/dario.cat/mergo/README.md @@ -44,21 +44,13 @@ Also a lovely [comune](http://en.wikipedia.org/wiki/Mergo) (municipality) in the ## Status -Mergo is stable and frozen, ready for production. Check a short list of the projects using at large scale it [here](https://github.com/imdario/mergo#mergo-in-the-wild). - -No new features are accepted. They will be considered for a future v2 that improves the implementation and fixes bugs for corner cases. +It is ready for production use. [It is used in several projects by Docker, Google, The Linux Foundation, VMWare, Shopify, Microsoft, etc](https://github.com/imdario/mergo#mergo-in-the-wild). ### Important notes #### 1.0.0 -In [1.0.0](//github.com/imdario/mergo/releases/tag/1.0.0) Mergo moves to a vanity URL `dario.cat/mergo`. No more v1 versions will be released. - -If the vanity URL is causing issues in your project due to a dependency pulling Mergo - it isn't a direct dependency in your project - it is recommended to use [replace](https://github.com/golang/go/wiki/Modules#when-should-i-use-the-replace-directive) to pin the version to the last one with the old import URL: - -``` -replace github.com/imdario/mergo => github.com/imdario/mergo v0.3.16 -``` +In [1.0.0](//github.com/imdario/mergo/releases/tag/1.0.0) Mergo moves to a vanity URL `dario.cat/mergo`. #### 0.3.9 @@ -72,23 +64,55 @@ If you were using Mergo before April 6th, 2015, please check your project works If Mergo is useful to you, consider buying me a coffee, a beer, or making a monthly donation to allow me to keep building great free software. :heart_eyes: +Buy Me a Coffee at ko-fi.com Donate using Liberapay Become my sponsor ### Mergo in the wild -Mergo is used by [thousands](https://deps.dev/go/dario.cat%2Fmergo/v1.0.0/dependents) [of](https://deps.dev/go/github.com%2Fimdario%2Fmergo/v0.3.16/dependents) [projects](https://deps.dev/go/github.com%2Fimdario%2Fmergo/v0.3.12), including: - -* [containerd/containerd](https://github.com/containerd/containerd) -* [datadog/datadog-agent](https://github.com/datadog/datadog-agent) -* [docker/cli/](https://github.com/docker/cli/) -* [goreleaser/goreleaser](https://github.com/goreleaser/goreleaser) -* [go-micro/go-micro](https://github.com/go-micro/go-micro) -* [grafana/loki](https://github.com/grafana/loki) -* [masterminds/sprig](github.com/Masterminds/sprig) -* [moby/moby](https://github.com/moby/moby) -* [slackhq/nebula](https://github.com/slackhq/nebula) -* [volcano-sh/volcano](https://github.com/volcano-sh/volcano) +- [moby/moby](https://github.com/moby/moby) +- [kubernetes/kubernetes](https://github.com/kubernetes/kubernetes) +- [vmware/dispatch](https://github.com/vmware/dispatch) +- [Shopify/themekit](https://github.com/Shopify/themekit) +- [imdario/zas](https://github.com/imdario/zas) +- [matcornic/hermes](https://github.com/matcornic/hermes) +- [OpenBazaar/openbazaar-go](https://github.com/OpenBazaar/openbazaar-go) +- [kataras/iris](https://github.com/kataras/iris) +- [michaelsauter/crane](https://github.com/michaelsauter/crane) +- [go-task/task](https://github.com/go-task/task) +- [sensu/uchiwa](https://github.com/sensu/uchiwa) +- [ory/hydra](https://github.com/ory/hydra) +- [sisatech/vcli](https://github.com/sisatech/vcli) +- [dairycart/dairycart](https://github.com/dairycart/dairycart) +- [projectcalico/felix](https://github.com/projectcalico/felix) +- [resin-os/balena](https://github.com/resin-os/balena) +- [go-kivik/kivik](https://github.com/go-kivik/kivik) +- [Telefonica/govice](https://github.com/Telefonica/govice) +- [supergiant/supergiant](supergiant/supergiant) +- [SergeyTsalkov/brooce](https://github.com/SergeyTsalkov/brooce) +- [soniah/dnsmadeeasy](https://github.com/soniah/dnsmadeeasy) +- [ohsu-comp-bio/funnel](https://github.com/ohsu-comp-bio/funnel) +- [EagerIO/Stout](https://github.com/EagerIO/Stout) +- [lynndylanhurley/defsynth-api](https://github.com/lynndylanhurley/defsynth-api) +- [russross/canvasassignments](https://github.com/russross/canvasassignments) +- [rdegges/cryptly-api](https://github.com/rdegges/cryptly-api) +- [casualjim/exeggutor](https://github.com/casualjim/exeggutor) +- [divshot/gitling](https://github.com/divshot/gitling) +- [RWJMurphy/gorl](https://github.com/RWJMurphy/gorl) +- [andrerocker/deploy42](https://github.com/andrerocker/deploy42) +- [elwinar/rambler](https://github.com/elwinar/rambler) +- [tmaiaroto/gopartman](https://github.com/tmaiaroto/gopartman) +- [jfbus/impressionist](https://github.com/jfbus/impressionist) +- [Jmeyering/zealot](https://github.com/Jmeyering/zealot) +- [godep-migrator/rigger-host](https://github.com/godep-migrator/rigger-host) +- [Dronevery/MultiwaySwitch-Go](https://github.com/Dronevery/MultiwaySwitch-Go) +- [thoas/picfit](https://github.com/thoas/picfit) +- [mantasmatelis/whooplist-server](https://github.com/mantasmatelis/whooplist-server) +- [jnuthong/item_search](https://github.com/jnuthong/item_search) +- [bukalapak/snowboard](https://github.com/bukalapak/snowboard) +- [containerssh/containerssh](https://github.com/containerssh/containerssh) +- [goreleaser/goreleaser](https://github.com/goreleaser/goreleaser) +- [tjpnz/structbot](https://github.com/tjpnz/structbot) ## Install @@ -117,39 +141,6 @@ if err := mergo.Merge(&dst, src, mergo.WithOverride); err != nil { } ``` -If you need to override pointers, so the source pointer's value is assigned to the destination's pointer, you must use `WithoutDereference`: - -```go -package main - -import ( - "fmt" - - "dario.cat/mergo" -) - -type Foo struct { - A *string - B int64 -} - -func main() { - first := "first" - second := "second" - src := Foo{ - A: &first, - B: 2, - } - - dest := Foo{ - A: &second, - B: 1, - } - - mergo.Merge(&dest, src, mergo.WithOverride, mergo.WithoutDereference) -} -``` - Additionally, you can map a `map[string]interface{}` to a struct (and otherwise, from struct to map), following the same restrictions as in `Merge()`. Keys are capitalized to find each corresponding exported field. ```go @@ -190,6 +181,10 @@ func main() { } ``` +Note: if test are failing due missing package, please execute: + + go get gopkg.in/yaml.v3 + ### Transformers Transformers allow to merge specific types differently than in the default behavior. In other words, now you can customize how some types are merged. For example, `time.Time` is a struct; it doesn't have zero value but IsZero can return true because it has fields with zero value. How can we merge a non-zero `time.Time`? diff --git a/git-sensor/vendor/dario.cat/mergo/SECURITY.md b/git-sensor/vendor/dario.cat/mergo/SECURITY.md index 3788fcc1c..a5de61f77 100644 --- a/git-sensor/vendor/dario.cat/mergo/SECURITY.md +++ b/git-sensor/vendor/dario.cat/mergo/SECURITY.md @@ -4,8 +4,8 @@ | Version | Supported | | ------- | ------------------ | -| 1.x.x | :white_check_mark: | -| < 1.0 | :x: | +| 0.3.x | :white_check_mark: | +| < 0.3 | :x: | ## Security contact information diff --git a/git-sensor/vendor/dario.cat/mergo/map.go b/git-sensor/vendor/dario.cat/mergo/map.go index 759b4f74f..b50d5c2a4 100644 --- a/git-sensor/vendor/dario.cat/mergo/map.go +++ b/git-sensor/vendor/dario.cat/mergo/map.go @@ -58,7 +58,7 @@ func deepMap(dst, src reflect.Value, visited map[uintptr]*visit, depth int, conf } fieldName := field.Name fieldName = changeInitialCase(fieldName, unicode.ToLower) - if _, ok := dstMap[fieldName]; !ok || (!isEmptyValue(reflect.ValueOf(src.Field(i).Interface()), !config.ShouldNotDereference) && overwrite) || config.overwriteWithEmptyValue { + if v, ok := dstMap[fieldName]; !ok || (isEmptyValue(reflect.ValueOf(v), !config.ShouldNotDereference) || overwrite) { dstMap[fieldName] = src.Field(i).Interface() } } diff --git a/git-sensor/vendor/dario.cat/mergo/merge.go b/git-sensor/vendor/dario.cat/mergo/merge.go index fd47c95b2..0ef9b2138 100644 --- a/git-sensor/vendor/dario.cat/mergo/merge.go +++ b/git-sensor/vendor/dario.cat/mergo/merge.go @@ -269,7 +269,7 @@ func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, co if err = deepMerge(dst.Elem(), src.Elem(), visited, depth+1, config); err != nil { return } - } else if src.Elem().Kind() != reflect.Struct { + } else { if overwriteWithEmptySrc || (overwrite && !src.IsNil()) || dst.IsNil() { dst.Set(src) } diff --git a/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/errors/errors.go b/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/errors/errors.go index 2e341507a..0eb3937b3 100644 --- a/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/errors/errors.go +++ b/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/errors/errors.go @@ -6,7 +6,6 @@ package errors // import "github.com/ProtonMail/go-crypto/openpgp/errors" import ( - "fmt" "strconv" ) @@ -179,32 +178,3 @@ type ErrMalformedMessage string func (dke ErrMalformedMessage) Error() string { return "openpgp: malformed message " + string(dke) } - -type messageTooLargeError int - -func (e messageTooLargeError) Error() string { - return "openpgp: decompressed message size exceeds provided limit" -} - -// ErrMessageTooLarge is returned if the read data from -// a compressed packet exceeds the provided limit. -var ErrMessageTooLarge error = messageTooLargeError(0) - -// ErrEncryptionKeySelection is returned if encryption key selection fails (v2 API). -type ErrEncryptionKeySelection struct { - PrimaryKeyId string - PrimaryKeyErr error - EncSelectionKeyId *string - EncSelectionErr error -} - -func (eks ErrEncryptionKeySelection) Error() string { - prefix := fmt.Sprintf("openpgp: key selection for primary key %s:", eks.PrimaryKeyId) - if eks.PrimaryKeyErr != nil { - return fmt.Sprintf("%s invalid primary key: %s", prefix, eks.PrimaryKeyErr) - } - if eks.EncSelectionKeyId != nil { - return fmt.Sprintf("%s invalid encryption key %s: %s", prefix, *eks.EncSelectionKeyId, eks.EncSelectionErr) - } - return fmt.Sprintf("%s no encryption key: %s", prefix, eks.EncSelectionErr) -} diff --git a/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/aead_config.go b/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/aead_config.go index ef100d372..fec41a0e7 100644 --- a/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/aead_config.go +++ b/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/aead_config.go @@ -37,7 +37,7 @@ func (conf *AEADConfig) Mode() AEADMode { // ChunkSizeByte returns the byte indicating the chunk size. The effective // chunk size is computed with the formula uint64(1) << (chunkSizeByte + 6) -// limit chunkSizeByte to 16 which equals to 2^22 = 4 MiB +// limit to 16 = 4 MiB // https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-07.html#section-5.13.2 func (conf *AEADConfig) ChunkSizeByte() byte { if conf == nil || conf.ChunkSize == 0 { @@ -49,8 +49,8 @@ func (conf *AEADConfig) ChunkSizeByte() byte { switch { case exponent < 6: exponent = 6 - case exponent > 22: - exponent = 22 + case exponent > 16: + exponent = 16 } return byte(exponent - 6) diff --git a/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/compressed.go b/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/compressed.go index 931f55a4e..0bcb38cac 100644 --- a/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/compressed.go +++ b/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/compressed.go @@ -98,16 +98,6 @@ func (c *Compressed) parse(r io.Reader) error { return err } -// LimitedBodyReader wraps the provided body reader with a limiter that restricts -// the number of bytes read to the specified limit. -// If limit is nil, the reader is unbounded. -func (c *Compressed) LimitedBodyReader(limit *int64) io.Reader { - if limit == nil { - return c.Body - } - return &LimitReader{R: c.Body, N: *limit} -} - // compressedWriterCloser represents the serialized compression stream // header and the compressor. Its Close() method ensures that both the // compressor and serialized stream header are closed. Its Write() @@ -169,24 +159,3 @@ func SerializeCompressed(w io.WriteCloser, algo CompressionAlgo, cc *Compression return } - -// LimitReader is an io.Reader that fails with MessageToLarge if read bytes exceed N. -type LimitReader struct { - R io.Reader // underlying reader - N int64 // max bytes allowed -} - -func (l *LimitReader) Read(p []byte) (int, error) { - if l.N <= 0 { - return 0, errors.ErrMessageTooLarge - } - - n, err := l.R.Read(p) - l.N -= int64(n) - - if err == nil && l.N <= 0 { - err = errors.ErrMessageTooLarge - } - - return n, err -} diff --git a/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/config.go b/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/config.go index 30167ed9d..8bf8e6e51 100644 --- a/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/config.go +++ b/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/config.go @@ -173,16 +173,6 @@ type Config struct { // weaknesses in the hash algo, potentially hindering e.g. some chosen-prefix attacks. // The default behavior, when the config or flag is nil, is to enable the feature. NonDeterministicSignaturesViaNotation *bool - - // InsecureAllowAllKeyFlagsWhenMissing determines how a key without valid key flags is handled. - // When set to true, a key without flags is treated as if all flags are enabled. - // This behavior is consistent with GPG. - InsecureAllowAllKeyFlagsWhenMissing bool - - // MaxDecompressedMessageSize specifies the maximum number of bytes that can be - // read from a compressed packet. This serves as an upper limit to prevent - // excessively large decompressed messages. - MaxDecompressedMessageSize *int64 } func (c *Config) Random() io.Reader { @@ -413,20 +403,6 @@ func (c *Config) RandomizeSignaturesViaNotation() bool { return *c.NonDeterministicSignaturesViaNotation } -func (c *Config) AllowAllKeyFlagsWhenMissing() bool { - if c == nil { - return false - } - return c.InsecureAllowAllKeyFlagsWhenMissing -} - -func (c *Config) DecompressedMessageSizeLimit() *int64 { - if c == nil { - return nil - } - return c.MaxDecompressedMessageSize -} - // BoolPointer is a helper function to set a boolean pointer in the Config. // e.g., config.CheckPacketSequence = BoolPointer(true) func BoolPointer(value bool) *bool { diff --git a/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/public_key.go b/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/public_key.go index e2813396e..f8da781bb 100644 --- a/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/public_key.go +++ b/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/public_key.go @@ -1048,17 +1048,12 @@ func (pk *PublicKey) VerifyDirectKeySignature(sig *Signature) (err error) { // KeyIdString returns the public key's fingerprint in capital hex // (e.g. "6C7EE1B8621CC013"). func (pk *PublicKey) KeyIdString() string { - return fmt.Sprintf("%016X", pk.KeyId) + return fmt.Sprintf("%X", pk.Fingerprint[12:20]) } // KeyIdShortString returns the short form of public key's fingerprint // in capital hex, as shown by gpg --list-keys (e.g. "621CC013"). -// This function will return the full key id for v5 and v6 keys -// since the short key id is undefined for them. func (pk *PublicKey) KeyIdShortString() string { - if pk.Version >= 5 { - return pk.KeyIdString() - } return fmt.Sprintf("%X", pk.Fingerprint[16:20]) } diff --git a/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/signature.go b/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/signature.go index 84dd3b86f..3a4b366d8 100644 --- a/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/signature.go +++ b/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/signature.go @@ -1288,9 +1288,7 @@ func (sig *Signature) buildSubpackets(issuer PublicKey) (subpackets []outputSubp if sig.IssuerKeyId != nil && sig.Version == 4 { keyId := make([]byte, 8) binary.BigEndian.PutUint64(keyId, *sig.IssuerKeyId) - // Note: making this critical breaks RPM <=4.16. - // See: https://github.com/ProtonMail/go-crypto/issues/263 - subpackets = append(subpackets, outputSubpacket{true, issuerSubpacket, false, keyId}) + subpackets = append(subpackets, outputSubpacket{true, issuerSubpacket, true, keyId}) } // Notation Data for _, notation := range sig.Notations { diff --git a/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/read.go b/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/read.go index 5578797ed..e6dd9b5fd 100644 --- a/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/read.go +++ b/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/read.go @@ -259,7 +259,7 @@ FindLiteralData: } switch p := p.(type) { case *packet.Compressed: - if err := packets.Push(p.LimitedBodyReader(config.DecompressedMessageSizeLimit())); err != nil { + if err := packets.Push(p.Body); err != nil { return nil, err } case *packet.OnePassSignature: diff --git a/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/write.go b/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/write.go index 84bc27d83..b0f6ef7b0 100644 --- a/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/write.go +++ b/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/write.go @@ -253,12 +253,34 @@ func writeAndSign(payload io.WriteCloser, candidateHashes []uint8, signed *Entit } var hash crypto.Hash - var salt []byte - if signer != nil { - if hash, err = selectHash(candidateHashes, config.Hash(), signer); err != nil { - return nil, err + for _, hashId := range candidateHashes { + if h, ok := algorithm.HashIdToHash(hashId); ok && h.Available() { + hash = h + break + } + } + + // If the hash specified by config is a candidate, we'll use that. + if configuredHash := config.Hash(); configuredHash.Available() { + for _, hashId := range candidateHashes { + if h, ok := algorithm.HashIdToHash(hashId); ok && h == configuredHash { + hash = h + break + } + } + } + + if hash == 0 { + hashId := candidateHashes[0] + name, ok := algorithm.HashIdToString(hashId) + if !ok { + name = "#" + strconv.Itoa(int(hashId)) } + return nil, errors.InvalidArgumentError("cannot encrypt because no candidate hash functions are compiled in. (Wanted " + name + " in this case.)") + } + var salt []byte + if signer != nil { var opsVersion = 3 if signer.Version == 6 { opsVersion = signer.Version @@ -536,34 +558,13 @@ func (s signatureWriter) Close() error { return s.encryptedData.Close() } -func selectHashForSigningKey(config *packet.Config, signer *packet.PublicKey) crypto.Hash { - acceptableHashes := acceptableHashesToWrite(signer) - hash, ok := algorithm.HashToHashId(config.Hash()) - if !ok { - return config.Hash() - } - for _, acceptableHashes := range acceptableHashes { - if acceptableHashes == hash { - return config.Hash() - } - } - if len(acceptableHashes) > 0 { - defaultAcceptedHash, ok := algorithm.HashIdToHash(acceptableHashes[0]) - if ok { - return defaultAcceptedHash - } - } - return config.Hash() -} - func createSignaturePacket(signer *packet.PublicKey, sigType packet.SignatureType, config *packet.Config) *packet.Signature { sigLifetimeSecs := config.SigLifetime() - hash := selectHashForSigningKey(config, signer) return &packet.Signature{ Version: signer.Version, SigType: sigType, PubKeyAlgo: signer.PubKeyAlgo, - Hash: hash, + Hash: config.Hash(), CreationTime: config.Now(), IssuerKeyId: &signer.KeyId, IssuerFingerprint: signer.Fingerprint, @@ -617,74 +618,3 @@ func handleCompression(compressed io.WriteCloser, candidateCompression []uint8, } return data, nil } - -// selectHash selects the preferred hash given the candidateHashes and the configuredHash -func selectHash(candidateHashes []byte, configuredHash crypto.Hash, signer *packet.PrivateKey) (hash crypto.Hash, err error) { - acceptableHashes := acceptableHashesToWrite(&signer.PublicKey) - candidateHashes = intersectPreferences(acceptableHashes, candidateHashes) - - for _, hashId := range candidateHashes { - if h, ok := algorithm.HashIdToHash(hashId); ok && h.Available() { - hash = h - break - } - } - - // If the hash specified by config is a candidate, we'll use that. - if configuredHash.Available() { - for _, hashId := range candidateHashes { - if h, ok := algorithm.HashIdToHash(hashId); ok && h == configuredHash { - hash = h - break - } - } - } - - if hash == 0 { - if len(acceptableHashes) > 0 { - if h, ok := algorithm.HashIdToHash(acceptableHashes[0]); ok { - hash = h - } else { - return 0, errors.UnsupportedError("no candidate hash functions are compiled in.") - } - } else { - return 0, errors.UnsupportedError("no candidate hash functions are compiled in.") - } - } - return -} - -func acceptableHashesToWrite(singingKey *packet.PublicKey) []uint8 { - switch singingKey.PubKeyAlgo { - case packet.PubKeyAlgoEd448: - return []uint8{ - hashToHashId(crypto.SHA512), - hashToHashId(crypto.SHA3_512), - } - case packet.PubKeyAlgoECDSA, packet.PubKeyAlgoEdDSA: - if curve, err := singingKey.Curve(); err == nil { - if curve == packet.Curve448 || - curve == packet.CurveNistP521 || - curve == packet.CurveBrainpoolP512 { - return []uint8{ - hashToHashId(crypto.SHA512), - hashToHashId(crypto.SHA3_512), - } - } else if curve == packet.CurveBrainpoolP384 || - curve == packet.CurveNistP384 { - return []uint8{ - hashToHashId(crypto.SHA384), - hashToHashId(crypto.SHA512), - hashToHashId(crypto.SHA3_512), - } - } - } - } - return []uint8{ - hashToHashId(crypto.SHA256), - hashToHashId(crypto.SHA384), - hashToHashId(crypto.SHA512), - hashToHashId(crypto.SHA3_256), - hashToHashId(crypto.SHA3_512), - } -} diff --git a/git-sensor/vendor/github.com/cloudflare/circl/dh/x25519/curve_amd64.s b/git-sensor/vendor/github.com/cloudflare/circl/dh/x25519/curve_amd64.s index ce9f06289..b7723185b 100644 --- a/git-sensor/vendor/github.com/cloudflare/circl/dh/x25519/curve_amd64.s +++ b/git-sensor/vendor/github.com/cloudflare/circl/dh/x25519/curve_amd64.s @@ -1,5 +1,4 @@ -//go:build amd64 && !purego -// +build amd64,!purego +// +build amd64 #include "textflag.h" diff --git a/git-sensor/vendor/github.com/cloudflare/circl/dh/x448/curve_amd64.s b/git-sensor/vendor/github.com/cloudflare/circl/dh/x448/curve_amd64.s index ed33ba3d0..810aa9e64 100644 --- a/git-sensor/vendor/github.com/cloudflare/circl/dh/x448/curve_amd64.s +++ b/git-sensor/vendor/github.com/cloudflare/circl/dh/x448/curve_amd64.s @@ -1,5 +1,4 @@ -//go:build amd64 && !purego -// +build amd64,!purego +// +build amd64 #include "textflag.h" diff --git a/git-sensor/vendor/github.com/cloudflare/circl/ecc/goldilocks/curve.go b/git-sensor/vendor/github.com/cloudflare/circl/ecc/goldilocks/curve.go index 1f165141a..5a939100d 100644 --- a/git-sensor/vendor/github.com/cloudflare/circl/ecc/goldilocks/curve.go +++ b/git-sensor/vendor/github.com/cloudflare/circl/ecc/goldilocks/curve.go @@ -18,9 +18,6 @@ func (Curve) Identity() *Point { func (Curve) IsOnCurve(P *Point) bool { x2, y2, t, t2, z2 := &fp.Elt{}, &fp.Elt{}, &fp.Elt{}, &fp.Elt{}, &fp.Elt{} rhs, lhs := &fp.Elt{}, &fp.Elt{} - // Check z != 0 - eq0 := !fp.IsZero(&P.z) - fp.Mul(t, &P.ta, &P.tb) // t = ta*tb fp.Sqr(x2, &P.x) // x^2 fp.Sqr(y2, &P.y) // y^2 @@ -30,14 +27,13 @@ func (Curve) IsOnCurve(P *Point) bool { fp.Mul(rhs, t2, ¶mD) // dt^2 fp.Add(rhs, rhs, z2) // z^2 + dt^2 fp.Sub(lhs, lhs, rhs) // x^2 + y^2 - (z^2 + dt^2) - eq1 := fp.IsZero(lhs) + eq0 := fp.IsZero(lhs) fp.Mul(lhs, &P.x, &P.y) // xy fp.Mul(rhs, t, &P.z) // tz fp.Sub(lhs, lhs, rhs) // xy - tz - eq2 := fp.IsZero(lhs) - - return eq0 && eq1 && eq2 + eq1 := fp.IsZero(lhs) + return eq0 && eq1 } // Generator returns the generator point. diff --git a/git-sensor/vendor/github.com/cloudflare/circl/internal/conv/conv.go b/git-sensor/vendor/github.com/cloudflare/circl/internal/conv/conv.go index 3fd0df496..649a8e931 100644 --- a/git-sensor/vendor/github.com/cloudflare/circl/internal/conv/conv.go +++ b/git-sensor/vendor/github.com/cloudflare/circl/internal/conv/conv.go @@ -5,8 +5,6 @@ import ( "fmt" "math/big" "strings" - - "golang.org/x/crypto/cryptobyte" ) // BytesLe2Hex returns an hexadecimal string of a number stored in a @@ -140,34 +138,3 @@ func BigInt2Uint64Le(z []uint64, x *big.Int) { z[i] = 0 } } - -// MarshalBinary encodes a value into a byte array in a format readable by UnmarshalBinary. -func MarshalBinary(v cryptobyte.MarshalingValue) ([]byte, error) { - const DefaultSize = 32 - b := cryptobyte.NewBuilder(make([]byte, 0, DefaultSize)) - b.AddValue(v) - return b.Bytes() -} - -// MarshalBinaryLen encodes a value into an array of n bytes in a format readable by UnmarshalBinary. -func MarshalBinaryLen(v cryptobyte.MarshalingValue, length uint) ([]byte, error) { - b := cryptobyte.NewFixedBuilder(make([]byte, 0, length)) - b.AddValue(v) - return b.Bytes() -} - -// A UnmarshalingValue decodes itself from a cryptobyte.String and advances the pointer. -// It reports whether the read was successful. -type UnmarshalingValue interface { - Unmarshal(*cryptobyte.String) bool -} - -// UnmarshalBinary recovers a value from a byte array. -// It returns an error if the read was unsuccessful. -func UnmarshalBinary(v UnmarshalingValue, data []byte) (err error) { - s := cryptobyte.String(data) - if data == nil || !v.Unmarshal(&s) || !s.Empty() { - err = fmt.Errorf("cannot read %T from input string", v) - } - return -} diff --git a/git-sensor/vendor/github.com/cloudflare/circl/math/fp25519/fp_amd64.s b/git-sensor/vendor/github.com/cloudflare/circl/math/fp25519/fp_amd64.s index 1fcc2dee1..5c4aeddec 100644 --- a/git-sensor/vendor/github.com/cloudflare/circl/math/fp25519/fp_amd64.s +++ b/git-sensor/vendor/github.com/cloudflare/circl/math/fp25519/fp_amd64.s @@ -1,5 +1,4 @@ -//go:build amd64 && !purego -// +build amd64,!purego +// +build amd64 #include "textflag.h" #include "fp_amd64.h" diff --git a/git-sensor/vendor/github.com/cloudflare/circl/math/fp448/fp_amd64.s b/git-sensor/vendor/github.com/cloudflare/circl/math/fp448/fp_amd64.s index 3f1f07c98..435addf5e 100644 --- a/git-sensor/vendor/github.com/cloudflare/circl/math/fp448/fp_amd64.s +++ b/git-sensor/vendor/github.com/cloudflare/circl/math/fp448/fp_amd64.s @@ -1,5 +1,4 @@ -//go:build amd64 && !purego -// +build amd64,!purego +// +build amd64 #include "textflag.h" #include "fp_amd64.h" diff --git a/git-sensor/vendor/github.com/cloudflare/circl/math/integer.go b/git-sensor/vendor/github.com/cloudflare/circl/math/integer.go deleted file mode 100644 index 9c80c23b5..000000000 --- a/git-sensor/vendor/github.com/cloudflare/circl/math/integer.go +++ /dev/null @@ -1,16 +0,0 @@ -package math - -import "math/bits" - -// NextPow2 finds the next power of two (N=2^k, k>=0) greater than n. -// If n is already a power of two, then this function returns n, and log2(n). -func NextPow2(n uint) (N uint, k uint) { - if bits.OnesCount(n) == 1 { - k = uint(bits.TrailingZeros(n)) - N = n - } else { - k = uint(bits.Len(n)) - N = uint(1) << k - } - return -} diff --git a/git-sensor/vendor/github.com/cloudflare/circl/sign/ed25519/point.go b/git-sensor/vendor/github.com/cloudflare/circl/sign/ed25519/point.go index d1c3b146b..374a69503 100644 --- a/git-sensor/vendor/github.com/cloudflare/circl/sign/ed25519/point.go +++ b/git-sensor/vendor/github.com/cloudflare/circl/sign/ed25519/point.go @@ -164,7 +164,7 @@ func (P *pointR1) isEqual(Q *pointR1) bool { fp.Mul(r, r, &P.z) fp.Sub(l, l, r) b = b && fp.IsZero(l) - return b && !fp.IsZero(&P.z) && !fp.IsZero(&Q.z) + return b } func (P *pointR3) neg() { diff --git a/git-sensor/vendor/github.com/cloudflare/circl/sign/ed448/ed448.go b/git-sensor/vendor/github.com/cloudflare/circl/sign/ed448/ed448.go index c368b181b..324bd8f33 100644 --- a/git-sensor/vendor/github.com/cloudflare/circl/sign/ed448/ed448.go +++ b/git-sensor/vendor/github.com/cloudflare/circl/sign/ed448/ed448.go @@ -206,7 +206,7 @@ func newKeyFromSeed(privateKey, seed []byte) { func signAll(signature []byte, privateKey PrivateKey, message, ctx []byte, preHash bool) { if len(ctx) > ContextMaxSize { - panic(fmt.Errorf("ed448: bad context length: %v", len(ctx))) + panic(fmt.Errorf("ed448: bad context length: " + strconv.Itoa(len(ctx)))) } H := sha3.NewShake256() diff --git a/git-sensor/vendor/github.com/cloudflare/circl/sign/sign.go b/git-sensor/vendor/github.com/cloudflare/circl/sign/sign.go index 557d6f096..13b20fa4b 100644 --- a/git-sensor/vendor/github.com/cloudflare/circl/sign/sign.go +++ b/git-sensor/vendor/github.com/cloudflare/circl/sign/sign.go @@ -107,7 +107,4 @@ var ( // ErrContextNotSupported is the error used if a context is not // supported. ErrContextNotSupported = errors.New("context not supported") - - // ErrContextTooLong is the error used if the context string is too long. - ErrContextTooLong = errors.New("context string too long") ) diff --git a/git-sensor/vendor/github.com/cyphar/filepath-securejoin/CHANGELOG.md b/git-sensor/vendor/github.com/cyphar/filepath-securejoin/CHANGELOG.md index ca0e3c62c..cb1252b53 100644 --- a/git-sensor/vendor/github.com/cyphar/filepath-securejoin/CHANGELOG.md +++ b/git-sensor/vendor/github.com/cyphar/filepath-securejoin/CHANGELOG.md @@ -6,51 +6,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] ## -## [0.4.1] - 2025-01-28 ## - -### Fixed ### -- The restrictions added for `root` paths passed to `SecureJoin` in 0.4.0 was - found to be too strict and caused some regressions when folks tried to - update, so this restriction has been relaxed to only return an error if the - path contains a `..` component. We still recommend users use `filepath.Clean` - (and even `filepath.EvalSymlinks`) on the `root` path they are using, but at - least you will no longer be punished for "trivial" unclean paths. - -## [0.4.0] - 2025-01-13 ## - -### Breaking #### -- `SecureJoin(VFS)` will now return an error if the provided `root` is not a - `filepath.Clean`'d path. - - While it is ultimately the responsibility of the caller to ensure the root is - a safe path to use, passing a path like `/symlink/..` as a root would result - in the `SecureJoin`'d path being placed in `/` even though `/symlink/..` - might be a different directory, and so we should more strongly discourage - such usage. - - All major users of `securejoin.SecureJoin` already ensure that the paths they - provide are safe (and this is ultimately a question of user error), but - removing this foot-gun is probably a good idea. Of course, this is - necessarily a breaking API change (though we expect no real users to be - affected by it). - - Thanks to [Erik Sjölund](https://github.com/eriksjolund), who initially - reported this issue as a possible security issue. - -- `MkdirAll` and `MkdirHandle` now take an `os.FileMode`-style mode argument - instead of a raw `unix.S_*`-style mode argument, which may cause compile-time - type errors depending on how you use `filepath-securejoin`. For most users, - there will be no change in behaviour aside from the type change (as the - bottom `0o777` bits are the same in both formats, and most users are probably - only using those bits). - - However, if you were using `unix.S_ISVTX` to set the sticky bit with - `MkdirAll(Handle)` you will need to switch to `os.ModeSticky` otherwise you - will get a runtime error with this update. In addition, the error message you - will get from passing `unix.S_ISUID` and `unix.S_ISGID` will be different as - they are treated as invalid bits now (note that previously passing said bits - was also an error). - ## [0.3.6] - 2024-12-17 ## ### Compatibility ### @@ -238,9 +193,7 @@ This is our first release of `github.com/cyphar/filepath-securejoin`, containing a full implementation with a coverage of 93.5% (the only missing cases are the error cases, which are hard to mocktest at the moment). -[Unreleased]: https://github.com/cyphar/filepath-securejoin/compare/v0.4.1...HEAD -[0.4.1]: https://github.com/cyphar/filepath-securejoin/compare/v0.4.0...v0.4.1 -[0.4.0]: https://github.com/cyphar/filepath-securejoin/compare/v0.3.6...v0.4.0 +[Unreleased]: https://github.com/cyphar/filepath-securejoin/compare/v0.3.6...HEAD [0.3.6]: https://github.com/cyphar/filepath-securejoin/compare/v0.3.5...v0.3.6 [0.3.5]: https://github.com/cyphar/filepath-securejoin/compare/v0.3.4...v0.3.5 [0.3.4]: https://github.com/cyphar/filepath-securejoin/compare/v0.3.3...v0.3.4 diff --git a/git-sensor/vendor/github.com/cyphar/filepath-securejoin/VERSION b/git-sensor/vendor/github.com/cyphar/filepath-securejoin/VERSION index 267577d47..449d7e73a 100644 --- a/git-sensor/vendor/github.com/cyphar/filepath-securejoin/VERSION +++ b/git-sensor/vendor/github.com/cyphar/filepath-securejoin/VERSION @@ -1 +1 @@ -0.4.1 +0.3.6 diff --git a/git-sensor/vendor/github.com/cyphar/filepath-securejoin/join.go b/git-sensor/vendor/github.com/cyphar/filepath-securejoin/join.go index e6634d477..e0ee3f2b5 100644 --- a/git-sensor/vendor/github.com/cyphar/filepath-securejoin/join.go +++ b/git-sensor/vendor/github.com/cyphar/filepath-securejoin/join.go @@ -1,5 +1,5 @@ // Copyright (C) 2014-2015 Docker Inc & Go Authors. All rights reserved. -// Copyright (C) 2017-2025 SUSE LLC. All rights reserved. +// Copyright (C) 2017-2024 SUSE LLC. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. @@ -24,31 +24,6 @@ func IsNotExist(err error) bool { return errors.Is(err, os.ErrNotExist) || errors.Is(err, syscall.ENOTDIR) || errors.Is(err, syscall.ENOENT) } -// errUnsafeRoot is returned if the user provides SecureJoinVFS with a path -// that contains ".." components. -var errUnsafeRoot = errors.New("root path provided to SecureJoin contains '..' components") - -// stripVolume just gets rid of the Windows volume included in a path. Based on -// some godbolt tests, the Go compiler is smart enough to make this a no-op on -// Linux. -func stripVolume(path string) string { - return path[len(filepath.VolumeName(path)):] -} - -// hasDotDot checks if the path contains ".." components in a platform-agnostic -// way. -func hasDotDot(path string) bool { - // If we are on Windows, strip any volume letters. It turns out that - // C:..\foo may (or may not) be a valid pathname and we need to handle that - // leading "..". - path = stripVolume(path) - // Look for "/../" in the path, but we need to handle leading and trailing - // ".."s by adding separators. Doing this with filepath.Separator is ugly - // so just convert to Unix-style "/" first. - path = filepath.ToSlash(path) - return strings.Contains("/"+path+"/", "/../") -} - // SecureJoinVFS joins the two given path components (similar to [filepath.Join]) except // that the returned path is guaranteed to be scoped inside the provided root // path (when evaluated). Any symbolic links in the path are evaluated with the @@ -71,22 +46,7 @@ func hasDotDot(path string) bool { // provided via direct input or when evaluating symlinks. Therefore: // // "C:\Temp" + "D:\path\to\file.txt" results in "C:\Temp\path\to\file.txt" -// -// If the provided root is not [filepath.Clean] then an error will be returned, -// as such root paths are bordering on somewhat unsafe and using such paths is -// not best practice. We also strongly suggest that any root path is first -// fully resolved using [filepath.EvalSymlinks] or otherwise constructed to -// avoid containing symlink components. Of course, the root also *must not* be -// attacker-controlled. func SecureJoinVFS(root, unsafePath string, vfs VFS) (string, error) { - // The root path must not contain ".." components, otherwise when we join - // the subpath we will end up with a weird path. We could work around this - // in other ways but users shouldn't be giving us non-lexical root paths in - // the first place. - if hasDotDot(root) { - return "", errUnsafeRoot - } - // Use the os.* VFS implementation if none was specified. if vfs == nil { vfs = osVFS{} @@ -99,10 +59,9 @@ func SecureJoinVFS(root, unsafePath string, vfs VFS) (string, error) { linksWalked int ) for remainingPath != "" { - // On Windows, if we managed to end up at a path referencing a volume, - // drop the volume to make sure we don't end up with broken paths or - // escaping the root volume. - remainingPath = stripVolume(remainingPath) + if v := filepath.VolumeName(remainingPath); v != "" { + remainingPath = remainingPath[len(v):] + } // Get the next path component. var part string diff --git a/git-sensor/vendor/github.com/cyphar/filepath-securejoin/mkdir_linux.go b/git-sensor/vendor/github.com/cyphar/filepath-securejoin/mkdir_linux.go index a17ae3b03..5e559bb7a 100644 --- a/git-sensor/vendor/github.com/cyphar/filepath-securejoin/mkdir_linux.go +++ b/git-sensor/vendor/github.com/cyphar/filepath-securejoin/mkdir_linux.go @@ -21,33 +21,6 @@ var ( errPossibleAttack = errors.New("possible attack detected") ) -// modePermExt is like os.ModePerm except that it also includes the set[ug]id -// and sticky bits. -const modePermExt = os.ModePerm | os.ModeSetuid | os.ModeSetgid | os.ModeSticky - -//nolint:cyclop // this function needs to handle a lot of cases -func toUnixMode(mode os.FileMode) (uint32, error) { - sysMode := uint32(mode.Perm()) - if mode&os.ModeSetuid != 0 { - sysMode |= unix.S_ISUID - } - if mode&os.ModeSetgid != 0 { - sysMode |= unix.S_ISGID - } - if mode&os.ModeSticky != 0 { - sysMode |= unix.S_ISVTX - } - // We don't allow file type bits. - if mode&os.ModeType != 0 { - return 0, fmt.Errorf("%w %+.3o (%s): type bits not permitted", errInvalidMode, mode, mode) - } - // We don't allow other unknown modes. - if mode&^modePermExt != 0 || sysMode&unix.S_IFMT != 0 { - return 0, fmt.Errorf("%w %+.3o (%s): unknown mode bits", errInvalidMode, mode, mode) - } - return sysMode, nil -} - // MkdirAllHandle is equivalent to [MkdirAll], except that it is safer to use // in two respects: // @@ -66,17 +39,17 @@ func toUnixMode(mode os.FileMode) (uint32, error) { // a brand new lookup of unsafePath (such as with [SecureJoin] or openat2) after // doing [MkdirAll]. If you intend to open the directory after creating it, you // should use MkdirAllHandle. -func MkdirAllHandle(root *os.File, unsafePath string, mode os.FileMode) (_ *os.File, Err error) { - unixMode, err := toUnixMode(mode) - if err != nil { - return nil, err +func MkdirAllHandle(root *os.File, unsafePath string, mode int) (_ *os.File, Err error) { + // Make sure there are no os.FileMode bits set. + if mode&^0o7777 != 0 { + return nil, fmt.Errorf("%w for mkdir 0o%.3o", errInvalidMode, mode) } // On Linux, mkdirat(2) (and os.Mkdir) silently ignore the suid and sgid // bits. We could also silently ignore them but since we have very few // users it seems more prudent to return an error so users notice that // these bits will not be set. - if unixMode&^0o1777 != 0 { - return nil, fmt.Errorf("%w for mkdir %+.3o: suid and sgid are ignored by mkdir", errInvalidMode, mode) + if mode&^0o1777 != 0 { + return nil, fmt.Errorf("%w for mkdir 0o%.3o: suid and sgid are ignored by mkdir", errInvalidMode, mode) } // Try to open as much of the path as possible. @@ -131,6 +104,9 @@ func MkdirAllHandle(root *os.File, unsafePath string, mode os.FileMode) (_ *os.F return nil, fmt.Errorf("%w: yet-to-be-created path %q contains '..' components", unix.ENOENT, remainingPath) } + // Make sure the mode doesn't have any type bits. + mode &^= unix.S_IFMT + // Create the remaining components. for _, part := range remainingParts { switch part { @@ -147,7 +123,7 @@ func MkdirAllHandle(root *os.File, unsafePath string, mode os.FileMode) (_ *os.F // directory at the same time as us. In that case, just continue on as // if we created it (if the created inode is not a directory, the // following open call will fail). - if err := unix.Mkdirat(int(currentDir.Fd()), part, unixMode); err != nil && !errors.Is(err, unix.EEXIST) { + if err := unix.Mkdirat(int(currentDir.Fd()), part, uint32(mode)); err != nil && !errors.Is(err, unix.EEXIST) { err = &os.PathError{Op: "mkdirat", Path: currentDir.Name() + "/" + part, Err: err} // Make the error a bit nicer if the directory is dead. if deadErr := isDeadInode(currentDir); deadErr != nil { @@ -220,7 +196,10 @@ func MkdirAllHandle(root *os.File, unsafePath string, mode os.FileMode) (_ *os.F // If you plan to open the directory after you have created it or want to use // an open directory handle as the root, you should use [MkdirAllHandle] instead. // This function is a wrapper around [MkdirAllHandle]. -func MkdirAll(root, unsafePath string, mode os.FileMode) error { +// +// NOTE: The mode argument must be set the unix mode bits (unix.S_I...), not +// the Go generic mode bits ([os.FileMode]...). +func MkdirAll(root, unsafePath string, mode int) error { rootDir, err := os.OpenFile(root, unix.O_PATH|unix.O_DIRECTORY|unix.O_CLOEXEC, 0) if err != nil { return err diff --git a/git-sensor/vendor/github.com/devtron-labs/common-lib/securestore/AttributesRepoDBConnection.go b/git-sensor/vendor/github.com/devtron-labs/common-lib/securestore/AttributesRepoDBConnection.go new file mode 100644 index 000000000..907d202bd --- /dev/null +++ b/git-sensor/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/git-sensor/vendor/github.com/devtron-labs/common-lib/securestore/AttributesRepository.go b/git-sensor/vendor/github.com/devtron-labs/common-lib/securestore/AttributesRepository.go new file mode 100644 index 000000000..eadf7a8f4 --- /dev/null +++ b/git-sensor/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/git-sensor/vendor/github.com/devtron-labs/common-lib/securestore/EncryptionKeyService.go b/git-sensor/vendor/github.com/devtron-labs/common-lib/securestore/EncryptionKeyService.go new file mode 100644 index 000000000..f8a37acec --- /dev/null +++ b/git-sensor/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/git-sensor/vendor/github.com/devtron-labs/common-lib/securestore/common.go b/git-sensor/vendor/github.com/devtron-labs/common-lib/securestore/common.go new file mode 100644 index 000000000..4444765e3 --- /dev/null +++ b/git-sensor/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/git-sensor/vendor/github.com/devtron-labs/common-lib/securestore/map.go b/git-sensor/vendor/github.com/devtron-labs/common-lib/securestore/map.go new file mode 100644 index 000000000..dd9c25846 --- /dev/null +++ b/git-sensor/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/git-sensor/vendor/github.com/devtron-labs/common-lib/securestore/strings.go b/git-sensor/vendor/github.com/devtron-labs/common-lib/securestore/strings.go new file mode 100644 index 000000000..e7c5128b2 --- /dev/null +++ b/git-sensor/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/git-sensor/vendor/github.com/devtron-labs/common-lib/utils/sql/AuditLog.go b/git-sensor/vendor/github.com/devtron-labs/common-lib/utils/sql/AuditLog.go new file mode 100644 index 000000000..fb3a38e79 --- /dev/null +++ b/git-sensor/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/git-sensor/vendor/github.com/devtron-labs/common-lib/utils/sql/TransactionWrapper.go b/git-sensor/vendor/github.com/devtron-labs/common-lib/utils/sql/TransactionWrapper.go new file mode 100644 index 000000000..3c797e1e1 --- /dev/null +++ b/git-sensor/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/git-sensor/vendor/github.com/devtron-labs/common-lib/utils/sql/connection.go b/git-sensor/vendor/github.com/devtron-labs/common-lib/utils/sql/connection.go new file mode 100644 index 000000000..fa6858e5d --- /dev/null +++ b/git-sensor/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/git-sensor/vendor/github.com/devtron-labs/common-lib/utils/sql/wire_sql.go b/git-sensor/vendor/github.com/devtron-labs/common-lib/utils/sql/wire_sql.go new file mode 100644 index 000000000..32aee8f5b --- /dev/null +++ b/git-sensor/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/git-sensor/vendor/github.com/felixge/httpsnoop/.gitignore b/git-sensor/vendor/github.com/felixge/httpsnoop/.gitignore deleted file mode 100644 index e69de29bb..000000000 diff --git a/git-sensor/vendor/github.com/felixge/httpsnoop/LICENSE.txt b/git-sensor/vendor/github.com/felixge/httpsnoop/LICENSE.txt deleted file mode 100644 index e028b46a9..000000000 --- a/git-sensor/vendor/github.com/felixge/httpsnoop/LICENSE.txt +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2016 Felix Geisendörfer (felix@debuggable.com) - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. diff --git a/git-sensor/vendor/github.com/felixge/httpsnoop/Makefile b/git-sensor/vendor/github.com/felixge/httpsnoop/Makefile deleted file mode 100644 index 4e12afdd9..000000000 --- a/git-sensor/vendor/github.com/felixge/httpsnoop/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -.PHONY: ci generate clean - -ci: clean generate - go test -race -v ./... - -generate: - go generate . - -clean: - rm -rf *_generated*.go diff --git a/git-sensor/vendor/github.com/felixge/httpsnoop/README.md b/git-sensor/vendor/github.com/felixge/httpsnoop/README.md deleted file mode 100644 index cf6b42f3d..000000000 --- a/git-sensor/vendor/github.com/felixge/httpsnoop/README.md +++ /dev/null @@ -1,95 +0,0 @@ -# httpsnoop - -Package httpsnoop provides an easy way to capture http related metrics (i.e. -response time, bytes written, and http status code) from your application's -http.Handlers. - -Doing this requires non-trivial wrapping of the http.ResponseWriter interface, -which is also exposed for users interested in a more low-level API. - -[![Go Reference](https://pkg.go.dev/badge/github.com/felixge/httpsnoop.svg)](https://pkg.go.dev/github.com/felixge/httpsnoop) -[![Build Status](https://github.com/felixge/httpsnoop/actions/workflows/main.yaml/badge.svg)](https://github.com/felixge/httpsnoop/actions/workflows/main.yaml) - -## Usage Example - -```go -// myH is your app's http handler, perhaps a http.ServeMux or similar. -var myH http.Handler -// wrappedH wraps myH in order to log every request. -wrappedH := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - m := httpsnoop.CaptureMetrics(myH, w, r) - log.Printf( - "%s %s (code=%d dt=%s written=%d)", - r.Method, - r.URL, - m.Code, - m.Duration, - m.Written, - ) -}) -http.ListenAndServe(":8080", wrappedH) -``` - -## Why this package exists - -Instrumenting an application's http.Handler is surprisingly difficult. - -However if you google for e.g. "capture ResponseWriter status code" you'll find -lots of advise and code examples that suggest it to be a fairly trivial -undertaking. Unfortunately everything I've seen so far has a high chance of -breaking your application. - -The main problem is that a `http.ResponseWriter` often implements additional -interfaces such as `http.Flusher`, `http.CloseNotifier`, `http.Hijacker`, `http.Pusher`, and -`io.ReaderFrom`. So the naive approach of just wrapping `http.ResponseWriter` -in your own struct that also implements the `http.ResponseWriter` interface -will hide the additional interfaces mentioned above. This has a high change of -introducing subtle bugs into any non-trivial application. - -Another approach I've seen people take is to return a struct that implements -all of the interfaces above. However, that's also problematic, because it's -difficult to fake some of these interfaces behaviors when the underlying -`http.ResponseWriter` doesn't have an implementation. It's also dangerous, -because an application may choose to operate differently, merely because it -detects the presence of these additional interfaces. - -This package solves this problem by checking which additional interfaces a -`http.ResponseWriter` implements, returning a wrapped version implementing the -exact same set of interfaces. - -Additionally this package properly handles edge cases such as `WriteHeader` not -being called, or called more than once, as well as concurrent calls to -`http.ResponseWriter` methods, and even calls happening after the wrapped -`ServeHTTP` has already returned. - -Unfortunately this package is not perfect either. It's possible that it is -still missing some interfaces provided by the go core (let me know if you find -one), and it won't work for applications adding their own interfaces into the -mix. You can however use `httpsnoop.Unwrap(w)` to access the underlying -`http.ResponseWriter` and type-assert the result to its other interfaces. - -However, hopefully the explanation above has sufficiently scared you of rolling -your own solution to this problem. httpsnoop may still break your application, -but at least it tries to avoid it as much as possible. - -Anyway, the real problem here is that smuggling additional interfaces inside -`http.ResponseWriter` is a problematic design choice, but it probably goes as -deep as the Go language specification itself. But that's okay, I still prefer -Go over the alternatives ;). - -## Performance - -``` -BenchmarkBaseline-8 20000 94912 ns/op -BenchmarkCaptureMetrics-8 20000 95461 ns/op -``` - -As you can see, using `CaptureMetrics` on a vanilla http.Handler introduces an -overhead of ~500 ns per http request on my machine. However, the margin of -error appears to be larger than that, therefor it should be reasonable to -assume that the overhead introduced by `CaptureMetrics` is absolutely -negligible. - -## License - -MIT diff --git a/git-sensor/vendor/github.com/felixge/httpsnoop/capture_metrics.go b/git-sensor/vendor/github.com/felixge/httpsnoop/capture_metrics.go deleted file mode 100644 index bec7b71b3..000000000 --- a/git-sensor/vendor/github.com/felixge/httpsnoop/capture_metrics.go +++ /dev/null @@ -1,86 +0,0 @@ -package httpsnoop - -import ( - "io" - "net/http" - "time" -) - -// Metrics holds metrics captured from CaptureMetrics. -type Metrics struct { - // Code is the first http response code passed to the WriteHeader func of - // the ResponseWriter. If no such call is made, a default code of 200 is - // assumed instead. - Code int - // Duration is the time it took to execute the handler. - Duration time.Duration - // Written is the number of bytes successfully written by the Write or - // ReadFrom function of the ResponseWriter. ResponseWriters may also write - // data to their underlaying connection directly (e.g. headers), but those - // are not tracked. Therefor the number of Written bytes will usually match - // the size of the response body. - Written int64 -} - -// CaptureMetrics wraps the given hnd, executes it with the given w and r, and -// returns the metrics it captured from it. -func CaptureMetrics(hnd http.Handler, w http.ResponseWriter, r *http.Request) Metrics { - return CaptureMetricsFn(w, func(ww http.ResponseWriter) { - hnd.ServeHTTP(ww, r) - }) -} - -// CaptureMetricsFn wraps w and calls fn with the wrapped w and returns the -// resulting metrics. This is very similar to CaptureMetrics (which is just -// sugar on top of this func), but is a more usable interface if your -// application doesn't use the Go http.Handler interface. -func CaptureMetricsFn(w http.ResponseWriter, fn func(http.ResponseWriter)) Metrics { - m := Metrics{Code: http.StatusOK} - m.CaptureMetrics(w, fn) - return m -} - -// CaptureMetrics wraps w and calls fn with the wrapped w and updates -// Metrics m with the resulting metrics. This is similar to CaptureMetricsFn, -// but allows one to customize starting Metrics object. -func (m *Metrics) CaptureMetrics(w http.ResponseWriter, fn func(http.ResponseWriter)) { - var ( - start = time.Now() - headerWritten bool - hooks = Hooks{ - WriteHeader: func(next WriteHeaderFunc) WriteHeaderFunc { - return func(code int) { - next(code) - - if !(code >= 100 && code <= 199) && !headerWritten { - m.Code = code - headerWritten = true - } - } - }, - - Write: func(next WriteFunc) WriteFunc { - return func(p []byte) (int, error) { - n, err := next(p) - - m.Written += int64(n) - headerWritten = true - return n, err - } - }, - - ReadFrom: func(next ReadFromFunc) ReadFromFunc { - return func(src io.Reader) (int64, error) { - n, err := next(src) - - headerWritten = true - m.Written += n - return n, err - } - }, - } - ) - - fn(Wrap(w, hooks)) - m.Duration += time.Since(start) -} diff --git a/git-sensor/vendor/github.com/felixge/httpsnoop/docs.go b/git-sensor/vendor/github.com/felixge/httpsnoop/docs.go deleted file mode 100644 index 203c35b3c..000000000 --- a/git-sensor/vendor/github.com/felixge/httpsnoop/docs.go +++ /dev/null @@ -1,10 +0,0 @@ -// Package httpsnoop provides an easy way to capture http related metrics (i.e. -// response time, bytes written, and http status code) from your application's -// http.Handlers. -// -// Doing this requires non-trivial wrapping of the http.ResponseWriter -// interface, which is also exposed for users interested in a more low-level -// API. -package httpsnoop - -//go:generate go run codegen/main.go diff --git a/git-sensor/vendor/github.com/felixge/httpsnoop/wrap_generated_gteq_1.8.go b/git-sensor/vendor/github.com/felixge/httpsnoop/wrap_generated_gteq_1.8.go deleted file mode 100644 index 101cedde6..000000000 --- a/git-sensor/vendor/github.com/felixge/httpsnoop/wrap_generated_gteq_1.8.go +++ /dev/null @@ -1,436 +0,0 @@ -// +build go1.8 -// Code generated by "httpsnoop/codegen"; DO NOT EDIT. - -package httpsnoop - -import ( - "bufio" - "io" - "net" - "net/http" -) - -// HeaderFunc is part of the http.ResponseWriter interface. -type HeaderFunc func() http.Header - -// WriteHeaderFunc is part of the http.ResponseWriter interface. -type WriteHeaderFunc func(code int) - -// WriteFunc is part of the http.ResponseWriter interface. -type WriteFunc func(b []byte) (int, error) - -// FlushFunc is part of the http.Flusher interface. -type FlushFunc func() - -// CloseNotifyFunc is part of the http.CloseNotifier interface. -type CloseNotifyFunc func() <-chan bool - -// HijackFunc is part of the http.Hijacker interface. -type HijackFunc func() (net.Conn, *bufio.ReadWriter, error) - -// ReadFromFunc is part of the io.ReaderFrom interface. -type ReadFromFunc func(src io.Reader) (int64, error) - -// PushFunc is part of the http.Pusher interface. -type PushFunc func(target string, opts *http.PushOptions) error - -// Hooks defines a set of method interceptors for methods included in -// http.ResponseWriter as well as some others. You can think of them as -// middleware for the function calls they target. See Wrap for more details. -type Hooks struct { - Header func(HeaderFunc) HeaderFunc - WriteHeader func(WriteHeaderFunc) WriteHeaderFunc - Write func(WriteFunc) WriteFunc - Flush func(FlushFunc) FlushFunc - CloseNotify func(CloseNotifyFunc) CloseNotifyFunc - Hijack func(HijackFunc) HijackFunc - ReadFrom func(ReadFromFunc) ReadFromFunc - Push func(PushFunc) PushFunc -} - -// Wrap returns a wrapped version of w that provides the exact same interface -// as w. Specifically if w implements any combination of: -// -// - http.Flusher -// - http.CloseNotifier -// - http.Hijacker -// - io.ReaderFrom -// - http.Pusher -// -// The wrapped version will implement the exact same combination. If no hooks -// are set, the wrapped version also behaves exactly as w. Hooks targeting -// methods not supported by w are ignored. Any other hooks will intercept the -// method they target and may modify the call's arguments and/or return values. -// The CaptureMetrics implementation serves as a working example for how the -// hooks can be used. -func Wrap(w http.ResponseWriter, hooks Hooks) http.ResponseWriter { - rw := &rw{w: w, h: hooks} - _, i0 := w.(http.Flusher) - _, i1 := w.(http.CloseNotifier) - _, i2 := w.(http.Hijacker) - _, i3 := w.(io.ReaderFrom) - _, i4 := w.(http.Pusher) - switch { - // combination 1/32 - case !i0 && !i1 && !i2 && !i3 && !i4: - return struct { - Unwrapper - http.ResponseWriter - }{rw, rw} - // combination 2/32 - case !i0 && !i1 && !i2 && !i3 && i4: - return struct { - Unwrapper - http.ResponseWriter - http.Pusher - }{rw, rw, rw} - // combination 3/32 - case !i0 && !i1 && !i2 && i3 && !i4: - return struct { - Unwrapper - http.ResponseWriter - io.ReaderFrom - }{rw, rw, rw} - // combination 4/32 - case !i0 && !i1 && !i2 && i3 && i4: - return struct { - Unwrapper - http.ResponseWriter - io.ReaderFrom - http.Pusher - }{rw, rw, rw, rw} - // combination 5/32 - case !i0 && !i1 && i2 && !i3 && !i4: - return struct { - Unwrapper - http.ResponseWriter - http.Hijacker - }{rw, rw, rw} - // combination 6/32 - case !i0 && !i1 && i2 && !i3 && i4: - return struct { - Unwrapper - http.ResponseWriter - http.Hijacker - http.Pusher - }{rw, rw, rw, rw} - // combination 7/32 - case !i0 && !i1 && i2 && i3 && !i4: - return struct { - Unwrapper - http.ResponseWriter - http.Hijacker - io.ReaderFrom - }{rw, rw, rw, rw} - // combination 8/32 - case !i0 && !i1 && i2 && i3 && i4: - return struct { - Unwrapper - http.ResponseWriter - http.Hijacker - io.ReaderFrom - http.Pusher - }{rw, rw, rw, rw, rw} - // combination 9/32 - case !i0 && i1 && !i2 && !i3 && !i4: - return struct { - Unwrapper - http.ResponseWriter - http.CloseNotifier - }{rw, rw, rw} - // combination 10/32 - case !i0 && i1 && !i2 && !i3 && i4: - return struct { - Unwrapper - http.ResponseWriter - http.CloseNotifier - http.Pusher - }{rw, rw, rw, rw} - // combination 11/32 - case !i0 && i1 && !i2 && i3 && !i4: - return struct { - Unwrapper - http.ResponseWriter - http.CloseNotifier - io.ReaderFrom - }{rw, rw, rw, rw} - // combination 12/32 - case !i0 && i1 && !i2 && i3 && i4: - return struct { - Unwrapper - http.ResponseWriter - http.CloseNotifier - io.ReaderFrom - http.Pusher - }{rw, rw, rw, rw, rw} - // combination 13/32 - case !i0 && i1 && i2 && !i3 && !i4: - return struct { - Unwrapper - http.ResponseWriter - http.CloseNotifier - http.Hijacker - }{rw, rw, rw, rw} - // combination 14/32 - case !i0 && i1 && i2 && !i3 && i4: - return struct { - Unwrapper - http.ResponseWriter - http.CloseNotifier - http.Hijacker - http.Pusher - }{rw, rw, rw, rw, rw} - // combination 15/32 - case !i0 && i1 && i2 && i3 && !i4: - return struct { - Unwrapper - http.ResponseWriter - http.CloseNotifier - http.Hijacker - io.ReaderFrom - }{rw, rw, rw, rw, rw} - // combination 16/32 - case !i0 && i1 && i2 && i3 && i4: - return struct { - Unwrapper - http.ResponseWriter - http.CloseNotifier - http.Hijacker - io.ReaderFrom - http.Pusher - }{rw, rw, rw, rw, rw, rw} - // combination 17/32 - case i0 && !i1 && !i2 && !i3 && !i4: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - }{rw, rw, rw} - // combination 18/32 - case i0 && !i1 && !i2 && !i3 && i4: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.Pusher - }{rw, rw, rw, rw} - // combination 19/32 - case i0 && !i1 && !i2 && i3 && !i4: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - io.ReaderFrom - }{rw, rw, rw, rw} - // combination 20/32 - case i0 && !i1 && !i2 && i3 && i4: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - io.ReaderFrom - http.Pusher - }{rw, rw, rw, rw, rw} - // combination 21/32 - case i0 && !i1 && i2 && !i3 && !i4: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.Hijacker - }{rw, rw, rw, rw} - // combination 22/32 - case i0 && !i1 && i2 && !i3 && i4: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.Hijacker - http.Pusher - }{rw, rw, rw, rw, rw} - // combination 23/32 - case i0 && !i1 && i2 && i3 && !i4: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.Hijacker - io.ReaderFrom - }{rw, rw, rw, rw, rw} - // combination 24/32 - case i0 && !i1 && i2 && i3 && i4: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.Hijacker - io.ReaderFrom - http.Pusher - }{rw, rw, rw, rw, rw, rw} - // combination 25/32 - case i0 && i1 && !i2 && !i3 && !i4: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.CloseNotifier - }{rw, rw, rw, rw} - // combination 26/32 - case i0 && i1 && !i2 && !i3 && i4: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.CloseNotifier - http.Pusher - }{rw, rw, rw, rw, rw} - // combination 27/32 - case i0 && i1 && !i2 && i3 && !i4: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.CloseNotifier - io.ReaderFrom - }{rw, rw, rw, rw, rw} - // combination 28/32 - case i0 && i1 && !i2 && i3 && i4: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.CloseNotifier - io.ReaderFrom - http.Pusher - }{rw, rw, rw, rw, rw, rw} - // combination 29/32 - case i0 && i1 && i2 && !i3 && !i4: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.CloseNotifier - http.Hijacker - }{rw, rw, rw, rw, rw} - // combination 30/32 - case i0 && i1 && i2 && !i3 && i4: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.CloseNotifier - http.Hijacker - http.Pusher - }{rw, rw, rw, rw, rw, rw} - // combination 31/32 - case i0 && i1 && i2 && i3 && !i4: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.CloseNotifier - http.Hijacker - io.ReaderFrom - }{rw, rw, rw, rw, rw, rw} - // combination 32/32 - case i0 && i1 && i2 && i3 && i4: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.CloseNotifier - http.Hijacker - io.ReaderFrom - http.Pusher - }{rw, rw, rw, rw, rw, rw, rw} - } - panic("unreachable") -} - -type rw struct { - w http.ResponseWriter - h Hooks -} - -func (w *rw) Unwrap() http.ResponseWriter { - return w.w -} - -func (w *rw) Header() http.Header { - f := w.w.(http.ResponseWriter).Header - if w.h.Header != nil { - f = w.h.Header(f) - } - return f() -} - -func (w *rw) WriteHeader(code int) { - f := w.w.(http.ResponseWriter).WriteHeader - if w.h.WriteHeader != nil { - f = w.h.WriteHeader(f) - } - f(code) -} - -func (w *rw) Write(b []byte) (int, error) { - f := w.w.(http.ResponseWriter).Write - if w.h.Write != nil { - f = w.h.Write(f) - } - return f(b) -} - -func (w *rw) Flush() { - f := w.w.(http.Flusher).Flush - if w.h.Flush != nil { - f = w.h.Flush(f) - } - f() -} - -func (w *rw) CloseNotify() <-chan bool { - f := w.w.(http.CloseNotifier).CloseNotify - if w.h.CloseNotify != nil { - f = w.h.CloseNotify(f) - } - return f() -} - -func (w *rw) Hijack() (net.Conn, *bufio.ReadWriter, error) { - f := w.w.(http.Hijacker).Hijack - if w.h.Hijack != nil { - f = w.h.Hijack(f) - } - return f() -} - -func (w *rw) ReadFrom(src io.Reader) (int64, error) { - f := w.w.(io.ReaderFrom).ReadFrom - if w.h.ReadFrom != nil { - f = w.h.ReadFrom(f) - } - return f(src) -} - -func (w *rw) Push(target string, opts *http.PushOptions) error { - f := w.w.(http.Pusher).Push - if w.h.Push != nil { - f = w.h.Push(f) - } - return f(target, opts) -} - -type Unwrapper interface { - Unwrap() http.ResponseWriter -} - -// Unwrap returns the underlying http.ResponseWriter from within zero or more -// layers of httpsnoop wrappers. -func Unwrap(w http.ResponseWriter) http.ResponseWriter { - if rw, ok := w.(Unwrapper); ok { - // recurse until rw.Unwrap() returns a non-Unwrapper - return Unwrap(rw.Unwrap()) - } else { - return w - } -} diff --git a/git-sensor/vendor/github.com/felixge/httpsnoop/wrap_generated_lt_1.8.go b/git-sensor/vendor/github.com/felixge/httpsnoop/wrap_generated_lt_1.8.go deleted file mode 100644 index e0951df15..000000000 --- a/git-sensor/vendor/github.com/felixge/httpsnoop/wrap_generated_lt_1.8.go +++ /dev/null @@ -1,278 +0,0 @@ -// +build !go1.8 -// Code generated by "httpsnoop/codegen"; DO NOT EDIT. - -package httpsnoop - -import ( - "bufio" - "io" - "net" - "net/http" -) - -// HeaderFunc is part of the http.ResponseWriter interface. -type HeaderFunc func() http.Header - -// WriteHeaderFunc is part of the http.ResponseWriter interface. -type WriteHeaderFunc func(code int) - -// WriteFunc is part of the http.ResponseWriter interface. -type WriteFunc func(b []byte) (int, error) - -// FlushFunc is part of the http.Flusher interface. -type FlushFunc func() - -// CloseNotifyFunc is part of the http.CloseNotifier interface. -type CloseNotifyFunc func() <-chan bool - -// HijackFunc is part of the http.Hijacker interface. -type HijackFunc func() (net.Conn, *bufio.ReadWriter, error) - -// ReadFromFunc is part of the io.ReaderFrom interface. -type ReadFromFunc func(src io.Reader) (int64, error) - -// Hooks defines a set of method interceptors for methods included in -// http.ResponseWriter as well as some others. You can think of them as -// middleware for the function calls they target. See Wrap for more details. -type Hooks struct { - Header func(HeaderFunc) HeaderFunc - WriteHeader func(WriteHeaderFunc) WriteHeaderFunc - Write func(WriteFunc) WriteFunc - Flush func(FlushFunc) FlushFunc - CloseNotify func(CloseNotifyFunc) CloseNotifyFunc - Hijack func(HijackFunc) HijackFunc - ReadFrom func(ReadFromFunc) ReadFromFunc -} - -// Wrap returns a wrapped version of w that provides the exact same interface -// as w. Specifically if w implements any combination of: -// -// - http.Flusher -// - http.CloseNotifier -// - http.Hijacker -// - io.ReaderFrom -// -// The wrapped version will implement the exact same combination. If no hooks -// are set, the wrapped version also behaves exactly as w. Hooks targeting -// methods not supported by w are ignored. Any other hooks will intercept the -// method they target and may modify the call's arguments and/or return values. -// The CaptureMetrics implementation serves as a working example for how the -// hooks can be used. -func Wrap(w http.ResponseWriter, hooks Hooks) http.ResponseWriter { - rw := &rw{w: w, h: hooks} - _, i0 := w.(http.Flusher) - _, i1 := w.(http.CloseNotifier) - _, i2 := w.(http.Hijacker) - _, i3 := w.(io.ReaderFrom) - switch { - // combination 1/16 - case !i0 && !i1 && !i2 && !i3: - return struct { - Unwrapper - http.ResponseWriter - }{rw, rw} - // combination 2/16 - case !i0 && !i1 && !i2 && i3: - return struct { - Unwrapper - http.ResponseWriter - io.ReaderFrom - }{rw, rw, rw} - // combination 3/16 - case !i0 && !i1 && i2 && !i3: - return struct { - Unwrapper - http.ResponseWriter - http.Hijacker - }{rw, rw, rw} - // combination 4/16 - case !i0 && !i1 && i2 && i3: - return struct { - Unwrapper - http.ResponseWriter - http.Hijacker - io.ReaderFrom - }{rw, rw, rw, rw} - // combination 5/16 - case !i0 && i1 && !i2 && !i3: - return struct { - Unwrapper - http.ResponseWriter - http.CloseNotifier - }{rw, rw, rw} - // combination 6/16 - case !i0 && i1 && !i2 && i3: - return struct { - Unwrapper - http.ResponseWriter - http.CloseNotifier - io.ReaderFrom - }{rw, rw, rw, rw} - // combination 7/16 - case !i0 && i1 && i2 && !i3: - return struct { - Unwrapper - http.ResponseWriter - http.CloseNotifier - http.Hijacker - }{rw, rw, rw, rw} - // combination 8/16 - case !i0 && i1 && i2 && i3: - return struct { - Unwrapper - http.ResponseWriter - http.CloseNotifier - http.Hijacker - io.ReaderFrom - }{rw, rw, rw, rw, rw} - // combination 9/16 - case i0 && !i1 && !i2 && !i3: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - }{rw, rw, rw} - // combination 10/16 - case i0 && !i1 && !i2 && i3: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - io.ReaderFrom - }{rw, rw, rw, rw} - // combination 11/16 - case i0 && !i1 && i2 && !i3: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.Hijacker - }{rw, rw, rw, rw} - // combination 12/16 - case i0 && !i1 && i2 && i3: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.Hijacker - io.ReaderFrom - }{rw, rw, rw, rw, rw} - // combination 13/16 - case i0 && i1 && !i2 && !i3: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.CloseNotifier - }{rw, rw, rw, rw} - // combination 14/16 - case i0 && i1 && !i2 && i3: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.CloseNotifier - io.ReaderFrom - }{rw, rw, rw, rw, rw} - // combination 15/16 - case i0 && i1 && i2 && !i3: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.CloseNotifier - http.Hijacker - }{rw, rw, rw, rw, rw} - // combination 16/16 - case i0 && i1 && i2 && i3: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.CloseNotifier - http.Hijacker - io.ReaderFrom - }{rw, rw, rw, rw, rw, rw} - } - panic("unreachable") -} - -type rw struct { - w http.ResponseWriter - h Hooks -} - -func (w *rw) Unwrap() http.ResponseWriter { - return w.w -} - -func (w *rw) Header() http.Header { - f := w.w.(http.ResponseWriter).Header - if w.h.Header != nil { - f = w.h.Header(f) - } - return f() -} - -func (w *rw) WriteHeader(code int) { - f := w.w.(http.ResponseWriter).WriteHeader - if w.h.WriteHeader != nil { - f = w.h.WriteHeader(f) - } - f(code) -} - -func (w *rw) Write(b []byte) (int, error) { - f := w.w.(http.ResponseWriter).Write - if w.h.Write != nil { - f = w.h.Write(f) - } - return f(b) -} - -func (w *rw) Flush() { - f := w.w.(http.Flusher).Flush - if w.h.Flush != nil { - f = w.h.Flush(f) - } - f() -} - -func (w *rw) CloseNotify() <-chan bool { - f := w.w.(http.CloseNotifier).CloseNotify - if w.h.CloseNotify != nil { - f = w.h.CloseNotify(f) - } - return f() -} - -func (w *rw) Hijack() (net.Conn, *bufio.ReadWriter, error) { - f := w.w.(http.Hijacker).Hijack - if w.h.Hijack != nil { - f = w.h.Hijack(f) - } - return f() -} - -func (w *rw) ReadFrom(src io.Reader) (int64, error) { - f := w.w.(io.ReaderFrom).ReadFrom - if w.h.ReadFrom != nil { - f = w.h.ReadFrom(f) - } - return f(src) -} - -type Unwrapper interface { - Unwrap() http.ResponseWriter -} - -// Unwrap returns the underlying http.ResponseWriter from within zero or more -// layers of httpsnoop wrappers. -func Unwrap(w http.ResponseWriter) http.ResponseWriter { - if rw, ok := w.(Unwrapper); ok { - // recurse until rw.Unwrap() returns a non-Unwrapper - return Unwrap(rw.Unwrap()) - } else { - return w - } -} diff --git a/git-sensor/vendor/github.com/go-git/go-git/v5/options.go b/git-sensor/vendor/github.com/go-git/go-git/v5/options.go index e2c77edca..3cd0f952c 100644 --- a/git-sensor/vendor/github.com/go-git/go-git/v5/options.go +++ b/git-sensor/vendor/github.com/go-git/go-git/v5/options.go @@ -8,7 +8,6 @@ import ( "time" "github.com/ProtonMail/go-crypto/openpgp" - "github.com/go-git/go-git/v5/config" "github.com/go-git/go-git/v5/plumbing" formatcfg "github.com/go-git/go-git/v5/plumbing/format/config" @@ -73,16 +72,9 @@ type CloneOptions struct { // Tags describe how the tags will be fetched from the remote repository, // by default is AllTags. Tags TagMode - // InsecureSkipTLS skips SSL verification if protocol is HTTPS. + // InsecureSkipTLS skips ssl verify if protocol is https InsecureSkipTLS bool - // ClientCert is the client certificate to use for mutual TLS authentication - // over the HTTPS protocol. - ClientCert []byte - // ClientKey is the client key to use for mutual TLS authentication over - // the HTTPS protocol. - ClientKey []byte - // CABundle specifies an additional CA bundle to use together with the - // system cert pool. + // CABundle specify additional ca bundle with system cert pool CABundle []byte // ProxyOptions provides info required for connecting to a proxy. ProxyOptions transport.ProxyOptions @@ -161,16 +153,9 @@ type PullOptions struct { // Force allows the pull to update a local branch even when the remote // branch does not descend from it. Force bool - // InsecureSkipTLS skips SSL verification if protocol is HTTPS. + // InsecureSkipTLS skips ssl verify if protocol is https InsecureSkipTLS bool - // ClientCert is the client certificate to use for mutual TLS authentication - // over the HTTPS protocol. - ClientCert []byte - // ClientKey is the client key to use for mutual TLS authentication over - // the HTTPS protocol. - ClientKey []byte - // CABundle specifies an additional CA bundle to use together with the - // system cert pool. + // CABundle specify additional ca bundle with system cert pool CABundle []byte // ProxyOptions provides info required for connecting to a proxy. ProxyOptions transport.ProxyOptions @@ -226,16 +211,9 @@ type FetchOptions struct { // Force allows the fetch to update a local branch even when the remote // branch does not descend from it. Force bool - // InsecureSkipTLS skips SSL verification if protocol is HTTPS. + // InsecureSkipTLS skips ssl verify if protocol is https InsecureSkipTLS bool - // ClientCert is the client certificate to use for mutual TLS authentication - // over the HTTPS protocol. - ClientCert []byte - // ClientKey is the client key to use for mutual TLS authentication over - // the HTTPS protocol. - ClientKey []byte - // CABundle specifies an additional CA bundle to use together with the - // system cert pool. + // CABundle specify additional ca bundle with system cert pool CABundle []byte // ProxyOptions provides info required for connecting to a proxy. ProxyOptions transport.ProxyOptions @@ -289,16 +267,9 @@ type PushOptions struct { // Force allows the push to update a remote branch even when the local // branch does not descend from it. Force bool - // InsecureSkipTLS skips SSL verification if protocol is HTTPS. + // InsecureSkipTLS skips ssl verify if protocol is https InsecureSkipTLS bool - // ClientCert is the client certificate to use for mutual TLS authentication - // over the HTTPS protocol. - ClientCert []byte - // ClientKey is the client key to use for mutual TLS authentication over - // the HTTPS protocol. - ClientKey []byte - // CABundle specifies an additional CA bundle to use together with the - // system cert pool. + // CABundle specify additional ca bundle with system cert pool CABundle []byte // RequireRemoteRefs only allows a remote ref to be updated if its current // value is the one specified here. @@ -722,16 +693,9 @@ func (o *CreateTagOptions) loadConfigTagger(r *Repository) error { type ListOptions struct { // Auth credentials, if required, to use with the remote repository. Auth transport.AuthMethod - // InsecureSkipTLS skips SSL verification if protocol is HTTPS. + // InsecureSkipTLS skips ssl verify if protocol is https InsecureSkipTLS bool - // ClientCert is the client certificate to use for mutual TLS authentication - // over the HTTPS protocol. - ClientCert []byte - // ClientKey is the client key to use for mutual TLS authentication over - // the HTTPS protocol. - ClientKey []byte - // CABundle specifies an additional CA bundle to use together with the - // system cert pool. + // CABundle specify additional ca bundle with system cert pool CABundle []byte // PeelingOption defines how peeled objects are handled during a // remote list. diff --git a/git-sensor/vendor/github.com/go-git/go-git/v5/plumbing/transport/common.go b/git-sensor/vendor/github.com/go-git/go-git/v5/plumbing/transport/common.go index b4c5e98be..fae1aa98c 100644 --- a/git-sensor/vendor/github.com/go-git/go-git/v5/plumbing/transport/common.go +++ b/git-sensor/vendor/github.com/go-git/go-git/v5/plumbing/transport/common.go @@ -113,17 +113,9 @@ type Endpoint struct { Port int // Path is the repository path. Path string - // InsecureSkipTLS skips SSL verification if Protocol is HTTPS. + // InsecureSkipTLS skips ssl verify if protocol is https InsecureSkipTLS bool - // ClientCert specifies an optional client certificate to use for mutual - // TLS authentication if Protocol is HTTPS. - ClientCert []byte - // ClientKey specifies an optional client key to use for mutual TLS - // authentication if Protocol is HTTPS. - ClientKey []byte - // CaBundle specifies an optional CA bundle to use for SSL verification - // if Protocol is HTTPS. The bundle is added in addition to the system - // CA bundle. + // CaBundle specify additional ca bundle with system cert pool CaBundle []byte // Proxy provides info required for connecting to a proxy. Proxy ProxyOptions diff --git a/git-sensor/vendor/github.com/go-git/go-git/v5/plumbing/transport/http/common.go b/git-sensor/vendor/github.com/go-git/go-git/v5/plumbing/transport/http/common.go index 5dd2e311f..df01890b2 100644 --- a/git-sensor/vendor/github.com/go-git/go-git/v5/plumbing/transport/http/common.go +++ b/git-sensor/vendor/github.com/go-git/go-git/v5/plumbing/transport/http/common.go @@ -15,13 +15,12 @@ import ( "strings" "sync" - "github.com/golang/groupcache/lru" - "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing/protocol/packp" "github.com/go-git/go-git/v5/plumbing/protocol/packp/capability" "github.com/go-git/go-git/v5/plumbing/transport" "github.com/go-git/go-git/v5/utils/ioutil" + "github.com/golang/groupcache/lru" ) // it requires a bytes.Buffer, because we need to know the length @@ -186,18 +185,6 @@ func transportWithInsecureTLS(transport *http.Transport) { transport.TLSClientConfig.InsecureSkipVerify = true } -func transportWithClientCert(transport *http.Transport, cert, key []byte) error { - keyPair, err := tls.X509KeyPair(cert, key) - if err != nil { - return err - } - if transport.TLSClientConfig == nil { - transport.TLSClientConfig = &tls.Config{} - } - transport.TLSClientConfig.Certificates = []tls.Certificate{keyPair} - return nil -} - func transportWithCABundle(transport *http.Transport, caBundle []byte) error { rootCAs, err := x509.SystemCertPool() if err != nil { @@ -219,11 +206,6 @@ func transportWithProxy(transport *http.Transport, proxyURL *url.URL) { } func configureTransport(transport *http.Transport, ep *transport.Endpoint) error { - if len(ep.ClientCert) > 0 && len(ep.ClientKey) > 0 { - if err := transportWithClientCert(transport, ep.ClientCert, ep.ClientKey); err != nil { - return err - } - } if len(ep.CaBundle) > 0 { if err := transportWithCABundle(transport, ep.CaBundle); err != nil { return err @@ -248,7 +230,7 @@ func newSession(c *client, ep *transport.Endpoint, auth transport.AuthMethod) (* // We need to configure the http transport if there are transport specific // options present in the endpoint. - if len(ep.ClientKey) > 0 || len(ep.ClientCert) > 0 || len(ep.CaBundle) > 0 || ep.InsecureSkipTLS || ep.Proxy.URL != "" { + if len(ep.CaBundle) > 0 || ep.InsecureSkipTLS || ep.Proxy.URL != "" { var transport *http.Transport // if the client wasn't configured to have a cache for transports then just configure // the transport and use it directly, otherwise try to use the cache. @@ -260,13 +242,9 @@ func newSession(c *client, ep *transport.Endpoint, auth transport.AuthMethod) (* } transport = tr.Clone() - if err := configureTransport(transport, ep); err != nil { - return nil, err - } + configureTransport(transport, ep) } else { transportOpts := transportOptions{ - clientCert: string(ep.ClientCert), - clientKey: string(ep.ClientKey), caBundle: string(ep.CaBundle), insecureSkipTLS: ep.InsecureSkipTLS, } @@ -282,9 +260,7 @@ func newSession(c *client, ep *transport.Endpoint, auth transport.AuthMethod) (* if !found { transport = c.client.Transport.(*http.Transport).Clone() - if err := configureTransport(transport, ep); err != nil { - return nil, err - } + configureTransport(transport, ep) c.addTransport(transportOpts, transport) } } diff --git a/git-sensor/vendor/github.com/go-git/go-git/v5/plumbing/transport/http/transport.go b/git-sensor/vendor/github.com/go-git/go-git/v5/plumbing/transport/http/transport.go index 1991d0512..c8db38920 100644 --- a/git-sensor/vendor/github.com/go-git/go-git/v5/plumbing/transport/http/transport.go +++ b/git-sensor/vendor/github.com/go-git/go-git/v5/plumbing/transport/http/transport.go @@ -9,10 +9,8 @@ import ( type transportOptions struct { insecureSkipTLS bool // []byte is not comparable. - clientCert string - clientKey string - caBundle string - proxyURL url.URL + caBundle string + proxyURL url.URL } func (c *client) addTransport(opts transportOptions, transport *http.Transport) { diff --git a/git-sensor/vendor/github.com/go-git/go-git/v5/plumbing/transport/ssh/auth_method.go b/git-sensor/vendor/github.com/go-git/go-git/v5/plumbing/transport/ssh/auth_method.go index a61610601..ac4e3583c 100644 --- a/git-sensor/vendor/github.com/go-git/go-git/v5/plumbing/transport/ssh/auth_method.go +++ b/git-sensor/vendor/github.com/go-git/go-git/v5/plumbing/transport/ssh/auth_method.go @@ -54,7 +54,7 @@ func (a *KeyboardInteractive) String() string { } func (a *KeyboardInteractive) ClientConfig() (*ssh.ClientConfig, error) { - return a.SetHostKeyCallbackAndAlgorithms(&ssh.ClientConfig{ + return a.SetHostKeyCallback(&ssh.ClientConfig{ User: a.User, Auth: []ssh.AuthMethod{ a.Challenge, @@ -78,7 +78,7 @@ func (a *Password) String() string { } func (a *Password) ClientConfig() (*ssh.ClientConfig, error) { - return a.SetHostKeyCallbackAndAlgorithms(&ssh.ClientConfig{ + return a.SetHostKeyCallback(&ssh.ClientConfig{ User: a.User, Auth: []ssh.AuthMethod{ssh.Password(a.Password)}, }) @@ -101,7 +101,7 @@ func (a *PasswordCallback) String() string { } func (a *PasswordCallback) ClientConfig() (*ssh.ClientConfig, error) { - return a.SetHostKeyCallbackAndAlgorithms(&ssh.ClientConfig{ + return a.SetHostKeyCallback(&ssh.ClientConfig{ User: a.User, Auth: []ssh.AuthMethod{ssh.PasswordCallback(a.Callback)}, }) @@ -150,7 +150,7 @@ func (a *PublicKeys) String() string { } func (a *PublicKeys) ClientConfig() (*ssh.ClientConfig, error) { - return a.SetHostKeyCallbackAndAlgorithms(&ssh.ClientConfig{ + return a.SetHostKeyCallback(&ssh.ClientConfig{ User: a.User, Auth: []ssh.AuthMethod{ssh.PublicKeys(a.Signer)}, }) @@ -211,7 +211,7 @@ func (a *PublicKeysCallback) String() string { } func (a *PublicKeysCallback) ClientConfig() (*ssh.ClientConfig, error) { - return a.SetHostKeyCallbackAndAlgorithms(&ssh.ClientConfig{ + return a.SetHostKeyCallback(&ssh.ClientConfig{ User: a.User, Auth: []ssh.AuthMethod{ssh.PublicKeysCallback(a.Callback)}, }) @@ -230,26 +230,11 @@ func (a *PublicKeysCallback) ClientConfig() (*ssh.ClientConfig, error) { // ~/.ssh/known_hosts // /etc/ssh/ssh_known_hosts func NewKnownHostsCallback(files ...string) (ssh.HostKeyCallback, error) { - kh, err := NewKnownHostsDb(files...) - if err != nil { - return nil, err - } - return kh.HostKeyCallback(), nil + kh, err := newKnownHosts(files...) + return ssh.HostKeyCallback(kh), err } -// NewKnownHostsDb returns knownhosts.HostKeyDB based on a file based on a -// known_hosts file. http://man.openbsd.org/sshd#SSH_KNOWN_HOSTS_FILE_FORMAT -// -// If list of files is empty, then it will be read from the SSH_KNOWN_HOSTS -// environment variable, example: -// -// /home/foo/custom_known_hosts_file:/etc/custom_known/hosts_file -// -// If SSH_KNOWN_HOSTS is not set the following file locations will be used: -// -// ~/.ssh/known_hosts -// /etc/ssh/ssh_known_hosts -func NewKnownHostsDb(files ...string) (*knownhosts.HostKeyDB, error) { +func newKnownHosts(files ...string) (knownhosts.HostKeyCallback, error) { var err error if len(files) == 0 { @@ -262,7 +247,7 @@ func NewKnownHostsDb(files ...string) (*knownhosts.HostKeyDB, error) { return nil, err } - return knownhosts.NewDB(files...) + return knownhosts.New(files...) } func getDefaultKnownHostsFiles() ([]string, error) { @@ -304,50 +289,25 @@ func filterKnownHostsFiles(files ...string) ([]string, error) { } // HostKeyCallbackHelper is a helper that provides common functionality to -// configure HostKeyCallback and HostKeyAlgorithms into a ssh.ClientConfig. +// configure HostKeyCallback into a ssh.ClientConfig. type HostKeyCallbackHelper struct { // HostKeyCallback is the function type used for verifying server keys. - // If nil, a default callback will be created using NewKnownHostsDb + // If nil default callback will be create using NewKnownHostsCallback // without argument. HostKeyCallback ssh.HostKeyCallback - - // HostKeyAlgorithms is a list of supported host key algorithms that will - // be used for host key verification. - HostKeyAlgorithms []string - - // fallback allows for injecting the fallback call, which is called - // when a HostKeyCallback is not set. - fallback func(files ...string) (ssh.HostKeyCallback, error) } -// SetHostKeyCallbackAndAlgorithms sets the field HostKeyCallback and HostKeyAlgorithms in the given cfg. -// If the host key callback or algorithms is empty it is left empty. It will be handled by the dial method, -// falling back to knownhosts. -func (m *HostKeyCallbackHelper) SetHostKeyCallbackAndAlgorithms(cfg *ssh.ClientConfig) (*ssh.ClientConfig, error) { - if cfg == nil { - cfg = &ssh.ClientConfig{} - } - +// SetHostKeyCallback sets the field HostKeyCallback in the given cfg. If +// HostKeyCallback is empty a default callback is created using +// NewKnownHostsCallback. +func (m *HostKeyCallbackHelper) SetHostKeyCallback(cfg *ssh.ClientConfig) (*ssh.ClientConfig, error) { + var err error if m.HostKeyCallback == nil { - if m.fallback == nil { - m.fallback = NewKnownHostsCallback + if m.HostKeyCallback, err = NewKnownHostsCallback(); err != nil { + return cfg, err } - - hkcb, err := m.fallback() - if err != nil { - return nil, fmt.Errorf("cannot create known hosts callback: %w", err) - } - - cfg.HostKeyCallback = hkcb - cfg.HostKeyAlgorithms = m.HostKeyAlgorithms - return cfg, err } cfg.HostKeyCallback = m.HostKeyCallback - cfg.HostKeyAlgorithms = m.HostKeyAlgorithms return cfg, nil } - -func (m *HostKeyCallbackHelper) SetHostKeyCallback(cfg *ssh.ClientConfig) (*ssh.ClientConfig, error) { - return m.SetHostKeyCallbackAndAlgorithms(cfg) -} diff --git a/git-sensor/vendor/github.com/go-git/go-git/v5/plumbing/transport/ssh/common.go b/git-sensor/vendor/github.com/go-git/go-git/v5/plumbing/transport/ssh/common.go index ae6f2174a..05dea448f 100644 --- a/git-sensor/vendor/github.com/go-git/go-git/v5/plumbing/transport/ssh/common.go +++ b/git-sensor/vendor/github.com/go-git/go-git/v5/plumbing/transport/ssh/common.go @@ -11,6 +11,7 @@ import ( "github.com/go-git/go-git/v5/plumbing/transport" "github.com/go-git/go-git/v5/plumbing/transport/internal/common" + "github.com/skeema/knownhosts" "github.com/kevinburke/ssh_config" "golang.org/x/crypto/ssh" @@ -126,17 +127,17 @@ func (c *command) connect() error { } hostWithPort := c.getHostWithPort() if config.HostKeyCallback == nil { - db, err := NewKnownHostsDb() + kh, err := newKnownHosts() if err != nil { return err } - config.HostKeyCallback = db.HostKeyCallback() - config.HostKeyAlgorithms = db.HostKeyAlgorithms(hostWithPort) - } else { - // If the user gave a custom HostKeyCallback, we do not try to detect host key algorithms - // based on knownhosts functionality, as the user may be requesting a FixedKey or using a - // different key approval strategy. In that case, the user is responsible for populating - // HostKeyAlgorithms appropriately + config.HostKeyCallback = kh.HostKeyCallback() + config.HostKeyAlgorithms = kh.HostKeyAlgorithms(hostWithPort) + } else if len(config.HostKeyAlgorithms) == 0 { + // Set the HostKeyAlgorithms based on HostKeyCallback. + // For background see https://github.com/go-git/go-git/issues/411 as well as + // https://github.com/golang/go/issues/29286 for root cause. + config.HostKeyAlgorithms = knownhosts.HostKeyAlgorithms(config.HostKeyCallback, hostWithPort) } overrideConfig(c.config, config) diff --git a/git-sensor/vendor/github.com/go-git/go-git/v5/remote.go b/git-sensor/vendor/github.com/go-git/go-git/v5/remote.go index 730812797..e2c734e75 100644 --- a/git-sensor/vendor/github.com/go-git/go-git/v5/remote.go +++ b/git-sensor/vendor/github.com/go-git/go-git/v5/remote.go @@ -114,7 +114,7 @@ func (r *Remote) PushContext(ctx context.Context, o *PushOptions) (err error) { o.RemoteURL = r.c.URLs[len(r.c.URLs)-1] } - s, err := newSendPackSession(o.RemoteURL, o.Auth, o.InsecureSkipTLS, o.ClientCert, o.ClientKey, o.CABundle, o.ProxyOptions) + s, err := newSendPackSession(o.RemoteURL, o.Auth, o.InsecureSkipTLS, o.CABundle, o.ProxyOptions) if err != nil { return err } @@ -416,7 +416,7 @@ func (r *Remote) fetch(ctx context.Context, o *FetchOptions) (sto storer.Referen o.RemoteURL = r.c.URLs[0] } - s, err := newUploadPackSession(o.RemoteURL, o.Auth, o.InsecureSkipTLS, o.ClientCert, o.ClientKey, o.CABundle, o.ProxyOptions) + s, err := newUploadPackSession(o.RemoteURL, o.Auth, o.InsecureSkipTLS, o.CABundle, o.ProxyOptions) if err != nil { return nil, err } @@ -532,8 +532,8 @@ func depthChanged(before []plumbing.Hash, s storage.Storer) (bool, error) { return false, nil } -func newUploadPackSession(url string, auth transport.AuthMethod, insecure bool, clientCert, clientKey, caBundle []byte, proxyOpts transport.ProxyOptions) (transport.UploadPackSession, error) { - c, ep, err := newClient(url, insecure, clientCert, clientKey, caBundle, proxyOpts) +func newUploadPackSession(url string, auth transport.AuthMethod, insecure bool, cabundle []byte, proxyOpts transport.ProxyOptions) (transport.UploadPackSession, error) { + c, ep, err := newClient(url, insecure, cabundle, proxyOpts) if err != nil { return nil, err } @@ -541,8 +541,8 @@ func newUploadPackSession(url string, auth transport.AuthMethod, insecure bool, return c.NewUploadPackSession(ep, auth) } -func newSendPackSession(url string, auth transport.AuthMethod, insecure bool, clientCert, clientKey, caBundle []byte, proxyOpts transport.ProxyOptions) (transport.ReceivePackSession, error) { - c, ep, err := newClient(url, insecure, clientCert, clientKey, caBundle, proxyOpts) +func newSendPackSession(url string, auth transport.AuthMethod, insecure bool, cabundle []byte, proxyOpts transport.ProxyOptions) (transport.ReceivePackSession, error) { + c, ep, err := newClient(url, insecure, cabundle, proxyOpts) if err != nil { return nil, err } @@ -550,15 +550,13 @@ func newSendPackSession(url string, auth transport.AuthMethod, insecure bool, cl return c.NewReceivePackSession(ep, auth) } -func newClient(url string, insecure bool, clientCert, clientKey, caBundle []byte, proxyOpts transport.ProxyOptions) (transport.Transport, *transport.Endpoint, error) { +func newClient(url string, insecure bool, cabundle []byte, proxyOpts transport.ProxyOptions) (transport.Transport, *transport.Endpoint, error) { ep, err := transport.NewEndpoint(url) if err != nil { return nil, nil, err } ep.InsecureSkipTLS = insecure - ep.ClientCert = clientCert - ep.ClientKey = clientKey - ep.CaBundle = caBundle + ep.CaBundle = cabundle ep.Proxy = proxyOpts c, err := client.NewClient(ep) @@ -1358,7 +1356,7 @@ func (r *Remote) list(ctx context.Context, o *ListOptions) (rfs []*plumbing.Refe return nil, ErrEmptyUrls } - s, err := newUploadPackSession(r.c.URLs[0], o.Auth, o.InsecureSkipTLS, o.ClientCert, o.ClientKey, o.CABundle, o.ProxyOptions) + s, err := newUploadPackSession(r.c.URLs[0], o.Auth, o.InsecureSkipTLS, o.CABundle, o.ProxyOptions) if err != nil { return nil, err } diff --git a/git-sensor/vendor/github.com/go-git/go-git/v5/repository.go b/git-sensor/vendor/github.com/go-git/go-git/v5/repository.go index 401590544..200098e7a 100644 --- a/git-sensor/vendor/github.com/go-git/go-git/v5/repository.go +++ b/git-sensor/vendor/github.com/go-git/go-git/v5/repository.go @@ -19,7 +19,6 @@ import ( "github.com/go-git/go-billy/v5" "github.com/go-git/go-billy/v5/osfs" "github.com/go-git/go-billy/v5/util" - "github.com/go-git/go-git/v5/config" "github.com/go-git/go-git/v5/internal/path_util" "github.com/go-git/go-git/v5/internal/revision" @@ -931,8 +930,6 @@ func (r *Repository) clone(ctx context.Context, o *CloneOptions) error { Tags: o.Tags, RemoteName: o.RemoteName, InsecureSkipTLS: o.InsecureSkipTLS, - ClientCert: o.ClientCert, - ClientKey: o.ClientKey, CABundle: o.CABundle, ProxyOptions: o.ProxyOptions, }, o.ReferenceName) diff --git a/git-sensor/vendor/github.com/go-git/go-git/v5/worktree.go b/git-sensor/vendor/github.com/go-git/go-git/v5/worktree.go index 479904e0c..dded08e99 100644 --- a/git-sensor/vendor/github.com/go-git/go-git/v5/worktree.go +++ b/git-sensor/vendor/github.com/go-git/go-git/v5/worktree.go @@ -12,7 +12,6 @@ import ( "github.com/go-git/go-billy/v5" "github.com/go-git/go-billy/v5/util" - "github.com/go-git/go-git/v5/config" "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing/filemode" @@ -80,8 +79,6 @@ func (w *Worktree) PullContext(ctx context.Context, o *PullOptions) error { Progress: o.Progress, Force: o.Force, InsecureSkipTLS: o.InsecureSkipTLS, - ClientCert: o.ClientCert, - ClientKey: o.ClientKey, CABundle: o.CABundle, ProxyOptions: o.ProxyOptions, }) diff --git a/git-sensor/vendor/github.com/gorilla/handlers/.editorconfig b/git-sensor/vendor/github.com/gorilla/handlers/.editorconfig deleted file mode 100644 index c6b74c3e0..000000000 --- a/git-sensor/vendor/github.com/gorilla/handlers/.editorconfig +++ /dev/null @@ -1,20 +0,0 @@ -; https://editorconfig.org/ - -root = true - -[*] -insert_final_newline = true -charset = utf-8 -trim_trailing_whitespace = true -indent_style = space -indent_size = 2 - -[{Makefile,go.mod,go.sum,*.go,.gitmodules}] -indent_style = tab -indent_size = 4 - -[*.md] -indent_size = 4 -trim_trailing_whitespace = false - -eclint_indent_style = unset \ No newline at end of file diff --git a/git-sensor/vendor/github.com/gorilla/handlers/.gitignore b/git-sensor/vendor/github.com/gorilla/handlers/.gitignore deleted file mode 100644 index 577a89e81..000000000 --- a/git-sensor/vendor/github.com/gorilla/handlers/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# Output of the go test coverage tool -coverage.coverprofile diff --git a/git-sensor/vendor/github.com/gorilla/handlers/LICENSE b/git-sensor/vendor/github.com/gorilla/handlers/LICENSE index bb9d80bc9..66ea3c8ae 100644 --- a/git-sensor/vendor/github.com/gorilla/handlers/LICENSE +++ b/git-sensor/vendor/github.com/gorilla/handlers/LICENSE @@ -1,27 +1,22 @@ -Copyright (c) 2023 The Gorilla Authors. All rights reserved. +Copyright (c) 2013 The Gorilla Handlers Authors. All rights reserved. Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: +modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. + Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/git-sensor/vendor/github.com/gorilla/handlers/Makefile b/git-sensor/vendor/github.com/gorilla/handlers/Makefile deleted file mode 100644 index 003b784f7..000000000 --- a/git-sensor/vendor/github.com/gorilla/handlers/Makefile +++ /dev/null @@ -1,34 +0,0 @@ -GO_LINT=$(shell which golangci-lint 2> /dev/null || echo '') -GO_LINT_URI=github.com/golangci/golangci-lint/cmd/golangci-lint@latest - -GO_SEC=$(shell which gosec 2> /dev/null || echo '') -GO_SEC_URI=github.com/securego/gosec/v2/cmd/gosec@latest - -GO_VULNCHECK=$(shell which govulncheck 2> /dev/null || echo '') -GO_VULNCHECK_URI=golang.org/x/vuln/cmd/govulncheck@latest - -.PHONY: verify -verify: sec govulncheck lint test - -.PHONY: lint -lint: - $(if $(GO_LINT), ,go install $(GO_LINT_URI)) - @echo "##### Running golangci-lint #####" - golangci-lint run -v - -.PHONY: sec -sec: - $(if $(GO_SEC), ,go install $(GO_SEC_URI)) - @echo "##### Running gosec #####" - gosec ./... - -.PHONY: govulncheck -govulncheck: - $(if $(GO_VULNCHECK), ,go install $(GO_VULNCHECK_URI)) - @echo "##### Running govulncheck #####" - govulncheck ./... - -.PHONY: test -test: - @echo "##### Running tests #####" - go test -race -cover -coverprofile=coverage.coverprofile -covermode=atomic -v ./... diff --git a/git-sensor/vendor/github.com/gorilla/handlers/README.md b/git-sensor/vendor/github.com/gorilla/handlers/README.md index 02555b264..6eba66bf3 100644 --- a/git-sensor/vendor/github.com/gorilla/handlers/README.md +++ b/git-sensor/vendor/github.com/gorilla/handlers/README.md @@ -1,10 +1,10 @@ -# gorilla/handlers - -![Testing](https://github.com/gorilla/handlers/actions/workflows/test.yml/badge.svg) -[![Codecov](https://codecov.io/github/gorilla/handlers/branch/main/graph/badge.svg)](https://codecov.io/github/gorilla/handlers) +gorilla/handlers +================ [![GoDoc](https://godoc.org/github.com/gorilla/handlers?status.svg)](https://godoc.org/github.com/gorilla/handlers) +[![CircleCI](https://circleci.com/gh/gorilla/handlers.svg?style=svg)](https://circleci.com/gh/gorilla/handlers) [![Sourcegraph](https://sourcegraph.com/github.com/gorilla/handlers/-/badge.svg)](https://sourcegraph.com/github.com/gorilla/handlers?badge) + Package handlers is a collection of handlers (aka "HTTP middleware") for use with Go's `net/http` package (or any framework supporting `http.Handler`), including: diff --git a/git-sensor/vendor/github.com/gorilla/handlers/canonical.go b/git-sensor/vendor/github.com/gorilla/handlers/canonical.go index 7121f5307..8437fefc1 100644 --- a/git-sensor/vendor/github.com/gorilla/handlers/canonical.go +++ b/git-sensor/vendor/github.com/gorilla/handlers/canonical.go @@ -21,11 +21,12 @@ type canonical struct { // // Example: // -// r := mux.NewRouter() -// canonical := handlers.CanonicalHost("http://www.gorillatoolkit.org", 302) -// r.HandleFunc("/route", YourHandler) +// r := mux.NewRouter() +// canonical := handlers.CanonicalHost("http://www.gorillatoolkit.org", 302) +// r.HandleFunc("/route", YourHandler) +// +// log.Fatal(http.ListenAndServe(":7000", canonical(r))) // -// log.Fatal(http.ListenAndServe(":7000", canonical(r))) func CanonicalHost(domain string, code int) func(h http.Handler) http.Handler { fn := func(h http.Handler) http.Handler { return canonical{h, domain, code} diff --git a/git-sensor/vendor/github.com/gorilla/handlers/compress.go b/git-sensor/vendor/github.com/gorilla/handlers/compress.go index d6f589503..e46a7bfd6 100644 --- a/git-sensor/vendor/github.com/gorilla/handlers/compress.go +++ b/git-sensor/vendor/github.com/gorilla/handlers/compress.go @@ -10,48 +10,47 @@ import ( "io" "net/http" "strings" - - "github.com/felixge/httpsnoop" ) -const acceptEncoding string = "Accept-Encoding" - type compressResponseWriter struct { - compressor io.Writer - w http.ResponseWriter + io.Writer + http.ResponseWriter + http.Hijacker + http.Flusher + http.CloseNotifier } -func (cw *compressResponseWriter) WriteHeader(c int) { - cw.w.Header().Del("Content-Length") - cw.w.WriteHeader(c) +func (w *compressResponseWriter) WriteHeader(c int) { + w.ResponseWriter.Header().Del("Content-Length") + w.ResponseWriter.WriteHeader(c) } -func (cw *compressResponseWriter) Write(b []byte) (int, error) { - h := cw.w.Header() +func (w *compressResponseWriter) Header() http.Header { + return w.ResponseWriter.Header() +} + +func (w *compressResponseWriter) Write(b []byte) (int, error) { + h := w.ResponseWriter.Header() if h.Get("Content-Type") == "" { h.Set("Content-Type", http.DetectContentType(b)) } h.Del("Content-Length") - return cw.compressor.Write(b) -} - -func (cw *compressResponseWriter) ReadFrom(r io.Reader) (int64, error) { - return io.Copy(cw.compressor, r) + return w.Writer.Write(b) } type flusher interface { Flush() error } -func (cw *compressResponseWriter) Flush() { +func (w *compressResponseWriter) Flush() { // Flush compressed data if compressor supports it. - if f, ok := cw.compressor.(flusher); ok { - _ = f.Flush() + if f, ok := w.Writer.(flusher); ok { + f.Flush() } // Flush HTTP response. - if f, ok := cw.w.(http.Flusher); ok { - f.Flush() + if w.Flusher != nil { + w.Flusher.Flush() } } @@ -75,69 +74,77 @@ func CompressHandlerLevel(h http.Handler, level int) http.Handler { level = gzip.DefaultCompression } - const ( - gzipEncoding = "gzip" - flateEncoding = "deflate" - ) - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - // detect what encoding to use - var encoding string - for _, curEnc := range strings.Split(r.Header.Get(acceptEncoding), ",") { - curEnc = strings.TrimSpace(curEnc) - if curEnc == gzipEncoding || curEnc == flateEncoding { - encoding = curEnc - break + L: + for _, enc := range strings.Split(r.Header.Get("Accept-Encoding"), ",") { + switch strings.TrimSpace(enc) { + case "gzip": + w.Header().Set("Content-Encoding", "gzip") + r.Header.Del("Accept-Encoding") + w.Header().Add("Vary", "Accept-Encoding") + + gw, _ := gzip.NewWriterLevel(w, level) + defer gw.Close() + + h, hok := w.(http.Hijacker) + if !hok { /* w is not Hijacker... oh well... */ + h = nil + } + + f, fok := w.(http.Flusher) + if !fok { + f = nil + } + + cn, cnok := w.(http.CloseNotifier) + if !cnok { + cn = nil + } + + w = &compressResponseWriter{ + Writer: gw, + ResponseWriter: w, + Hijacker: h, + Flusher: f, + CloseNotifier: cn, + } + + break L + case "deflate": + w.Header().Set("Content-Encoding", "deflate") + r.Header.Del("Accept-Encoding") + w.Header().Add("Vary", "Accept-Encoding") + + fw, _ := flate.NewWriter(w, level) + defer fw.Close() + + h, hok := w.(http.Hijacker) + if !hok { /* w is not Hijacker... oh well... */ + h = nil + } + + f, fok := w.(http.Flusher) + if !fok { + f = nil + } + + cn, cnok := w.(http.CloseNotifier) + if !cnok { + cn = nil + } + + w = &compressResponseWriter{ + Writer: fw, + ResponseWriter: w, + Hijacker: h, + Flusher: f, + CloseNotifier: cn, + } + + break L } } - // always add Accept-Encoding to Vary to prevent intermediate caches corruption - w.Header().Add("Vary", acceptEncoding) - - // if we weren't able to identify an encoding we're familiar with, pass on the - // request to the handler and return - if encoding == "" { - h.ServeHTTP(w, r) - return - } - - if r.Header.Get("Upgrade") != "" { - h.ServeHTTP(w, r) - return - } - - // wrap the ResponseWriter with the writer for the chosen encoding - var encWriter io.WriteCloser - if encoding == gzipEncoding { - encWriter, _ = gzip.NewWriterLevel(w, level) - } else if encoding == flateEncoding { - encWriter, _ = flate.NewWriter(w, level) - } - defer encWriter.Close() - - w.Header().Set("Content-Encoding", encoding) - r.Header.Del(acceptEncoding) - - cw := &compressResponseWriter{ - w: w, - compressor: encWriter, - } - - w = httpsnoop.Wrap(w, httpsnoop.Hooks{ - Write: func(httpsnoop.WriteFunc) httpsnoop.WriteFunc { - return cw.Write - }, - WriteHeader: func(httpsnoop.WriteHeaderFunc) httpsnoop.WriteHeaderFunc { - return cw.WriteHeader - }, - Flush: func(httpsnoop.FlushFunc) httpsnoop.FlushFunc { - return cw.Flush - }, - ReadFrom: func(rff httpsnoop.ReadFromFunc) httpsnoop.ReadFromFunc { - return cw.ReadFrom - }, - }) - h.ServeHTTP(w, r) }) } diff --git a/git-sensor/vendor/github.com/gorilla/handlers/cors.go b/git-sensor/vendor/github.com/gorilla/handlers/cors.go index 8af9c096e..0dcdffb3d 100644 --- a/git-sensor/vendor/github.com/gorilla/handlers/cors.go +++ b/git-sensor/vendor/github.com/gorilla/handlers/cors.go @@ -26,14 +26,14 @@ type cors struct { type OriginValidator func(string) bool var ( - defaultCorsOptionStatusCode = http.StatusOK - defaultCorsMethods = []string{http.MethodGet, http.MethodHead, http.MethodPost} + defaultCorsOptionStatusCode = 200 + defaultCorsMethods = []string{"GET", "HEAD", "POST"} defaultCorsHeaders = []string{"Accept", "Accept-Language", "Content-Language", "Origin"} - // (WebKit/Safari v9 sends the Origin header by default in AJAX requests). + // (WebKit/Safari v9 sends the Origin header by default in AJAX requests) ) const ( - corsOptionMethod string = http.MethodOptions + corsOptionMethod string = "OPTIONS" corsAllowOriginHeader string = "Access-Control-Allow-Origin" corsExposeHeadersHeader string = "Access-Control-Expose-Headers" corsMaxAgeHeader string = "Access-Control-Max-Age" @@ -101,8 +101,10 @@ func (ch *cors) ServeHTTP(w http.ResponseWriter, r *http.Request) { if !ch.isMatch(method, defaultCorsMethods) { w.Header().Set(corsAllowMethodsHeader, method) } - } else if len(ch.exposedHeaders) > 0 { - w.Header().Set(corsExposeHeadersHeader, strings.Join(ch.exposedHeaders, ",")) + } else { + if len(ch.exposedHeaders) > 0 { + w.Header().Set(corsExposeHeadersHeader, strings.Join(ch.exposedHeaders, ",")) + } } if ch.allowCredentials { @@ -139,21 +141,22 @@ func (ch *cors) ServeHTTP(w http.ResponseWriter, r *http.Request) { // CORS provides Cross-Origin Resource Sharing middleware. // Example: // -// import ( -// "net/http" +// import ( +// "net/http" +// +// "github.com/gorilla/handlers" +// "github.com/gorilla/mux" +// ) // -// "github.com/gorilla/handlers" -// "github.com/gorilla/mux" -// ) +// func main() { +// r := mux.NewRouter() +// r.HandleFunc("/users", UserEndpoint) +// r.HandleFunc("/projects", ProjectEndpoint) // -// func main() { -// r := mux.NewRouter() -// r.HandleFunc("/users", UserEndpoint) -// r.HandleFunc("/projects", ProjectEndpoint) +// // Apply the CORS middleware to our top-level router, with the defaults. +// http.ListenAndServe(":8000", handlers.CORS()(r)) +// } // -// // Apply the CORS middleware to our top-level router, with the defaults. -// http.ListenAndServe(":8000", handlers.CORS()(r)) -// } func CORS(opts ...CORSOption) func(http.Handler) http.Handler { return func(h http.Handler) http.Handler { ch := parseCORSOptions(opts...) @@ -171,7 +174,7 @@ func parseCORSOptions(opts ...CORSOption) *cors { } for _, option := range opts { - _ = option(ch) //TODO: @bharat-rajani, return error to caller if not nil? + option(ch) } return ch diff --git a/git-sensor/vendor/github.com/gorilla/handlers/handlers.go b/git-sensor/vendor/github.com/gorilla/handlers/handlers.go index 9b92fce33..d03f2bf13 100644 --- a/git-sensor/vendor/github.com/gorilla/handlers/handlers.go +++ b/git-sensor/vendor/github.com/gorilla/handlers/handlers.go @@ -35,7 +35,7 @@ func (h MethodHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { } sort.Strings(allow) w.Header().Set("Allow", strings.Join(allow, ", ")) - if req.Method == http.MethodOptions { + if req.Method == "OPTIONS" { w.WriteHeader(http.StatusOK) } else { http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) @@ -44,13 +44,17 @@ func (h MethodHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { } // responseLogger is wrapper of http.ResponseWriter that keeps track of its HTTP -// status code and body size. +// status code and body size type responseLogger struct { w http.ResponseWriter status int size int } +func (l *responseLogger) Header() http.Header { + return l.w.Header() +} + func (l *responseLogger) Write(b []byte) (int, error) { size, err := l.w.Write(b) l.size += size @@ -70,16 +74,39 @@ func (l *responseLogger) Size() int { return l.size } -func (l *responseLogger) Hijack() (net.Conn, *bufio.ReadWriter, error) { - conn, rw, err := l.w.(http.Hijacker).Hijack() - if err == nil && l.status == 0 { +func (l *responseLogger) Flush() { + f, ok := l.w.(http.Flusher) + if ok { + f.Flush() + } +} + +type hijackLogger struct { + responseLogger +} + +func (l *hijackLogger) Hijack() (net.Conn, *bufio.ReadWriter, error) { + h := l.responseLogger.w.(http.Hijacker) + conn, rw, err := h.Hijack() + if err == nil && l.responseLogger.status == 0 { // The status will be StatusSwitchingProtocols if there was no error and // WriteHeader has not been called yet - l.status = http.StatusSwitchingProtocols + l.responseLogger.status = http.StatusSwitchingProtocols } return conn, rw, err } +type closeNotifyWriter struct { + loggingResponseWriter + http.CloseNotifier +} + +type hijackCloseNotifier struct { + loggingResponseWriter + http.Hijacker + http.CloseNotifier +} + // isContentType validates the Content-Type header matches the supplied // contentType. That is, its type and subtype match. func isContentType(h http.Header, contentType string) bool { @@ -97,7 +124,7 @@ func isContentType(h http.Header, contentType string) bool { // Only PUT, POST, and PATCH requests are considered. func ContentTypeHandler(h http.Handler, contentTypes ...string) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if !(r.Method == http.MethodPut || r.Method == http.MethodPost || r.Method == http.MethodPatch) { + if !(r.Method == "PUT" || r.Method == "POST" || r.Method == "PATCH") { h.ServeHTTP(w, r) return } @@ -108,10 +135,7 @@ func ContentTypeHandler(h http.Handler, contentTypes ...string) http.Handler { return } } - http.Error(w, fmt.Sprintf("Unsupported content type %q; expected one of %q", - r.Header.Get("Content-Type"), - contentTypes), - http.StatusUnsupportedMediaType) + http.Error(w, fmt.Sprintf("Unsupported content type %q; expected one of %q", r.Header.Get("Content-Type"), contentTypes), http.StatusUnsupportedMediaType) }) } @@ -136,12 +160,12 @@ const ( // Form method takes precedence over header method. func HTTPMethodOverrideHandler(h http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if r.Method == http.MethodPost { + if r.Method == "POST" { om := r.FormValue(HTTPMethodOverrideFormKey) if om == "" { om = r.Header.Get(HTTPMethodOverrideHeader) } - if om == http.MethodPut || om == http.MethodPatch || om == http.MethodDelete { + if om == "PUT" || om == "PATCH" || om == "DELETE" { r.Method = om } } diff --git a/git-sensor/vendor/github.com/gorilla/handlers/handlers_go18.go b/git-sensor/vendor/github.com/gorilla/handlers/handlers_go18.go new file mode 100644 index 000000000..40f69146b --- /dev/null +++ b/git-sensor/vendor/github.com/gorilla/handlers/handlers_go18.go @@ -0,0 +1,29 @@ +// +build go1.8 + +package handlers + +import ( + "fmt" + "net/http" +) + +type loggingResponseWriter interface { + commonLoggingResponseWriter + http.Pusher +} + +func (l *responseLogger) Push(target string, opts *http.PushOptions) error { + p, ok := l.w.(http.Pusher) + if !ok { + return fmt.Errorf("responseLogger does not implement http.Pusher") + } + return p.Push(target, opts) +} + +func (c *compressResponseWriter) Push(target string, opts *http.PushOptions) error { + p, ok := c.ResponseWriter.(http.Pusher) + if !ok { + return fmt.Errorf("compressResponseWriter does not implement http.Pusher") + } + return p.Push(target, opts) +} diff --git a/git-sensor/vendor/github.com/gorilla/handlers/handlers_pre18.go b/git-sensor/vendor/github.com/gorilla/handlers/handlers_pre18.go new file mode 100644 index 000000000..197836abb --- /dev/null +++ b/git-sensor/vendor/github.com/gorilla/handlers/handlers_pre18.go @@ -0,0 +1,7 @@ +// +build !go1.8 + +package handlers + +type loggingResponseWriter interface { + commonLoggingResponseWriter +} diff --git a/git-sensor/vendor/github.com/gorilla/handlers/logging.go b/git-sensor/vendor/github.com/gorilla/handlers/logging.go index 2badb6fbf..88c25e72d 100644 --- a/git-sensor/vendor/github.com/gorilla/handlers/logging.go +++ b/git-sensor/vendor/github.com/gorilla/handlers/logging.go @@ -12,13 +12,11 @@ import ( "strconv" "time" "unicode/utf8" - - "github.com/felixge/httpsnoop" ) // Logging -// LogFormatterParams is the structure any formatter will be handed when time to log comes. +// LogFormatterParams is the structure any formatter will be handed when time to log comes type LogFormatterParams struct { Request *http.Request URL url.URL @@ -27,7 +25,7 @@ type LogFormatterParams struct { Size int } -// LogFormatter gives the signature of the formatter function passed to CustomLoggingHandler. +// LogFormatter gives the signature of the formatter function passed to CustomLoggingHandler type LogFormatter func(writer io.Writer, params LogFormatterParams) // loggingHandler is the http.Handler implementation for LoggingHandlerTo and its @@ -41,15 +39,12 @@ type loggingHandler struct { func (h loggingHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { t := time.Now() - logger, w := makeLogger(w) + logger := makeLogger(w) url := *req.URL - h.handler.ServeHTTP(w, req) + h.handler.ServeHTTP(logger, req) if req.MultipartForm != nil { - err := req.MultipartForm.RemoveAll() - if err != nil { - return - } + req.MultipartForm.RemoveAll() } params := LogFormatterParams{ @@ -63,23 +58,34 @@ func (h loggingHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { h.formatter(h.writer, params) } -func makeLogger(w http.ResponseWriter) (*responseLogger, http.ResponseWriter) { - logger := &responseLogger{w: w, status: http.StatusOK} - return logger, httpsnoop.Wrap(w, httpsnoop.Hooks{ - Write: func(httpsnoop.WriteFunc) httpsnoop.WriteFunc { - return logger.Write - }, - WriteHeader: func(httpsnoop.WriteHeaderFunc) httpsnoop.WriteHeaderFunc { - return logger.WriteHeader - }, - }) +func makeLogger(w http.ResponseWriter) loggingResponseWriter { + var logger loggingResponseWriter = &responseLogger{w: w, status: http.StatusOK} + if _, ok := w.(http.Hijacker); ok { + logger = &hijackLogger{responseLogger{w: w, status: http.StatusOK}} + } + h, ok1 := logger.(http.Hijacker) + c, ok2 := w.(http.CloseNotifier) + if ok1 && ok2 { + return hijackCloseNotifier{logger, h, c} + } + if ok2 { + return &closeNotifyWriter{logger, c} + } + return logger +} + +type commonLoggingResponseWriter interface { + http.ResponseWriter + http.Flusher + Status() int + Size() int } const lowerhex = "0123456789abcdef" func appendQuoted(buf []byte, s string) []byte { var runeTmp [utf8.UTFMax]byte - for width := 0; len(s) > 0; s = s[width:] { //nolint: wastedassign //TODO: why width starts from 0and reassigned as 1 + for width := 0; len(s) > 0; s = s[width:] { r := rune(s[0]) width = 1 if r >= utf8.RuneSelf { @@ -139,6 +145,7 @@ func appendQuoted(buf []byte, s string) []byte { } } return buf + } // buildCommonLogLine builds a log entry for req in Apache Common Log Format. @@ -153,6 +160,7 @@ func buildCommonLogLine(req *http.Request, url url.URL, ts time.Time, status int } host, _, err := net.SplitHostPort(req.RemoteAddr) + if err != nil { host = req.RemoteAddr } @@ -194,7 +202,7 @@ func buildCommonLogLine(req *http.Request, url url.URL, ts time.Time, status int func writeLog(writer io.Writer, params LogFormatterParams) { buf := buildCommonLogLine(params.Request, params.URL, params.TimeStamp, params.StatusCode, params.Size) buf = append(buf, '\n') - _, _ = writer.Write(buf) + writer.Write(buf) } // writeCombinedLog writes a log entry for req to w in Apache Combined Log Format. @@ -207,7 +215,7 @@ func writeCombinedLog(writer io.Writer, params LogFormatterParams) { buf = append(buf, `" "`...) buf = appendQuoted(buf, params.Request.UserAgent()) buf = append(buf, '"', '\n') - _, _ = writer.Write(buf) + writer.Write(buf) } // CombinedLoggingHandler return a http.Handler that wraps h and logs requests to out in @@ -215,7 +223,7 @@ func writeCombinedLog(writer io.Writer, params LogFormatterParams) { // // See http://httpd.apache.org/docs/2.2/logs.html#combined for a description of this format. // -// LoggingHandler always sets the ident field of the log to -. +// LoggingHandler always sets the ident field of the log to - func CombinedLoggingHandler(out io.Writer, h http.Handler) http.Handler { return loggingHandler{out, h, writeCombinedLog} } @@ -229,18 +237,19 @@ func CombinedLoggingHandler(out io.Writer, h http.Handler) http.Handler { // // Example: // -// r := mux.NewRouter() -// r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { -// w.Write([]byte("This is a catch-all route")) -// }) -// loggedRouter := handlers.LoggingHandler(os.Stdout, r) -// http.ListenAndServe(":1123", loggedRouter) +// r := mux.NewRouter() +// r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { +// w.Write([]byte("This is a catch-all route")) +// }) +// loggedRouter := handlers.LoggingHandler(os.Stdout, r) +// http.ListenAndServe(":1123", loggedRouter) +// func LoggingHandler(out io.Writer, h http.Handler) http.Handler { return loggingHandler{out, h, writeLog} } // CustomLoggingHandler provides a way to supply a custom log formatter -// while taking advantage of the mechanisms in this package. +// while taking advantage of the mechanisms in this package func CustomLoggingHandler(out io.Writer, h http.Handler, f LogFormatter) http.Handler { return loggingHandler{out, h, f} } diff --git a/git-sensor/vendor/github.com/gorilla/handlers/proxy_headers.go b/git-sensor/vendor/github.com/gorilla/handlers/proxy_headers.go index 281d753e9..ed939dcef 100644 --- a/git-sensor/vendor/github.com/gorilla/handlers/proxy_headers.go +++ b/git-sensor/vendor/github.com/gorilla/handlers/proxy_headers.go @@ -18,7 +18,7 @@ var ( var ( // RFC7239 defines a new "Forwarded: " header designed to replace the // existing use of X-Forwarded-* headers. - // e.g. Forwarded: for=192.0.2.60;proto=https;by=203.0.113.43. + // e.g. Forwarded: for=192.0.2.60;proto=https;by=203.0.113.43 forwarded = http.CanonicalHeaderKey("Forwarded") // Allows for a sub-match of the first value after 'for=' to the next // comma, semi-colon or space. The match is case-insensitive. @@ -67,9 +67,7 @@ func ProxyHeaders(h http.Handler) http.Handler { func getIP(r *http.Request) string { var addr string - switch { - case r.Header.Get(xForwardedFor) != "": - fwd := r.Header.Get(xForwardedFor) + if fwd := r.Header.Get(xForwardedFor); fwd != "" { // Only grab the first (client) address. Note that '192.168.0.1, // 10.1.1.1' is a valid key for X-Forwarded-For where addresses after // the first may represent forwarding proxies earlier in the chain. @@ -78,15 +76,17 @@ func getIP(r *http.Request) string { s = len(fwd) } addr = fwd[:s] - case r.Header.Get(xRealIP) != "": - addr = r.Header.Get(xRealIP) - case r.Header.Get(forwarded) != "": + } else if fwd := r.Header.Get(xRealIP); fwd != "" { + // X-Real-IP should only contain one IP address (the client making the + // request). + addr = fwd + } else if fwd := r.Header.Get(forwarded); fwd != "" { // match should contain at least two elements if the protocol was // specified in the Forwarded header. The first element will always be // the 'for=' capture, which we ignore. In the case of multiple IP // addresses (for=8.8.8.8, 8.8.4.4,172.16.1.20 is valid) we only // extract the first, which should be the client IP. - if match := forRegex.FindStringSubmatch(r.Header.Get(forwarded)); len(match) > 1 { + if match := forRegex.FindStringSubmatch(fwd); len(match) > 1 { // IPv6 addresses in Forwarded headers are quoted-strings. We strip // these quotes. addr = strings.Trim(match[1], `"`) diff --git a/git-sensor/vendor/github.com/gorilla/handlers/recovery.go b/git-sensor/vendor/github.com/gorilla/handlers/recovery.go index 0d4f955ec..b1be9dc83 100644 --- a/git-sensor/vendor/github.com/gorilla/handlers/recovery.go +++ b/git-sensor/vendor/github.com/gorilla/handlers/recovery.go @@ -19,7 +19,7 @@ type recoveryHandler struct { // RecoveryOption provides a functional approach to define // configuration for a handler; such as setting the logging -// whether or not to print stack traces on panic. +// whether or not to print strack traces on panic. type RecoveryOption func(http.Handler) func parseRecoveryOptions(h http.Handler, opts ...RecoveryOption) http.Handler { @@ -36,12 +36,12 @@ func parseRecoveryOptions(h http.Handler, opts ...RecoveryOption) http.Handler { // // Example: // -// r := mux.NewRouter() -// r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { -// panic("Unexpected error!") -// }) +// r := mux.NewRouter() +// r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { +// panic("Unexpected error!") +// }) // -// http.ListenAndServe(":1123", handlers.RecoveryHandler()(r)) +// http.ListenAndServe(":1123", handlers.RecoveryHandler()(r)) func RecoveryHandler(opts ...RecoveryOption) func(h http.Handler) http.Handler { return func(h http.Handler) http.Handler { r := &recoveryHandler{handler: h} @@ -50,22 +50,20 @@ func RecoveryHandler(opts ...RecoveryOption) func(h http.Handler) http.Handler { } // RecoveryLogger is a functional option to override -// the default logger. +// the default logger func RecoveryLogger(logger RecoveryHandlerLogger) RecoveryOption { return func(h http.Handler) { - r := h.(*recoveryHandler) //nolint:errcheck //TODO: - // @bharat-rajani should return type-assertion error but would break the API? + r := h.(*recoveryHandler) r.logger = logger } } // PrintRecoveryStack is a functional option to enable // or disable printing stack traces on panic. -func PrintRecoveryStack(shouldPrint bool) RecoveryOption { +func PrintRecoveryStack(print bool) RecoveryOption { return func(h http.Handler) { - r := h.(*recoveryHandler) //nolint:errcheck //TODO: - // @bharat-rajani should return type-assertion error but would break the API? - r.printStack = shouldPrint + r := h.(*recoveryHandler) + r.printStack = print } } @@ -88,11 +86,6 @@ func (h recoveryHandler) log(v ...interface{}) { } if h.printStack { - stack := string(debug.Stack()) - if h.logger != nil { - h.logger.Println(stack) - } else { - log.Println(stack) - } + debug.PrintStack() } } diff --git a/git-sensor/vendor/github.com/skeema/knownhosts/NOTICE b/git-sensor/vendor/github.com/skeema/knownhosts/NOTICE index 224b20248..a92cb34d6 100644 --- a/git-sensor/vendor/github.com/skeema/knownhosts/NOTICE +++ b/git-sensor/vendor/github.com/skeema/knownhosts/NOTICE @@ -1,4 +1,4 @@ -Copyright 2025 Skeema LLC and the Skeema Knownhosts authors +Copyright 2024 Skeema LLC and the Skeema Knownhosts authors Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/git-sensor/vendor/github.com/skeema/knownhosts/README.md b/git-sensor/vendor/github.com/skeema/knownhosts/README.md index 170e04d14..046bc0edc 100644 --- a/git-sensor/vendor/github.com/skeema/knownhosts/README.md +++ b/git-sensor/vendor/github.com/skeema/knownhosts/README.md @@ -116,7 +116,7 @@ config := &ssh.ClientConfig{ ## License -**Source code copyright 2025 Skeema LLC and the Skeema Knownhosts authors** +**Source code copyright 2024 Skeema LLC and the Skeema Knownhosts authors** ```text Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/git-sensor/vendor/github.com/tidwall/gjson/README.md b/git-sensor/vendor/github.com/tidwall/gjson/README.md index 387766d50..b7848de60 100644 --- a/git-sensor/vendor/github.com/tidwall/gjson/README.md +++ b/git-sensor/vendor/github.com/tidwall/gjson/README.md @@ -1,14 +1,10 @@

- - - - GJSON - +GJSON
GoDoc -GJSON Playground -GJSON Syntax - +GJSON Playground

get json values quickly

@@ -18,10 +14,6 @@ It has features such as [one line retrieval](#get-a-value), [dot notation paths] Also check out [SJSON](https://github.com/tidwall/sjson) for modifying json, and the [JJ](https://github.com/tidwall/jj) command line tool. -This README is a quick overview of how to use GJSON, for more information check out [GJSON Syntax](SYNTAX.md). - -GJSON is also available for [Python](https://github.com/volans-/gjson-py) and [Rust](https://github.com/tidwall/gjson.rs) - Getting Started =============== @@ -178,7 +170,7 @@ The `result.Int()` and `result.Uint()` calls are capable of reading all 64 bits, ```go result.Int() int64 // -9223372036854775808 to 9223372036854775807 -result.Uint() uint64 // 0 to 18446744073709551615 +result.Uint() int64 // 0 to 18446744073709551615 ``` ## Modifiers and path chaining @@ -208,12 +200,6 @@ There are currently the following built-in modifiers: - `@valid`: Ensure the json document is valid. - `@flatten`: Flattens an array. - `@join`: Joins multiple objects into a single object. -- `@keys`: Returns an array of keys for an object. -- `@values`: Returns an array of values for an object. -- `@tostr`: Converts json to a string. Wraps a json string. -- `@fromstr`: Converts a string from json. Unwraps a json string. -- `@group`: Groups arrays of objects. See [e4fc67c](https://github.com/tidwall/gjson/commit/e4fc67c92aeebf2089fabc7872f010e340d105db). -- `@dig`: Search for a value without providing its entire path. See [e8e87f2](https://github.com/tidwall/gjson/commit/e8e87f2a00dc41f3aba5631094e21f59a8cf8cbf). ### Modifier arguments @@ -429,6 +415,16 @@ if result.Index > 0 { This is a best-effort no allocation sub slice of the original json. This method utilizes the `result.Index` field, which is the position of the raw data in the original json. It's possible that the value of `result.Index` equals zero, in which case the `result.Raw` is converted to a `[]byte`. +## Get multiple values at once + +The `GetMany` function can be used to get multiple values at the same time. + +```go +results := gjson.GetMany(json, "name.first", "name.last", "age") +``` + +The return value is a `[]Result`, which will always contain exactly the same number of items as the input paths. + ## Performance Benchmarks of GJSON alongside [encoding/json](https://golang.org/pkg/encoding/json/), @@ -438,15 +434,14 @@ Benchmarks of GJSON alongside [encoding/json](https://golang.org/pkg/encoding/js and [json-iterator](https://github.com/json-iterator/go) ``` -BenchmarkGJSONGet-10 17893731 202.1 ns/op 0 B/op 0 allocs/op -BenchmarkGJSONUnmarshalMap-10 1663548 2157 ns/op 1920 B/op 26 allocs/op -BenchmarkJSONUnmarshalMap-10 832236 4279 ns/op 2920 B/op 68 allocs/op -BenchmarkJSONUnmarshalStruct-10 1076475 3219 ns/op 920 B/op 12 allocs/op -BenchmarkJSONDecoder-10 585729 6126 ns/op 3845 B/op 160 allocs/op -BenchmarkFFJSONLexer-10 2508573 1391 ns/op 880 B/op 8 allocs/op -BenchmarkEasyJSONLexer-10 3000000 537.9 ns/op 501 B/op 5 allocs/op -BenchmarkJSONParserGet-10 13707510 263.9 ns/op 21 B/op 0 allocs/op -BenchmarkJSONIterator-10 3000000 561.2 ns/op 693 B/op 14 allocs/op +BenchmarkGJSONGet-8 3000000 372 ns/op 0 B/op 0 allocs/op +BenchmarkGJSONUnmarshalMap-8 900000 4154 ns/op 1920 B/op 26 allocs/op +BenchmarkJSONUnmarshalMap-8 600000 9019 ns/op 3048 B/op 69 allocs/op +BenchmarkJSONDecoder-8 300000 14120 ns/op 4224 B/op 184 allocs/op +BenchmarkFFJSONLexer-8 1500000 3111 ns/op 896 B/op 8 allocs/op +BenchmarkEasyJSONLexer-8 3000000 887 ns/op 613 B/op 6 allocs/op +BenchmarkJSONParserGet-8 3000000 499 ns/op 21 B/op 0 allocs/op +BenchmarkJSONIterator-8 3000000 812 ns/op 544 B/op 9 allocs/op ``` JSON document used: @@ -487,6 +482,4 @@ widget.image.hOffset widget.text.onMouseUp ``` -** - -*These benchmarks were run on a MacBook Pro M1 Max using Go 1.22 and can be found [here](https://github.com/tidwall/gjson-benchmarks).* +*These benchmarks were run on a MacBook Pro 15" 2.8 GHz Intel Core i7 using Go 1.8 and can be found [here](https://github.com/tidwall/gjson-benchmarks).* diff --git a/git-sensor/vendor/github.com/tidwall/gjson/SYNTAX.md b/git-sensor/vendor/github.com/tidwall/gjson/SYNTAX.md index a3f0fac23..34fdccf47 100644 --- a/git-sensor/vendor/github.com/tidwall/gjson/SYNTAX.md +++ b/git-sensor/vendor/github.com/tidwall/gjson/SYNTAX.md @@ -1,6 +1,6 @@ # GJSON Path Syntax -A GJSON Path is a text string syntax that describes a search pattern for quickly retrieving values from a JSON payload. +A GJSON Path is a text string syntax that describes a search pattern for quickly retreiving values from a JSON payload. This document is designed to explain the structure of a GJSON Path through examples. @@ -13,16 +13,16 @@ This document is designed to explain the structure of a GJSON Path through examp - [Dot vs Pipe](#dot-vs-pipe) - [Modifiers](#modifiers) - [Multipaths](#multipaths) -- [Literals](#literals) -The definitive implementation is [github.com/tidwall/gjson](https://github.com/tidwall/gjson). +The definitive implemenation is [github.com/tidwall/gjson](https://github.com/tidwall/gjson). Use the [GJSON Playground](https://gjson.dev) to experiment with the syntax online. + ## Path structure -A GJSON Path is intended to be easily expressed as a series of components separated by a `.` character. +A GJSON Path is intended to be easily expressed as a series of components seperated by a `.` character. -Along with `.` character, there are a few more that have special meaning, including `|`, `#`, `@`, `\`, `*`, `!`, and `?`. +Along with `.` character, there are a few more that have special meaning, including `|`, `#`, `@`, `\`, `*`, and `?`. ## Example @@ -46,7 +46,7 @@ The following GJSON Paths evaluate to the accompanying values. ### Basic -In many cases you'll just want to retrieve values by object name or array index. +In many cases you'll just want to retreive values by object name or array index. ```go name.last "Anderson" @@ -77,7 +77,7 @@ Special purpose characters, such as `.`, `*`, and `?` can be escaped with `\`. fav\.movie "Deer Hunter" ``` -You'll also need to make sure that the `\` character is correctly escaped when hardcoding a path in your source code. +You'll also need to make sure that the `\` character is correctly escaped when hardcoding a path in you source code. ```go // Go @@ -137,21 +137,12 @@ next major release.* The `~` (tilde) operator will convert a value to a boolean before comparison. -Supported tilde comparison type are: - -``` -~true Converts true-ish values to true -~false Converts false-ish and non-existent values to true -~null Converts null and non-existent values to true -~* Converts any existing value to true -``` - For example, using the following JSON: ```json { "vals": [ - { "a": 1, "b": "data" }, + { "a": 1, "b": true }, { "a": 2, "b": true }, { "a": 3, "b": false }, { "a": 4, "b": "0" }, @@ -166,23 +157,15 @@ For example, using the following JSON: } ``` -To query for all true-ish or false-ish values: +You can now query for all true(ish) or false(ish) values: ``` -vals.#(b==~true)#.a >> [2,6,7,8] +vals.#(b==~true)#.a >> [1,2,6,7,8] vals.#(b==~false)#.a >> [3,4,5,9,10,11] ``` The last value which was non-existent is treated as `false` -To query for null and explicit value existence: - -``` -vals.#(b==~null)#.a >> [10,11] -vals.#(b==~*)#.a >> [1,2,3,4,5,6,7,8,9,10] -vals.#(b!=~*)#.a >> [11] -``` - ### Dot vs Pipe The `.` is standard separator, but it's also possible to use a `|`. @@ -253,12 +236,6 @@ There are currently the following built-in modifiers: - `@valid`: Ensure the json document is valid. - `@flatten`: Flattens an array. - `@join`: Joins multiple objects into a single object. -- `@keys`: Returns an array of keys for an object. -- `@values`: Returns an array of values for an object. -- `@tostr`: Converts json to a string. Wraps a json string. -- `@fromstr`: Converts a string from json. Unwraps a json string. -- `@group`: Groups arrays of objects. See [e4fc67c](https://github.com/tidwall/gjson/commit/e4fc67c92aeebf2089fabc7872f010e340d105db). -- `@dig`: Search for a value without providing its entire path. See [e8e87f2](https://github.com/tidwall/gjson/commit/e8e87f2a00dc41f3aba5631094e21f59a8cf8cbf). #### Modifier arguments @@ -317,7 +294,7 @@ Starting with v1.3.0, GJSON added the ability to join multiple paths together to form new documents. Wrapping comma-separated paths between `[...]` or `{...}` will result in a new array or object, respectively. -For example, using the given multipath: +For example, using the given multipath ``` {name.first,age,"the_murphys":friends.#(last="Murphy")#.first} @@ -333,28 +310,8 @@ determined, then "_" is used. This results in -```json -{"first":"Tom","age":37,"the_murphys":["Dale","Jane"]} -``` - -### Literals - -Starting with v1.12.0, GJSON added support of json literals, which provides a way for constructing static blocks of json. This is can be particularly useful when constructing a new json document using [multipaths](#multipaths). - -A json literal begins with the '!' declaration character. - -For example, using the given multipath: - ``` -{name.first,age,"company":!"Happysoft","employed":!true} +{"first":"Tom","age":37,"the_murphys":["Dale","Jane"]} ``` -Here we selected the first name and age. Then add two new fields, "company" and "employed". - -This results in - -```json -{"first":"Tom","age":37,"company":"Happysoft","employed":true} -``` -*See issue [#249](https://github.com/tidwall/gjson/issues/249) for additional context on JSON Literals.* diff --git a/git-sensor/vendor/github.com/tidwall/gjson/gjson.go b/git-sensor/vendor/github.com/tidwall/gjson/gjson.go index 5aa2a4ffa..95d210b23 100644 --- a/git-sensor/vendor/github.com/tidwall/gjson/gjson.go +++ b/git-sensor/vendor/github.com/tidwall/gjson/gjson.go @@ -2,6 +2,7 @@ package gjson import ( + "encoding/json" "strconv" "strings" "time" @@ -188,15 +189,14 @@ func (t Result) Time() time.Time { } // Array returns back an array of values. -// If the result represents a null value or is non-existent, then an empty -// array will be returned. -// If the result is not a JSON array, the return value will be an +// If the result represents a non-existent value, then an empty array will be +// returned. If the result is not a JSON array, the return value will be an // array containing one result. func (t Result) Array() []Result { if t.Type == Null { return []Result{} } - if !t.IsArray() { + if t.Type != JSON { return []Result{t} } r := t.arrayOrMap('[', false) @@ -213,11 +213,6 @@ func (t Result) IsArray() bool { return t.Type == JSON && len(t.Raw) > 0 && t.Raw[0] == '[' } -// IsBool returns true if the result value is a JSON boolean. -func (t Result) IsBool() bool { - return t.Type == True || t.Type == False -} - // ForEach iterates through values. // If the result represents a non-existent value, then no values will be // iterated. If the result is an Object, the iterator will pass the key and @@ -233,19 +228,17 @@ func (t Result) ForEach(iterator func(key, value Result) bool) { return } json := t.Raw - var obj bool + var keys bool var i int var key, value Result for ; i < len(json); i++ { if json[i] == '{' { i++ key.Type = String - obj = true + keys = true break } else if json[i] == '[' { i++ - key.Type = Number - key.Num = -1 break } if json[i] > ' ' { @@ -255,9 +248,8 @@ func (t Result) ForEach(iterator func(key, value Result) bool) { var str string var vesc bool var ok bool - var idx int for ; i < len(json); i++ { - if obj { + if keys { if json[i] != '"' { continue } @@ -272,9 +264,7 @@ func (t Result) ForEach(iterator func(key, value Result) bool) { key.Str = str[1 : len(str)-1] } key.Raw = str - key.Index = s + t.Index - } else { - key.Num += 1 + key.Index = s } for ; i < len(json); i++ { if json[i] <= ' ' || json[i] == ',' || json[i] == ':' { @@ -287,17 +277,10 @@ func (t Result) ForEach(iterator func(key, value Result) bool) { if !ok { return } - if t.Indexes != nil { - if idx < len(t.Indexes) { - value.Index = t.Indexes[idx] - } - } else { - value.Index = s + t.Index - } + value.Index = s if !iterator(key, value) { return } - idx++ } } @@ -314,15 +297,7 @@ func (t Result) Map() map[string]Result { // Get searches result for the specified path. // The result should be a JSON array or object. func (t Result) Get(path string) Result { - r := Get(t.Raw, path) - if r.Indexes != nil { - for i := 0; i < len(r.Indexes); i++ { - r.Indexes[i] += t.Index - } - } else { - r.Index += t.Index - } - return r + return Get(t.Raw, path) } type arrayOrMapResult struct { @@ -413,8 +388,6 @@ func (t Result) arrayOrMap(vc byte, valueize bool) (r arrayOrMapResult) { value.Raw, value.Str = tostr(json[i:]) value.Num = 0 } - value.Index = i + t.Index - i += len(value.Raw) - 1 if r.vc == '{' { @@ -441,17 +414,6 @@ func (t Result) arrayOrMap(vc byte, valueize bool) (r arrayOrMapResult) { } } end: - if t.Indexes != nil { - if len(t.Indexes) != len(r.a) { - for i := 0; i < len(r.a); i++ { - r.a[i].Index = 0 - } - } else { - for i := 0; i < len(r.a); i++ { - r.a[i].Index = t.Indexes[i] - } - } - } return } @@ -463,8 +425,7 @@ end: // use the Valid function first. func Parse(json string) Result { var value Result - i := 0 - for ; i < len(json); i++ { + for i := 0; i < len(json); i++ { if json[i] == '{' || json[i] == '[' { value.Type = JSON value.Raw = json[i:] // just take the entire raw @@ -474,20 +435,16 @@ func Parse(json string) Result { continue } switch json[i] { - case '+', '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - 'i', 'I', 'N': - value.Type = Number - value.Raw, value.Num = tonum(json[i:]) - case 'n': - if i+1 < len(json) && json[i+1] != 'u' { - // nan + default: + if (json[i] >= '0' && json[i] <= '9') || json[i] == '-' { value.Type = Number value.Raw, value.Num = tonum(json[i:]) } else { - // null - value.Type = Null - value.Raw = tolit(json[i:]) + return Result{} } + case 'n': + value.Type = Null + value.Raw = tolit(json[i:]) case 't': value.Type = True value.Raw = tolit(json[i:]) @@ -497,14 +454,9 @@ func Parse(json string) Result { case '"': value.Type = String value.Raw, value.Str = tostr(json[i:]) - default: - return Result{} } break } - if value.Exists() { - value.Index = i - } return value } @@ -578,12 +530,20 @@ func tonum(json string) (raw string, num float64) { return } // could be a '+' or '-'. let's assume so. - } else if json[i] == ']' || json[i] == '}' { - // break on ']' or '}' - raw = json[:i] - num, _ = strconv.ParseFloat(raw, 64) - return + continue + } + if json[i] < ']' { + // probably a valid number + continue + } + if json[i] == 'e' || json[i] == 'E' { + // allow for exponential numbers + continue } + // likely a ']' or '}' + raw = json[:i] + num, _ = strconv.ParseFloat(raw, 64) + return } raw = json num, _ = strconv.ParseFloat(raw, 64) @@ -645,9 +605,9 @@ func tostr(json string) (raw string, str string) { // Exists returns true if value exists. // -// if gjson.Get(json, "name.last").Exists(){ -// println("value exists") -// } +// if gjson.Get(json, "name.last").Exists(){ +// println("value exists") +// } func (t Result) Exists() bool { return t.Type != Null || len(t.Raw) != 0 } @@ -661,6 +621,7 @@ func (t Result) Exists() bool { // nil, for JSON null // map[string]interface{}, for JSON objects // []interface{}, for JSON arrays +// func (t Result) Value() interface{} { if t.Type == String { return t.Str @@ -774,7 +735,7 @@ func parseArrayPath(path string) (r arrayPathResult) { } if path[i] == '.' { r.part = path[:i] - if !r.arrch && i < len(path)-1 && isDotPiperChar(path[i+1:]) { + if !r.arrch && i < len(path)-1 && isDotPiperChar(path[i+1]) { r.pipe = path[i+1:] r.piped = true } else { @@ -799,7 +760,7 @@ func parseArrayPath(path string) (r arrayPathResult) { // bad query, end now break } - if len(value) >= 2 && value[0] == '"' && + if len(value) > 2 && value[0] == '"' && value[len(value)-1] == '"' { value = value[1 : len(value)-1] if vesc { @@ -825,28 +786,19 @@ func parseArrayPath(path string) (r arrayPathResult) { } // splitQuery takes a query and splits it into three parts: -// -// path, op, middle, and right. -// +// path, op, middle, and right. // So for this query: -// -// #(first_name=="Murphy").last -// +// #(first_name=="Murphy").last // Becomes -// -// first_name # path -// =="Murphy" # middle -// .last # right -// +// first_name # path +// =="Murphy" # middle +// .last # right // Or, -// -// #(service_roles.#(=="one")).cap -// +// #(service_roles.#(=="one")).cap // Becomes -// -// service_roles.#(=="one") # path -// # middle -// .cap # right +// service_roles.#(=="one") # path +// # middle +// .cap # right func parseQuery(query string) ( path, op, value, remain string, i int, vesc, ok bool, ) { @@ -944,23 +896,8 @@ right: } // peek at the next byte and see if it's a '@', '[', or '{'. -func isDotPiperChar(s string) bool { - if DisableModifiers { - return false - } - c := s[0] - if c == '@' { - // check that the next component is *not* a modifier. - i := 1 - for ; i < len(s); i++ { - if s[i] == '.' || s[i] == '|' || s[i] == ':' { - break - } - } - _, ok := modifiers[s[1:i]] - return ok - } - return c == '[' || c == '{' +func isDotPiperChar(c byte) bool { + return !DisableModifiers && (c == '@' || c == '[' || c == '{') } type objectPathResult struct { @@ -982,7 +919,7 @@ func parseObjectPath(path string) (r objectPathResult) { } if path[i] == '.' { r.part = path[:i] - if i < len(path)-1 && isDotPiperChar(path[i+1:]) { + if i < len(path)-1 && isDotPiperChar(path[i+1]) { r.pipe = path[i+1:] r.piped = true } else { @@ -1012,13 +949,13 @@ func parseObjectPath(path string) (r objectPathResult) { continue } else if path[i] == '.' { r.part = string(epart) - if i < len(path)-1 && isDotPiperChar(path[i+1:]) { + if i < len(path)-1 && isDotPiperChar(path[i+1]) { r.pipe = path[i+1:] r.piped = true } else { r.path = path[i+1:] - r.more = true } + r.more = true return } else if path[i] == '|' { r.part = string(epart) @@ -1040,10 +977,6 @@ func parseObjectPath(path string) (r objectPathResult) { return } -var vchars = [256]byte{ - '"': 2, '{': 3, '(': 3, '[': 3, '}': 1, ')': 1, ']': 1, -} - func parseSquash(json string, i int) (int, string) { // expects that the lead character is a '[' or '{' or '(' // squash the value, ignoring all nested arrays and objects. @@ -1051,137 +984,43 @@ func parseSquash(json string, i int) (int, string) { s := i i++ depth := 1 - var c byte - for i < len(json) { - for i < len(json)-8 { - jslice := json[i : i+8] - c = vchars[jslice[0]] - if c != 0 { - i += 0 - goto token - } - c = vchars[jslice[1]] - if c != 0 { - i += 1 - goto token - } - c = vchars[jslice[2]] - if c != 0 { - i += 2 - goto token - } - c = vchars[jslice[3]] - if c != 0 { - i += 3 - goto token - } - c = vchars[jslice[4]] - if c != 0 { - i += 4 - goto token - } - c = vchars[jslice[5]] - if c != 0 { - i += 5 - goto token - } - c = vchars[jslice[6]] - if c != 0 { - i += 6 - goto token - } - c = vchars[jslice[7]] - if c != 0 { - i += 7 - goto token - } - i += 8 - } - c = vchars[json[i]] - if c == 0 { - i++ - continue - } - token: - if c == 2 { - // '"' string - i++ - s2 := i - nextquote: - for i < len(json)-8 { - jslice := json[i : i+8] - if jslice[0] == '"' { - i += 0 - goto strchkesc - } - if jslice[1] == '"' { - i += 1 - goto strchkesc - } - if jslice[2] == '"' { - i += 2 - goto strchkesc - } - if jslice[3] == '"' { - i += 3 - goto strchkesc - } - if jslice[4] == '"' { - i += 4 - goto strchkesc - } - if jslice[5] == '"' { - i += 5 - goto strchkesc - } - if jslice[6] == '"' { - i += 6 - goto strchkesc - } - if jslice[7] == '"' { - i += 7 - goto strchkesc - } - i += 8 - } - goto strchkstd - strchkesc: - if json[i-1] != '\\' { + for ; i < len(json); i++ { + if json[i] >= '"' && json[i] <= '}' { + switch json[i] { + case '"': i++ - continue - } - strchkstd: - for i < len(json) { - if json[i] > '\\' || json[i] != '"' { - i++ - continue - } - // look for an escaped slash - if json[i-1] == '\\' { - n := 0 - for j := i - 2; j > s2-1; j-- { - if json[j] != '\\' { - break - } - n++ + s2 := i + for ; i < len(json); i++ { + if json[i] > '\\' { + continue } - if n%2 == 0 { - i++ - goto nextquote + if json[i] == '"' { + // look for an escaped slash + if json[i-1] == '\\' { + n := 0 + for j := i - 2; j > s2-1; j-- { + if json[j] != '\\' { + break + } + n++ + } + if n%2 == 0 { + continue + } + } + break } } - break - } - } else { - // '{', '[', '(', '}', ']', ')' - // open close tokens - depth += int(c) - 2 - if depth == 0 { - i++ - return i, json[s:i] + case '{', '[', '(': + depth++ + case '}', ']', ')': + depth-- + if depth == 0 { + i++ + return i, json[s:i] + } } } - i++ } return i, json[s:] } @@ -1263,7 +1102,6 @@ func parseObject(c *parseContext, i int, path string) (int, bool) { } hit = pmatch && !rp.more for ; i < len(c.json); i++ { - var num bool switch c.json[i] { default: continue @@ -1311,13 +1149,15 @@ func parseObject(c *parseContext, i int, path string) (int, bool) { return i, true } } - case 'n': - if i+1 < len(c.json) && c.json[i+1] != 'u' { - num = true - break + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + i, val = parseNumber(c.json, i) + if hit { + c.value.Raw = val + c.value.Type = Number + c.value.Num, _ = strconv.ParseFloat(val, 64) + return i, true } - fallthrough - case 't', 'f': + case 't', 'f', 'n': vc := c.json[i] i, val = parseLiteral(c.json, i) if hit { @@ -1330,18 +1170,6 @@ func parseObject(c *parseContext, i int, path string) (int, bool) { } return i, true } - case '+', '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - 'i', 'I', 'N': - num = true - } - if num { - i, val = parseNumber(c.json, i) - if hit { - c.value.Raw = val - c.value.Type = Number - c.value.Num, _ = strconv.ParseFloat(val, 64) - return i, true - } } break } @@ -1350,81 +1178,22 @@ func parseObject(c *parseContext, i int, path string) (int, bool) { } // matchLimit will limit the complexity of the match operation to avoid ReDos -// attacks from arbitrary inputs. +// attacks from arbritary inputs. // See the github.com/tidwall/match.MatchLimit function for more information. func matchLimit(str, pattern string) bool { matched, _ := match.MatchLimit(str, pattern, 10000) return matched } -func falseish(t Result) bool { - switch t.Type { - case Null: - return true - case False: - return true - case String: - b, err := strconv.ParseBool(strings.ToLower(t.Str)) - if err != nil { - return false - } - return !b - case Number: - return t.Num == 0 - default: - return false - } -} - -func trueish(t Result) bool { - switch t.Type { - case True: - return true - case String: - b, err := strconv.ParseBool(strings.ToLower(t.Str)) - if err != nil { - return false - } - return b - case Number: - return t.Num != 0 - default: - return false - } -} - -func nullish(t Result) bool { - return t.Type == Null -} - func queryMatches(rp *arrayPathResult, value Result) bool { rpv := rp.query.value - if len(rpv) > 0 { - if rpv[0] == '~' { - // convert to bool - rpv = rpv[1:] - var ish, ok bool - switch rpv { - case "*": - ish, ok = value.Exists(), true - case "null": - ish, ok = nullish(value), true - case "true": - ish, ok = trueish(value), true - case "false": - ish, ok = falseish(value), true - } - if ok { - rpv = "true" - if ish { - value = Result{Type: True} - } else { - value = Result{Type: False} - } - } else { - rpv = "" - value = Result{} - } + if len(rpv) > 0 && rpv[0] == '~' { + // convert to bool + rpv = rpv[1:] + if value.Bool() { + value = Result{Type: True} + } else { + value = Result{Type: False} } } if !value.Exists() { @@ -1588,7 +1357,6 @@ func parseArray(c *parseContext, i int, path string) (int, bool) { } else { ch = c.json[i] } - var num bool switch ch { default: continue @@ -1671,13 +1439,26 @@ func parseArray(c *parseContext, i int, path string) (int, bool) { return i, true } } - case 'n': - if i+1 < len(c.json) && c.json[i+1] != 'u' { - num = true - break + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + i, val = parseNumber(c.json, i) + if rp.query.on { + var qval Result + qval.Raw = val + qval.Type = Number + qval.Num, _ = strconv.ParseFloat(val, 64) + if procQuery(qval) { + return i, true + } + } else if hit { + if rp.alogok { + break + } + c.value.Raw = val + c.value.Type = Number + c.value.Num, _ = strconv.ParseFloat(val, 64) + return i, true } - fallthrough - case 't', 'f': + case 't', 'f', 'n': vc := c.json[i] i, val = parseLiteral(c.json, i) if rp.query.on { @@ -1705,9 +1486,6 @@ func parseArray(c *parseContext, i int, path string) (int, bool) { } return i, true } - case '+', '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - 'i', 'I', 'N': - num = true case ']': if rp.arrch && rp.part == "#" { if rp.alogok { @@ -1732,6 +1510,7 @@ func parseArray(c *parseContext, i int, path string) (int, bool) { } if idx < len(c.json) && c.json[idx] != ']' { _, res, ok := parseAny(c.json, idx, true) + parentIndex := res.Index if ok { res := res.Get(rp.alogkey) if res.Exists() { @@ -1743,7 +1522,8 @@ func parseArray(c *parseContext, i int, path string) (int, bool) { raw = res.String() } jsons = append(jsons, []byte(raw)...) - indexes = append(indexes, res.Index) + indexes = append(indexes, + res.Index+parentIndex) k++ } } @@ -1781,26 +1561,6 @@ func parseArray(c *parseContext, i int, path string) (int, bool) { } return i + 1, false } - if num { - i, val = parseNumber(c.json, i) - if rp.query.on { - var qval Result - qval.Raw = val - qval.Type = Number - qval.Num, _ = strconv.ParseFloat(val, 64) - if procQuery(qval) { - return i, true - } - } else if hit { - if rp.alogok { - break - } - c.value.Raw = val - c.value.Type = Number - c.value.Num, _ = strconv.ParseFloat(val, 64) - return i, true - } - } break } } @@ -1916,7 +1676,7 @@ type subSelector struct { // first character in path is either '[' or '{', and has already been checked // prior to calling this function. func parseSubSelectors(path string) (sels []subSelector, out string, ok bool) { - modifier := 0 + modifer := 0 depth := 1 colon := 0 start := 1 @@ -1931,7 +1691,6 @@ func parseSubSelectors(path string) (sels []subSelector, out string, ok bool) { } sels = append(sels, sel) colon = 0 - modifier = 0 start = i + 1 } for ; i < len(path); i++ { @@ -1939,11 +1698,11 @@ func parseSubSelectors(path string) (sels []subSelector, out string, ok bool) { case '\\': i++ case '@': - if modifier == 0 && i > 0 && (path[i-1] == '.' || path[i-1] == '|') { - modifier = i + if modifer == 0 && i > 0 && (path[i-1] == '.' || path[i-1] == '|') { + modifer = i } case ':': - if modifier == 0 && colon == 0 && depth == 1 { + if modifer == 0 && colon == 0 && depth == 1 { colon = i } case ',': @@ -1996,86 +1755,24 @@ func isSimpleName(component string) bool { return false } switch component[i] { - case '[', ']', '{', '}', '(', ')', '#', '|', '!': + case '[', ']', '{', '}', '(', ')', '#', '|': return false } } return true } -var hexchars = [...]byte{ - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - 'a', 'b', 'c', 'd', 'e', 'f', -} - -func appendHex16(dst []byte, x uint16) []byte { - return append(dst, - hexchars[x>>12&0xF], hexchars[x>>8&0xF], - hexchars[x>>4&0xF], hexchars[x>>0&0xF], - ) -} - -// DisableEscapeHTML will disable the automatic escaping of certain -// "problamatic" HTML characters when encoding to JSON. -// These character include '>', '<' and '&', which get escaped to \u003e, -// \u0026, and \u003c respectively. -// -// This is a global flag and will affect all further gjson operations. -// Ideally, if used, it should be set one time before other gjson functions -// are called. -var DisableEscapeHTML = false - -// AppendJSONString is a convenience function that converts the provided string -// to a valid JSON string and appends it to dst. -func AppendJSONString(dst []byte, s string) []byte { - dst = append(dst, make([]byte, len(s)+2)...) - dst = append(dst[:len(dst)-len(s)-2], '"') +func appendJSONString(dst []byte, s string) []byte { for i := 0; i < len(s); i++ { - if s[i] < ' ' { - dst = append(dst, '\\') - switch s[i] { - case '\b': - dst = append(dst, 'b') - case '\f': - dst = append(dst, 'f') - case '\n': - dst = append(dst, 'n') - case '\r': - dst = append(dst, 'r') - case '\t': - dst = append(dst, 't') - default: - dst = append(dst, 'u') - dst = appendHex16(dst, uint16(s[i])) - } - } else if !DisableEscapeHTML && - (s[i] == '>' || s[i] == '<' || s[i] == '&') { - dst = append(dst, '\\', 'u') - dst = appendHex16(dst, uint16(s[i])) - } else if s[i] == '\\' { - dst = append(dst, '\\', '\\') - } else if s[i] == '"' { - dst = append(dst, '\\', '"') - } else if s[i] > 127 { - // read utf8 character - r, n := utf8.DecodeRuneInString(s[i:]) - if n == 0 { - break - } - if r == utf8.RuneError && n == 1 { - dst = append(dst, `\ufffd`...) - } else if r == '\u2028' || r == '\u2029' { - dst = append(dst, `\u202`...) - dst = append(dst, hexchars[r&0xF]) - } else { - dst = append(dst, s[i:i+n]...) - } - i = i + n - 1 - } else { - dst = append(dst, s[i]) + if s[i] < ' ' || s[i] == '\\' || s[i] == '"' || s[i] > 126 { + d, _ := json.Marshal(s) + return append(dst, string(d)...) } } - return append(dst, '"') + dst = append(dst, '"') + dst = append(dst, s...) + dst = append(dst, '"') + return dst } type parseContext struct { @@ -2098,23 +1795,23 @@ type parseContext struct { // the '#' character. // The dot and wildcard character can be escaped with '\'. // -// { -// "name": {"first": "Tom", "last": "Anderson"}, -// "age":37, -// "children": ["Sara","Alex","Jack"], -// "friends": [ -// {"first": "James", "last": "Murphy"}, -// {"first": "Roger", "last": "Craig"} -// ] -// } -// "name.last" >> "Anderson" -// "age" >> 37 -// "children" >> ["Sara","Alex","Jack"] -// "children.#" >> 3 -// "children.1" >> "Alex" -// "child*.2" >> "Jack" -// "c?ildren.0" >> "Sara" -// "friends.#.first" >> ["James","Roger"] +// { +// "name": {"first": "Tom", "last": "Anderson"}, +// "age":37, +// "children": ["Sara","Alex","Jack"], +// "friends": [ +// {"first": "James", "last": "Murphy"}, +// {"first": "Roger", "last": "Craig"} +// ] +// } +// "name.last" >> "Anderson" +// "age" >> 37 +// "children" >> ["Sara","Alex","Jack"] +// "children.#" >> 3 +// "children.1" >> "Alex" +// "child*.2" >> "Jack" +// "c?ildren.0" >> "Sara" +// "friends.#.first" >> ["James","Roger"] // // This function expects that the json is well-formed, and does not validate. // Invalid json will not panic, but it may return back unexpected results. @@ -2122,25 +1819,23 @@ type parseContext struct { // use the Valid function first. func Get(json, path string) Result { if len(path) > 1 { - if (path[0] == '@' && !DisableModifiers) || path[0] == '!' { - // possible modifier - var ok bool - var npath string - var rjson string - if path[0] == '@' && !DisableModifiers { + if !DisableModifiers { + if path[0] == '@' { + // possible modifier + var ok bool + var npath string + var rjson string npath, rjson, ok = execModifier(json, path) - } else if path[0] == '!' { - npath, rjson, ok = execStatic(json, path) - } - if ok { - path = npath - if len(path) > 0 && (path[0] == '|' || path[0] == '.') { - res := Get(rjson, path[1:]) - res.Index = 0 - res.Indexes = nil - return res + if ok { + path = npath + if len(path) > 0 && (path[0] == '|' || path[0] == '.') { + res := Get(rjson, path[1:]) + res.Index = 0 + res.Indexes = nil + return res + } + return Parse(rjson) } - return Parse(rjson) } } if path[0] == '[' || path[0] == '{' { @@ -2165,14 +1860,14 @@ func Get(json, path string) Result { if sub.name[0] == '"' && Valid(sub.name) { b = append(b, sub.name...) } else { - b = AppendJSONString(b, sub.name) + b = appendJSONString(b, sub.name) } } else { last := nameOfLast(sub.path) if isSimpleName(last) { - b = AppendJSONString(b, last) + b = appendJSONString(b, last) } else { - b = AppendJSONString(b, "_") + b = appendJSONString(b, "_") } } b = append(b, ':') @@ -2303,10 +1998,11 @@ func unescape(json string) string { } // Less return true if a token is less than another token. -// The caseSensitive parameter is used when the tokens are Strings. +// The caseSensitive paramater is used when the tokens are Strings. // The order when comparing two different type is: // -// Null < False < Number < String < True < JSON +// Null < False < Number < String < True < JSON +// func (t Result) Less(token Result, caseSensitive bool) bool { if t.Type < token.Type { return true @@ -2384,7 +2080,6 @@ func parseAny(json string, i int, hit bool) (int, Result, bool) { if json[i] <= ' ' { continue } - var num bool switch json[i] { case '"': i++ @@ -2404,13 +2099,15 @@ func parseAny(json string, i int, hit bool) (int, Result, bool) { } } return i, res, true - case 'n': - if i+1 < len(json) && json[i+1] != 'u' { - num = true - break + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + i, val = parseNumber(json, i) + if hit { + res.Raw = val + res.Type = Number + res.Num, _ = strconv.ParseFloat(val, 64) } - fallthrough - case 't', 'f': + return i, res, true + case 't', 'f', 'n': vc := json[i] i, val = parseLiteral(json, i) if hit { @@ -2423,20 +2120,7 @@ func parseAny(json string, i int, hit bool) (int, Result, bool) { } return i, res, true } - case '+', '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - 'i', 'I', 'N': - num = true - } - if num { - i, val = parseNumber(json, i) - if hit { - res.Raw = val - res.Type = Number - res.Num, _ = strconv.ParseFloat(val, 64) - } - return i, res, true } - } return i, res, false } @@ -2735,10 +2419,11 @@ func validnull(data []byte, i int) (outi int, ok bool) { // Valid returns true if the input is valid json. // -// if !gjson.Valid(json) { -// return errors.New("invalid json") -// } -// value := gjson.Get(json, "name.last") +// if !gjson.Valid(json) { +// return errors.New("invalid json") +// } +// value := gjson.Get(json, "name.last") +// func Valid(json string) bool { _, ok := validpayload(stringBytes(json), 0) return ok @@ -2746,12 +2431,13 @@ func Valid(json string) bool { // ValidBytes returns true if the input is valid json. // -// if !gjson.Valid(json) { -// return errors.New("invalid json") -// } -// value := gjson.Get(json, "name.last") +// if !gjson.Valid(json) { +// return errors.New("invalid json") +// } +// value := gjson.Get(json, "name.last") // // If working with bytes, this method preferred over ValidBytes(string(data)) +// func ValidBytes(json []byte) bool { _, ok := validpayload(json, 0) return ok @@ -2806,40 +2492,8 @@ func safeInt(f float64) (n int64, ok bool) { return int64(f), true } -// execStatic parses the path to find a static value. -// The input expects that the path already starts with a '!' -func execStatic(json, path string) (pathOut, res string, ok bool) { - name := path[1:] - if len(name) > 0 { - switch name[0] { - case '{', '[', '"', '+', '-', '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9': - _, res = parseSquash(name, 0) - pathOut = name[len(res):] - return pathOut, res, true - } - } - for i := 1; i < len(path); i++ { - if path[i] == '|' { - pathOut = path[i:] - name = path[1:i] - break - } - if path[i] == '.' { - pathOut = path[i:] - name = path[1:i] - break - } - } - switch strings.ToLower(name) { - case "true", "false", "null", "nan", "inf": - return pathOut, name, true - } - return pathOut, res, false -} - // execModifier parses the path to find a matching modifier function. -// The input expects that the path already starts with a '@' +// then input expects that the path already starts with a '@' func execModifier(json, path string) (pathOut, res string, ok bool) { name := path[1:] var hasArgs bool @@ -2867,7 +2521,6 @@ func execModifier(json, path string) (pathOut, res string, ok bool) { var parsedArgs bool switch pathOut[0] { case '{', '[', '"': - // json arg res := Parse(pathOut) if res.Exists() { args = squash(pathOut) @@ -2876,20 +2529,14 @@ func execModifier(json, path string) (pathOut, res string, ok bool) { } } if !parsedArgs { - // simple arg - i := 0 - for ; i < len(pathOut); i++ { - if pathOut[i] == '|' { - break - } - switch pathOut[i] { - case '{', '[', '"', '(': - s := squash(pathOut[i:]) - i += len(s) - 1 - } + idx := strings.IndexByte(pathOut, '|') + if idx == -1 { + args = pathOut + pathOut = "" + } else { + args = pathOut[:idx] + pathOut = pathOut[idx:] } - args = pathOut[:i] - pathOut = pathOut[i:] } } return pathOut, fn(json, args), true @@ -2909,24 +2556,14 @@ func unwrap(json string) string { // DisableModifiers will disable the modifier syntax var DisableModifiers = false -var modifiers map[string]func(json, arg string) string - -func init() { - modifiers = map[string]func(json, arg string) string{ - "pretty": modPretty, - "ugly": modUgly, - "reverse": modReverse, - "this": modThis, - "flatten": modFlatten, - "join": modJoin, - "valid": modValid, - "keys": modKeys, - "values": modValues, - "tostr": modToStr, - "fromstr": modFromStr, - "group": modGroup, - "dig": modDig, - } +var modifiers = map[string]func(json, arg string) string{ + "pretty": modPretty, + "ugly": modUgly, + "reverse": modReverse, + "this": modThis, + "flatten": modFlatten, + "join": modJoin, + "valid": modValid, } // AddModifier binds a custom modifier command to the GJSON syntax. @@ -3037,13 +2674,9 @@ func modReverse(json, arg string) string { } // @flatten an array with child arrays. -// -// [1,[2],[3,4],[5,[6,7]]] -> [1,2,3,4,5,[6,7]] -// +// [1,[2],[3,4],[5,[6,7]]] -> [1,2,3,4,5,[6,7]] // The {"deep":true} arg can be provide for deep flattening. -// -// [1,[2],[3,4],[5,[6,7]]] -> [1,2,3,4,5,6,7] -// +// [1,[2],[3,4],[5,[6,7]]] -> [1,2,3,4,5,6,7] // The original json is returned when the json is not an array. func modFlatten(json, arg string) string { res := Parse(json) @@ -3087,72 +2720,12 @@ func modFlatten(json, arg string) string { return bytesString(out) } -// @keys extracts the keys from an object. -// -// {"first":"Tom","last":"Smith"} -> ["first","last"] -func modKeys(json, arg string) string { - v := Parse(json) - if !v.Exists() { - return "[]" - } - obj := v.IsObject() - var out strings.Builder - out.WriteByte('[') - var i int - v.ForEach(func(key, _ Result) bool { - if i > 0 { - out.WriteByte(',') - } - if obj { - out.WriteString(key.Raw) - } else { - out.WriteString("null") - } - i++ - return true - }) - out.WriteByte(']') - return out.String() -} - -// @values extracts the values from an object. -// -// {"first":"Tom","last":"Smith"} -> ["Tom","Smith"] -func modValues(json, arg string) string { - v := Parse(json) - if !v.Exists() { - return "[]" - } - if v.IsArray() { - return json - } - var out strings.Builder - out.WriteByte('[') - var i int - v.ForEach(func(_, value Result) bool { - if i > 0 { - out.WriteByte(',') - } - out.WriteString(value.Raw) - i++ - return true - }) - out.WriteByte(']') - return out.String() -} - // @join multiple objects into a single object. -// -// [{"first":"Tom"},{"last":"Smith"}] -> {"first","Tom","last":"Smith"} -// +// [{"first":"Tom"},{"last":"Smith"}] -> {"first","Tom","last":"Smith"} // The arg can be "true" to specify that duplicate keys should be preserved. -// -// [{"first":"Tom","age":37},{"age":41}] -> {"first","Tom","age":37,"age":41} -// +// [{"first":"Tom","age":37},{"age":41}] -> {"first","Tom","age":37,"age":41} // Without preserved keys: -// -// [{"first":"Tom","age":37},{"age":41}] -> {"first","Tom","age":41} -// +// [{"first":"Tom","age":37},{"age":41}] -> {"first","Tom","age":41} // The original json is returned when the json is not an object. func modJoin(json, arg string) string { res := Parse(json) @@ -3224,58 +2797,6 @@ func modValid(json, arg string) string { return json } -// @fromstr converts a string to json -// -// "{\"id\":1023,\"name\":\"alert\"}" -> {"id":1023,"name":"alert"} -func modFromStr(json, arg string) string { - if !Valid(json) { - return "" - } - return Parse(json).String() -} - -// @tostr converts a string to json -// -// {"id":1023,"name":"alert"} -> "{\"id\":1023,\"name\":\"alert\"}" -func modToStr(str, arg string) string { - return string(AppendJSONString(nil, str)) -} - -func modGroup(json, arg string) string { - res := Parse(json) - if !res.IsObject() { - return "" - } - var all [][]byte - res.ForEach(func(key, value Result) bool { - if !value.IsArray() { - return true - } - var idx int - value.ForEach(func(_, value Result) bool { - if idx == len(all) { - all = append(all, []byte{}) - } - all[idx] = append(all[idx], ("," + key.Raw + ":" + value.Raw)...) - idx++ - return true - }) - return true - }) - var data []byte - data = append(data, '[') - for i, item := range all { - if i > 0 { - data = append(data, ',') - } - data = append(data, '{') - data = append(data, item[1:]...) - data = append(data, '}') - } - data = append(data, ']') - return string(data) -} - // stringHeader instead of reflect.StringHeader type stringHeader struct { data unsafe.Pointer @@ -3361,243 +2882,3 @@ func stringBytes(s string) []byte { func bytesString(b []byte) string { return *(*string)(unsafe.Pointer(&b)) } - -func revSquash(json string) string { - // reverse squash - // expects that the tail character is a ']' or '}' or ')' or '"' - // squash the value, ignoring all nested arrays and objects. - i := len(json) - 1 - var depth int - if json[i] != '"' { - depth++ - } - if json[i] == '}' || json[i] == ']' || json[i] == ')' { - i-- - } - for ; i >= 0; i-- { - switch json[i] { - case '"': - i-- - for ; i >= 0; i-- { - if json[i] == '"' { - esc := 0 - for i > 0 && json[i-1] == '\\' { - i-- - esc++ - } - if esc%2 == 1 { - continue - } - i += esc - break - } - } - if depth == 0 { - if i < 0 { - i = 0 - } - return json[i:] - } - case '}', ']', ')': - depth++ - case '{', '[', '(': - depth-- - if depth == 0 { - return json[i:] - } - } - } - return json -} - -// Paths returns the original GJSON paths for a Result where the Result came -// from a simple query path that returns an array, like: -// -// gjson.Get(json, "friends.#.first") -// -// The returned value will be in the form of a JSON array: -// -// ["friends.0.first","friends.1.first","friends.2.first"] -// -// The param 'json' must be the original JSON used when calling Get. -// -// Returns an empty string if the paths cannot be determined, which can happen -// when the Result came from a path that contained a multipath, modifier, -// or a nested query. -func (t Result) Paths(json string) []string { - if t.Indexes == nil { - return nil - } - paths := make([]string, 0, len(t.Indexes)) - t.ForEach(func(_, value Result) bool { - paths = append(paths, value.Path(json)) - return true - }) - if len(paths) != len(t.Indexes) { - return nil - } - return paths -} - -// Path returns the original GJSON path for a Result where the Result came -// from a simple path that returns a single value, like: -// -// gjson.Get(json, "friends.#(last=Murphy)") -// -// The returned value will be in the form of a JSON string: -// -// "friends.0" -// -// The param 'json' must be the original JSON used when calling Get. -// -// Returns an empty string if the paths cannot be determined, which can happen -// when the Result came from a path that contained a multipath, modifier, -// or a nested query. -func (t Result) Path(json string) string { - var path []byte - var comps []string // raw components - i := t.Index - 1 - if t.Index+len(t.Raw) > len(json) { - // JSON cannot safely contain Result. - goto fail - } - if !strings.HasPrefix(json[t.Index:], t.Raw) { - // Result is not at the JSON index as expected. - goto fail - } - for ; i >= 0; i-- { - if json[i] <= ' ' { - continue - } - if json[i] == ':' { - // inside of object, get the key - for ; i >= 0; i-- { - if json[i] != '"' { - continue - } - break - } - raw := revSquash(json[:i+1]) - i = i - len(raw) - comps = append(comps, raw) - // key gotten, now squash the rest - raw = revSquash(json[:i+1]) - i = i - len(raw) - i++ // increment the index for next loop step - } else if json[i] == '{' { - // Encountered an open object. The original result was probably an - // object key. - goto fail - } else if json[i] == ',' || json[i] == '[' { - // inside of an array, count the position - var arrIdx int - if json[i] == ',' { - arrIdx++ - i-- - } - for ; i >= 0; i-- { - if json[i] == ':' { - // Encountered an unexpected colon. The original result was - // probably an object key. - goto fail - } else if json[i] == ',' { - arrIdx++ - } else if json[i] == '[' { - comps = append(comps, strconv.Itoa(arrIdx)) - break - } else if json[i] == ']' || json[i] == '}' || json[i] == '"' { - raw := revSquash(json[:i+1]) - i = i - len(raw) + 1 - } - } - } - } - if len(comps) == 0 { - if DisableModifiers { - goto fail - } - return "@this" - } - for i := len(comps) - 1; i >= 0; i-- { - rcomp := Parse(comps[i]) - if !rcomp.Exists() { - goto fail - } - comp := Escape(rcomp.String()) - path = append(path, '.') - path = append(path, comp...) - } - if len(path) > 0 { - path = path[1:] - } - return string(path) -fail: - return "" -} - -// isSafePathKeyChar returns true if the input character is safe for not -// needing escaping. -func isSafePathKeyChar(c byte) bool { - return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || - (c >= '0' && c <= '9') || c <= ' ' || c > '~' || c == '_' || - c == '-' || c == ':' -} - -// Escape returns an escaped path component. -// -// json := `{ -// "user":{ -// "first.name": "Janet", -// "last.name": "Prichard" -// } -// }` -// user := gjson.Get(json, "user") -// println(user.Get(gjson.Escape("first.name")) -// println(user.Get(gjson.Escape("last.name")) -// // Output: -// // Janet -// // Prichard -func Escape(comp string) string { - for i := 0; i < len(comp); i++ { - if !isSafePathKeyChar(comp[i]) { - ncomp := make([]byte, len(comp)+1) - copy(ncomp, comp[:i]) - ncomp = ncomp[:i] - for ; i < len(comp); i++ { - if !isSafePathKeyChar(comp[i]) { - ncomp = append(ncomp, '\\') - } - ncomp = append(ncomp, comp[i]) - } - return string(ncomp) - } - } - return comp -} - -func parseRecursiveDescent(all []Result, parent Result, path string) []Result { - if res := parent.Get(path); res.Exists() { - all = append(all, res) - } - if parent.IsArray() || parent.IsObject() { - parent.ForEach(func(_, val Result) bool { - all = parseRecursiveDescent(all, val, path) - return true - }) - } - return all -} - -func modDig(json, arg string) string { - all := parseRecursiveDescent(nil, Parse(json), arg) - var out []byte - out = append(out, '[') - for i, res := range all { - if i > 0 { - out = append(out, ',') - } - out = append(out, res.Raw...) - } - out = append(out, ']') - return string(out) -} diff --git a/git-sensor/vendor/github.com/tidwall/gjson/logo.png b/git-sensor/vendor/github.com/tidwall/gjson/logo.png new file mode 100644 index 000000000..17a8bbe9d Binary files /dev/null and b/git-sensor/vendor/github.com/tidwall/gjson/logo.png differ diff --git a/git-sensor/vendor/github.com/tidwall/pretty/README.md b/git-sensor/vendor/github.com/tidwall/pretty/README.md index 76c06a5e5..d3be5e54e 100644 --- a/git-sensor/vendor/github.com/tidwall/pretty/README.md +++ b/git-sensor/vendor/github.com/tidwall/pretty/README.md @@ -59,7 +59,7 @@ Will format the json to: Color will colorize the json for outputing to the screen. -```go +```json result = pretty.Color(json, nil) ``` diff --git a/git-sensor/vendor/github.com/tidwall/pretty/pretty.go b/git-sensor/vendor/github.com/tidwall/pretty/pretty.go index d705f9cdb..f3f756aad 100644 --- a/git-sensor/vendor/github.com/tidwall/pretty/pretty.go +++ b/git-sensor/vendor/github.com/tidwall/pretty/pretty.go @@ -422,7 +422,6 @@ type Style struct { Key, String, Number [2]string True, False, Null [2]string Escape [2]string - Brackets [2]string Append func(dst []byte, c byte) []byte } @@ -440,14 +439,13 @@ var TerminalStyle *Style func init() { TerminalStyle = &Style{ - Key: [2]string{"\x1B[1m\x1B[94m", "\x1B[0m"}, - String: [2]string{"\x1B[32m", "\x1B[0m"}, - Number: [2]string{"\x1B[33m", "\x1B[0m"}, - True: [2]string{"\x1B[36m", "\x1B[0m"}, - False: [2]string{"\x1B[36m", "\x1B[0m"}, - Null: [2]string{"\x1B[2m", "\x1B[0m"}, - Escape: [2]string{"\x1B[35m", "\x1B[0m"}, - Brackets: [2]string{"\x1B[1m", "\x1B[0m"}, + Key: [2]string{"\x1B[94m", "\x1B[0m"}, + String: [2]string{"\x1B[92m", "\x1B[0m"}, + Number: [2]string{"\x1B[93m", "\x1B[0m"}, + True: [2]string{"\x1B[96m", "\x1B[0m"}, + False: [2]string{"\x1B[96m", "\x1B[0m"}, + Null: [2]string{"\x1B[91m", "\x1B[0m"}, + Escape: [2]string{"\x1B[35m", "\x1B[0m"}, Append: func(dst []byte, c byte) []byte { if c < ' ' && (c != '\r' && c != '\n' && c != '\t' && c != '\v') { dst = append(dst, "\\u00"...) @@ -541,19 +539,13 @@ func Color(src []byte, style *Style) []byte { } } else if src[i] == '{' || src[i] == '[' { stack = append(stack, stackt{src[i], src[i] == '{'}) - dst = append(dst, style.Brackets[0]...) dst = apnd(dst, src[i]) - dst = append(dst, style.Brackets[1]...) } else if (src[i] == '}' || src[i] == ']') && len(stack) > 0 { stack = stack[:len(stack)-1] - dst = append(dst, style.Brackets[0]...) dst = apnd(dst, src[i]) - dst = append(dst, style.Brackets[1]...) } else if (src[i] == ':' || src[i] == ',') && len(stack) > 0 && stack[len(stack)-1].kind == '{' { stack[len(stack)-1].key = !stack[len(stack)-1].key - dst = append(dst, style.Brackets[0]...) dst = apnd(dst, src[i]) - dst = append(dst, style.Brackets[1]...) } else { var kind byte if (src[i] >= '0' && src[i] <= '9') || src[i] == '-' || isNaNOrInf(src[i:]) { diff --git a/git-sensor/vendor/golang.org/x/crypto/cryptobyte/asn1.go b/git-sensor/vendor/golang.org/x/crypto/cryptobyte/asn1.go deleted file mode 100644 index d25979d9f..000000000 --- a/git-sensor/vendor/golang.org/x/crypto/cryptobyte/asn1.go +++ /dev/null @@ -1,825 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cryptobyte - -import ( - encoding_asn1 "encoding/asn1" - "fmt" - "math/big" - "reflect" - "time" - - "golang.org/x/crypto/cryptobyte/asn1" -) - -// This file contains ASN.1-related methods for String and Builder. - -// Builder - -// AddASN1Int64 appends a DER-encoded ASN.1 INTEGER. -func (b *Builder) AddASN1Int64(v int64) { - b.addASN1Signed(asn1.INTEGER, v) -} - -// AddASN1Int64WithTag appends a DER-encoded ASN.1 INTEGER with the -// given tag. -func (b *Builder) AddASN1Int64WithTag(v int64, tag asn1.Tag) { - b.addASN1Signed(tag, v) -} - -// AddASN1Enum appends a DER-encoded ASN.1 ENUMERATION. -func (b *Builder) AddASN1Enum(v int64) { - b.addASN1Signed(asn1.ENUM, v) -} - -func (b *Builder) addASN1Signed(tag asn1.Tag, v int64) { - b.AddASN1(tag, func(c *Builder) { - length := 1 - for i := v; i >= 0x80 || i < -0x80; i >>= 8 { - length++ - } - - for ; length > 0; length-- { - i := v >> uint((length-1)*8) & 0xff - c.AddUint8(uint8(i)) - } - }) -} - -// AddASN1Uint64 appends a DER-encoded ASN.1 INTEGER. -func (b *Builder) AddASN1Uint64(v uint64) { - b.AddASN1(asn1.INTEGER, func(c *Builder) { - length := 1 - for i := v; i >= 0x80; i >>= 8 { - length++ - } - - for ; length > 0; length-- { - i := v >> uint((length-1)*8) & 0xff - c.AddUint8(uint8(i)) - } - }) -} - -// AddASN1BigInt appends a DER-encoded ASN.1 INTEGER. -func (b *Builder) AddASN1BigInt(n *big.Int) { - if b.err != nil { - return - } - - b.AddASN1(asn1.INTEGER, func(c *Builder) { - if n.Sign() < 0 { - // A negative number has to be converted to two's-complement form. So we - // invert and subtract 1. If the most-significant-bit isn't set then - // we'll need to pad the beginning with 0xff in order to keep the number - // negative. - nMinus1 := new(big.Int).Neg(n) - nMinus1.Sub(nMinus1, bigOne) - bytes := nMinus1.Bytes() - for i := range bytes { - bytes[i] ^= 0xff - } - if len(bytes) == 0 || bytes[0]&0x80 == 0 { - c.add(0xff) - } - c.add(bytes...) - } else if n.Sign() == 0 { - c.add(0) - } else { - bytes := n.Bytes() - if bytes[0]&0x80 != 0 { - c.add(0) - } - c.add(bytes...) - } - }) -} - -// AddASN1OctetString appends a DER-encoded ASN.1 OCTET STRING. -func (b *Builder) AddASN1OctetString(bytes []byte) { - b.AddASN1(asn1.OCTET_STRING, func(c *Builder) { - c.AddBytes(bytes) - }) -} - -const generalizedTimeFormatStr = "20060102150405Z0700" - -// AddASN1GeneralizedTime appends a DER-encoded ASN.1 GENERALIZEDTIME. -func (b *Builder) AddASN1GeneralizedTime(t time.Time) { - if t.Year() < 0 || t.Year() > 9999 { - b.err = fmt.Errorf("cryptobyte: cannot represent %v as a GeneralizedTime", t) - return - } - b.AddASN1(asn1.GeneralizedTime, func(c *Builder) { - c.AddBytes([]byte(t.Format(generalizedTimeFormatStr))) - }) -} - -// AddASN1UTCTime appends a DER-encoded ASN.1 UTCTime. -func (b *Builder) AddASN1UTCTime(t time.Time) { - b.AddASN1(asn1.UTCTime, func(c *Builder) { - // As utilized by the X.509 profile, UTCTime can only - // represent the years 1950 through 2049. - if t.Year() < 1950 || t.Year() >= 2050 { - b.err = fmt.Errorf("cryptobyte: cannot represent %v as a UTCTime", t) - return - } - c.AddBytes([]byte(t.Format(defaultUTCTimeFormatStr))) - }) -} - -// AddASN1BitString appends a DER-encoded ASN.1 BIT STRING. This does not -// support BIT STRINGs that are not a whole number of bytes. -func (b *Builder) AddASN1BitString(data []byte) { - b.AddASN1(asn1.BIT_STRING, func(b *Builder) { - b.AddUint8(0) - b.AddBytes(data) - }) -} - -func (b *Builder) addBase128Int(n int64) { - var length int - if n == 0 { - length = 1 - } else { - for i := n; i > 0; i >>= 7 { - length++ - } - } - - for i := length - 1; i >= 0; i-- { - o := byte(n >> uint(i*7)) - o &= 0x7f - if i != 0 { - o |= 0x80 - } - - b.add(o) - } -} - -func isValidOID(oid encoding_asn1.ObjectIdentifier) bool { - if len(oid) < 2 { - return false - } - - if oid[0] > 2 || (oid[0] <= 1 && oid[1] >= 40) { - return false - } - - for _, v := range oid { - if v < 0 { - return false - } - } - - return true -} - -func (b *Builder) AddASN1ObjectIdentifier(oid encoding_asn1.ObjectIdentifier) { - b.AddASN1(asn1.OBJECT_IDENTIFIER, func(b *Builder) { - if !isValidOID(oid) { - b.err = fmt.Errorf("cryptobyte: invalid OID: %v", oid) - return - } - - b.addBase128Int(int64(oid[0])*40 + int64(oid[1])) - for _, v := range oid[2:] { - b.addBase128Int(int64(v)) - } - }) -} - -func (b *Builder) AddASN1Boolean(v bool) { - b.AddASN1(asn1.BOOLEAN, func(b *Builder) { - if v { - b.AddUint8(0xff) - } else { - b.AddUint8(0) - } - }) -} - -func (b *Builder) AddASN1NULL() { - b.add(uint8(asn1.NULL), 0) -} - -// MarshalASN1 calls encoding_asn1.Marshal on its input and appends the result if -// successful or records an error if one occurred. -func (b *Builder) MarshalASN1(v interface{}) { - // NOTE(martinkr): This is somewhat of a hack to allow propagation of - // encoding_asn1.Marshal errors into Builder.err. N.B. if you call MarshalASN1 with a - // value embedded into a struct, its tag information is lost. - if b.err != nil { - return - } - bytes, err := encoding_asn1.Marshal(v) - if err != nil { - b.err = err - return - } - b.AddBytes(bytes) -} - -// AddASN1 appends an ASN.1 object. The object is prefixed with the given tag. -// Tags greater than 30 are not supported and result in an error (i.e. -// low-tag-number form only). The child builder passed to the -// BuilderContinuation can be used to build the content of the ASN.1 object. -func (b *Builder) AddASN1(tag asn1.Tag, f BuilderContinuation) { - if b.err != nil { - return - } - // Identifiers with the low five bits set indicate high-tag-number format - // (two or more octets), which we don't support. - if tag&0x1f == 0x1f { - b.err = fmt.Errorf("cryptobyte: high-tag number identifier octets not supported: 0x%x", tag) - return - } - b.AddUint8(uint8(tag)) - b.addLengthPrefixed(1, true, f) -} - -// String - -// ReadASN1Boolean decodes an ASN.1 BOOLEAN and converts it to a boolean -// representation into out and advances. It reports whether the read -// was successful. -func (s *String) ReadASN1Boolean(out *bool) bool { - var bytes String - if !s.ReadASN1(&bytes, asn1.BOOLEAN) || len(bytes) != 1 { - return false - } - - switch bytes[0] { - case 0: - *out = false - case 0xff: - *out = true - default: - return false - } - - return true -} - -// ReadASN1Integer decodes an ASN.1 INTEGER into out and advances. If out does -// not point to an integer, to a big.Int, or to a []byte it panics. Only -// positive and zero values can be decoded into []byte, and they are returned as -// big-endian binary values that share memory with s. Positive values will have -// no leading zeroes, and zero will be returned as a single zero byte. -// ReadASN1Integer reports whether the read was successful. -func (s *String) ReadASN1Integer(out interface{}) bool { - switch out := out.(type) { - case *int, *int8, *int16, *int32, *int64: - var i int64 - if !s.readASN1Int64(&i) || reflect.ValueOf(out).Elem().OverflowInt(i) { - return false - } - reflect.ValueOf(out).Elem().SetInt(i) - return true - case *uint, *uint8, *uint16, *uint32, *uint64: - var u uint64 - if !s.readASN1Uint64(&u) || reflect.ValueOf(out).Elem().OverflowUint(u) { - return false - } - reflect.ValueOf(out).Elem().SetUint(u) - return true - case *big.Int: - return s.readASN1BigInt(out) - case *[]byte: - return s.readASN1Bytes(out) - default: - panic("out does not point to an integer type") - } -} - -func checkASN1Integer(bytes []byte) bool { - if len(bytes) == 0 { - // An INTEGER is encoded with at least one octet. - return false - } - if len(bytes) == 1 { - return true - } - if bytes[0] == 0 && bytes[1]&0x80 == 0 || bytes[0] == 0xff && bytes[1]&0x80 == 0x80 { - // Value is not minimally encoded. - return false - } - return true -} - -var bigOne = big.NewInt(1) - -func (s *String) readASN1BigInt(out *big.Int) bool { - var bytes String - if !s.ReadASN1(&bytes, asn1.INTEGER) || !checkASN1Integer(bytes) { - return false - } - if bytes[0]&0x80 == 0x80 { - // Negative number. - neg := make([]byte, len(bytes)) - for i, b := range bytes { - neg[i] = ^b - } - out.SetBytes(neg) - out.Add(out, bigOne) - out.Neg(out) - } else { - out.SetBytes(bytes) - } - return true -} - -func (s *String) readASN1Bytes(out *[]byte) bool { - var bytes String - if !s.ReadASN1(&bytes, asn1.INTEGER) || !checkASN1Integer(bytes) { - return false - } - if bytes[0]&0x80 == 0x80 { - return false - } - for len(bytes) > 1 && bytes[0] == 0 { - bytes = bytes[1:] - } - *out = bytes - return true -} - -func (s *String) readASN1Int64(out *int64) bool { - var bytes String - if !s.ReadASN1(&bytes, asn1.INTEGER) || !checkASN1Integer(bytes) || !asn1Signed(out, bytes) { - return false - } - return true -} - -func asn1Signed(out *int64, n []byte) bool { - length := len(n) - if length > 8 { - return false - } - for i := 0; i < length; i++ { - *out <<= 8 - *out |= int64(n[i]) - } - // Shift up and down in order to sign extend the result. - *out <<= 64 - uint8(length)*8 - *out >>= 64 - uint8(length)*8 - return true -} - -func (s *String) readASN1Uint64(out *uint64) bool { - var bytes String - if !s.ReadASN1(&bytes, asn1.INTEGER) || !checkASN1Integer(bytes) || !asn1Unsigned(out, bytes) { - return false - } - return true -} - -func asn1Unsigned(out *uint64, n []byte) bool { - length := len(n) - if length > 9 || length == 9 && n[0] != 0 { - // Too large for uint64. - return false - } - if n[0]&0x80 != 0 { - // Negative number. - return false - } - for i := 0; i < length; i++ { - *out <<= 8 - *out |= uint64(n[i]) - } - return true -} - -// ReadASN1Int64WithTag decodes an ASN.1 INTEGER with the given tag into out -// and advances. It reports whether the read was successful and resulted in a -// value that can be represented in an int64. -func (s *String) ReadASN1Int64WithTag(out *int64, tag asn1.Tag) bool { - var bytes String - return s.ReadASN1(&bytes, tag) && checkASN1Integer(bytes) && asn1Signed(out, bytes) -} - -// ReadASN1Enum decodes an ASN.1 ENUMERATION into out and advances. It reports -// whether the read was successful. -func (s *String) ReadASN1Enum(out *int) bool { - var bytes String - var i int64 - if !s.ReadASN1(&bytes, asn1.ENUM) || !checkASN1Integer(bytes) || !asn1Signed(&i, bytes) { - return false - } - if int64(int(i)) != i { - return false - } - *out = int(i) - return true -} - -func (s *String) readBase128Int(out *int) bool { - ret := 0 - for i := 0; len(*s) > 0; i++ { - if i == 5 { - return false - } - // Avoid overflowing int on a 32-bit platform. - // We don't want different behavior based on the architecture. - if ret >= 1<<(31-7) { - return false - } - ret <<= 7 - b := s.read(1)[0] - - // ITU-T X.690, section 8.19.2: - // The subidentifier shall be encoded in the fewest possible octets, - // that is, the leading octet of the subidentifier shall not have the value 0x80. - if i == 0 && b == 0x80 { - return false - } - - ret |= int(b & 0x7f) - if b&0x80 == 0 { - *out = ret - return true - } - } - return false // truncated -} - -// ReadASN1ObjectIdentifier decodes an ASN.1 OBJECT IDENTIFIER into out and -// advances. It reports whether the read was successful. -func (s *String) ReadASN1ObjectIdentifier(out *encoding_asn1.ObjectIdentifier) bool { - var bytes String - if !s.ReadASN1(&bytes, asn1.OBJECT_IDENTIFIER) || len(bytes) == 0 { - return false - } - - // In the worst case, we get two elements from the first byte (which is - // encoded differently) and then every varint is a single byte long. - components := make([]int, len(bytes)+1) - - // The first varint is 40*value1 + value2: - // According to this packing, value1 can take the values 0, 1 and 2 only. - // When value1 = 0 or value1 = 1, then value2 is <= 39. When value1 = 2, - // then there are no restrictions on value2. - var v int - if !bytes.readBase128Int(&v) { - return false - } - if v < 80 { - components[0] = v / 40 - components[1] = v % 40 - } else { - components[0] = 2 - components[1] = v - 80 - } - - i := 2 - for ; len(bytes) > 0; i++ { - if !bytes.readBase128Int(&v) { - return false - } - components[i] = v - } - *out = components[:i] - return true -} - -// ReadASN1GeneralizedTime decodes an ASN.1 GENERALIZEDTIME into out and -// advances. It reports whether the read was successful. -func (s *String) ReadASN1GeneralizedTime(out *time.Time) bool { - var bytes String - if !s.ReadASN1(&bytes, asn1.GeneralizedTime) { - return false - } - t := string(bytes) - res, err := time.Parse(generalizedTimeFormatStr, t) - if err != nil { - return false - } - if serialized := res.Format(generalizedTimeFormatStr); serialized != t { - return false - } - *out = res - return true -} - -const defaultUTCTimeFormatStr = "060102150405Z0700" - -// ReadASN1UTCTime decodes an ASN.1 UTCTime into out and advances. -// It reports whether the read was successful. -func (s *String) ReadASN1UTCTime(out *time.Time) bool { - var bytes String - if !s.ReadASN1(&bytes, asn1.UTCTime) { - return false - } - t := string(bytes) - - formatStr := defaultUTCTimeFormatStr - var err error - res, err := time.Parse(formatStr, t) - if err != nil { - // Fallback to minute precision if we can't parse second - // precision. If we are following X.509 or X.690 we shouldn't - // support this, but we do. - formatStr = "0601021504Z0700" - res, err = time.Parse(formatStr, t) - } - if err != nil { - return false - } - - if serialized := res.Format(formatStr); serialized != t { - return false - } - - if res.Year() >= 2050 { - // UTCTime interprets the low order digits 50-99 as 1950-99. - // This only applies to its use in the X.509 profile. - // See https://tools.ietf.org/html/rfc5280#section-4.1.2.5.1 - res = res.AddDate(-100, 0, 0) - } - *out = res - return true -} - -// ReadASN1BitString decodes an ASN.1 BIT STRING into out and advances. -// It reports whether the read was successful. -func (s *String) ReadASN1BitString(out *encoding_asn1.BitString) bool { - var bytes String - if !s.ReadASN1(&bytes, asn1.BIT_STRING) || len(bytes) == 0 || - len(bytes)*8/8 != len(bytes) { - return false - } - - paddingBits := bytes[0] - bytes = bytes[1:] - if paddingBits > 7 || - len(bytes) == 0 && paddingBits != 0 || - len(bytes) > 0 && bytes[len(bytes)-1]&(1< 4 || len(*s) < int(2+lenLen) { - return false - } - - lenBytes := String((*s)[2 : 2+lenLen]) - if !lenBytes.readUnsigned(&len32, int(lenLen)) { - return false - } - - // ITU-T X.690 section 10.1 (DER length forms) requires encoding the length - // with the minimum number of octets. - if len32 < 128 { - // Length should have used short-form encoding. - return false - } - if len32>>((lenLen-1)*8) == 0 { - // Leading octet is 0. Length should have been at least one byte shorter. - return false - } - - headerLen = 2 + uint32(lenLen) - if headerLen+len32 < len32 { - // Overflow. - return false - } - length = headerLen + len32 - } - - if int(length) < 0 || !s.ReadBytes((*[]byte)(out), int(length)) { - return false - } - if skipHeader && !out.Skip(int(headerLen)) { - panic("cryptobyte: internal error") - } - - return true -} diff --git a/git-sensor/vendor/golang.org/x/crypto/cryptobyte/asn1/asn1.go b/git-sensor/vendor/golang.org/x/crypto/cryptobyte/asn1/asn1.go deleted file mode 100644 index 90ef6a241..000000000 --- a/git-sensor/vendor/golang.org/x/crypto/cryptobyte/asn1/asn1.go +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package asn1 contains supporting types for parsing and building ASN.1 -// messages with the cryptobyte package. -package asn1 - -// Tag represents an ASN.1 identifier octet, consisting of a tag number -// (indicating a type) and class (such as context-specific or constructed). -// -// Methods in the cryptobyte package only support the low-tag-number form, i.e. -// a single identifier octet with bits 7-8 encoding the class and bits 1-6 -// encoding the tag number. -type Tag uint8 - -const ( - classConstructed = 0x20 - classContextSpecific = 0x80 -) - -// Constructed returns t with the constructed class bit set. -func (t Tag) Constructed() Tag { return t | classConstructed } - -// ContextSpecific returns t with the context-specific class bit set. -func (t Tag) ContextSpecific() Tag { return t | classContextSpecific } - -// The following is a list of standard tag and class combinations. -const ( - BOOLEAN = Tag(1) - INTEGER = Tag(2) - BIT_STRING = Tag(3) - OCTET_STRING = Tag(4) - NULL = Tag(5) - OBJECT_IDENTIFIER = Tag(6) - ENUM = Tag(10) - UTF8String = Tag(12) - SEQUENCE = Tag(16 | classConstructed) - SET = Tag(17 | classConstructed) - PrintableString = Tag(19) - T61String = Tag(20) - IA5String = Tag(22) - UTCTime = Tag(23) - GeneralizedTime = Tag(24) - GeneralString = Tag(27) -) diff --git a/git-sensor/vendor/golang.org/x/crypto/cryptobyte/builder.go b/git-sensor/vendor/golang.org/x/crypto/cryptobyte/builder.go deleted file mode 100644 index cf254f5f1..000000000 --- a/git-sensor/vendor/golang.org/x/crypto/cryptobyte/builder.go +++ /dev/null @@ -1,350 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cryptobyte - -import ( - "errors" - "fmt" -) - -// A Builder builds byte strings from fixed-length and length-prefixed values. -// Builders either allocate space as needed, or are ‘fixed’, which means that -// they write into a given buffer and produce an error if it's exhausted. -// -// The zero value is a usable Builder that allocates space as needed. -// -// Simple values are marshaled and appended to a Builder using methods on the -// Builder. Length-prefixed values are marshaled by providing a -// BuilderContinuation, which is a function that writes the inner contents of -// the value to a given Builder. See the documentation for BuilderContinuation -// for details. -type Builder struct { - err error - result []byte - fixedSize bool - child *Builder - offset int - pendingLenLen int - pendingIsASN1 bool - inContinuation *bool -} - -// NewBuilder creates a Builder that appends its output to the given buffer. -// Like append(), the slice will be reallocated if its capacity is exceeded. -// Use Bytes to get the final buffer. -func NewBuilder(buffer []byte) *Builder { - return &Builder{ - result: buffer, - } -} - -// NewFixedBuilder creates a Builder that appends its output into the given -// buffer. This builder does not reallocate the output buffer. Writes that -// would exceed the buffer's capacity are treated as an error. -func NewFixedBuilder(buffer []byte) *Builder { - return &Builder{ - result: buffer, - fixedSize: true, - } -} - -// SetError sets the value to be returned as the error from Bytes. Writes -// performed after calling SetError are ignored. -func (b *Builder) SetError(err error) { - b.err = err -} - -// Bytes returns the bytes written by the builder or an error if one has -// occurred during building. -func (b *Builder) Bytes() ([]byte, error) { - if b.err != nil { - return nil, b.err - } - return b.result[b.offset:], nil -} - -// BytesOrPanic returns the bytes written by the builder or panics if an error -// has occurred during building. -func (b *Builder) BytesOrPanic() []byte { - if b.err != nil { - panic(b.err) - } - return b.result[b.offset:] -} - -// AddUint8 appends an 8-bit value to the byte string. -func (b *Builder) AddUint8(v uint8) { - b.add(byte(v)) -} - -// AddUint16 appends a big-endian, 16-bit value to the byte string. -func (b *Builder) AddUint16(v uint16) { - b.add(byte(v>>8), byte(v)) -} - -// AddUint24 appends a big-endian, 24-bit value to the byte string. The highest -// byte of the 32-bit input value is silently truncated. -func (b *Builder) AddUint24(v uint32) { - b.add(byte(v>>16), byte(v>>8), byte(v)) -} - -// AddUint32 appends a big-endian, 32-bit value to the byte string. -func (b *Builder) AddUint32(v uint32) { - b.add(byte(v>>24), byte(v>>16), byte(v>>8), byte(v)) -} - -// AddUint48 appends a big-endian, 48-bit value to the byte string. -func (b *Builder) AddUint48(v uint64) { - b.add(byte(v>>40), byte(v>>32), byte(v>>24), byte(v>>16), byte(v>>8), byte(v)) -} - -// AddUint64 appends a big-endian, 64-bit value to the byte string. -func (b *Builder) AddUint64(v uint64) { - b.add(byte(v>>56), byte(v>>48), byte(v>>40), byte(v>>32), byte(v>>24), byte(v>>16), byte(v>>8), byte(v)) -} - -// AddBytes appends a sequence of bytes to the byte string. -func (b *Builder) AddBytes(v []byte) { - b.add(v...) -} - -// BuilderContinuation is a continuation-passing interface for building -// length-prefixed byte sequences. Builder methods for length-prefixed -// sequences (AddUint8LengthPrefixed etc) will invoke the BuilderContinuation -// supplied to them. The child builder passed to the continuation can be used -// to build the content of the length-prefixed sequence. For example: -// -// parent := cryptobyte.NewBuilder() -// parent.AddUint8LengthPrefixed(func (child *Builder) { -// child.AddUint8(42) -// child.AddUint8LengthPrefixed(func (grandchild *Builder) { -// grandchild.AddUint8(5) -// }) -// }) -// -// It is an error to write more bytes to the child than allowed by the reserved -// length prefix. After the continuation returns, the child must be considered -// invalid, i.e. users must not store any copies or references of the child -// that outlive the continuation. -// -// If the continuation panics with a value of type BuildError then the inner -// error will be returned as the error from Bytes. If the child panics -// otherwise then Bytes will repanic with the same value. -type BuilderContinuation func(child *Builder) - -// BuildError wraps an error. If a BuilderContinuation panics with this value, -// the panic will be recovered and the inner error will be returned from -// Builder.Bytes. -type BuildError struct { - Err error -} - -// AddUint8LengthPrefixed adds a 8-bit length-prefixed byte sequence. -func (b *Builder) AddUint8LengthPrefixed(f BuilderContinuation) { - b.addLengthPrefixed(1, false, f) -} - -// AddUint16LengthPrefixed adds a big-endian, 16-bit length-prefixed byte sequence. -func (b *Builder) AddUint16LengthPrefixed(f BuilderContinuation) { - b.addLengthPrefixed(2, false, f) -} - -// AddUint24LengthPrefixed adds a big-endian, 24-bit length-prefixed byte sequence. -func (b *Builder) AddUint24LengthPrefixed(f BuilderContinuation) { - b.addLengthPrefixed(3, false, f) -} - -// AddUint32LengthPrefixed adds a big-endian, 32-bit length-prefixed byte sequence. -func (b *Builder) AddUint32LengthPrefixed(f BuilderContinuation) { - b.addLengthPrefixed(4, false, f) -} - -func (b *Builder) callContinuation(f BuilderContinuation, arg *Builder) { - if !*b.inContinuation { - *b.inContinuation = true - - defer func() { - *b.inContinuation = false - - r := recover() - if r == nil { - return - } - - if buildError, ok := r.(BuildError); ok { - b.err = buildError.Err - } else { - panic(r) - } - }() - } - - f(arg) -} - -func (b *Builder) addLengthPrefixed(lenLen int, isASN1 bool, f BuilderContinuation) { - // Subsequent writes can be ignored if the builder has encountered an error. - if b.err != nil { - return - } - - offset := len(b.result) - b.add(make([]byte, lenLen)...) - - if b.inContinuation == nil { - b.inContinuation = new(bool) - } - - b.child = &Builder{ - result: b.result, - fixedSize: b.fixedSize, - offset: offset, - pendingLenLen: lenLen, - pendingIsASN1: isASN1, - inContinuation: b.inContinuation, - } - - b.callContinuation(f, b.child) - b.flushChild() - if b.child != nil { - panic("cryptobyte: internal error") - } -} - -func (b *Builder) flushChild() { - if b.child == nil { - return - } - b.child.flushChild() - child := b.child - b.child = nil - - if child.err != nil { - b.err = child.err - return - } - - length := len(child.result) - child.pendingLenLen - child.offset - - if length < 0 { - panic("cryptobyte: internal error") // result unexpectedly shrunk - } - - if child.pendingIsASN1 { - // For ASN.1, we reserved a single byte for the length. If that turned out - // to be incorrect, we have to move the contents along in order to make - // space. - if child.pendingLenLen != 1 { - panic("cryptobyte: internal error") - } - var lenLen, lenByte uint8 - if int64(length) > 0xfffffffe { - b.err = errors.New("pending ASN.1 child too long") - return - } else if length > 0xffffff { - lenLen = 5 - lenByte = 0x80 | 4 - } else if length > 0xffff { - lenLen = 4 - lenByte = 0x80 | 3 - } else if length > 0xff { - lenLen = 3 - lenByte = 0x80 | 2 - } else if length > 0x7f { - lenLen = 2 - lenByte = 0x80 | 1 - } else { - lenLen = 1 - lenByte = uint8(length) - length = 0 - } - - // Insert the initial length byte, make space for successive length bytes, - // and adjust the offset. - child.result[child.offset] = lenByte - extraBytes := int(lenLen - 1) - if extraBytes != 0 { - child.add(make([]byte, extraBytes)...) - childStart := child.offset + child.pendingLenLen - copy(child.result[childStart+extraBytes:], child.result[childStart:]) - } - child.offset++ - child.pendingLenLen = extraBytes - } - - l := length - for i := child.pendingLenLen - 1; i >= 0; i-- { - child.result[child.offset+i] = uint8(l) - l >>= 8 - } - if l != 0 { - b.err = fmt.Errorf("cryptobyte: pending child length %d exceeds %d-byte length prefix", length, child.pendingLenLen) - return - } - - if b.fixedSize && &b.result[0] != &child.result[0] { - panic("cryptobyte: BuilderContinuation reallocated a fixed-size buffer") - } - - b.result = child.result -} - -func (b *Builder) add(bytes ...byte) { - if b.err != nil { - return - } - if b.child != nil { - panic("cryptobyte: attempted write while child is pending") - } - if len(b.result)+len(bytes) < len(bytes) { - b.err = errors.New("cryptobyte: length overflow") - } - if b.fixedSize && len(b.result)+len(bytes) > cap(b.result) { - b.err = errors.New("cryptobyte: Builder is exceeding its fixed-size buffer") - return - } - b.result = append(b.result, bytes...) -} - -// Unwrite rolls back non-negative n bytes written directly to the Builder. -// An attempt by a child builder passed to a continuation to unwrite bytes -// from its parent will panic. -func (b *Builder) Unwrite(n int) { - if b.err != nil { - return - } - if b.child != nil { - panic("cryptobyte: attempted unwrite while child is pending") - } - length := len(b.result) - b.pendingLenLen - b.offset - if length < 0 { - panic("cryptobyte: internal error") - } - if n < 0 { - panic("cryptobyte: attempted to unwrite negative number of bytes") - } - if n > length { - panic("cryptobyte: attempted to unwrite more than was written") - } - b.result = b.result[:len(b.result)-n] -} - -// A MarshalingValue marshals itself into a Builder. -type MarshalingValue interface { - // Marshal is called by Builder.AddValue. It receives a pointer to a builder - // to marshal itself into. It may return an error that occurred during - // marshaling, such as unset or invalid values. - Marshal(b *Builder) error -} - -// AddValue calls Marshal on v, passing a pointer to the builder to append to. -// If Marshal returns an error, it is set on the Builder so that subsequent -// appends don't have an effect. -func (b *Builder) AddValue(v MarshalingValue) { - err := v.Marshal(b) - if err != nil { - b.err = err - } -} diff --git a/git-sensor/vendor/golang.org/x/crypto/cryptobyte/string.go b/git-sensor/vendor/golang.org/x/crypto/cryptobyte/string.go deleted file mode 100644 index 4b0f8097f..000000000 --- a/git-sensor/vendor/golang.org/x/crypto/cryptobyte/string.go +++ /dev/null @@ -1,183 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package cryptobyte contains types that help with parsing and constructing -// length-prefixed, binary messages, including ASN.1 DER. (The asn1 subpackage -// contains useful ASN.1 constants.) -// -// The String type is for parsing. It wraps a []byte slice and provides helper -// functions for consuming structures, value by value. -// -// The Builder type is for constructing messages. It providers helper functions -// for appending values and also for appending length-prefixed submessages – -// without having to worry about calculating the length prefix ahead of time. -// -// See the documentation and examples for the Builder and String types to get -// started. -package cryptobyte - -// String represents a string of bytes. It provides methods for parsing -// fixed-length and length-prefixed values from it. -type String []byte - -// read advances a String by n bytes and returns them. If less than n bytes -// remain, it returns nil. -func (s *String) read(n int) []byte { - if len(*s) < n || n < 0 { - return nil - } - v := (*s)[:n] - *s = (*s)[n:] - return v -} - -// Skip advances the String by n byte and reports whether it was successful. -func (s *String) Skip(n int) bool { - return s.read(n) != nil -} - -// ReadUint8 decodes an 8-bit value into out and advances over it. -// It reports whether the read was successful. -func (s *String) ReadUint8(out *uint8) bool { - v := s.read(1) - if v == nil { - return false - } - *out = uint8(v[0]) - return true -} - -// ReadUint16 decodes a big-endian, 16-bit value into out and advances over it. -// It reports whether the read was successful. -func (s *String) ReadUint16(out *uint16) bool { - v := s.read(2) - if v == nil { - return false - } - *out = uint16(v[0])<<8 | uint16(v[1]) - return true -} - -// ReadUint24 decodes a big-endian, 24-bit value into out and advances over it. -// It reports whether the read was successful. -func (s *String) ReadUint24(out *uint32) bool { - v := s.read(3) - if v == nil { - return false - } - *out = uint32(v[0])<<16 | uint32(v[1])<<8 | uint32(v[2]) - return true -} - -// ReadUint32 decodes a big-endian, 32-bit value into out and advances over it. -// It reports whether the read was successful. -func (s *String) ReadUint32(out *uint32) bool { - v := s.read(4) - if v == nil { - return false - } - *out = uint32(v[0])<<24 | uint32(v[1])<<16 | uint32(v[2])<<8 | uint32(v[3]) - return true -} - -// ReadUint48 decodes a big-endian, 48-bit value into out and advances over it. -// It reports whether the read was successful. -func (s *String) ReadUint48(out *uint64) bool { - v := s.read(6) - if v == nil { - return false - } - *out = uint64(v[0])<<40 | uint64(v[1])<<32 | uint64(v[2])<<24 | uint64(v[3])<<16 | uint64(v[4])<<8 | uint64(v[5]) - return true -} - -// ReadUint64 decodes a big-endian, 64-bit value into out and advances over it. -// It reports whether the read was successful. -func (s *String) ReadUint64(out *uint64) bool { - v := s.read(8) - if v == nil { - return false - } - *out = uint64(v[0])<<56 | uint64(v[1])<<48 | uint64(v[2])<<40 | uint64(v[3])<<32 | uint64(v[4])<<24 | uint64(v[5])<<16 | uint64(v[6])<<8 | uint64(v[7]) - return true -} - -func (s *String) readUnsigned(out *uint32, length int) bool { - v := s.read(length) - if v == nil { - return false - } - var result uint32 - for i := 0; i < length; i++ { - result <<= 8 - result |= uint32(v[i]) - } - *out = result - return true -} - -func (s *String) readLengthPrefixed(lenLen int, outChild *String) bool { - lenBytes := s.read(lenLen) - if lenBytes == nil { - return false - } - var length uint32 - for _, b := range lenBytes { - length = length << 8 - length = length | uint32(b) - } - v := s.read(int(length)) - if v == nil { - return false - } - *outChild = v - return true -} - -// ReadUint8LengthPrefixed reads the content of an 8-bit length-prefixed value -// into out and advances over it. It reports whether the read was successful. -func (s *String) ReadUint8LengthPrefixed(out *String) bool { - return s.readLengthPrefixed(1, out) -} - -// ReadUint16LengthPrefixed reads the content of a big-endian, 16-bit -// length-prefixed value into out and advances over it. It reports whether the -// read was successful. -func (s *String) ReadUint16LengthPrefixed(out *String) bool { - return s.readLengthPrefixed(2, out) -} - -// ReadUint24LengthPrefixed reads the content of a big-endian, 24-bit -// length-prefixed value into out and advances over it. It reports whether -// the read was successful. -func (s *String) ReadUint24LengthPrefixed(out *String) bool { - return s.readLengthPrefixed(3, out) -} - -// ReadBytes reads n bytes into out and advances over them. It reports -// whether the read was successful. -func (s *String) ReadBytes(out *[]byte, n int) bool { - v := s.read(n) - if v == nil { - return false - } - *out = v - return true -} - -// CopyBytes copies len(out) bytes into out and advances over them. It reports -// whether the copy operation was successful -func (s *String) CopyBytes(out []byte) bool { - n := len(out) - v := s.read(n) - if v == nil { - return false - } - return copy(out, v) == n -} - -// Empty reports whether the string does not contain any bytes. -func (s String) Empty() bool { - return len(s) == 0 -} diff --git a/git-sensor/vendor/modules.txt b/git-sensor/vendor/modules.txt index 64366ab2b..708f55895 100644 --- a/git-sensor/vendor/modules.txt +++ b/git-sensor/vendor/modules.txt @@ -1,4 +1,4 @@ -# dario.cat/mergo v1.0.2 +# dario.cat/mergo v1.0.0 ## explicit; go 1.13 dario.cat/mergo # github.com/Microsoft/go-winio v0.6.2 @@ -8,8 +8,8 @@ github.com/Microsoft/go-winio/internal/fs github.com/Microsoft/go-winio/internal/socket github.com/Microsoft/go-winio/internal/stringbuffer github.com/Microsoft/go-winio/pkg/guid -# github.com/ProtonMail/go-crypto v1.3.0 -## explicit; go 1.22.0 +# github.com/ProtonMail/go-crypto v1.1.5 +## explicit; go 1.17 github.com/ProtonMail/go-crypto/bitcurves github.com/ProtonMail/go-crypto/brainpool github.com/ProtonMail/go-crypto/eax @@ -46,8 +46,8 @@ github.com/caarlos0/env # github.com/cespare/xxhash/v2 v2.3.0 ## explicit; go 1.11 github.com/cespare/xxhash/v2 -# github.com/cloudflare/circl v1.6.1 -## explicit; go 1.22.0 +# github.com/cloudflare/circl v1.3.7 +## explicit; go 1.19 github.com/cloudflare/circl/dh/x25519 github.com/cloudflare/circl/dh/x448 github.com/cloudflare/circl/ecc/goldilocks @@ -60,13 +60,13 @@ github.com/cloudflare/circl/math/mlsbset github.com/cloudflare/circl/sign github.com/cloudflare/circl/sign/ed25519 github.com/cloudflare/circl/sign/ed448 -# github.com/cyphar/filepath-securejoin v0.4.1 +# github.com/cyphar/filepath-securejoin v0.3.6 ## explicit; go 1.18 github.com/cyphar/filepath-securejoin # github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc ## explicit github.com/davecgh/go-spew/spew -# github.com/devtron-labs/common-lib v0.19.1 => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3 +# github.com/devtron-labs/common-lib v0.0.0 => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20251013041509-9d1c5175da2d ## explicit; go 1.24.0 github.com/devtron-labs/common-lib/constants github.com/devtron-labs/common-lib/fetchAllEnv @@ -79,8 +79,10 @@ 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/sql # github.com/devtron-labs/protos v0.0.3-0.20250323220609-ecf8a0f7305e ## explicit; go 1.17 github.com/devtron-labs/protos/gitSensor @@ -95,9 +97,6 @@ github.com/emirpasic/gods/lists/arraylist github.com/emirpasic/gods/trees github.com/emirpasic/gods/trees/binaryheap github.com/emirpasic/gods/utils -# github.com/felixge/httpsnoop v1.0.4 -## explicit; go 1.13 -github.com/felixge/httpsnoop # github.com/gammazero/deque v1.0.0 ## explicit; go 1.22 github.com/gammazero/deque @@ -118,8 +117,8 @@ github.com/go-git/go-billy/v5/helper/polyfill github.com/go-git/go-billy/v5/memfs github.com/go-git/go-billy/v5/osfs github.com/go-git/go-billy/v5/util -# github.com/go-git/go-git/v5 v5.16.0 -## explicit; go 1.23.0 +# github.com/go-git/go-git/v5 v5.13.2 +## explicit; go 1.21 github.com/go-git/go-git/v5 github.com/go-git/go-git/v5/config github.com/go-git/go-git/v5/internal/path_util @@ -174,8 +173,8 @@ github.com/go-pg/pg/internal/parser github.com/go-pg/pg/internal/pool github.com/go-pg/pg/orm github.com/go-pg/pg/types -# github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 -## explicit; go 1.20 +# github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da +## explicit github.com/golang/groupcache/lru # github.com/golang/protobuf v1.5.4 ## explicit; go 1.17 @@ -186,8 +185,8 @@ github.com/google/uuid # github.com/google/wire v0.6.0 ## explicit; go 1.12 github.com/google/wire -# github.com/gorilla/handlers v1.5.2 -## explicit; go 1.20 +# github.com/gorilla/handlers v1.4.2 +## explicit github.com/gorilla/handlers # github.com/gorilla/mux v1.8.1 ## explicit; go 1.20 @@ -198,8 +197,8 @@ github.com/gorilla/schema # github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 ## explicit; go 1.20 github.com/gorilla/websocket -# github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2 -## explicit; go 1.23.0 +# github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.1 +## explicit; go 1.19 github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/recovery # github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 ## explicit @@ -272,8 +271,8 @@ github.com/sergi/go-diff/diffmatchpatch # github.com/sirupsen/logrus v1.9.3 ## explicit; go 1.13 github.com/sirupsen/logrus -# github.com/skeema/knownhosts v1.3.1 -## explicit; go 1.22 +# github.com/skeema/knownhosts v1.3.0 +## explicit; go 1.17 github.com/skeema/knownhosts # github.com/stretchr/objx v0.5.2 ## explicit; go 1.20 @@ -283,13 +282,13 @@ github.com/stretchr/objx github.com/stretchr/testify/assert github.com/stretchr/testify/assert/yaml github.com/stretchr/testify/mock -# github.com/tidwall/gjson v1.18.0 +# github.com/tidwall/gjson v1.9.3 ## explicit; go 1.12 github.com/tidwall/gjson # github.com/tidwall/match v1.1.1 ## explicit; go 1.15 github.com/tidwall/match -# github.com/tidwall/pretty v1.2.1 +# github.com/tidwall/pretty v1.2.0 ## explicit; go 1.16 github.com/tidwall/pretty # github.com/xanzy/ssh-agent v0.3.3 @@ -316,8 +315,6 @@ golang.org/x/crypto/blake2b golang.org/x/crypto/blowfish golang.org/x/crypto/cast5 golang.org/x/crypto/chacha20 -golang.org/x/crypto/cryptobyte -golang.org/x/crypto/cryptobyte/asn1 golang.org/x/crypto/curve25519 golang.org/x/crypto/hkdf golang.org/x/crypto/internal/alias @@ -472,4 +469,4 @@ gopkg.in/yaml.v3 # mellium.im/sasl v0.3.2 ## explicit; go 1.20 mellium.im/sasl -# github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3 +# github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20251013041509-9d1c5175da2d diff --git a/git-sensor/wire_gen.go b/git-sensor/wire_gen.go index a9a99e1f0..3f2d145cb 100644 --- a/git-sensor/wire_gen.go +++ b/git-sensor/wire_gen.go @@ -1,6 +1,6 @@ // Code generated by Wire. DO NOT EDIT. -//go:generate go run github.com/google/wire/cmd/wire +//go:generate go run -mod=mod github.com/google/wire/cmd/wire //go:build !wireinject // +build !wireinject diff --git a/image-scanner/App.go b/image-scanner/App.go index f91652c1c..bcf9d7dfc 100644 --- a/image-scanner/App.go +++ b/image-scanner/App.go @@ -21,6 +21,7 @@ import ( "errors" "fmt" "github.com/caarlos0/env" + "github.com/devtron-labs/common-lib/securestore" "github.com/devtron-labs/image-scanner/pkg/middleware" "net/http" "os" @@ -51,6 +52,10 @@ func NewApp(Router *api.Router, Logger *zap.SugaredLogger, if err != nil { Logger.Errorw("error in getting server config", "err", err) } + err = securestore.SetEncryptionKey() + if err != nil { + Logger.Errorw("error in setting encryption key", "err", err) + } return &App{ Router: Router, Logger: Logger, diff --git a/image-scanner/env_gen.json b/image-scanner/env_gen.json index 3e8d728a6..f3e92f765 100644 --- a/image-scanner/env_gen.json +++ b/image-scanner/env_gen.json @@ -1 +1 @@ -[{"Category":"DEVTRON","Fields":[{"Env":"APP","EnvType":"string","EnvValue":"image-scanner","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"CLAIR_ADDR","EnvType":"string","EnvValue":"http://localhost:6060","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"CLAIR_TIMEOUT","EnvType":"int","EnvValue":"30","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_PROGRESSING_SCAN_CHECK","EnvType":"bool","EnvValue":"true","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"ENABLE_STATSVIZ","EnvType":"bool","EnvValue":"false","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"IMAGE_SCAN_ASYNC_TIMEOUT","EnvType":"int","EnvValue":"3","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"IMAGE_SCAN_TIMEOUT","EnvType":"int","EnvValue":"10","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"IMAGE_SCAN_TRY_COUNT","EnvType":"int","EnvValue":"1","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"JSON_OUTPUT","EnvType":"bool","EnvValue":"true","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"LOG_LEVEL","EnvType":"int","EnvValue":"0","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":"PROJECT_ID","EnvType":"string","EnvValue":"projects/devtron-project-id","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"SCANNER_TYPE","EnvType":"string","EnvValue":"","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"SERVER_HTTP_PORT","EnvType":"int","EnvValue":"8080","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"SERVER_SHUTDOWN_TIMEOUT","EnvType":"","EnvValue":"5m","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"STREAM_CONFIG_JSON","EnvType":"string","EnvValue":"","EnvDescription":"","Example":"","Deprecated":"false"}]}] \ No newline at end of file +[{"Category":"DEVTRON","Fields":[{"Env":"APP","EnvType":"string","EnvValue":"image-scanner","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"CLAIR_ADDR","EnvType":"string","EnvValue":"http://localhost:6060","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"CLAIR_TIMEOUT","EnvType":"int","EnvValue":"30","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_PROGRESSING_SCAN_CHECK","EnvType":"bool","EnvValue":"true","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"ENABLE_STATSVIZ","EnvType":"bool","EnvValue":"false","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"IMAGE_SCAN_ASYNC_TIMEOUT","EnvType":"int","EnvValue":"3","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"IMAGE_SCAN_TIMEOUT","EnvType":"int","EnvValue":"10","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"IMAGE_SCAN_TRY_COUNT","EnvType":"int","EnvValue":"1","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"JSON_OUTPUT","EnvType":"bool","EnvValue":"true","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"LOG_LEVEL","EnvType":"int","EnvValue":"0","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":"PROJECT_ID","EnvType":"string","EnvValue":"projects/devtron-project-id","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"SCANNER_TYPE","EnvType":"string","EnvValue":"","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"SERVER_HTTP_PORT","EnvType":"int","EnvValue":"8080","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"SERVER_SHUTDOWN_TIMEOUT","EnvType":"","EnvValue":"5m","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"STREAM_CONFIG_JSON","EnvType":"string","EnvValue":"","EnvDescription":"","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/image-scanner/env_gen.md b/image-scanner/env_gen.md index 3cac40aa9..d24ede0a9 100644 --- a/image-scanner/env_gen.md +++ b/image-scanner/env_gen.md @@ -37,3 +37,11 @@ | SERVER_SHUTDOWN_TIMEOUT | |5m | | | false | | STREAM_CONFIG_JSON | string | | | | 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/image-scanner/go.mod b/image-scanner/go.mod index ca39474ec..ada354cad 100644 --- a/image-scanner/go.mod +++ b/image-scanner/go.mod @@ -70,4 +70,4 @@ require ( mellium.im/sasl v0.3.2 // indirect ) -replace github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3 +replace github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20251013041509-9d1c5175da2d diff --git a/image-scanner/go.sum b/image-scanner/go.sum index 77eb02326..45524f2d9 100644 --- a/image-scanner/go.sum +++ b/image-scanner/go.sum @@ -279,8 +279,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0= -github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3 h1:jCxpB8+6KD29jenB4SLTimCYzsmazBAPKv6637xRT5M= -github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3/go.mod h1:/Ciy9tD9OxZOWBDPIasM448H7uvSo4+ZJiExpfwBZpA= +github.com/devtron-labs/devtron-services/common-lib v0.0.0-20251013041509-9d1c5175da2d h1:EAGZ+sei6Hl98Hp09HgNcnOIWgI43jcx1q0Mb6V5HdQ= +github.com/devtron-labs/devtron-services/common-lib v0.0.0-20251013041509-9d1c5175da2d/go.mod h1:/Ciy9tD9OxZOWBDPIasM448H7uvSo4+ZJiExpfwBZpA= github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= diff --git a/image-scanner/pkg/klarService/KlarService.go b/image-scanner/pkg/klarService/KlarService.go index 9a00ece73..f12a9cbf6 100644 --- a/image-scanner/pkg/klarService/KlarService.go +++ b/image-scanner/pkg/klarService/KlarService.go @@ -24,6 +24,7 @@ import ( "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/ecr" bean2 "github.com/devtron-labs/common-lib/imageScan/bean" + "github.com/devtron-labs/common-lib/securestore" "github.com/devtron-labs/image-scanner/common" "github.com/devtron-labs/image-scanner/pkg/security" "github.com/devtron-labs/image-scanner/pkg/sql/bean" @@ -112,7 +113,7 @@ func (impl *KlarServiceImpl) Process(scanEvent *bean2.ImageScanEvent, executionH tokenData := "" tokenAddr := &tokenData if dockerRegistry.RegistryType == repository.REGISTRYTYPE_ECR { - accessKey, secretKey := dockerRegistry.AWSAccessKeyId, dockerRegistry.AWSSecretAccessKey + accessKey, secretKey := dockerRegistry.AWSAccessKeyId, dockerRegistry.AWSSecretAccessKey.String() var creds *credentials.Credentials if len(dockerRegistry.AWSAccessKeyId) == 0 || len(dockerRegistry.AWSSecretAccessKey) == 0 { sess, err := session.NewSession(&aws.Config{ @@ -146,8 +147,8 @@ func (impl *KlarServiceImpl) Process(scanEvent *bean2.ImageScanEvent, executionH } else if dockerRegistry.Username == "_json_key" { lenPassword := len(dockerRegistry.Password) if lenPassword > 1 { - dockerRegistry.Password = strings.TrimPrefix(dockerRegistry.Password, "'") - dockerRegistry.Password = strings.TrimSuffix(dockerRegistry.Password, "'") + dockerRegistry.Password = securestore.ToEncryptedString(strings.TrimPrefix(dockerRegistry.Password.String(), "'")) + dockerRegistry.Password = securestore.ToEncryptedString(strings.TrimSuffix(dockerRegistry.Password.String(), "'")) } jwtToken, err := google.JWTAccessTokenSourceWithScope([]byte(dockerRegistry.Password), "") if err != nil { @@ -164,7 +165,7 @@ func (impl *KlarServiceImpl) Process(scanEvent *bean2.ImageScanEvent, executionH config := &docker.Config{ ImageName: scanEvent.Image, User: dockerRegistry.Username, - Password: dockerRegistry.Password, + Password: dockerRegistry.Password.String(), Token: *tokenAddr, //InsecureRegistry: true, //InsecureTLS: true, diff --git a/image-scanner/pkg/roundTripper/RoundTripperService.go b/image-scanner/pkg/roundTripper/RoundTripperService.go index b16ec2aba..1133a474a 100644 --- a/image-scanner/pkg/roundTripper/RoundTripperService.go +++ b/image-scanner/pkg/roundTripper/RoundTripperService.go @@ -24,6 +24,7 @@ import ( "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/ecr" "github.com/devtron-labs/common-lib/imageScan/bean" + "github.com/devtron-labs/common-lib/securestore" "github.com/devtron-labs/image-scanner/pkg/security" "github.com/devtron-labs/image-scanner/pkg/sql/repository" "github.com/google/go-containerregistry/pkg/authn" @@ -79,7 +80,7 @@ func (impl *RoundTripperServiceImpl) GetRoundTripper(scanEvent *bean.ImageScanEv } rtConfig := &RoundTripperConfig{ Username: dockerRegistry.Username, - Password: dockerRegistry.Password, + Password: dockerRegistry.Password.String(), ProxyUrl: proxyUrl, } rt, err := impl.GetRoundTripperTransport(rtConfig) @@ -104,16 +105,16 @@ func (impl *RoundTripperServiceImpl) GetAuthenticatorByDockerRegistryId(dockerRe if dockerRegistry.Username == "_json_key" { lenPassword := len(dockerRegistry.Password) if lenPassword > 1 { - dockerRegistry.Password = strings.TrimPrefix(dockerRegistry.Password, "'") - dockerRegistry.Password = strings.TrimSuffix(dockerRegistry.Password, "'") + dockerRegistry.Password = securestore.ToEncryptedString(strings.TrimPrefix(dockerRegistry.Password.String(), "'")) + dockerRegistry.Password = securestore.ToEncryptedString(strings.TrimSuffix(dockerRegistry.Password.String(), "'")) } } authConfig := authn.AuthConfig{ Username: dockerRegistry.Username, - Password: dockerRegistry.Password, + Password: dockerRegistry.Password.String(), } if dockerRegistry.RegistryType == repository.REGISTRYTYPE_ECR { - accessKey, secretKey := dockerRegistry.AWSAccessKeyId, dockerRegistry.AWSSecretAccessKey + accessKey, secretKey := dockerRegistry.AWSAccessKeyId, dockerRegistry.AWSSecretAccessKey.String() var creds *credentials.Credentials if len(dockerRegistry.AWSAccessKeyId) == 0 || len(dockerRegistry.AWSSecretAccessKey) == 0 { sess, err := session.NewSession(&aws.Config{ diff --git a/image-scanner/pkg/security/ImageScanService.go b/image-scanner/pkg/security/ImageScanService.go index 4ad6762ae..100399348 100644 --- a/image-scanner/pkg/security/ImageScanService.go +++ b/image-scanner/pkg/security/ImageScanService.go @@ -246,9 +246,9 @@ func (impl *ImageScanServiceImpl) GetImageScanRenderDto(registryId string, scanE imageScanRenderDto := &common.ImageScanRenderDto{ RegistryType: dockerRegistry.RegistryType, Username: dockerRegistry.Username, - Password: dockerRegistry.Password, + Password: dockerRegistry.Password.String(), AWSAccessKeyId: dockerRegistry.AWSAccessKeyId, - AWSSecretAccessKey: dockerRegistry.AWSSecretAccessKey, + AWSSecretAccessKey: dockerRegistry.AWSSecretAccessKey.String(), AWSRegion: dockerRegistry.AWSRegion, Image: scanEvent.Image, DockerConnection: scanEvent.DockerConnection, diff --git a/image-scanner/pkg/sql/repository/DockerArtifactStoreRepository.go b/image-scanner/pkg/sql/repository/DockerArtifactStoreRepository.go index 4a1201014..e7b62a69c 100644 --- a/image-scanner/pkg/sql/repository/DockerArtifactStoreRepository.go +++ b/image-scanner/pkg/sql/repository/DockerArtifactStoreRepository.go @@ -17,6 +17,7 @@ package repository import ( + "github.com/devtron-labs/common-lib/securestore" "github.com/devtron-labs/image-scanner/common" "github.com/go-pg/pg" "go.uber.org/zap" @@ -32,21 +33,21 @@ const ( ) type DockerArtifactStore struct { - tableName struct{} `sql:"docker_artifact_store" json:",omitempty" pg:",discard_unknown_columns"` - Id string `sql:"id,pk" json:"id,,omitempty"` - PluginId string `sql:"plugin_id,notnull" json:"pluginId,omitempty"` - RemoteConnectionConfigId int `sql:"remote_connection_config_id" json:"remoteConnectionConfigId,omitempty"` - RegistryURL string `sql:"registry_url" json:"registryUrl,omitempty"` - RegistryType common.RegistryType `sql:"registry_type,notnull" json:"registryType,omitempty"` - AWSAccessKeyId string `sql:"aws_accesskey_id" json:"awsAccessKeyId,omitempty" ` - AWSSecretAccessKey string `sql:"aws_secret_accesskey" json:"awsSecretAccessKey,omitempty"` - AWSRegion string `sql:"aws_region" json:"awsRegion,omitempty"` - Username string `sql:"username" json:"username,omitempty"` - Password string `sql:"password" json:"password,omitempty"` - IsDefault bool `sql:"is_default,notnull" json:"isDefault"` - Connection string `sql:"connection" json:"connection,omitempty"` - Cert string `sql:"cert" json:"cert,omitempty"` - Active bool `sql:"active,notnull" json:"active"` + tableName struct{} `sql:"docker_artifact_store" json:",omitempty" pg:",discard_unknown_columns"` + Id string `sql:"id,pk" json:"id,,omitempty"` + PluginId string `sql:"plugin_id,notnull" json:"pluginId,omitempty"` + RemoteConnectionConfigId int `sql:"remote_connection_config_id" json:"remoteConnectionConfigId,omitempty"` + RegistryURL string `sql:"registry_url" json:"registryUrl,omitempty"` + RegistryType common.RegistryType `sql:"registry_type,notnull" json:"registryType,omitempty"` + AWSAccessKeyId string `sql:"aws_accesskey_id" json:"awsAccessKeyId,omitempty" ` + AWSSecretAccessKey securestore.EncryptedString `sql:"aws_secret_accesskey" json:"awsSecretAccessKey,omitempty"` + AWSRegion string `sql:"aws_region" json:"awsRegion,omitempty"` + Username string `sql:"username" json:"username,omitempty"` + Password securestore.EncryptedString `sql:"password" json:"password,omitempty"` + IsDefault bool `sql:"is_default,notnull" json:"isDefault"` + Connection string `sql:"connection" json:"connection,omitempty"` + Cert string `sql:"cert" json:"cert,omitempty"` + Active bool `sql:"active,notnull" json:"active"` RemoteConnectionConfig *RemoteConnectionConfig AuditLog } diff --git a/image-scanner/pkg/sql/repository/ServerConnectionRepository.go b/image-scanner/pkg/sql/repository/ServerConnectionRepository.go index 2f07dd407..b90950853 100644 --- a/image-scanner/pkg/sql/repository/ServerConnectionRepository.go +++ b/image-scanner/pkg/sql/repository/ServerConnectionRepository.go @@ -17,6 +17,7 @@ package repository import ( + "github.com/devtron-labs/common-lib/securestore" "github.com/devtron-labs/common-lib/utils/remoteConnection/bean" "github.com/go-pg/pg" "go.uber.org/zap" @@ -45,8 +46,8 @@ type RemoteConnectionConfig struct { ProxyUrl string `sql:"proxy_url"` SSHServerAddress string `sql:"ssh_server_address"` SSHUsername string `sql:"ssh_username"` - SSHPassword string `sql:"ssh_password"` - SSHAuthKey string `sql:"ssh_auth_key"` + SSHPassword securestore.EncryptedString `sql:"ssh_password"` + SSHAuthKey securestore.EncryptedString `sql:"ssh_auth_key"` Deleted bool `sql:"deleted,notnull"` AuditLog } diff --git a/image-scanner/vendor/github.com/devtron-labs/common-lib/securestore/AttributesRepoDBConnection.go b/image-scanner/vendor/github.com/devtron-labs/common-lib/securestore/AttributesRepoDBConnection.go new file mode 100644 index 000000000..907d202bd --- /dev/null +++ b/image-scanner/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/image-scanner/vendor/github.com/devtron-labs/common-lib/securestore/AttributesRepository.go b/image-scanner/vendor/github.com/devtron-labs/common-lib/securestore/AttributesRepository.go new file mode 100644 index 000000000..eadf7a8f4 --- /dev/null +++ b/image-scanner/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/image-scanner/vendor/github.com/devtron-labs/common-lib/securestore/EncryptionKeyService.go b/image-scanner/vendor/github.com/devtron-labs/common-lib/securestore/EncryptionKeyService.go new file mode 100644 index 000000000..f8a37acec --- /dev/null +++ b/image-scanner/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/image-scanner/vendor/github.com/devtron-labs/common-lib/securestore/common.go b/image-scanner/vendor/github.com/devtron-labs/common-lib/securestore/common.go new file mode 100644 index 000000000..4444765e3 --- /dev/null +++ b/image-scanner/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/image-scanner/vendor/github.com/devtron-labs/common-lib/securestore/map.go b/image-scanner/vendor/github.com/devtron-labs/common-lib/securestore/map.go new file mode 100644 index 000000000..dd9c25846 --- /dev/null +++ b/image-scanner/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/image-scanner/vendor/github.com/devtron-labs/common-lib/securestore/strings.go b/image-scanner/vendor/github.com/devtron-labs/common-lib/securestore/strings.go new file mode 100644 index 000000000..e7c5128b2 --- /dev/null +++ b/image-scanner/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/image-scanner/vendor/github.com/devtron-labs/common-lib/utils/sql/AuditLog.go b/image-scanner/vendor/github.com/devtron-labs/common-lib/utils/sql/AuditLog.go new file mode 100644 index 000000000..fb3a38e79 --- /dev/null +++ b/image-scanner/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/image-scanner/vendor/github.com/devtron-labs/common-lib/utils/sql/TransactionWrapper.go b/image-scanner/vendor/github.com/devtron-labs/common-lib/utils/sql/TransactionWrapper.go new file mode 100644 index 000000000..3c797e1e1 --- /dev/null +++ b/image-scanner/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/image-scanner/vendor/github.com/devtron-labs/common-lib/utils/sql/connection.go b/image-scanner/vendor/github.com/devtron-labs/common-lib/utils/sql/connection.go new file mode 100644 index 000000000..fa6858e5d --- /dev/null +++ b/image-scanner/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/image-scanner/vendor/github.com/devtron-labs/common-lib/utils/sql/wire_sql.go b/image-scanner/vendor/github.com/devtron-labs/common-lib/utils/sql/wire_sql.go new file mode 100644 index 000000000..32aee8f5b --- /dev/null +++ b/image-scanner/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/image-scanner/vendor/modules.txt b/image-scanner/vendor/modules.txt index db18a5bc9..b528b6e22 100644 --- a/image-scanner/vendor/modules.txt +++ b/image-scanner/vendor/modules.txt @@ -74,7 +74,7 @@ github.com/cespare/xxhash/v2 github.com/coreos/clair/api/v3/clairpb github.com/coreos/clair/database github.com/coreos/clair/ext/versionfmt -# github.com/devtron-labs/common-lib v0.19.0 => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3 +# github.com/devtron-labs/common-lib v0.19.0 => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20251013041509-9d1c5175da2d ## explicit; go 1.24.0 github.com/devtron-labs/common-lib/async github.com/devtron-labs/common-lib/constants @@ -89,10 +89,12 @@ 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/remoteConnection/bean github.com/devtron-labs/common-lib/utils/runTime +github.com/devtron-labs/common-lib/utils/sql # github.com/docker/cli v28.1.1+incompatible ## explicit github.com/docker/cli/cli/config @@ -456,4 +458,4 @@ google.golang.org/protobuf/types/known/wrapperspb # mellium.im/sasl v0.3.2 ## explicit; go 1.20 mellium.im/sasl -# github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3 +# github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20251013041509-9d1c5175da2d diff --git a/image-scanner/wire_gen.go b/image-scanner/wire_gen.go index 0c48cbb0b..b85ef6b67 100644 --- a/image-scanner/wire_gen.go +++ b/image-scanner/wire_gen.go @@ -1,6 +1,6 @@ // Code generated by Wire. DO NOT EDIT. -//go:generate go run github.com/google/wire/cmd/wire +//go:generate go run -mod=mod github.com/google/wire/cmd/wire //go:build !wireinject // +build !wireinject diff --git a/kubelink/App.go b/kubelink/App.go index c019dc203..7229c4240 100644 --- a/kubelink/App.go +++ b/kubelink/App.go @@ -23,6 +23,7 @@ import ( "github.com/devtron-labs/common-lib/constants" "github.com/devtron-labs/common-lib/middlewares" "github.com/devtron-labs/common-lib/pubsub-lib/metrics" + "github.com/devtron-labs/common-lib/securestore" grpcUtil "github.com/devtron-labs/common-lib/utils/grpc" "github.com/devtron-labs/kubelink/api/router" client "github.com/devtron-labs/kubelink/grpc" @@ -60,6 +61,10 @@ func NewApp(Logger *zap.SugaredLogger, router *router.RouterImpl, k8sInformer k8sInformer.K8sInformer, db *pg.DB, cfg *grpcUtil.Configuration) *App { + err := securestore.SetEncryptionKey() + if err != nil { + Logger.Errorw("error in setting encryption key", "err", err) + } return &App{ Logger: Logger, ServerImpl: ServerImpl, diff --git a/kubelink/env_gen.json b/kubelink/env_gen.json index 88c7e64a1..62187e591 100644 --- a/kubelink/env_gen.json +++ b/kubelink/env_gen.json @@ -1 +1 @@ -[{"Category":"DEVTRON","Fields":[{"Env":"APP","EnvType":"string","EnvValue":"kubelink","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":"HELM_RELEASE","Fields":[{"Env":"BUILD_NODES_BATCH_SIZE","EnvType":"int","EnvValue":"2","EnvDescription":"Resource tree build nodes parallelism batch size (applied only for depth-1 child objects of a parent object)","Example":"2","Deprecated":"false"},{"Env":"CHART_WORKING_DIRECTORY","EnvType":"string","EnvValue":"/home/devtron/devtroncd/charts/","EnvDescription":"Helm charts working directory","Example":"/home/devtron/devtroncd/charts/","Deprecated":"false"},{"Env":"ENABLE_HELM_RELEASE_CACHE","EnvType":"bool","EnvValue":"true","EnvDescription":"Enable helm releases list cache","Example":"true","Deprecated":"false"},{"Env":"FEAT_CHILD_OBJECT_LISTING_PAGINATION","EnvType":"bool","EnvValue":"true","EnvDescription":"use pagination in listing all the dependent child objects. use 'CHILD_OBJECT_LISTING_PAGE_SIZE' to set the page size.","Example":"true","Deprecated":"false"},{"Env":"MANIFEST_FETCH_BATCH_SIZE","EnvType":"int","EnvValue":"2","EnvDescription":"Manifest fetch parallelism batch size (applied only for parent objects)","Example":"2","Deprecated":"false"},{"Env":"MAX_COUNT_FOR_HELM_RELEASE","EnvType":"int","EnvValue":"20","EnvDescription":"Max count for helm release history list","Example":"20","Deprecated":"false"},{"Env":"RUN_HELM_INSTALL_IN_ASYNC_MODE","EnvType":"bool","EnvValue":"false","EnvDescription":"Run helm install/ upgrade in async mode","Example":"false","Deprecated":"false"}]},{"Category":"INFRA_SETUP","Fields":[{"Env":"KUBELINK_GRPC_MAX_RECEIVE_MSG_SIZE","EnvType":"int","EnvValue":"20","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"KUBELINK_GRPC_MAX_SEND_MSG_SIZE","EnvType":"int","EnvValue":"4","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"KUBELINK_GRPC_SERVICE_CONFIG","EnvType":"string","EnvValue":"{\"loadBalancingPolicy\":\"round_robin\"}","EnvDescription":"kubelink grpc service config","Example":"","Deprecated":"false"}]},{"Category":"K8S_RESOURCE_SERVICE_CONFIG","Fields":[{"Env":"CHILD_OBJECT_LISTING_PAGE_SIZE","EnvType":"int64","EnvValue":"1000","EnvDescription":"Resource tree child object listing page size","Example":"100","Deprecated":"false"},{"Env":"PARENT_CHILD_GVK_MAPPING","EnvType":"string","EnvValue":"","EnvDescription":"Parent child GVK mapping for resource tree","Example":"","Deprecated":"false"}]}] \ No newline at end of file +[{"Category":"DEVTRON","Fields":[{"Env":"APP","EnvType":"string","EnvValue":"kubelink","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":"HELM_RELEASE","Fields":[{"Env":"BUILD_NODES_BATCH_SIZE","EnvType":"int","EnvValue":"2","EnvDescription":"Resource tree build nodes parallelism batch size (applied only for depth-1 child objects of a parent object)","Example":"2","Deprecated":"false"},{"Env":"CHART_WORKING_DIRECTORY","EnvType":"string","EnvValue":"/home/devtron/devtroncd/charts/","EnvDescription":"Helm charts working directory","Example":"/home/devtron/devtroncd/charts/","Deprecated":"false"},{"Env":"ENABLE_HELM_RELEASE_CACHE","EnvType":"bool","EnvValue":"true","EnvDescription":"Enable helm releases list cache","Example":"true","Deprecated":"false"},{"Env":"FEAT_CHILD_OBJECT_LISTING_PAGINATION","EnvType":"bool","EnvValue":"true","EnvDescription":"use pagination in listing all the dependent child objects. use 'CHILD_OBJECT_LISTING_PAGE_SIZE' to set the page size.","Example":"true","Deprecated":"false"},{"Env":"MANIFEST_FETCH_BATCH_SIZE","EnvType":"int","EnvValue":"2","EnvDescription":"Manifest fetch parallelism batch size (applied only for parent objects)","Example":"2","Deprecated":"false"},{"Env":"MAX_COUNT_FOR_HELM_RELEASE","EnvType":"int","EnvValue":"20","EnvDescription":"Max count for helm release history list","Example":"20","Deprecated":"false"},{"Env":"RUN_HELM_INSTALL_IN_ASYNC_MODE","EnvType":"bool","EnvValue":"false","EnvDescription":"Run helm install/ upgrade in async mode","Example":"false","Deprecated":"false"}]},{"Category":"INFRA_SETUP","Fields":[{"Env":"KUBELINK_GRPC_MAX_RECEIVE_MSG_SIZE","EnvType":"int","EnvValue":"20","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"KUBELINK_GRPC_MAX_SEND_MSG_SIZE","EnvType":"int","EnvValue":"4","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"KUBELINK_GRPC_SERVICE_CONFIG","EnvType":"string","EnvValue":"{\"loadBalancingPolicy\":\"round_robin\"}","EnvDescription":"kubelink grpc service config","Example":"","Deprecated":"false"}]},{"Category":"K8S_RESOURCE_SERVICE_CONFIG","Fields":[{"Env":"CHILD_OBJECT_LISTING_PAGE_SIZE","EnvType":"int64","EnvValue":"1000","EnvDescription":"Resource tree child object listing page size","Example":"100","Deprecated":"false"},{"Env":"PARENT_CHILD_GVK_MAPPING","EnvType":"string","EnvValue":"","EnvDescription":"Parent child GVK mapping for resource tree","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/kubelink/env_gen.md b/kubelink/env_gen.md index ab8957ff7..fcc5f79c1 100644 --- a/kubelink/env_gen.md +++ b/kubelink/env_gen.md @@ -60,3 +60,11 @@ | CHILD_OBJECT_LISTING_PAGE_SIZE | int64 |1000 | Resource tree child object listing page size | 100 | false | | PARENT_CHILD_GVK_MAPPING | string | | Parent child GVK mapping for resource tree | | 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/kubelink/go.mod b/kubelink/go.mod index 02cdc4b8c..c7f8c74eb 100644 --- a/kubelink/go.mod +++ b/kubelink/go.mod @@ -168,4 +168,4 @@ require ( sigs.k8s.io/structured-merge-diff/v4 v4.7.0 // indirect ) -replace github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3 +replace github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20251013041509-9d1c5175da2d diff --git a/kubelink/go.sum b/kubelink/go.sum index 56493c2f1..55be15cac 100644 --- a/kubelink/go.sum +++ b/kubelink/go.sum @@ -65,8 +65,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3 h1:jCxpB8+6KD29jenB4SLTimCYzsmazBAPKv6637xRT5M= -github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3/go.mod h1:/Ciy9tD9OxZOWBDPIasM448H7uvSo4+ZJiExpfwBZpA= +github.com/devtron-labs/devtron-services/common-lib v0.0.0-20251013041509-9d1c5175da2d h1:EAGZ+sei6Hl98Hp09HgNcnOIWgI43jcx1q0Mb6V5HdQ= +github.com/devtron-labs/devtron-services/common-lib v0.0.0-20251013041509-9d1c5175da2d/go.mod h1:/Ciy9tD9OxZOWBDPIasM448H7uvSo4+ZJiExpfwBZpA= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/distribution/distribution/v3 v3.0.0 h1:q4R8wemdRQDClzoNNStftB2ZAfqOiN6UX90KJc4HjyM= diff --git a/kubelink/pkg/cluster/ClusterRepository.go b/kubelink/pkg/cluster/ClusterRepository.go index 7854078ef..f5ef27e01 100644 --- a/kubelink/pkg/cluster/ClusterRepository.go +++ b/kubelink/pkg/cluster/ClusterRepository.go @@ -17,6 +17,7 @@ package repository import ( + "github.com/devtron-labs/common-lib/securestore" "github.com/devtron-labs/kubelink/pkg/remoteConnection" "github.com/devtron-labs/kubelink/pkg/sql" "github.com/go-pg/pg" @@ -25,30 +26,30 @@ 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"` - RemoteConnectionConfigId int `sql:"remote_connection_config_id"` - 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"` - IsVirtualCluster bool `sql:"is_virtual_cluster"` - InsecureSkipTlsVerify bool `sql:"insecure_skip_tls_verify"` - ProxyUrl string `sql:"proxy_url"` - ToConnectWithSSHTunnel bool `sql:"to_connect_with_ssh_tunnel"` - SSHTunnelUser string `sql:"ssh_tunnel_user"` - SSHTunnelPassword string `sql:"ssh_tunnel_password"` - SSHTunnelAuthKey string `sql:"ssh_tunnel_auth_key"` - SSHTunnelServerAddress string `sql:"ssh_tunnel_server_address"` + tableName struct{} `sql:"cluster" pg:",discard_unknown_columns"` + Id int `sql:"id,pk"` + ClusterName string `sql:"cluster_name"` + ServerUrl string `sql:"server_url"` + RemoteConnectionConfigId int `sql:"remote_connection_config_id"` + 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"` + IsVirtualCluster bool `sql:"is_virtual_cluster"` + InsecureSkipTlsVerify bool `sql:"insecure_skip_tls_verify"` + ProxyUrl string `sql:"proxy_url"` + ToConnectWithSSHTunnel bool `sql:"to_connect_with_ssh_tunnel"` + SSHTunnelUser string `sql:"ssh_tunnel_user"` + SSHTunnelPassword string `sql:"ssh_tunnel_password"` + SSHTunnelAuthKey string `sql:"ssh_tunnel_auth_key"` + SSHTunnelServerAddress string `sql:"ssh_tunnel_server_address"` RemoteConnectionConfig *remoteConnection.RemoteConnectionConfig sql.AuditLog } diff --git a/kubelink/pkg/remoteConnection/RemoteConnectionRepository.go b/kubelink/pkg/remoteConnection/RemoteConnectionRepository.go index 6308e4576..909fdb6ac 100644 --- a/kubelink/pkg/remoteConnection/RemoteConnectionRepository.go +++ b/kubelink/pkg/remoteConnection/RemoteConnectionRepository.go @@ -17,6 +17,7 @@ package remoteConnection import ( + "github.com/devtron-labs/common-lib/securestore" remoteConnectionBean "github.com/devtron-labs/common-lib/utils/remoteConnection/bean" "github.com/devtron-labs/kubelink/pkg/sql" "github.com/go-pg/pg" @@ -46,8 +47,8 @@ type RemoteConnectionConfig struct { ProxyUrl string `sql:"proxy_url"` SSHServerAddress string `sql:"ssh_server_address"` SSHUsername string `sql:"ssh_username"` - SSHPassword string `sql:"ssh_password"` - SSHAuthKey string `sql:"ssh_auth_key"` + SSHPassword securestore.EncryptedString `sql:"ssh_password"` + SSHAuthKey securestore.EncryptedString `sql:"ssh_auth_key"` Deleted bool `sql:"deleted,notnull"` sql.AuditLog } diff --git a/kubelink/vendor/github.com/devtron-labs/common-lib/securestore/AttributesRepoDBConnection.go b/kubelink/vendor/github.com/devtron-labs/common-lib/securestore/AttributesRepoDBConnection.go new file mode 100644 index 000000000..907d202bd --- /dev/null +++ b/kubelink/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/kubelink/vendor/github.com/devtron-labs/common-lib/securestore/AttributesRepository.go b/kubelink/vendor/github.com/devtron-labs/common-lib/securestore/AttributesRepository.go new file mode 100644 index 000000000..eadf7a8f4 --- /dev/null +++ b/kubelink/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/kubelink/vendor/github.com/devtron-labs/common-lib/securestore/EncryptionKeyService.go b/kubelink/vendor/github.com/devtron-labs/common-lib/securestore/EncryptionKeyService.go new file mode 100644 index 000000000..f8a37acec --- /dev/null +++ b/kubelink/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/kubelink/vendor/github.com/devtron-labs/common-lib/securestore/common.go b/kubelink/vendor/github.com/devtron-labs/common-lib/securestore/common.go new file mode 100644 index 000000000..4444765e3 --- /dev/null +++ b/kubelink/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/kubelink/vendor/github.com/devtron-labs/common-lib/securestore/map.go b/kubelink/vendor/github.com/devtron-labs/common-lib/securestore/map.go new file mode 100644 index 000000000..dd9c25846 --- /dev/null +++ b/kubelink/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/kubelink/vendor/github.com/devtron-labs/common-lib/securestore/strings.go b/kubelink/vendor/github.com/devtron-labs/common-lib/securestore/strings.go new file mode 100644 index 000000000..e7c5128b2 --- /dev/null +++ b/kubelink/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/kubelink/vendor/github.com/devtron-labs/common-lib/utils/sql/AuditLog.go b/kubelink/vendor/github.com/devtron-labs/common-lib/utils/sql/AuditLog.go new file mode 100644 index 000000000..fb3a38e79 --- /dev/null +++ b/kubelink/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/kubelink/vendor/github.com/devtron-labs/common-lib/utils/sql/TransactionWrapper.go b/kubelink/vendor/github.com/devtron-labs/common-lib/utils/sql/TransactionWrapper.go new file mode 100644 index 000000000..3c797e1e1 --- /dev/null +++ b/kubelink/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/kubelink/vendor/github.com/devtron-labs/common-lib/utils/sql/connection.go b/kubelink/vendor/github.com/devtron-labs/common-lib/utils/sql/connection.go new file mode 100644 index 000000000..fa6858e5d --- /dev/null +++ b/kubelink/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/kubelink/vendor/github.com/devtron-labs/common-lib/utils/sql/wire_sql.go b/kubelink/vendor/github.com/devtron-labs/common-lib/utils/sql/wire_sql.go new file mode 100644 index 000000000..32aee8f5b --- /dev/null +++ b/kubelink/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/kubelink/vendor/modules.txt b/kubelink/vendor/modules.txt index 31223746e..ae054f9d5 100644 --- a/kubelink/vendor/modules.txt +++ b/kubelink/vendor/modules.txt @@ -125,7 +125,7 @@ github.com/cyphar/filepath-securejoin # github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc ## explicit github.com/davecgh/go-spew/spew -# github.com/devtron-labs/common-lib v0.0.0 => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3 +# github.com/devtron-labs/common-lib v0.0.0 => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20251013041509-9d1c5175da2d ## explicit; go 1.24.0 github.com/devtron-labs/common-lib/async github.com/devtron-labs/common-lib/constants @@ -142,6 +142,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/grpc @@ -154,6 +155,7 @@ github.com/devtron-labs/common-lib/utils/k8sObjectsUtil github.com/devtron-labs/common-lib/utils/reflectUtils 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/devtron-labs/common-lib/workerPool # github.com/docker/cli v28.1.1+incompatible @@ -1388,4 +1390,4 @@ sigs.k8s.io/structured-merge-diff/v4/value sigs.k8s.io/yaml sigs.k8s.io/yaml/goyaml.v2 sigs.k8s.io/yaml/goyaml.v3 -# github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3 +# github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20251013041509-9d1c5175da2d diff --git a/kubelink/wire_gen.go b/kubelink/wire_gen.go index 3531a1858..e21d708c3 100644 --- a/kubelink/wire_gen.go +++ b/kubelink/wire_gen.go @@ -1,6 +1,6 @@ // Code generated by Wire. DO NOT EDIT. -//go:generate go run github.com/google/wire/cmd/wire +//go:generate go run -mod=mod github.com/google/wire/cmd/wire //go:build !wireinject // +build !wireinject diff --git a/kubewatch/go.mod b/kubewatch/go.mod index 4bf7c2b80..9f5726aee 100644 --- a/kubewatch/go.mod +++ b/kubewatch/go.mod @@ -238,5 +238,5 @@ require ( replace ( github.com/cyphar/filepath-securejoin v0.4.1 => github.com/cyphar/filepath-securejoin v0.3.6 // indirect - github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3 + github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20251013041509-9d1c5175da2d ) diff --git a/kubewatch/go.sum b/kubewatch/go.sum index d75a94a99..4109e9bf6 100644 --- a/kubewatch/go.sum +++ b/kubewatch/go.sum @@ -129,8 +129,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/denisenkom/go-mssqldb v0.12.3/go.mod h1:k0mtMFOnU+AihqFxPMiF05rtiDrorD1Vrm1KEz5hxDo= -github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3 h1:jCxpB8+6KD29jenB4SLTimCYzsmazBAPKv6637xRT5M= -github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3/go.mod h1:/Ciy9tD9OxZOWBDPIasM448H7uvSo4+ZJiExpfwBZpA= +github.com/devtron-labs/devtron-services/common-lib v0.0.0-20251013041509-9d1c5175da2d h1:EAGZ+sei6Hl98Hp09HgNcnOIWgI43jcx1q0Mb6V5HdQ= +github.com/devtron-labs/devtron-services/common-lib v0.0.0-20251013041509-9d1c5175da2d/go.mod h1:/Ciy9tD9OxZOWBDPIasM448H7uvSo4+ZJiExpfwBZpA= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= diff --git a/kubewatch/vendor/modules.txt b/kubewatch/vendor/modules.txt index 89d6333c4..d9bc3bd69 100644 --- a/kubewatch/vendor/modules.txt +++ b/kubewatch/vendor/modules.txt @@ -251,7 +251,7 @@ github.com/cyphar/filepath-securejoin # github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc ## explicit github.com/davecgh/go-spew/spew -# github.com/devtron-labs/common-lib v0.0.0 => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3 +# github.com/devtron-labs/common-lib v0.0.0 => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20251013041509-9d1c5175da2d ## explicit; go 1.24.0 github.com/devtron-labs/common-lib/async github.com/devtron-labs/common-lib/constants @@ -1981,4 +1981,4 @@ sigs.k8s.io/structured-merge-diff/v4/value sigs.k8s.io/yaml sigs.k8s.io/yaml/goyaml.v2 sigs.k8s.io/yaml/goyaml.v3 -# github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3 +# github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20251013041509-9d1c5175da2d diff --git a/lens/go.mod b/lens/go.mod index 0a77043cf..1d215d33a 100644 --- a/lens/go.mod +++ b/lens/go.mod @@ -59,6 +59,6 @@ require ( ) replace ( - github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3 + github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20251013041509-9d1c5175da2d go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 => go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1 ) diff --git a/lens/go.sum b/lens/go.sum index 28237eac8..09801f6e2 100644 --- a/lens/go.sum +++ b/lens/go.sum @@ -17,8 +17,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3 h1:jCxpB8+6KD29jenB4SLTimCYzsmazBAPKv6637xRT5M= -github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3/go.mod h1:/Ciy9tD9OxZOWBDPIasM448H7uvSo4+ZJiExpfwBZpA= +github.com/devtron-labs/devtron-services/common-lib v0.0.0-20251013041509-9d1c5175da2d h1:EAGZ+sei6Hl98Hp09HgNcnOIWgI43jcx1q0Mb6V5HdQ= +github.com/devtron-labs/devtron-services/common-lib v0.0.0-20251013041509-9d1c5175da2d/go.mod h1:/Ciy9tD9OxZOWBDPIasM448H7uvSo4+ZJiExpfwBZpA= github.com/devtron-labs/protos v0.0.3-0.20240912111807-605886d90b8d h1:IV6FWU6eWSfKq67Fs2DBx3LjkX/wtjMj9QB3ufZgga4= github.com/devtron-labs/protos v0.0.3-0.20240912111807-605886d90b8d/go.mod h1:1TqULGlTey+VNhAu/ag7NJuUvByJemkqodsc9L5PHJk= github.com/docker/cli v28.1.1+incompatible h1:eyUemzeI45DY7eDPuwUcmDyDj1pM98oD5MdSpiItp8k= diff --git a/lens/vendor/modules.txt b/lens/vendor/modules.txt index 72b9142be..ef60d8a4d 100644 --- a/lens/vendor/modules.txt +++ b/lens/vendor/modules.txt @@ -7,7 +7,7 @@ github.com/caarlos0/env # github.com/cespare/xxhash/v2 v2.3.0 ## explicit; go 1.11 github.com/cespare/xxhash/v2 -# github.com/devtron-labs/common-lib v0.19.1 => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3 +# github.com/devtron-labs/common-lib v0.19.1 => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20251013041509-9d1c5175da2d ## explicit; go 1.24.0 github.com/devtron-labs/common-lib/constants github.com/devtron-labs/common-lib/fetchAllEnv @@ -302,4 +302,4 @@ google.golang.org/protobuf/types/known/timestamppb # mellium.im/sasl v0.3.2 ## explicit; go 1.20 mellium.im/sasl -# github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3 +# github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20251013041509-9d1c5175da2d