Skip to content

Commit cb8d6ec

Browse files
authored
Merge pull request #290 from gardener/shoot_falco_rule_support
Shoot falco rule support
2 parents 53a363a + c23e2a4 commit cb8d6ec

14 files changed

Lines changed: 308 additions & 34 deletions

File tree

Makefile

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,6 @@ start-admission:
6464
--webhook-config-mode=$(WEBHOOK_CONFIG_MODE) \
6565
--health-bind-address=:8082 \
6666
--metrics-bind-address=:8083 \
67-
--restricted-usage \
68-
--restricted-centralized-logging \
6967
--autonomous-shoot-cluster=false \
7068
$(WEBHOOK_PARAM)
7169

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.66.0-dev
1+
v0.66.0-dev

charts/internal/falco/templates/0helpers.tpl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,8 @@ Set appropriate falco rule configuration if rules are managed by the Gardener ex
184184
{{- $rulesFile := printf "%s%s" "/etc/falco/rules.d/" $customRule.filename }}
185185
{{- $rulesFileList = append $rulesFileList $rulesFile }}
186186
{{- end }}
187-
{{- $_ := set .Values.falco "rules_files" $rulesFileList }}
187+
{{ $allRules := concat $rulesFileList .Values.rules_files_source }}
188+
{{- $_ := set .Values.falco "rules_files" $allRules }}
188189
{{- end -}}
189190

190191
{{/*

charts/internal/falco/templates/falco-pod-template.tpl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,10 @@ spec:
223223
- mountPath: /etc/falco/rules.d
224224
name: rules-volume
225225
readOnly: true
226+
{{- range $rulesConfigMap := $.Values.shoot_custom_rules }}
227+
- mountPath: {{ printf "/etc/falco/shoot-custom-rules/%s" $rulesConfigMap.name }}
228+
name: {{ printf "shoot-custom-rules-%s" $rulesConfigMap.name }}
229+
{{- end }}
226230
{{- if .Values.heartbeatRule }}
227231
- name: falco-heartbeat
228232
image: {{ include "falcoheartbeat.image" . }}
@@ -366,6 +370,14 @@ spec:
366370
- configMap:
367371
name: falco-custom-rules
368372
{{- end }}
373+
{{- range $rulesConfigMap := $.Values.shoot_custom_rules }}
374+
- name: {{ printf "shoot-custom-rules-%s" $rulesConfigMap.name }}
375+
projected:
376+
defaultMode: 0644
377+
sources:
378+
- configMap:
379+
name: {{ $rulesConfigMap.name }}
380+
{{- end }}
369381
{{- if or .Values.certs.existingSecret (and .Values.certs.server.key .Values.certs.server.crt .Values.certs.ca.crt) }}
370382
- name: certs-volume
371383
secret:

charts/internal/falco/values.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1661,3 +1661,9 @@ gardenerExtensionShootFalcoService:
16611661
output:
16621662
# -- Configure the destination of Falco events (e.g. central, cluster, custom, none)
16631663
eventCollector: "logging"
1664+
1665+
# name of configmaps in shoot cluster with Falco custom rules
1666+
shoot_custom_rules: []
1667+
1668+
# directories where shoot cluster Falco rules are mounted
1669+
rules_files_source: []

hack/api-reference/service.md

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,8 @@ Rules
106106
<td>
107107
<code>destinations</code></br>
108108
<em>
109-
<a href="#falco.extensions.gardener.cloud/v1alpha1.[]..Destination">
110-
[]..Destination
109+
<a href="#falco.extensions.gardener.cloud/v1alpha1.[]github.com/gardener/gardener-extension-shoot-falco-service/pkg/apis/service/v1alpha1.Destination">
110+
[]github.com/gardener/gardener-extension-shoot-falco-service/pkg/apis/service/v1alpha1.Destination
111111
</a>
112112
</em>
113113
</td>
@@ -138,6 +138,16 @@ string
138138
<td>
139139
</td>
140140
</tr>
141+
<tr>
142+
<td>
143+
<code>shootConfigMap</code></br>
144+
<em>
145+
string
146+
</em>
147+
</td>
148+
<td>
149+
</td>
150+
</tr>
141151
</tbody>
142152
</table>
143153
<h3 id="falco.extensions.gardener.cloud/v1alpha1.Destination">Destination
@@ -486,8 +496,8 @@ Webhook
486496
<td>
487497
<code>custom</code></br>
488498
<em>
489-
<a href="#falco.extensions.gardener.cloud/v1alpha1.[]..CustomRule">
490-
[]..CustomRule
499+
<a href="#falco.extensions.gardener.cloud/v1alpha1.[]github.com/gardener/gardener-extension-shoot-falco-service/pkg/apis/service/v1alpha1.CustomRule">
500+
[]github.com/gardener/gardener-extension-shoot-falco-service/pkg/apis/service/v1alpha1.CustomRule
491501
</a>
492502
</em>
493503
</td>

pkg/admission/mutator/shoot_mutator_test.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,45 @@ var (
277277
]
278278
}`
279279

280+
// shoot custom rules are not mutated
281+
mutate10 = `
282+
{
283+
"apiVersion": "falco.extensions.gardener.cloud/v1alpha1",
284+
"kind": "FalcoServiceConfig",
285+
"falcoVersion": "0.100.0",
286+
"rules": {
287+
"custom": [
288+
{
289+
"resourceName": "dummy-custom-rules-ref"
290+
}, {
291+
"shootConfigMap": "my-shoot-rules"
292+
}
293+
]
294+
}
295+
}`
296+
297+
expectedMutate10 = `
298+
{
299+
"kind":"FalcoServiceConfig",
300+
"apiVersion":"falco.extensions.gardener.cloud/v1alpha1",
301+
"falcoVersion":"0.100.0",
302+
"autoUpdate": true,
303+
"rules": {
304+
"custom": [
305+
{
306+
"resourceName": "dummy-custom-rules-ref"
307+
}, {
308+
"shootConfigMap": "my-shoot-rules"
309+
}
310+
]
311+
},
312+
"destinations": [
313+
{
314+
"name": "logging"
315+
}
316+
]
317+
}`
318+
280319
genericEmptyConf = &gardencorev1beta1.Shoot{
281320
Spec: gardencorev1beta1.ShootSpec{
282321
Extensions: []gardencorev1beta1.Extension{
@@ -706,5 +745,9 @@ var _ = Describe("Test mutator", Label("mutator"), func() {
706745
result = genericShoot.Spec.Extensions[0].ProviderConfig.Raw
707746
Expect(result).To(MatchJSON(expectedMutate9), "Mutator did not return expected result")
708747

748+
err = f(mutate10)
749+
Expect(err).To(BeNil(), "Mutator failed", err)
750+
result = genericShoot.Spec.Extensions[0].ProviderConfig.Raw
751+
Expect(result).To(MatchJSON(expectedMutate10), "Mutator did not return expected result")
709752
})
710753
})

pkg/admission/validator/shoot_validator.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -216,16 +216,24 @@ func verifyStandardRules(standardRules []string) error {
216216
func verifyCustomRules(customRules []service.CustomRule, shoot *core.Shoot) error {
217217
customRulesNames := make([]string, 0)
218218
for _, rule := range customRules {
219-
if rule.ResourceName == "" {
220-
return fmt.Errorf("found custom rule with empty resource referece")
219+
if rule.ResourceName != "" && rule.ShootConfigMap != "" {
220+
return fmt.Errorf("found custom rule with both resource name and shoot config map defined")
221+
} else if rule.ResourceName == "" && rule.ShootConfigMap == "" {
222+
return fmt.Errorf("found custom rule with neither resource name nor shoot config map defined")
223+
}
224+
if rule.ResourceName != "" {
225+
customRulesNames = append(customRulesNames, rule.ResourceName)
221226
}
222-
customRulesNames = append(customRulesNames, rule.ResourceName)
223227
}
224228

225229
if !unique(customRulesNames) {
226230
return fmt.Errorf("duplicate entry in custom rules")
227231
}
228232

233+
// note: we only verify rules defined in the shoot spec. we do not
234+
// verify custom rules stored in the shoot cluster
235+
// the reason is that the admission controller should not attempt to
236+
// contact the shoot cluster to verify the rules.
229237
for _, ruleName := range customRulesNames {
230238
found := false
231239
for _, r := range shoot.Spec.Resources {

pkg/admission/validator/shoot_validator_test.go

Lines changed: 115 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,58 @@ var (
194194
]
195195
}`
196196

197+
falcoExtensionwithShootRules1 = `
198+
{
199+
"apiVersion": "falco.extensions.gardener.cloud/v1alpha1",
200+
"kind": "FalcoServiceConfig",
201+
"falcoVersion": "1.2.3",
202+
"rules": {
203+
"custom": [
204+
{
205+
"resourceName": "dummy-custom-rules-ref"
206+
}, {
207+
"shootConfigMap": "my-shoot-rules"
208+
}
209+
]
210+
},
211+
"destinations": [
212+
{
213+
"name": "stdout"
214+
},
215+
{
216+
"name": "custom",
217+
"resourceSecretName": "my-custom-webhook-ref"
218+
}
219+
]
220+
}`
221+
222+
// legal
223+
falcoExtensionwithShootRules2 = `
224+
{
225+
"apiVersion": "falco.extensions.gardener.cloud/v1alpha1",
226+
"kind": "FalcoServiceConfig",
227+
"falcoVersion": "1.2.3",
228+
"rules": {
229+
"custom": [
230+
{
231+
"resourceName": "dummy-custom-rules-ref",
232+
"shootConfigMap": ""
233+
}, {
234+
"shootConfigMap": "my-shoot-rules"
235+
}
236+
]
237+
},
238+
"destinations": [
239+
{
240+
"name": "stdout"
241+
},
242+
{
243+
"name": "custom",
244+
"resourceSecretName": "my-custom-webhook-ref"
245+
}
246+
]
247+
}`
248+
197249
falcoExtensionIllegalNoDestination = `
198250
{
199251
"apiVersion": "falco.extensions.gardener.cloud/v1alpha1",
@@ -335,6 +387,53 @@ var (
335387
"kind":"dFalcoServiceConfig",
336388
"autoUpdate":true
337389
}`
390+
391+
falcoExtensionIllegalWrongCustomRule1 = `
392+
{
393+
"apiVersion":"falco.extensions.gardener.cloud/v1alpha1",
394+
"kind": "FalcoServiceConfig",
395+
"autoUpdate":true,
396+
"falcoVersion":"1.2.3",
397+
"rules": {
398+
"standard": [
399+
"falco-rules"
400+
],
401+
"custom": [
402+
{
403+
"shootConfigMap": ""
404+
}
405+
]
406+
},
407+
"destinations": [
408+
{
409+
"name": "stdout"
410+
}
411+
]
412+
}`
413+
414+
falcoExtensionIllegalWrongCustomRule2 = `
415+
{
416+
"apiVersion":"falco.extensions.gardener.cloud/v1alpha1",
417+
"kind": "FalcoServiceConfig",
418+
"autoUpdate":true,
419+
"falcoVersion":"1.2.3",
420+
"rules": {
421+
"standard": [
422+
"falco-rules"
423+
],
424+
"custom": [
425+
{
426+
"resourceName": "dummy-custom-rules-ref",
427+
"shootConfigMap": "dummy-config-map"
428+
}
429+
]
430+
},
431+
"destinations": [
432+
{
433+
"name": "stdout"
434+
}
435+
]
436+
}`
338437
)
339438

340439
func init() {
@@ -720,6 +819,12 @@ var _ = Describe("Test validator", Label("falcovalues"), func() {
720819

721820
err = f(falcoExtensionCustomWebookCustomRules)
722821
Expect(err).To(BeNil(), "Legal extension is not detected as such")
822+
823+
err = f(falcoExtensionwithShootRules1)
824+
Expect(err).To(BeNil(), "Legal extension is not detected as such")
825+
826+
err = f(falcoExtensionwithShootRules2)
827+
Expect(err).To(BeNil(), "Legal extension is not detected as such")
723828
})
724829

725830
It("verify illegal extensions", func(ctx SpecContext) {
@@ -762,11 +867,19 @@ var _ = Describe("Test validator", Label("falcovalues"), func() {
762867

763868
err = f(falcoExtensionIllegalCustomRuleWithoutRef)
764869
Expect(err).To(Not(BeNil()), "Illegal extension is not detected as such")
765-
Expect(err.Error()).To(ContainSubstring("found custom rule with empty resource referece"), "Illegal extension is not detected as such ")
870+
Expect(err.Error()).To(ContainSubstring("found custom rule with neither resource name nor shoot config map defined"), "Illegal extension is not detected as such ")
766871

767872
err = f(falcoExtensionIllegal7)
768873
Expect(err).To(Not(BeNil()), "Illegal extension is not detected as such")
769-
Expect(err.Error()).To(ContainSubstring("failed to decode shoot-falco-service provider confi"), "Illegal extension is not detected as such ")
874+
Expect(err.Error()).To(ContainSubstring("failed to decode shoot-falco-service provider config"), "Illegal extension is not detected as such ")
875+
876+
err = f(falcoExtensionIllegalWrongCustomRule1)
877+
Expect(err).To(Not(BeNil()), "Illegal extension is not detected as such")
878+
Expect(err.Error()).To(ContainSubstring("found custom rule with neither resource name nor shoot config map defined"), "Illegal extension is not detected as such ")
879+
880+
err = f(falcoExtensionIllegalWrongCustomRule2)
881+
Expect(err).To(Not(BeNil()), "Illegal extension is not detected as such")
882+
Expect(err.Error()).To(ContainSubstring("found custom rule with both resource name and shoot config map defined"), "Illegal extension is not detected as such ")
770883
})
771884

772885
It("checks if central logging is enabled", func(ctx SpecContext) {

pkg/apis/service/types.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ type Rules struct {
4545
}
4646

4747
type CustomRule struct {
48-
ResourceName string
48+
ResourceName string
49+
ShootConfigMap string
4950
}
5051

5152
type FalcoCtl struct {

0 commit comments

Comments
 (0)