Skip to content

ROX-34167: make compliance scan node roles configurable#21825

Draft
guzalv wants to merge 1 commit into
masterfrom
gualvare/rox-34167-configurable-node-roles
Draft

ROX-34167: make compliance scan node roles configurable#21825
guzalv wants to merge 1 commit into
masterfrom
gualvare/rox-34167-configurable-node-roles

Conversation

@guzalv

@guzalv guzalv commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Description

ACS previously hardcoded ["master", "worker"] as node roles in every ScanSetting it generated for the Compliance Operator. This prevented scanning nodes with custom roles (e.g., infra, control-plane, gpu).

This change makes node roles configurable through the API and UI, with backward-compatible defaults (["master", "worker"]).

Changes

Proto layer:

  • Storage: reserved old NodeRole enum field (tag 9), added repeated string node_roles (tag 19)
  • API: added node_roles field to BaseComplianceScanConfigurationSettings
  • Internal API: added node_roles to BaseScanSettings for Central-Sensor communication

Central:

  • Conversion layer: maps node_roles between API and storage, applies ["master", "worker"] default when empty
  • Validation: matches Compliance Operator rules (alphanumeric + hyphens, 1-39 chars, @all exclusive, rejects duplicates)
  • Manager: passes node_roles through buildScanConfigSensorMsg
  • Startup sync: includes node_roles in SyncComplianceScanConfigRequest

Sensor:

  • Reads roles from Central request instead of hardcoding ["master", "worker"]
  • Falls back to ["master", "worker"] when field is empty (backward compat with old Central)

UI:

  • Node roles section in scan config wizard as a top-level section below Schedule (with its own heading and divider)
  • Text input + label chips for adding/removing roles
  • Not marked as required — helper text explains defaults apply when empty
  • Inline validation error for invalid role names
  • Displays node roles in config detail view and review step
  • Default: master, worker pre-populated

Coverage page

Node roles are intentionally not shown on the compliance coverage pages. Coverage answers "what passed/failed?" while node roles are a scan configuration input. Surfacing them on results pages would conflate configuration with outcomes and add visual noise without actionable value. Node roles are visible on the scan schedule detail page, one click from the coverage dropdown.

Design decisions

  • Free-text repeated string over enum: The Compliance Operator accepts arbitrary role strings. An enum would require an ACS release for each new role name.
  • Default in Central, fallback in Sensor: Central applies defaults before DB persistence (clean source of truth). Sensor defaults as safety net for messages from old Central versions.
  • Proto tag 19 instead of reusing tag 9: The old field used NodeRole enum (varint wire type); changing to string would break wire compatibility. Reserved tag 9 per proto best practices.
  • Optional field (not required): Node roles are pre-populated with master and worker. Users can override or clear them; empty defaults to ["master", "worker"] server-side.

User-facing documentation

Testing and quality

  • the change is production ready: the change is GA, or otherwise the functionality is gated by a feature flag
  • CI results are inspected

Automated testing

  • added unit tests
  • modified existing tests

Unit tests added for:

  • Node role validation (Central): empty, @all, mixed @all, invalid chars, duplicates, too long
  • Node roles from request (Sensor): explicit roles, empty defaults, nil request, @all
  • Existing service tests updated with nodeRoles field

How I validated my change

Deployed to an OCP 4.22 cluster with Compliance Operator v1.9.1 and verified end-to-end.

API tests (curl against deployed Central 4.12.x-537-g9c2f276143):

Test Input ScanSetting on Cluster Result
Default (empty) omitted ["master","worker"] Pass
Worker + Infra ["worker","infra"] ["worker","infra"] Pass
@ALL ["@all"] ["@all"] Pass
Three roles ["master","worker","control-plane"] ["master","worker","control-plane"] Pass
Custom gpu ["gpu"] (label added to node) ["gpu"] Pass
UPDATE roles ["control-plane","worker"] ["control-plane","worker"] Pass
LIST all configs All show nodeRoles n/a Pass
@ALL+worker (invalid) rejected with error n/a Pass
inv@lid (invalid) rejected with error n/a Pass
Duplicates (invalid) rejected with error n/a Pass
Remove node label gpu label removed from node No breakage Pass

UI screenshots:

Create wizard — Node roles as a top-level section below Schedule, with defaults pre-populated:

create wizard

Adding multiple roles (master, worker, infra, +1 more):

multiple roles

Invalid role input error:

invalid error

Empty roles — no error, helper text explains defaults:

empty roles

Config detail view showing Node roles:

detail view

AI-assisted implementation.

@openshift-ci

openshift-ci Bot commented Jul 20, 2026

Copy link
Copy Markdown

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Compliance scan configurations now support node roles across API and storage schemas, Central validation and conversion, Central-to-Sensor requests, Sensor scan settings, and the scheduling UI. Empty roles retain the master and worker defaults, while @all receives exclusive handling.

Changes

Compliance scan node-role targeting

Layer / File(s) Summary
Node-role configuration contracts
proto/api/v2/..., proto/internalapi/..., proto/storage/..., ui/apps/platform/src/services/...
API, internal, storage, and TypeScript models add string-based node roles, documented defaults, and storage field compatibility changes.
Central conversion and validation
central/complianceoperator/v2/scanconfigurations/service/...
Central applies default roles during conversion, exposes roles in configuration and status responses, validates role syntax, duplicates, empty entries, and @all combinations, and updates fixtures and tests.
Central-to-Sensor propagation
central/complianceoperator/v2/compliancemanager/..., central/sensor/service/connection/...
Scheduled scan requests include node roles in shared scan settings for create, update, and Sensor connection paths.
Sensor role application
sensor/kubernetes/complianceoperator/...
Sensor scan-setting creation and updates use request-provided roles, defaulting omitted roles to master and worker; unit tests cover these cases.
Schedule role configuration
ui/apps/platform/src/Containers/ComplianceEnhanced/Schedules/Wizard/..., ui/apps/platform/src/Containers/ComplianceEnhanced/Schedules/compliance.scanConfigs.utils*
The scheduling form initializes, validates, converts, adds, removes, and tests node-role selections, including @all exclusivity.
Configured role display
ui/apps/platform/src/Containers/ComplianceEnhanced/Schedules/components/...
Review and configuration details views pass node roles to the parameters display and render non-empty role lists.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ScheduleUI
  participant CentralAPI
  participant ComplianceManager
  participant SensorConnection
  participant Sensor
  ScheduleUI->>CentralAPI: Submit scan configuration with nodeRoles
  CentralAPI->>ComplianceManager: Convert and validate scan request
  ComplianceManager->>SensorConnection: Build scan settings with NodeRoles
  SensorConnection->>Sensor: Send scheduled scan request
  Sensor->>Sensor: Apply explicit roles or default roles
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 10.53% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title is concise and accurately summarizes the main change: making compliance scan node roles configurable.
Description check ✅ Passed The description is detailed, matches the template sections, and includes validation and testing notes.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch gualvare/rox-34167-configurable-node-roles

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
ui/apps/platform/src/Containers/ComplianceEnhanced/Schedules/Wizard/ScanConfigOptions.tsx (1)

181-186: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Commit pending input on blur to prevent data loss.

If a user types a valid role but clicks outside the field before pressing Enter, their input is silently ignored. Updating onBlur to evaluate pending input ensures a smoother user experience and prevents incomplete configurations.

💡 Proposed fix to evaluate input on blur
-                                                onBlur={() =>
-                                                    formik.setFieldTouched(
-                                                        'parameters.nodeRoles',
-                                                        true
-                                                    )
-                                                }
+                                                onBlur={() => {
+                                                    if (nodeRoleInput) {
+                                                        addNodeRole(nodeRoleInput);
+                                                    }
+                                                    formik.setFieldTouched(
+                                                        'parameters.nodeRoles',
+                                                        true
+                                                    );
+                                                }}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@ui/apps/platform/src/Containers/ComplianceEnhanced/Schedules/Wizard/ScanConfigOptions.tsx`
around lines 181 - 186, Update the nodeRoles field’s onBlur handler to evaluate
and commit any valid pending input before marking parameters.nodeRoles as
touched. Preserve the existing Enter-key behavior and ensure clicking away does
not discard a typed role.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In
`@ui/apps/platform/src/Containers/ComplianceEnhanced/Schedules/Wizard/ScanConfigOptions.tsx`:
- Around line 181-186: Update the nodeRoles field’s onBlur handler to evaluate
and commit any valid pending input before marking parameters.nodeRoles as
touched. Preserve the existing Enter-key behavior and ensure clicking away does
not discard a typed role.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Central YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: e8c89221-acb4-48f9-882a-872be66c3743

📥 Commits

Reviewing files that changed from the base of the PR and between a7a9e16 and d02aa3d.

⛔ Files ignored due to path filters (7)
  • generated/api/v2/compliance_scan_configuration_service.pb.go is excluded by !**/*.pb.go, !**/generated/**
  • generated/api/v2/compliance_scan_configuration_service.swagger.json is excluded by !**/generated/**
  • generated/api/v2/compliance_scan_configuration_service_vtproto.pb.go is excluded by !**/*.pb.go, !**/generated/**
  • generated/internalapi/central/compliance_operator.pb.go is excluded by !**/*.pb.go, !**/generated/**
  • generated/internalapi/central/compliance_operator_vtproto.pb.go is excluded by !**/*.pb.go, !**/generated/**
  • generated/storage/compliance_operator_v2.pb.go is excluded by !**/*.pb.go, !**/generated/**
  • generated/storage/compliance_operator_v2_vtproto.pb.go is excluded by !**/*.pb.go, !**/generated/**
📒 Files selected for processing (20)
  • central/complianceoperator/v2/compliancemanager/manager_impl.go
  • central/complianceoperator/v2/compliancemanager/utils.go
  • central/complianceoperator/v2/scanconfigurations/service/convert.go
  • central/complianceoperator/v2/scanconfigurations/service/service_impl.go
  • central/complianceoperator/v2/scanconfigurations/service/service_impl_test.go
  • central/sensor/service/connection/connection_impl.go
  • proto/api/v2/compliance_scan_configuration_service.proto
  • proto/internalapi/central/compliance_operator.proto
  • proto/storage/compliance_operator_v2.proto
  • sensor/kubernetes/complianceoperator/types.go
  • sensor/kubernetes/complianceoperator/utils.go
  • sensor/kubernetes/complianceoperator/utils_test.go
  • ui/apps/platform/src/Containers/ComplianceEnhanced/Schedules/Wizard/ReviewConfig.tsx
  • ui/apps/platform/src/Containers/ComplianceEnhanced/Schedules/Wizard/ScanConfigOptions.tsx
  • ui/apps/platform/src/Containers/ComplianceEnhanced/Schedules/Wizard/useFormikScanConfig.tsx
  • ui/apps/platform/src/Containers/ComplianceEnhanced/Schedules/compliance.scanConfigs.utils.test.ts
  • ui/apps/platform/src/Containers/ComplianceEnhanced/Schedules/compliance.scanConfigs.utils.tsx
  • ui/apps/platform/src/Containers/ComplianceEnhanced/Schedules/components/ConfigDetails.tsx
  • ui/apps/platform/src/Containers/ComplianceEnhanced/Schedules/components/ScanConfigParametersView.tsx
  • ui/apps/platform/src/services/ComplianceScanConfigurationService.ts

@github-actions

github-actions Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

🚀 Build Images Ready

Images are ready for commit 9c2f276. To use with deploy scripts:

export MAIN_IMAGE_TAG=4.12.x-537-g9c2f276143

@github-actions

Copy link
Copy Markdown
Contributor

🚀 Build Images Ready

Images are ready for commit d02aa3d. To use with deploy scripts:

export MAIN_IMAGE_TAG=4.12.x-537-gd02aa3d3b3

@codecov

codecov Bot commented Jul 20, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 88.46154% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 51.33%. Comparing base (0f30bea) to head (9c2f276).
⚠️ Report is 9 commits behind head on master.

Files with missing lines Patch % Lines
...eoperator/v2/scanconfigurations/service/convert.go 42.85% 3 Missing and 1 partial ⚠️
...ator/v2/scanconfigurations/service/service_impl.go 91.30% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master   #21825      +/-   ##
==========================================
- Coverage   51.33%   51.33%   -0.01%     
==========================================
  Files        2855     2856       +1     
  Lines      178578   178612      +34     
==========================================
+ Hits        91678    91686       +8     
- Misses      78878    78895      +17     
- Partials     8022     8031       +9     
Flag Coverage Δ
go-unit-tests 51.33% <88.46%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

ACS previously hardcoded ["master", "worker"] as node roles in every
ScanSetting it generated for the Compliance Operator. This prevented
scanning nodes with other roles (e.g. infra, control-plane, custom).

Changes:
- Storage proto: replace unused NodeRole enum field (tag 9, reserved)
  with repeated string node_roles (tag 19) on scan config
- API proto: expose node_roles in BaseComplianceScanConfigurationSettings
- Internal API proto: add node_roles to BaseScanSettings for
  Central->Sensor communication
- Central: wire node_roles through conversion, validation, manager,
  and startup sync paths. Default to [master, worker] when empty.
- Sensor: read roles from request instead of hardcoding. Fall back to
  [master, worker] when field is empty (old Central compat).
- UI: add node roles input (text+labels) to scan config wizard
  Parameters step, with display in review and detail views.
- Validation matches Compliance Operator rules: alphanumeric+hyphens,
  1-39 chars, @ALL exclusive.

Partially generated by AI.
@guzalv
guzalv force-pushed the gualvare/rox-34167-configurable-node-roles branch from d02aa3d to 9c2f276 Compare July 21, 2026 12:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant