4
4
package common
5
5
6
6
import (
7
+ "context"
7
8
"fmt"
8
9
"strings"
9
10
10
11
corev1 "k8s.io/api/core/v1"
12
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
13
+ "k8s.io/client-go/kubernetes"
11
14
)
12
15
13
16
const k8sVisibility = "process,file,network,capabilities"
14
17
const appArmorAnnotation = "container.apparmor.security.beta.kubernetes.io/"
15
- const KubeArmorRestartedAnnotation = "kubearmor.io/restarted"
16
- const KubeArmorForceAppArmorAnnotation = "kubearmor.io/force-apparmor"
18
+ const KubeArmorRestartedAnnotation = "kubearmor.kubernetes.io/restartedAt"
17
19
18
20
// == Add AppArmor annotations == //
19
- func AppArmorAnnotator (pod * corev1.Pod ) {
21
+ func AppArmorAnnotator (pod * corev1.Pod , binding * corev1. Binding , isBinding bool ) {
20
22
podAnnotations := map [string ]string {}
21
23
var podOwnerName string
22
24
@@ -64,52 +66,57 @@ func AppArmorAnnotator(pod *corev1.Pod) {
64
66
if v == "unconfined" {
65
67
continue
66
68
}
67
- pod .Annotations [appArmorAnnotation + k ] = "localhost/" + v
69
+ if isBinding {
70
+ binding .Annotations [appArmorAnnotation + k ] = "localhost/" + v
71
+ } else {
72
+ pod .Annotations [appArmorAnnotation + k ] = "localhost/" + v
73
+ }
68
74
}
69
75
}
70
- func AddCommonAnnotations (pod * corev1.Pod ) {
71
- if pod .Annotations == nil {
72
- pod .Annotations = map [string ]string {}
76
+ func AddCommonAnnotations (obj * metav1.ObjectMeta ) {
77
+
78
+ if obj .Annotations == nil {
79
+ obj .Annotations = map [string ]string {}
73
80
}
74
81
75
82
// == Policy == //
76
83
77
- if _ , ok := pod .Annotations ["kubearmor-policy" ]; ! ok {
84
+ if _ , ok := obj .Annotations ["kubearmor-policy" ]; ! ok {
78
85
// if no annotation is set enable kubearmor by default
79
- pod .Annotations ["kubearmor-policy" ] = "enabled"
80
- } else if pod .Annotations ["kubearmor-policy" ] != "enabled" && pod .Annotations ["kubearmor-policy" ] != "disabled" && pod .Annotations ["kubearmor-policy" ] != "audited" {
86
+ obj .Annotations ["kubearmor-policy" ] = "enabled"
87
+ } else if obj .Annotations ["kubearmor-policy" ] != "enabled" && obj .Annotations ["kubearmor-policy" ] != "disabled" && obj .Annotations ["kubearmor-policy" ] != "audited" {
81
88
// if kubearmor policy is not set correctly, default it to enabled
82
- pod .Annotations ["kubearmor-policy" ] = "enabled"
89
+ obj .Annotations ["kubearmor-policy" ] = "enabled"
83
90
}
84
91
// == Exception == //
85
92
86
93
// exception: kubernetes app
87
- if pod .Namespace == "kube-system" {
88
- if _ , ok := pod .Labels ["k8s-app" ]; ok {
89
- pod .Annotations ["kubearmor-policy" ] = "audited"
94
+ if obj .Namespace == "kube-system" {
95
+ if _ , ok := obj .Labels ["k8s-app" ]; ok {
96
+ obj .Annotations ["kubearmor-policy" ] = "audited"
90
97
}
91
98
92
- if value , ok := pod .Labels ["component" ]; ok {
99
+ if value , ok := obj .Labels ["component" ]; ok {
93
100
if value == "etcd" || value == "kube-apiserver" || value == "kube-controller-manager" || value == "kube-scheduler" || value == "kube-proxy" {
94
- pod .Annotations ["kubearmor-policy" ] = "audited"
101
+ obj .Annotations ["kubearmor-policy" ] = "audited"
95
102
}
96
103
}
97
104
}
98
105
99
106
// exception: cilium-operator
100
- if _ , ok := pod .Labels ["io.cilium/app" ]; ok {
101
- pod .Annotations ["kubearmor-policy" ] = "audited"
107
+ if _ , ok := obj .Labels ["io.cilium/app" ]; ok {
108
+ obj .Annotations ["kubearmor-policy" ] = "audited"
102
109
}
103
110
104
111
// exception: kubearmor
105
- if _ , ok := pod .Labels ["kubearmor-app" ]; ok {
106
- pod .Annotations ["kubearmor-policy" ] = "audited"
112
+ if _ , ok := obj .Labels ["kubearmor-app" ]; ok {
113
+ obj .Annotations ["kubearmor-policy" ] = "audited"
107
114
}
108
115
109
116
// == Visibility == //
110
117
111
- if _ , ok := pod .Annotations ["kubearmor-visibility" ]; ! ok {
112
- pod .Annotations ["kubearmor-visibility" ] = k8sVisibility
118
+ if _ , ok := obj .Annotations ["kubearmor-visibility" ]; ! ok {
119
+ obj .Annotations ["kubearmor-visibility" ] = k8sVisibility
113
120
}
114
121
}
115
122
@@ -125,3 +132,64 @@ func RemoveApparmorAnnotation(pod *corev1.Pod) {
125
132
delete (pod .Annotations , key )
126
133
}
127
134
}
135
+
136
+ func CheckKubearmorStatus (nodeName string , c * kubernetes.Clientset ) (bool , error ) {
137
+ pods , err := c .CoreV1 ().Pods ("kubearmor" ).List (context .TODO (), metav1.ListOptions {
138
+ LabelSelector : "kubearmor-app=kubearmor" ,
139
+ })
140
+ if err != nil {
141
+ return false , fmt .Errorf ("failed to list pods: %v" , err )
142
+ }
143
+ // Filter Pods by nodeName and return their status.phase
144
+ for _ , pod := range pods .Items {
145
+ if pod .Spec .NodeName == nodeName {
146
+ return true , nil
147
+ }
148
+ }
149
+
150
+ return false , nil
151
+
152
+ }
153
+ func hasApparmorAnnotation (annotations map [string ]string ) bool {
154
+ for key := range annotations {
155
+ if strings .HasPrefix (key , "container.apparmor.security.beta.kubernetes.io/" ) {
156
+ return true
157
+ }
158
+ }
159
+ return false
160
+ }
161
+
162
+ func HandleAppArmor (annotations map [string ]string ) bool {
163
+ return ! hasApparmorAnnotation (annotations )
164
+ }
165
+
166
+ func HandleBPF (annotations map [string ]string ) bool {
167
+ return hasApparmorAnnotation (annotations )
168
+ }
169
+
170
+ func IsAppArmorExempt (labels map [string ]string , namespace string ) bool {
171
+
172
+ // exception: kubernetes app
173
+ if namespace == "kube-system" {
174
+ if _ , ok := labels ["k8s-app" ]; ok {
175
+ return true
176
+ }
177
+
178
+ if value , ok := labels ["component" ]; ok {
179
+ if value == "etcd" || value == "kube-apiserver" || value == "kube-controller-manager" || value == "kube-scheduler" || value == "kube-proxy" {
180
+ return true
181
+ }
182
+ }
183
+ }
184
+
185
+ // exception: cilium-operator
186
+ if _ , ok := labels ["io.cilium/app" ]; ok {
187
+ return true
188
+ }
189
+
190
+ // exception: kubearmor
191
+ if _ , ok := labels ["kubearmor-app" ]; ok {
192
+ return true
193
+ }
194
+ return false
195
+ }
0 commit comments