/
filter.go
149 lines (131 loc) · 3.54 KB
/
filter.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
145
146
147
148
149
package k8s
import (
"github.com/armory-io/bilgepump/pkg/mark"
"github.com/sirupsen/logrus"
v1 "k8s.io/api/core/v1"
"regexp"
"time"
)
var protectedNamespace = map[string]bool{
"default": true,
"kube-system": true,
"kube-public": true,
}
type filterable interface {
Ignore() bool
Compliant() bool
GetInterface() interface{}
GetType() string
}
func (k *K8SMarker) FilterK8SObject(f filterable) {
if f.Ignore() {
err := k.filterableUpdate(f.GetInterface(), f.GetType())
if err != nil {
k.Logger.Error(err)
}
return
}
if !f.Compliant() {
err := k.ttlRejected(f.GetInterface(), f.GetType())
if err != nil {
k.Logger.Error(err)
}
}
}
type k8sFilterable struct {
ignoreFilters []Filter
complianceFilters []Filter
id string
created time.Time
annotations map[string]string
log *logrus.Entry
object interface{}
k8sObjectType string
}
func (k *K8SMarker) newk8sFilterable(i interface{}) *k8sFilterable {
namespace, ok := i.(v1.Namespace)
if !ok {
return nil
}
return &k8sFilterable{
id: namespace.Name,
created: namespace.CreationTimestamp.Time,
annotations: namespace.ObjectMeta.Annotations,
log: k.Logger,
object: i,
k8sObjectType: "namespace",
}
}
func (e *k8sFilterable) WithIgnoreFilter(f Filter) *k8sFilterable {
e.ignoreFilters = append(e.ignoreFilters, f)
return e
}
func (e *k8sFilterable) WithComplianceFilter(f Filter) *k8sFilterable {
e.complianceFilters = append(e.complianceFilters, f)
return e
}
func (e *k8sFilterable) GetInterface() interface{} {
return e.object
}
func (e *k8sFilterable) GetType() string {
return e.k8sObjectType
}
func (e *k8sFilterable) Ignore() bool {
for _, f := range e.ignoreFilters {
if f(e.id, e.annotations, e.created, e.log) {
return true
}
}
return false
}
func (e *k8sFilterable) Compliant() bool {
for _, f := range e.complianceFilters {
if f(e.id, e.annotations, e.created, e.log) {
return false
}
}
return true
}
type Filter func(id string, annotations map[string]string, created time.Time, log *logrus.Entry) bool
func ignoreProtectedNamespaceFilter(id string, annotations map[string]string, created time.Time, log *logrus.Entry) bool {
if protectedNamespace[id] {
log.Debugf("Ignoring %s. Reason: protected namespace", id)
return true
}
return false
}
func NoTTLAnnotationFilter(id string, annotations map[string]string, created time.Time, log *logrus.Entry) bool {
if _, exists := annotations["armory.io/bilge.ttl"]; !exists {
log.Infof("Adding k8s namespace: %s. Reason: no TTL annotation", id)
return true
}
return false
}
func TTLExpiredFilter(id string, annotations map[string]string, created time.Time, log *logrus.Entry) bool {
ttl := annotations["armory.io/bilge.ttl"]
if ttl == "0" {
log.Debugf("Ignoring %s. Reason: Unlimted TTL", id)
return false
}
if !mark.WithinTTLTime(ttl, created) {
log.Infof("Adding namespace: %s. Reason: TTL expired. Created on: %v", id, created)
return true
}
return false
}
func (k *K8SMarker) ignoreNamespaceFilter(id string, annotations map[string]string, created time.Time, log *logrus.Entry) bool {
for _, n := range k.Config.Not {
if id == n {
log.Debugf("Ignoring %s. Reason: matched ignore rule", id)
return true
}
}
for _, regex := range k.Config.NotRegex {
// regex is already checked in config
if regex != "" && regexp.MustCompile(regex).MatchString(id) {
k.Logger.Debugf("Ignoring %s. Reason: matched ignore regex: %s", id, regex)
return true
}
}
return false
}