/
cache_flags.go
144 lines (128 loc) · 3.67 KB
/
cache_flags.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package flag
import (
"fmt"
"strings"
"time"
"github.com/samber/lo"
"golang.org/x/xerrors"
)
// e.g. config yaml:
//
// cache:
// clear: true
// backend: "redis://localhost:6379"
// redis:
// ca: ca-cert.pem
// cert: cert.pem
// key: key.pem
var (
ClearCacheFlag = Flag{
Name: "clear-cache",
ConfigName: "cache.clear",
Value: false,
Usage: "clear image caches without scanning",
}
CacheBackendFlag = Flag{
Name: "cache-backend",
ConfigName: "cache.backend",
Value: "fs",
Usage: "cache backend (e.g. redis://localhost:6379)",
}
CacheTTLFlag = Flag{
Name: "cache-ttl",
ConfigName: "cache.ttl",
Value: time.Duration(0),
Usage: "cache TTL when using redis as cache backend",
}
RedisCACertFlag = Flag{
Name: "redis-ca",
ConfigName: "cache.redis.ca",
Value: "",
Usage: "redis ca file location, if using redis as cache backend",
}
RedisCertFlag = Flag{
Name: "redis-cert",
ConfigName: "cache.redis.cert",
Value: "",
Usage: "redis certificate file location, if using redis as cache backend",
}
RedisKeyFlag = Flag{
Name: "redis-key",
ConfigName: "cache.redis.key",
Value: "",
Usage: "redis key file location, if using redis as cache backend",
}
)
// CacheFlagGroup composes common printer flag structs used for commands requiring cache logic.
type CacheFlagGroup struct {
ClearCache *Flag
CacheBackend *Flag
CacheTTL *Flag
RedisCACert *Flag
RedisCert *Flag
RedisKey *Flag
}
type CacheOptions struct {
ClearCache bool
CacheBackend string
CacheTTL time.Duration
RedisOptions
}
// RedisOptions holds the options for redis cache
type RedisOptions struct {
RedisCACert string
RedisCert string
RedisKey string
}
// NewCacheFlagGroup returns a default CacheFlagGroup
func NewCacheFlagGroup() *CacheFlagGroup {
return &CacheFlagGroup{
ClearCache: &ClearCacheFlag,
CacheBackend: &CacheBackendFlag,
CacheTTL: &CacheTTLFlag,
RedisCACert: &RedisCACertFlag,
RedisCert: &RedisCertFlag,
RedisKey: &RedisKeyFlag,
}
}
func (fg *CacheFlagGroup) Name() string {
return "Cache"
}
func (fg *CacheFlagGroup) Flags() []*Flag {
return []*Flag{fg.ClearCache, fg.CacheBackend, fg.CacheTTL, fg.RedisCACert, fg.RedisCert, fg.RedisKey}
}
func (fg *CacheFlagGroup) ToOptions() (CacheOptions, error) {
cacheBackend := getString(fg.CacheBackend)
redisOptions := RedisOptions{
RedisCACert: getString(fg.RedisCACert),
RedisCert: getString(fg.RedisCert),
RedisKey: getString(fg.RedisKey),
}
// "redis://" or "fs" are allowed for now
// An empty value is also allowed for testability
if !strings.HasPrefix(cacheBackend, "redis://") &&
cacheBackend != "fs" && cacheBackend != "" {
return CacheOptions{}, xerrors.Errorf("unsupported cache backend: %s", cacheBackend)
}
// if one of redis option not nil, make sure CA, cert, and key provided
if !lo.IsEmpty(redisOptions) {
if redisOptions.RedisCACert == "" || redisOptions.RedisCert == "" || redisOptions.RedisKey == "" {
return CacheOptions{}, xerrors.Errorf("you must provide Redis CA, cert and key file path when using TLS")
}
}
return CacheOptions{
ClearCache: getBool(fg.ClearCache),
CacheBackend: cacheBackend,
CacheTTL: getDuration(fg.CacheTTL),
RedisOptions: redisOptions,
}, nil
}
// CacheBackendMasked returns the redis connection string masking credentials
func (o *CacheOptions) CacheBackendMasked() string {
endIndex := strings.Index(o.CacheBackend, "@")
if endIndex == -1 {
return o.CacheBackend
}
startIndex := strings.Index(o.CacheBackend, "//")
return fmt.Sprintf("%s****%s", o.CacheBackend[:startIndex+2], o.CacheBackend[endIndex:])
}