-
Notifications
You must be signed in to change notification settings - Fork 185
/
io.go
129 lines (101 loc) · 3.6 KB
/
io.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
package configauditreport
import (
"context"
"github.com/aquasecurity/trivy-operator/pkg/apis/aquasecurity/v1alpha1"
"github.com/aquasecurity/trivy-operator/pkg/kube"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
)
// Writer is the interface for saving v1alpha1.ClusterConfigAuditReport
// and v1alpha1.ConfigAuditReport instances.
type Writer interface {
// WriteReport creates or updates the given v1alpha1.ConfigAuditReport instance.
WriteReport(ctx context.Context, report v1alpha1.ConfigAuditReport) error
// WriteClusterReport creates or updates the given v1alpha1.ClusterConfigAuditReport instance.
WriteClusterReport(ctx context.Context, report v1alpha1.ClusterConfigAuditReport) error
}
// Reader is the interface that wraps methods for finding v1alpha1.ConfigAuditReport
// and v1alpha1.ClusterConfigAuditReport objects.
type Reader interface {
// FindReportByOwner returns a v1alpha1.ConfigAuditReport owned by the given
// kube.ObjectRef or nil if the report is not found.
FindReportByOwner(ctx context.Context, owner kube.ObjectRef) (interface{}, error)
// FindClusterReportByOwner returns a v1alpha1.ClusterConfigAuditReport owned by the given
// kube.ObjectRef or nil if the report is not found.
FindClusterReportByOwner(ctx context.Context, owner kube.ObjectRef) (interface{}, error)
}
type ReadWriter interface {
Writer
Reader
}
type readWriter struct {
*kube.ObjectResolver
}
// NewReadWriter constructs a new ReadWriter which is using the client package
// provided by the controller-runtime libraries for interacting with the
// Kubernetes API server.
func NewReadWriter(ObjectResolver *kube.ObjectResolver) ReadWriter {
return &readWriter{
ObjectResolver: ObjectResolver,
}
}
func (r *readWriter) WriteReport(ctx context.Context, report v1alpha1.ConfigAuditReport) error {
var existing v1alpha1.ConfigAuditReport
err := r.Get(ctx, types.NamespacedName{
Name: report.Name,
Namespace: report.Namespace,
}, &existing)
if err == nil {
copied := existing.DeepCopy()
copied.Labels = report.Labels
copied.Report = report.Report
return r.Update(ctx, copied)
}
if errors.IsNotFound(err) {
return r.Create(ctx, &report)
}
return err
}
func (r *readWriter) WriteClusterReport(ctx context.Context, report v1alpha1.ClusterConfigAuditReport) error {
var existing v1alpha1.ClusterConfigAuditReport
err := r.Get(ctx, types.NamespacedName{
Name: report.Name,
}, &existing)
if err == nil {
copied := existing.DeepCopy()
copied.Labels = report.Labels
copied.Report = report.Report
return r.Update(ctx, copied)
}
if errors.IsNotFound(err) {
return r.Create(ctx, &report)
}
return err
}
func (r *readWriter) FindReportByOwner(ctx context.Context, owner kube.ObjectRef) (interface{}, error) {
var list v1alpha1.ConfigAuditReportList
labels := client.MatchingLabels(kube.ObjectRefToLabels(owner))
err := r.List(ctx, &list, labels, client.InNamespace(owner.Namespace))
if err != nil {
return nil, err
}
// Only one config audit per specific workload exists on the cluster
if len(list.Items) > 0 {
return &list.DeepCopy().Items[0], nil
}
return nil, nil
}
func (r *readWriter) FindClusterReportByOwner(ctx context.Context, owner kube.ObjectRef) (interface{}, error) {
var list v1alpha1.ClusterConfigAuditReportList
labels := client.MatchingLabels(kube.ObjectRefToLabels(owner))
err := r.List(ctx, &list, labels)
if err != nil {
return nil, err
}
// Only one config audit per specific workload exists on the cluster
if len(list.Items) > 0 {
return &list.DeepCopy().Items[0], nil
}
return nil, nil
}