Skip to content

Commit

Permalink
feat: support Redis sentinel connections (#109)
Browse files Browse the repository at this point in the history
Signed-off-by: Daniel Pacak <pacak.daniel@gmail.com>
  • Loading branch information
danielpacak committed Jun 22, 2022
1 parent 0af242e commit e6ee9f9
Show file tree
Hide file tree
Showing 14 changed files with 428 additions and 125 deletions.
56 changes: 30 additions & 26 deletions README.md

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module github.com/aquasecurity/harbor-scanner-aqua
go 1.18

require (
github.com/FZambia/sentinel v1.1.0
github.com/caarlos0/env/v6 v6.8.0
github.com/gomodule/redigo v1.8.8
github.com/google/uuid v1.3.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZ
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/FZambia/sentinel v1.1.0 h1:qrCBfxc8SvJihYNjBWgwUI93ZCvFe/PJIPTHKmlp8a8=
github.com/FZambia/sentinel v1.1.0/go.mod h1:ytL1Am/RLlAoAXG6Kj5LNuw/TRRQrv2rt2FT26vP5gI=
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
Expand Down
76 changes: 40 additions & 36 deletions helm/harbor-scanner-aqua/README.md

Large diffs are not rendered by default.

24 changes: 16 additions & 8 deletions helm/harbor-scanner-aqua/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -95,16 +95,24 @@ spec:
value: {{ .Values.scanner.aqua.scannerCLIRegisterImages | default "Never" | quote }}
- name: "SCANNER_AQUA_USE_IMAGE_TAG"
value: {{ .Values.scanner.aqua.useImageTag | default false | quote }}
- name: "SCANNER_STORE_REDIS_URL"
value: {{ .Values.scanner.store.redisURL | quote }}
- name: "SCANNER_STORE_REDIS_NAMESPACE"
value: {{ .Values.scanner.store.redisNamespace | default "harbor.scanner.aqua:store" | quote }}
- name: "SCANNER_STORE_REDIS_POOL_MAX_ACTIVE"
value: {{ .Values.scanner.store.redisPoolMaxActive | default 5 | quote }}
- name: "SCANNER_STORE_REDIS_POOL_MAX_IDLE"
value: {{ .Values.scanner.store.redisPoolMaxIdle | default 5 | quote }}
value: {{ .Values.scanner.store.redisNamespace | quote }}
- name: "SCANNER_STORE_REDIS_SCAN_JOB_TTL"
value: {{ .Values.scanner.store.redisScanJobTTL | default "1h" | quote }}
value: {{ .Values.scanner.store.redisScanJobTTL | quote }}
- name: "SCANNER_REDIS_URL"
value: {{ .Values.scanner.redis.poolURL | quote }}
- name: "SCANNER_REDIS_POOL_MAX_ACTIVE"
value: {{ .Values.scanner.redis.poolMaxActive | quote }}
- name: "SCANNER_REDIS_POOL_MAX_IDLE"
value: {{ .Values.scanner.redis.poolMaxIdle | quote }}
- name: "SCANNER_REDIS_POOL_IDLE_TIMEOUT"
value: {{ .Values.scanner.redis.poolIdleTimeout | quote }}
- name: "SCANNER_REDIS_POOL_CONNECTION_TIMEOUT"
value: {{ .Values.scanner.redis.poolConnectionTimeout | quote }}
- name: "SCANNER_REDIS_POOL_READ_TIMEOUT"
value: {{ .Values.scanner.redis.poolReadTimeout | quote }}
- name: "SCANNER_REDIS_POOL_WRITE_TIMEOUT"
value: {{ .Values.scanner.redis.poolWriteTimeout | quote }}
{{- if .Values.scanner.api.tlsEnabled }}
- name: "SCANNER_API_TLS_CERTIFICATE"
value: "/certs/tls.crt"
Expand Down
24 changes: 18 additions & 6 deletions helm/harbor-scanner-aqua/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,25 @@ scanner:
## `Always` - registers compliant and non-compliant images
scannerCLIRegisterImages: Never
store:
## redisURL the server URI for the Redis store
redisURL: "redis://harbor-harbor-redis:6379"
## redisNamespace the namespace for keys in the Redis store
redisNamespace: "harbor.scanner.aqua:store"
## redisPoolMaxActive the max number of connections allocated by the pool for the Redis store
redisPoolMaxActive: 5
## redisPoolMaxIdle the max number of idle connections in the pool for the Redis store
redisPoolMaxIdle: 5
## redisScanJobTTL the time to live for persisting scan jobs and associated scan reports
redisScanJobTTL: "1h"
redis:
## poolURL the Redis server URI. The URI supports schemas to connect to a standalone Redis server,
## i.e. `redis://:password@standalone_host:port/db-number` and Redis Sentinel deployment,
## i.e. `redis+sentinel://:password@sentinel_host1:port1,sentinel_host2:port2/monitor-name/db-number`.
poolURL: "redis://harbor-harbor-redis:6379"
## poolMaxActive the max number of connections allocated by the Redis connection pool
poolMaxActive: 5
## poolMaxIdle the max number of idle connections in the Redis connection pool
poolMaxIdle: 5
## poolIdleTimeout the duration after which idle connections to the Redis server are closed.
## If the value is zero, then idle connections are not closed.
poolIdleTimeout: 5m
## poolConnectionTimeout the timeout for connecting to the Redis server
poolConnectionTimeout: 1s
## poolReadTimeout the timeout for reading a single Redis command reply
poolReadTimeout: 1s
## poolWriteTimeout The timeout for writing a single Redis command
poolWriteTimeout: 1s
8 changes: 7 additions & 1 deletion pkg/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/aquasecurity/harbor-scanner-aqua/pkg/http/api"
"github.com/aquasecurity/harbor-scanner-aqua/pkg/http/api/v1"
"github.com/aquasecurity/harbor-scanner-aqua/pkg/persistence/redis"
"github.com/aquasecurity/harbor-scanner-aqua/pkg/redisx"
"github.com/aquasecurity/harbor-scanner-aqua/pkg/scanner"
"github.com/aquasecurity/harbor-scanner-aqua/pkg/work"
log "github.com/sirupsen/logrus"
Expand All @@ -37,11 +38,16 @@ func Run(info etc.BuildInfo) error {
}
}

pool, err := redisx.NewPool(config.RedisPool)
if err != nil {
return fmt.Errorf("constructing connection pool: %w", err)
}

workPool := work.New()
command := aqua.NewCommand(config.AquaCSP, ext.DefaultAmbassador)
transformer := scanner.NewTransformer(ext.NewSystemClock())
adapter := scanner.NewAdapter(command, transformer)
store := redis.NewStore(config.Store)
store := redis.NewStore(config.RedisStore, pool)
enqueuer := scanner.NewEnqueuer(workPool, adapter, store)
apiServer := api.NewServer(config.API, v1.NewAPIHandler(info, config, enqueuer, store))

Expand Down
35 changes: 21 additions & 14 deletions pkg/etc/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (

"github.com/aquasecurity/harbor-scanner-aqua/pkg/harbor"
"github.com/caarlos0/env/v6"
"github.com/sirupsen/logrus"
log "github.com/sirupsen/logrus"
)

Expand All @@ -24,9 +23,10 @@ type BuildInfo struct {
}

type Config struct {
API API
AquaCSP AquaCSP
Store Store
API API
AquaCSP AquaCSP
RedisStore RedisStore
RedisPool RedisPool
}

type API struct {
Expand Down Expand Up @@ -66,12 +66,19 @@ type AquaCSP struct {
ScannerCLIOverrideRegistryCredentials bool `env:"SCANNER_CLI_OVERRIDE_REGISTRY_CREDENTIALS" envDefault:"false"`
}

type Store struct {
RedisURL string `env:"SCANNER_STORE_REDIS_URL" envDefault:"redis://harbor-harbor-redis:6379"`
Namespace string `env:"SCANNER_STORE_REDIS_NAMESPACE" envDefault:"harbor.scanner.aqua:store"`
PoolMaxActive int `env:"SCANNER_STORE_REDIS_POOL_MAX_ACTIVE" envDefault:"5"`
PoolMaxIdle int `env:"SCANNER_STORE_REDIS_POOL_MAX_IDLE" envDefault:"5"`
ScanJobTTL time.Duration `env:"SCANNER_STORE_REDIS_SCAN_JOB_TTL" envDefault:"1h"`
type RedisStore struct {
Namespace string `env:"SCANNER_STORE_REDIS_NAMESPACE" envDefault:"harbor.scanner.aqua:store"`
ScanJobTTL time.Duration `env:"SCANNER_STORE_REDIS_SCAN_JOB_TTL" envDefault:"1h"`
}

type RedisPool struct {
URL string `env:"SCANNER_REDIS_URL" envDefault:"redis://harbor-harbor-redis:6379"`
MaxActive int `env:"SCANNER_REDIS_POOL_MAX_ACTIVE" envDefault:"5"`
MaxIdle int `env:"SCANNER_REDIS_POOL_MAX_IDLE" envDefault:"5"`
IdleTimeout time.Duration `env:"SCANNER_REDIS_POOL_IDLE_TIMEOUT" envDefault:"5m"`
ConnectionTimeout time.Duration `env:"SCANNER_REDIS_POOL_CONNECTION_TIMEOUT" envDefault:"1s"`
ReadTimeout time.Duration `env:"SCANNER_REDIS_POOL_READ_TIMEOUT" envDefault:"1s"`
WriteTimeout time.Duration `env:"SCANNER_REDIS_POOL_WRITE_TIMEOUT" envDefault:"1s"`
}

var (
Expand Down Expand Up @@ -99,15 +106,15 @@ func GetConfig() (Config, error) {
return cfg, nil
}

func GetLogLevel() logrus.Level {
func GetLogLevel() log.Level {
if value, ok := os.LookupEnv("SCANNER_LOG_LEVEL"); ok {
level, err := logrus.ParseLevel(value)
level, err := log.ParseLevel(value)
if err != nil {
return logrus.InfoLevel
return log.InfoLevel
}
return level
}
return logrus.InfoLevel
return log.InfoLevel
}

func GetScannerMetadata() harbor.Scanner {
Expand Down
37 changes: 25 additions & 12 deletions pkg/etc/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,18 @@ func TestGetConfig(t *testing.T) {
ScannerCLIOverrideRegistryCredentials: false,
ScannerCLIRegisterImages: Never,
},
Store: Store{
RedisURL: "redis://harbor-harbor-redis:6379",
Namespace: "harbor.scanner.aqua:store",
PoolMaxActive: 5,
PoolMaxIdle: 5,
ScanJobTTL: parseDuration(t, "1h"),
RedisStore: RedisStore{
Namespace: "harbor.scanner.aqua:store",
ScanJobTTL: parseDuration(t, "1h"),
},
RedisPool: RedisPool{
URL: "redis://harbor-harbor-redis:6379",
MaxActive: 5,
MaxIdle: 5,
IdleTimeout: parseDuration(t, "5m"),
ConnectionTimeout: parseDuration(t, "1s"),
ReadTimeout: parseDuration(t, "1s"),
WriteTimeout: parseDuration(t, "1s"),
},
},
},
Expand Down Expand Up @@ -75,6 +81,7 @@ func TestGetConfig(t *testing.T) {
"SCANNER_CLI_SHOW_NEGLIGIBLE": "false",
"SCANNER_CLI_REGISTER_IMAGES": "Compliant",
"SCANNER_CLI_OVERRIDE_REGISTRY_CREDENTIALS": "true",
"SCANNER_REDIS_URL": "redis://localhost:6379",
},
expectedConfig: Config{
API: API{
Expand All @@ -97,12 +104,18 @@ func TestGetConfig(t *testing.T) {
ScannerCLIRegisterImages: Compliant,
ScannerCLIOverrideRegistryCredentials: true,
},
Store: Store{
RedisURL: "redis://harbor-harbor-redis:6379",
Namespace: "harbor.scanner.aqua:store",
PoolMaxActive: 5,
PoolMaxIdle: 5,
ScanJobTTL: parseDuration(t, "1h"),
RedisStore: RedisStore{
Namespace: "harbor.scanner.aqua:store",
ScanJobTTL: parseDuration(t, "1h"),
},
RedisPool: RedisPool{
URL: "redis://localhost:6379",
MaxActive: 5,
MaxIdle: 5,
IdleTimeout: parseDuration(t, "5m"),
ConnectionTimeout: parseDuration(t, "1s"),
ReadTimeout: parseDuration(t, "1s"),
WriteTimeout: parseDuration(t, "1s"),
},
},
},
Expand Down
18 changes: 6 additions & 12 deletions pkg/persistence/redis/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package redis
import (
"encoding/json"
"fmt"

"github.com/aquasecurity/harbor-scanner-aqua/pkg/etc"
"github.com/aquasecurity/harbor-scanner-aqua/pkg/harbor"
"github.com/aquasecurity/harbor-scanner-aqua/pkg/job"
Expand All @@ -13,21 +14,14 @@ import (
)

type store struct {
cfg etc.Store
pool redis.Pool
cfg etc.RedisStore
pool *redis.Pool
}

func NewStore(cfg etc.Store) persistence.Store {
func NewStore(cfg etc.RedisStore, pool *redis.Pool) persistence.Store {
return &store{
cfg: cfg,
pool: redis.Pool{
Dial: func() (redis.Conn, error) {
return redis.DialURL(cfg.RedisURL)
},
MaxIdle: cfg.PoolMaxIdle,
MaxActive: cfg.PoolMaxActive,
Wait: true,
},
cfg: cfg,
pool: pool,
}
}

Expand Down

0 comments on commit e6ee9f9

Please sign in to comment.