mirror of
https://github.com/kyverno/policy-reporter.git
synced 2024-12-14 11:57:32 +00:00
1edff60f57
Signed-off-by: Frank Jogeleit <frank.jogeleit@lovoo.com>
100 lines
2.4 KiB
Go
100 lines
2.4 KiB
Go
package cache
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
|
|
goredis "github.com/go-redis/redis/v8"
|
|
"go.uber.org/zap"
|
|
|
|
"github.com/kyverno/policy-reporter/pkg/crd/api/policyreport/v1alpha2"
|
|
)
|
|
|
|
type rdb interface {
|
|
Set(ctx context.Context, key string, value interface{}, expiration time.Duration) *goredis.StatusCmd
|
|
Keys(ctx context.Context, pattern string) *goredis.StringSliceCmd
|
|
Expire(ctx context.Context, key string, expiration time.Duration) *goredis.BoolCmd
|
|
Del(ctx context.Context, keys ...string) *goredis.IntCmd
|
|
}
|
|
|
|
type redisCache struct {
|
|
rdb rdb
|
|
prefix string
|
|
ttl time.Duration
|
|
}
|
|
|
|
func (r *redisCache) AddReport(report v1alpha2.ReportInterface) {
|
|
next := make(map[string]bool)
|
|
|
|
for _, result := range report.GetResults() {
|
|
r.rdb.Set(context.Background(), r.generateKey(report.GetID(), result.GetID()), nil, 0)
|
|
next[result.GetID()] = true
|
|
}
|
|
|
|
for _, id := range r.GetResults(report.GetID()) {
|
|
if !next[id] {
|
|
r.rdb.Set(context.Background(), r.generateKey(report.GetID(), id), nil, r.ttl)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (r *redisCache) RemoveReport(id string) {
|
|
keys, err := r.rdb.Keys(context.Background(), r.generateKeyPattern(id)).Result()
|
|
if err != nil {
|
|
zap.L().Error("failed to load report keys", zap.Error(err))
|
|
return
|
|
}
|
|
|
|
for _, key := range keys {
|
|
r.rdb.Expire(context.Background(), key, 10*time.Minute)
|
|
}
|
|
}
|
|
|
|
func (r *redisCache) GetResults(id string) []string {
|
|
results := make([]string, 0)
|
|
pattern := r.generateKeyPattern(id)
|
|
|
|
keys, err := r.rdb.Keys(context.Background(), pattern).Result()
|
|
if err != nil {
|
|
zap.L().Error("failed to load report keys", zap.Error(err))
|
|
return results
|
|
}
|
|
|
|
prefix := strings.TrimSuffix(pattern, "*")
|
|
for _, key := range keys {
|
|
results = append(results, strings.TrimPrefix(key, prefix))
|
|
}
|
|
|
|
return results
|
|
}
|
|
|
|
func (r *redisCache) Shared() bool {
|
|
return true
|
|
}
|
|
|
|
func (r *redisCache) Clear() {
|
|
results := r.rdb.Keys(context.Background(), r.prefix+":*")
|
|
|
|
keys, err := results.Result()
|
|
if err != nil {
|
|
zap.L().Error("failed to find cache keys in redis", zap.Error(err))
|
|
}
|
|
|
|
for _, key := range keys {
|
|
r.rdb.Del(context.Background(), key)
|
|
}
|
|
}
|
|
|
|
func (r *redisCache) generateKey(report, id string) string {
|
|
return fmt.Sprintf("%s:%s:%s", r.prefix, report, id)
|
|
}
|
|
|
|
func (r *redisCache) generateKeyPattern(report string) string {
|
|
return fmt.Sprintf("%s:%s:*", r.prefix, report)
|
|
}
|
|
|
|
func NewRedisCache(prefix string, rdb rdb, ttl time.Duration) Cache {
|
|
return &redisCache{rdb: rdb, prefix: prefix, ttl: ttl}
|
|
}
|