ROX-33022: configure fact on policy sync#19089
ROX-33022: configure fact on policy sync#19089Stringy wants to merge 3 commits intogiles/ROX-33018-wildcard-support-for-pathsstackrox/stackrox:giles/ROX-33018-wildcard-support-for-pathsfrom giles/ROX-33022-configure-fact-from-policiesstackrox/stackrox:giles/ROX-33022-configure-fact-from-policiesCopy head branch name to clipboard
Conversation
|
Skipping CI for Draft Pull Request. |
There was a problem hiding this comment.
Hey - I've found 2 issues, and left some high level feedback:
- In
settingsManager.settingsToConfigMap,settingsis dereferenced before checking for nil (settings.GetClusterConfig()etc. thenif settings == nil || ...), which can panic; checksettingsfor nil before any method calls. - The new generic
configmapPersisterstill logs admission-controller-specific messages ("Could not apply admission controller config map"); consider usingp.namein the log text so it is accurate for all callers. - In
filesystem.settingsToConfigMap, the error log message saysfailed to unmarshal fact settingseven though it is marshaling; update the message (and consider removing the unusedconfigMapPathsKeyconstant if it is not needed).
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `settingsManager.settingsToConfigMap`, `settings` is dereferenced before checking for nil (`settings.GetClusterConfig()` etc. then `if settings == nil || ...`), which can panic; check `settings` for nil before any method calls.
- The new generic `configmapPersister` still logs admission-controller-specific messages (`"Could not apply admission controller config map"`); consider using `p.name` in the log text so it is accurate for all callers.
- In `filesystem.settingsToConfigMap`, the error log message says `failed to unmarshal fact settings` even though it is marshaling; update the message (and consider removing the unused `configMapPathsKey` constant if it is not needed).
## Individual Comments
### Comment 1
<location> `sensor/common/admissioncontroller/settings_manager_impl.go:200-201` </location>
<code_context>
p.sensorEventsStream.Push(converted)
}
+
+func (p *settingsManager) settingsToConfigMap(settings *sensor.AdmissionControlSettings) (*v1.ConfigMap, error) {
+ clusterConfig := settings.GetClusterConfig()
+ enforcedDeployTimePolicies := settings.GetEnforcedDeployTimePolicies()
+ runtimePolicies := settings.GetRuntimePolicies()
</code_context>
<issue_to_address>
**issue (bug_risk):** Guard against nil `settings` before dereferencing it in `settingsToConfigMap`.
`settingsToConfigMap` dereferences `settings` (via `GetClusterConfig()` etc.) before checking for nil, which can panic if `pushSettings` (or any future caller) passes `nil`. Add a nil guard at the top of the function before any method calls on `settings`, e.g.:
```go
func (p *settingsManager) settingsToConfigMap(settings *sensor.AdmissionControlSettings) (*v1.ConfigMap, error) {
if settings == nil {
return nil, nil
}
clusterConfig := settings.GetClusterConfig()
enforcedDeployTimePolicies := settings.GetEnforcedDeployTimePolicies()
runtimePolicies := settings.GetRuntimePolicies()
if clusterConfig == nil || enforcedDeployTimePolicies == nil || runtimePolicies == nil {
return nil, nil
}
// ...
}
```
</issue_to_address>
### Comment 2
<location> `sensor/common/filesystem/settings_manager_impl.go:72-83` </location>
<code_context>
+ continue
+ }
+
+ booleanpolicy.ForEachValueWithFieldName(policy, fieldnames.FilePath, func(value string) bool {
+ idx := strings.IndexFunc(value, func(r rune) bool {
+ return strings.ContainsRune("*?[]{}", r)
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Avoid adding empty path prefixes when policy file paths start with glob characters.
In `extractFileActivityPaths`, when the first glob is at index 0 (e.g., `"*.conf"`, `"**/foo"`), `value[:idx]` is `""` and gets added to `paths`. That empty string is not a valid path and will leak into FactSettings/config.
Consider skipping empty prefixes or falling back to the full value when the prefix is empty, for example:
```go
if idx < 0 {
paths.Add(value)
} else if prefix := value[:idx]; prefix != "" {
paths.Add(prefix)
}
```
This prevents empty entries in `paths`.
```suggestion
booleanpolicy.ForEachValueWithFieldName(policy, fieldnames.FilePath, func(value string) bool {
idx := strings.IndexFunc(value, func(r rune) bool {
return strings.ContainsRune("*?[]{}", r)
})
if idx < 0 {
paths.Add(value)
} else if prefix := value[:idx]; prefix != "" {
paths.Add(prefix)
}
return true
})
```
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| func (p *settingsManager) settingsToConfigMap(settings *sensor.AdmissionControlSettings) (*v1.ConfigMap, error) { | ||
| clusterConfig := settings.GetClusterConfig() |
There was a problem hiding this comment.
issue (bug_risk): Guard against nil settings before dereferencing it in settingsToConfigMap.
settingsToConfigMap dereferences settings (via GetClusterConfig() etc.) before checking for nil, which can panic if pushSettings (or any future caller) passes nil. Add a nil guard at the top of the function before any method calls on settings, e.g.:
func (p *settingsManager) settingsToConfigMap(settings *sensor.AdmissionControlSettings) (*v1.ConfigMap, error) {
if settings == nil {
return nil, nil
}
clusterConfig := settings.GetClusterConfig()
enforcedDeployTimePolicies := settings.GetEnforcedDeployTimePolicies()
runtimePolicies := settings.GetRuntimePolicies()
if clusterConfig == nil || enforcedDeployTimePolicies == nil || runtimePolicies == nil {
return nil, nil
}
// ...
}| booleanpolicy.ForEachValueWithFieldName(policy, fieldnames.FilePath, func(value string) bool { | ||
| idx := strings.IndexFunc(value, func(r rune) bool { | ||
| return strings.ContainsRune("*?[]{}", r) | ||
| }) | ||
|
|
||
| if idx < 0 { | ||
| paths.Add(value) | ||
| } else { | ||
| paths.Add(value[:idx]) | ||
| } | ||
| return true | ||
| }) |
There was a problem hiding this comment.
suggestion (bug_risk): Avoid adding empty path prefixes when policy file paths start with glob characters.
In extractFileActivityPaths, when the first glob is at index 0 (e.g., "*.conf", "**/foo"), value[:idx] is "" and gets added to paths. That empty string is not a valid path and will leak into FactSettings/config.
Consider skipping empty prefixes or falling back to the full value when the prefix is empty, for example:
if idx < 0 {
paths.Add(value)
} else if prefix := value[:idx]; prefix != "" {
paths.Add(prefix)
}This prevents empty entries in paths.
| booleanpolicy.ForEachValueWithFieldName(policy, fieldnames.FilePath, func(value string) bool { | |
| idx := strings.IndexFunc(value, func(r rune) bool { | |
| return strings.ContainsRune("*?[]{}", r) | |
| }) | |
| if idx < 0 { | |
| paths.Add(value) | |
| } else { | |
| paths.Add(value[:idx]) | |
| } | |
| return true | |
| }) | |
| booleanpolicy.ForEachValueWithFieldName(policy, fieldnames.FilePath, func(value string) bool { | |
| idx := strings.IndexFunc(value, func(r rune) bool { | |
| return strings.ContainsRune("*?[]{}", r) | |
| }) | |
| if idx < 0 { | |
| paths.Add(value) | |
| } else if prefix := value[:idx]; prefix != "" { | |
| paths.Add(prefix) | |
| } | |
| return true | |
| }) |
|
Images are ready for the commit at 31f2bb4. To use with deploy scripts, first |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## giles/ROX-33018-wildcard-support-for-paths #19089 +/- ##
==============================================================================
- Coverage 49.50% 49.48% -0.03%
==============================================================================
Files 2669 2669
Lines 201502 201568 +66
==============================================================================
- Hits 99761 99751 -10
- Misses 94292 94364 +72
- Partials 7449 7453 +4
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
871eae9 to
6fb5959
Compare
These changes allow for automatic configuration of Fact based on policies defined by the user. It constructs a set of path prefixes and writes them to a Fact ConfigMap, which is hot-reloaded by the Fact agent. This also includes a fairly significant refactor of the admission controller settings / config map persistence, so that there is a generic persistence component that can be initialized for specific settings (admission controller, and now Fact)
31f2bb4 to
5a8c65d
Compare
Description
These changes allow for automatic configuration of Fact based on policies defined by the user. It constructs a set of path prefixes and writes them to a Fact ConfigMap, which is hot-reloaded by the Fact agent.
This also includes a fairly significant refactor of the admission controller settings / config map persistence, so that there is a generic persistence component that can be initialized for specific settings (admission controller, and now Fact)
User-facing documentation
Testing and quality
Automated testing
How I validated my change
change me!