Skip to content

Commit 5f7c14e

Browse files
Merge branch 'kubernetes-sigs:main' into extra
2 parents 3ff9cf7 + 1c20504 commit 5f7c14e

File tree

1,219 files changed

+73877
-53893
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,219 files changed

+73877
-53893
lines changed

Dockerfile.ubi

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
# for more details
1919

2020
# hash below referred to latest
21-
FROM registry.access.redhat.com/ubi8/go-toolset@sha256:f28b875248f01fec44db5a5a0d842c89540c702144b341ee826d336bed5edaca AS build
21+
FROM registry.access.redhat.com/ubi8/go-toolset@sha256:621eebfdfc044df4bd4b50ec11f8791bc68986a7b0aa00089777b17bd2e9c751 AS build
2222
USER root
2323
WORKDIR /work
2424

@@ -45,7 +45,7 @@ ARG STATIC_LINK=no
4545
RUN make
4646

4747
# hash below referred to latest
48-
FROM registry.access.redhat.com/ubi9/ubi-minimal@sha256:92b1d5747a93608b6adb64dfd54515c3c5a360802db4706765ff3d8470df6290
48+
FROM registry.access.redhat.com/ubi9/ubi-minimal@sha256:11db23b63f9476e721f8d0b8a2de5c858571f76d5a0dae2ec28adf08cbaf3652
4949
ARG version
5050
USER root
5151

api/spod/v1alpha1/spod_types.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,24 @@ type JsonEnricherOptions struct {
246246
// within this interval are grouped together. The default is 60 seconds.
247247
// Increasing this interval will reduce the rate at which logs are written.
248248
AuditLogIntervalSeconds int32 `json:"auditLogIntervalSeconds,omitempty"`
249+
250+
// This field specifies the path for the accumulated audit log data.
251+
// The audit log will be written to this file in JSON format if a file path
252+
// is provided. If left unspecified, the output will be directed to
253+
// standard output (stdout).
254+
AuditLogPath *string `json:"auditLogPath,omitempty"`
255+
256+
// This field specifies the maximum number of audit log files to retain.
257+
// If left unspecified it defaults to 100 MB.
258+
AuditLogMaxSize *int32 `json:"auditLogMaxSize,omitempty"`
259+
260+
// This field specifies the maximum size in megabytes of the audit log file before it gets rotated.
261+
// The default is to retain all old log files (though MaxAge may still cause them to get deleted.)
262+
AuditLogMaxBackups *int32 `json:"auditLogMaxBackups,omitempty"`
263+
264+
// This field specifies the maximum number of days to retain old audit log files
265+
// The default is not to remove old log files based on age
266+
AuditLogMaxAge *int32 `json:"auditLogMaxAge,omitempty"`
249267
}
250268

251269
type WebhookOptions struct {
@@ -347,6 +365,18 @@ type SPODSpec struct {
347365
// artifact signature verification.
348366
// +optional
349367
DisableOCIArtifactSignatureVerification bool `json:"disableOciArtifactSignatureVerification"`
368+
369+
// LogEnricherFilters if defined, an optional JSON-format filter to determine if log lines should be emitted
370+
// for the log-enricher. Defaults to an empty string, meaning no filter is applied and all lines are logged.
371+
// +optional
372+
// +kubebuilder:default=""
373+
LogEnricherFilters string `json:"logEnricherFilters,omitempty"`
374+
375+
// JsonEnricherFilters if defined, an optional JSON-format filter to determine if log lines should be emitted
376+
// for the json-enricher. Defaults to an empty string, meaning no filter is applied and all lines are logged.
377+
// +optional
378+
// +kubebuilder:default=""
379+
JsonEnricherFilters string `json:"jsonEnricherFilters,omitempty"`
350380
}
351381

352382
// SPODState defines the state that the spod is in.

api/spod/v1alpha1/zz_generated.deepcopy.go

Lines changed: 21 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bundle/manifests/security-profiles-operator-profile_v1_configmap.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
apiVersion: v1
22
data:
3+
json-enricher-log-volume-source.json: |
4+
{
5+
"emptyDir": {
6+
"sizeLimit": "500Mi"
7+
}
8+
}
39
bpf-recorder.json: |
410
{
511
"defaultAction": "SCMP_ACT_ERRNO",

cmd/security-profiles-operator/main.go

Lines changed: 139 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,10 @@ import (
2626
_ "net/http/pprof" //nolint:gosec // required for profiling
2727
"os"
2828
"os/exec"
29+
"os/signal"
2930
"strconv"
3031
"strings"
32+
"syscall"
3133
"time"
3234

3335
certmanagerv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1"
@@ -73,25 +75,31 @@ import (
7375
"sigs.k8s.io/security-profiles-operator/internal/pkg/util"
7476
"sigs.k8s.io/security-profiles-operator/internal/pkg/version"
7577
"sigs.k8s.io/security-profiles-operator/internal/pkg/webhooks/binding"
78+
"sigs.k8s.io/security-profiles-operator/internal/pkg/webhooks/execmetadata"
7679
"sigs.k8s.io/security-profiles-operator/internal/pkg/webhooks/recording"
7780
)
7881

7982
const (
80-
spocCmd string = "spoc"
81-
jsonFlag string = "json"
82-
nodeStatusControllerFlag string = "with-nodestatus-controller"
83-
spodControllerFlag string = "with-spod-controller"
84-
workloadAnnotatorFlag string = "with-workload-annotator"
85-
recordingMergerFlag string = "with-recording-merger"
86-
recordingFlag string = "with-recording"
87-
seccompFlag string = "with-seccomp"
88-
selinuxFlag string = "with-selinux"
89-
apparmorFlag string = "with-apparmor"
90-
webhookFlag string = "webhook"
91-
memOptimFlag string = "with-mem-optim"
92-
defaultWebhookPort int = 9443
93-
auditLogIntervalSecondsParam string = "audit-log-interval-seconds"
94-
defaultAuditLogFlushIntervalSeconds int = 60
83+
spocCmd string = "spoc"
84+
jsonFlag string = "json"
85+
nodeStatusControllerFlag string = "with-nodestatus-controller"
86+
spodControllerFlag string = "with-spod-controller"
87+
workloadAnnotatorFlag string = "with-workload-annotator"
88+
recordingMergerFlag string = "with-recording-merger"
89+
recordingFlag string = "with-recording"
90+
seccompFlag string = "with-seccomp"
91+
selinuxFlag string = "with-selinux"
92+
apparmorFlag string = "with-apparmor"
93+
webhookFlag string = "webhook"
94+
memOptimFlag string = "with-mem-optim"
95+
defaultWebhookPort int = 9443
96+
auditLogIntervalSecondsParam string = "audit-log-interval-seconds"
97+
auditLogPathParam string = "audit-log-path"
98+
auditLogMaxSizeParam string = "audit-log-maxsize"
99+
// The plural form is not used for audit-log-file-maxbackup to match the k8s api server audit log options.
100+
auditLogMaxBackupParam string = "audit-log-maxbackup"
101+
auditLogMaxAgeParam string = "audit-log-maxage"
102+
enricherFiltersJsonParam string = "enricher-filters-json"
95103
)
96104

97105
var (
@@ -100,6 +108,21 @@ var (
100108
)
101109

102110
func main() {
111+
// This is required to close any open resource like a file
112+
mainctx, cancel := context.WithCancel(context.Background())
113+
defer cancel()
114+
115+
sigChan := make(chan os.Signal, 1)
116+
117+
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
118+
119+
go func() {
120+
sig := <-sigChan
121+
// No logger may be available hence using fmt
122+
fmt.Printf("\nReceived OS signal: %s. Initiating graceful shutdown...\n", sig)
123+
cancel()
124+
}()
125+
103126
app, info := cmd.DefaultApp()
104127
app.Name = config.OperatorName
105128
app.Usage = "Kubernetes Security Profiles Operator"
@@ -231,6 +254,13 @@ func main() {
231254
Name: "log-enricher",
232255
Aliases: []string{"l"},
233256
Usage: "run the audit's log enricher",
257+
Flags: []cli.Flag{
258+
&cli.StringFlag{
259+
Name: enricherFiltersJsonParam,
260+
Value: "",
261+
Usage: "Log Enricher filters JSON.",
262+
},
263+
},
234264
Action: func(ctx *cli.Context) error {
235265
return runLogEnricher(ctx, info)
236266
},
@@ -241,13 +271,61 @@ func main() {
241271
Aliases: []string{"j"},
242272
Usage: "run the audit's json enricher",
243273
Action: func(ctx *cli.Context) error {
244-
return runJsonEnricher(ctx, info)
274+
jsonEnricher, err := getJsonEnricher(ctx, info)
275+
if err != nil {
276+
return fmt.Errorf("could not create json enricher: %w", err)
277+
}
278+
279+
runErr := make(chan error)
280+
go jsonEnricher.Run(mainctx, runErr)
281+
282+
select {
283+
case <-runErr:
284+
return fmt.Errorf("error while executing JSON Enricher: %w", <-runErr)
285+
case <-mainctx.Done():
286+
// Cannot use CLI "After" as exit signal won't invoke it
287+
fmt.Printf("Exit JSON Enricher")
288+
jsonEnricher.ExitJsonEnricher(ctx)
289+
290+
return nil
291+
}
245292
},
246293
Flags: []cli.Flag{
247294
&cli.IntFlag{
248295
Name: auditLogIntervalSecondsParam,
249296
Aliases: []string{"a"},
250-
Usage: "Audit log interval in seconds for the JSON Log Enricher",
297+
Value: 60,
298+
Usage: "Audit log interval in seconds for the JSON Log Enricher.",
299+
},
300+
&cli.StringFlag{
301+
Name: auditLogPathParam,
302+
Value: "",
303+
Usage: "Audit log file path for the JSON Log Enricher. Default is stdout.",
304+
},
305+
&cli.IntFlag{
306+
Name: auditLogMaxBackupParam,
307+
Value: 0,
308+
Usage: "Audit log max file backup for the JSON Log Enricher. " +
309+
"The maximum number of old audit log files to retain. " +
310+
"Setting a value of 0 will mean there's no restriction on the number of files.",
311+
},
312+
&cli.IntFlag{
313+
Name: auditLogMaxSizeParam,
314+
Value: 100,
315+
Usage: "Audit log max file size for the JSON Log Enricher. " +
316+
"The maximum size in megabytes of the audit log file before it gets rotated.",
317+
},
318+
&cli.IntFlag{
319+
Name: auditLogMaxAgeParam,
320+
Value: 0,
321+
Usage: "Audit log max age for the JSON Log Enricher. " +
322+
"The maximum number of days to retain old audit log files based " +
323+
"on the timestamp encoded in their filename.",
324+
},
325+
&cli.StringFlag{
326+
Name: enricherFiltersJsonParam,
327+
Value: "",
328+
Usage: "JSON Enricher filters JSON file path.",
251329
},
252330
},
253331
},
@@ -293,8 +371,13 @@ func main() {
293371

294372
if err := app.Run(os.Args); err != nil {
295373
setupLog.Error(err, "running security-profiles-operator")
374+
//nolint:gocritic // this is intentional to return to correct exit code
296375
os.Exit(1)
297376
}
377+
378+
if err := app.RunContext(mainctx, os.Args); err != nil {
379+
fmt.Printf("application error: %v", err)
380+
}
298381
}
299382

300383
func initialize(ctx *cli.Context) error {
@@ -615,31 +698,60 @@ func runBPFRecorder(_ *cli.Context, info *version.Info) error {
615698
return bpfrecorder.New("", ctrl.Log.WithName(component), true, true).Run()
616699
}
617700

618-
func runLogEnricher(_ *cli.Context, info *version.Info) error {
701+
func runLogEnricher(ctx *cli.Context, info *version.Info) error {
619702
const component = "log-enricher"
620703

621704
printInfo(component, info)
622705

623-
return enricher.New(ctrl.Log.WithName(component)).Run()
706+
opts := &enricher.LogEnricherOptions{
707+
EnricherFiltersJson: ctx.String(enricherFiltersJsonParam),
708+
}
709+
710+
logEnricher, err := enricher.New(ctrl.Log.WithName(component), opts)
711+
if err != nil {
712+
return fmt.Errorf("create log enricher: %w", err)
713+
}
714+
715+
return logEnricher.Run()
624716
}
625717

626-
func runJsonEnricher(ctx *cli.Context, info *version.Info) error {
718+
func getJsonEnricher(ctx *cli.Context, info *version.Info) (*enricher.JsonEnricher, error) {
627719
const component = "json-enricher"
628720

629721
printInfo(component, info)
630722

631-
auditLogIntervalSeconds := ctx.Int(auditLogIntervalSecondsParam)
632-
if auditLogIntervalSeconds == 0 {
633-
auditLogIntervalSeconds = defaultAuditLogFlushIntervalSeconds
723+
opts := &enricher.JsonEnricherOptions{}
724+
725+
if auditLogIntervalSeconds := ctx.Int(auditLogIntervalSecondsParam); auditLogIntervalSeconds > 0 {
726+
opts.AuditFreq = time.Duration(auditLogIntervalSeconds) * time.Second
727+
}
728+
729+
if auditLogPath := ctx.String(auditLogPathParam); auditLogPath != "" {
730+
opts.AuditLogPath = auditLogPath
634731
}
635732

733+
opts.AuditLogMaxSize = ctx.Int(auditLogMaxSizeParam)
734+
opts.AuditLogMaxBackups = ctx.Int(auditLogMaxBackupParam)
735+
opts.AuditLogMaxAge = ctx.Int(auditLogMaxAgeParam)
736+
opts.EnricherFiltersJson = ctx.String(enricherFiltersJsonParam)
737+
636738
setupLog.Info(
637739
"JSON Enricher Configuration",
638-
"auditLogFlushIntervalSeconds", auditLogIntervalSeconds,
740+
"AuditFreq", opts.AuditFreq,
741+
"AuditLogPath", opts.AuditLogPath,
742+
"AuditLogMaxSize", opts.AuditLogMaxSize,
743+
"AuditLogMaxBackup", opts.AuditLogMaxBackups,
744+
"AuditLogMaxAge", opts.AuditLogMaxAge,
745+
"EnricherFiltersJson", opts.EnricherFiltersJson,
639746
)
640747

641-
return enricher.NewJsonEnricherArgs(ctrl.Log.WithName(component),
642-
time.Duration(auditLogIntervalSeconds)*time.Second).Run()
748+
jsonEnricher, err := enricher.NewJsonEnricherArgs(ctrl.Log.WithName(component),
749+
opts)
750+
if err != nil {
751+
return nil, err
752+
}
753+
754+
return jsonEnricher, nil
643755
}
644756

645757
func runNonRootEnabler(ctx *cli.Context, info *version.Info) error {
@@ -724,6 +836,7 @@ func runWebhook(ctx *cli.Context, info *version.Info) error {
724836
hookserver := mgr.GetWebhookServer()
725837
binding.RegisterWebhook(hookserver, mgr.GetScheme(), mgr.GetClient())
726838
recording.RegisterWebhook(hookserver, mgr.GetScheme(), mgr.GetEventRecorderFor("recording-webhook"), mgr.GetClient())
839+
execmetadata.RegisterWebhook(hookserver)
727840

728841
sigHandler := ctrl.SetupSignalHandler()
729842

0 commit comments

Comments
 (0)