-
Notifications
You must be signed in to change notification settings - Fork 207
/
auditpolicy_controller.go
128 lines (113 loc) · 4.16 KB
/
auditpolicy_controller.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
package auditpolicy
import (
"context"
"time"
configv1 "github.com/openshift/api/config/v1"
operatorsv1 "github.com/openshift/api/operator/v1"
operatorv1 "github.com/openshift/api/operator/v1"
configinformers "github.com/openshift/client-go/config/informers/externalversions"
configv1listers "github.com/openshift/client-go/config/listers/config/v1"
"github.com/openshift/library-go/pkg/controller/factory"
"github.com/openshift/library-go/pkg/operator/apiserver/audit"
"github.com/openshift/library-go/pkg/operator/events"
"github.com/openshift/library-go/pkg/operator/resource/resourceapply"
"github.com/openshift/library-go/pkg/operator/v1helpers"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
auditv1 "k8s.io/apiserver/pkg/apis/audit/v1"
kubeinformers "k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes"
"sigs.k8s.io/yaml"
)
type auditPolicyController struct {
apiserverConfigLister configv1listers.APIServerLister
kubeClient kubernetes.Interface
operatorClient v1helpers.OperatorClient
targetNamespace, targetConfigMapName string
}
// NewAuditPolicyController create a controller that watches the config.openshift.io/v1 APIServer object
// and reconciles a ConfigMap in the target namespace with the audit.k8s.io/v1 policy.yaml file.
func NewAuditPolicyController(
targetNamespace string,
targetConfigMapName string,
apiserverConfigLister configv1listers.APIServerLister,
operatorClient v1helpers.OperatorClient,
kubeClient kubernetes.Interface,
configInformers configinformers.SharedInformerFactory,
kubeInformersForTargetNamesace kubeinformers.SharedInformerFactory,
eventRecorder events.Recorder,
) factory.Controller {
c := &auditPolicyController{
operatorClient: operatorClient,
apiserverConfigLister: apiserverConfigLister,
kubeClient: kubeClient,
targetNamespace: targetNamespace,
targetConfigMapName: targetConfigMapName,
}
return factory.New().WithSync(c.sync).ResyncEvery(10*time.Second).WithInformers(
configInformers.Config().V1().APIServers().Informer(),
kubeInformersForTargetNamesace.Core().V1().ConfigMaps().Informer(),
operatorClient.Informer(),
).ToController("auditPolicyController", eventRecorder.WithComponentSuffix("audit-policy-controller"))
}
func (c *auditPolicyController) sync(ctx context.Context, syncCtx factory.SyncContext) error {
operatorConfigSpec, _, _, err := c.operatorClient.GetOperatorState()
if err != nil {
return err
}
switch operatorConfigSpec.ManagementState {
case operatorsv1.Managed:
case operatorsv1.Unmanaged:
return nil
case operatorsv1.Removed:
return c.kubeClient.CoreV1().ConfigMaps(c.targetNamespace).Delete(ctx, c.targetConfigMapName, metav1.DeleteOptions{})
default:
syncCtx.Recorder().Warningf("ManagementStateUnknown", "Unrecognized operator management state %q", operatorConfigSpec.ManagementState)
return nil
}
config, err := c.apiserverConfigLister.Get("cluster")
if err != nil {
return err
}
err = c.syncAuditPolicy(ctx, config.Spec.Audit, syncCtx.Recorder())
// update failing condition
cond := operatorv1.OperatorCondition{
Type: "AuditPolicyDegraded",
Status: operatorv1.ConditionFalse,
}
if err != nil {
cond.Status = operatorv1.ConditionTrue
cond.Reason = "Error"
cond.Message = err.Error()
}
if _, _, updateError := v1helpers.UpdateStatus(ctx, c.operatorClient, v1helpers.UpdateConditionFn(cond)); updateError != nil {
if err == nil {
return updateError
}
}
return err
}
func (c *auditPolicyController) syncAuditPolicy(ctx context.Context, config configv1.Audit, recorder events.Recorder) error {
desired, err := audit.GetAuditPolicy(config)
if err != nil {
return err
}
desired = desired.DeepCopy()
desired.Kind = "Policy"
desired.APIVersion = auditv1.SchemeGroupVersion.String()
bs, err := yaml.Marshal(desired)
if err != nil {
return err
}
cm := &v1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Namespace: c.targetNamespace,
Name: c.targetConfigMapName,
},
Data: map[string]string{
"policy.yaml": string(bs),
},
}
_, _, err = resourceapply.ApplyConfigMap(ctx, c.kubeClient.CoreV1(), recorder, cm)
return err
}