Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 76 additions & 0 deletions .github/workflows/e2e-tests-kind.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
name: E2E Tests (kind)

on:
workflow_call:
inputs:
image:
required: true
type: string

env:
REGISTRY: quay.io
IMAGE_NAME: rhacs-eng/roxie

jobs:
e2e-tests-kind:
runs-on: ubuntu-latest
env:
SKIP_OLM_TESTS: "true"
# TODO: Once the config-file-first approach lands, this will be changed from an
# environment variable to configuring a YAML configuration file, which will be
# used by the e2e tests.
ROXIE_RESOURCE_PROFILE: "tiny"
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha || github.sha }}

- name: Set up Go
uses: actions/setup-go@v6
with:
go-version-file: go.mod
cache: true

- name: Log in to Quay.io
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_TOKEN }}

- name: Extract roxie binary from image
run: |
docker create --name roxie-extract "${{ inputs.image }}"
docker cp roxie-extract:/usr/local/bin/roxie "$GITHUB_WORKSPACE/roxie"
docker rm roxie-extract

Comment on lines +43 to +48

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Avoid direct template expansion inside run: block.

"${{ inputs.image }}" is expanded directly into the shell command before execution, which zizmor flags as a template-injection risk. Prefer passing it through an environment variable so the shell treats it as data rather than as part of the script.

🔒 Proposed fix
       - name: Extract roxie binary from image
+        env:
+          IMAGE_REF: ${{ inputs.image }}
         run: |
-          docker create --name roxie-extract "${{ inputs.image }}"
+          docker create --name roxie-extract "$IMAGE_REF"
           docker cp roxie-extract:/usr/local/bin/roxie "$GITHUB_WORKSPACE/roxie"
           docker rm roxie-extract
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- name: Extract roxie binary from image
run: |
docker create --name roxie-extract "${{ inputs.image }}"
docker cp roxie-extract:/usr/local/bin/roxie "$GITHUB_WORKSPACE/roxie"
docker rm roxie-extract
- name: Extract roxie binary from image
env:
IMAGE_REF: ${{ inputs.image }}
run: |
docker create --name roxie-extract "$IMAGE_REF"
docker cp roxie-extract:/usr/local/bin/roxie "$GITHUB_WORKSPACE/roxie"
docker rm roxie-extract
🧰 Tools
🪛 zizmor (1.26.1)

[error] 45-45: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)

🤖 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 @.github/workflows/e2e-tests-kind.yml around lines 43 - 48, The “Extract
roxie binary from image” step in e2e-tests-kind.yml is expanding inputs.image
directly inside the run script, which should be avoided. Move the image
reference into an environment variable for that step and have the docker create
command use the env var instead, so the shell treats it as data; update the
workflow step using the existing inputs.image reference and the docker
create/docker cp/docker rm sequence.

Source: Linters/SAST tools

- name: Install roxie binary
run: |
cp "${GITHUB_WORKSPACE}/roxie" /usr/local/bin/roxie
chmod +x /usr/local/bin/roxie
roxie version

- name: Install roxctl
env:
ROXCTL_VERSION: "4.10.0"
ROXCTL_SHA256: "5db647b14569465866c0162522e83393ebf02f671f4556b1b3ed551b9f8433bc"
run: |
curl -fsSLo /usr/local/bin/roxctl \
"https://mirror.openshift.com/pub/rhacs/assets/${ROXCTL_VERSION}/bin/Linux/roxctl"
echo "${ROXCTL_SHA256} /usr/local/bin/roxctl" | sha256sum -c -
chmod +x /usr/local/bin/roxctl
roxctl version

- name: Create kind cluster
uses: helm/kind-action@v1
with:
cluster_name: roxie-e2e

- name: Run e2e tests
env:
REGISTRY_USERNAME: ${{ secrets.QUAY_RHACS_ENG_RO_USERNAME }}
REGISTRY_PASSWORD: ${{ secrets.QUAY_RHACS_ENG_RO_PASSWORD }}
run: |
make run-test-e2e
4 changes: 4 additions & 0 deletions .github/workflows/e2e-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ jobs:
KUBECONFIG: /github/home/artifacts/kubeconfig
INFRA_TOKEN: ${{ secrets.INFRA_CI_TOKEN }}
INFRACTL: bin/infractl -k -e localhost:8443
# TODO: Once the config-file-first approach lands, this will be changed from an
# environment variable to configuring a YAML configuration file, which will be
# used by the e2e tests.
ROXIE_RESOURCE_PROFILE: "small"
steps:
- name: Checkout
uses: actions/checkout@v6
Expand Down
7 changes: 7 additions & 0 deletions .github/workflows/main-push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@ jobs:
image: ${{ needs.build-roxie-image.outputs.image }}
secrets: inherit

e2e-tests-kind:
needs: [ build-roxie-image ]
uses: ./.github/workflows/e2e-tests-kind.yml
with:
image: ${{ needs.build-roxie-image.outputs.image }}
secrets: inherit

delete-dev-cluster:
if: ${{ always() && needs.create-dev-cluster.result == 'success' }}
needs: [ create-dev-cluster, e2e-tests ]
Expand Down
7 changes: 7 additions & 0 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,10 @@ jobs:
with:
cluster-name: ${{ needs.create-openshift-cluster.outputs.cluster-name }}
secrets: inherit

e2e-tests-kind:
needs: [ build-roxie-image ]
uses: ./.github/workflows/e2e-tests-kind.yml
with:
image: ${{ needs.build-roxie-image.outputs.image }}
secrets: inherit
2 changes: 1 addition & 1 deletion internal/clusterdefaults/clusterdefaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func ApplyClusterDefaults(
return nil, fmt.Errorf("deep-copying cluster defaults for cluster type %s: %w", clusterType, err)
}

if err := mergo.Merge(config, defaultsCopy, mergo.WithoutDereference); err != nil {
if err := mergo.Merge(config, defaultsCopy, mergo.WithoutDereference, mergo.WithAppendSlice); err != nil {
return nil, fmt.Errorf("merging-in cluster defaults for cluster type %s: %w", clusterType, err)
}

Expand Down
67 changes: 67 additions & 0 deletions internal/deployer/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,20 @@ var (
centralCrName = "stackrox-central-services"
securedClusterCrName = "stackrox-secured-cluster-services"

centralDbPVCSizeTiny = "10Gi"
centralDbPVCSizeSmall = "30Gi"

centralResourcesTiny = map[string]interface{}{
"requests": map[string]string{
"memory": "300Mi",
"cpu": "90m",
},
"limits": map[string]string{
"memory": "2Gi",
"cpu": "1",
},
}

centralResourcesSmall = map[string]interface{}{
"requests": map[string]string{
"memory": "1Gi",
Expand All @@ -19,6 +31,17 @@ var (
},
}

centralDbResourcesTiny = map[string]interface{}{
"requests": map[string]string{
"memory": "400Mi",
"cpu": "80m",
},
"limits": map[string]string{
"memory": "2Gi",
"cpu": "1",
},
}

centralDbResourcesSmall = map[string]interface{}{
"requests": map[string]string{
"memory": "1Gi",
Expand Down Expand Up @@ -52,6 +75,17 @@ var (
},
}

centralScannerV4DbResourcesTiny = map[string]interface{}{
"requests": map[string]string{
"memory": "400Mi",
"cpu": "80m",
},
"limits": map[string]string{
"memory": "2000Mi",
"cpu": "1000m",
},
}

centralScannerV4DbResourcesSmall = map[string]interface{}{
"requests": map[string]string{
"memory": "512Mi",
Expand All @@ -63,6 +97,17 @@ var (
},
}

centralScannerV4IndexerResourcesTiny = map[string]interface{}{
"requests": map[string]string{
"memory": "300Mi",
"cpu": "80m",
},
"limits": map[string]string{
"memory": "2Gi",
"cpu": "2000m",
},
}

centralScannerV4IndexerResourcesSmall = map[string]interface{}{
"requests": map[string]string{
"memory": "512Mi",
Expand All @@ -74,6 +119,17 @@ var (
},
}

centralScannerV4MatcherResourcesTiny = map[string]interface{}{
"requests": map[string]string{
"memory": "300Mi",
"cpu": "80m",
},
"limits": map[string]string{
"memory": "2Gi",
"cpu": "1000m",
},
}

centralScannerV4MatcherResourcesSmall = map[string]interface{}{
"requests": map[string]string{
"memory": "512Mi",
Expand All @@ -87,6 +143,17 @@ var (

// Secured Cluster

securedClusterSensorResourcesTiny = map[string]interface{}{
"requests": map[string]string{
"memory": "300Mi",
"cpu": "80m",
},
"limits": map[string]string{
"memory": "2Gi",
"cpu": "1000m",
},
}

securedClusterSensorResourcesSmall = map[string]interface{}{
"requests": map[string]string{
"memory": "500Mi",
Expand Down
67 changes: 67 additions & 0 deletions internal/deployer/deploy_via_operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,38 @@ func (d *Deployer) createAdminPasswordSecret(ctx context.Context) error {

func getCentralResourcesOperator(resourcesProfile types.ResourceProfile) map[string]interface{} {
switch resourcesProfile {
case types.ResourceProfileTiny:
return map[string]interface{}{
"spec": map[string]interface{}{
"central": map[string]interface{}{
"resources": centralResourcesTiny,
"db": map[string]interface{}{
"resources": centralDbResourcesTiny,
"persistence": map[string]interface{}{
"persistentVolumeClaim": map[string]interface{}{
"size": centralDbPVCSizeTiny,
},
},
},
},
"scanner": map[string]interface{}{
"scannerComponent": "Disabled",
},
"scannerV4": map[string]interface{}{
"db": map[string]interface{}{
"resources": centralScannerV4DbResourcesTiny,
},
"indexer": map[string]interface{}{
"resources": centralScannerV4IndexerResourcesTiny,
"scaling": noScaling,
},
"matcher": map[string]interface{}{
"resources": centralScannerV4MatcherResourcesTiny,
"scaling": noScaling,
},
},
},
}
case types.ResourceProfileSmall:
return map[string]interface{}{
"spec": map[string]interface{}{
Expand Down Expand Up @@ -705,9 +737,44 @@ func (d *Deployer) deploySecuredClusterOperator(ctx context.Context) error {

func getSecuredClusterResourcesOperator(resourceProfile types.ResourceProfile) map[string]interface{} {
switch resourceProfile {
case types.ResourceProfileTiny:
return map[string]interface{}{
"spec": map[string]interface{}{
"admissionControl": map[string]interface{}{
"replicas": 1,
},
"sensor": map[string]interface{}{
"resources": securedClusterSensorResourcesTiny,
},
"scanner": map[string]interface{}{
"scannerComponent": "Disabled",
},
"scannerV4": map[string]interface{}{
"scannerComponent": "Disabled",
},
// The "tiny" resource profile also patches the resources down for some containers, which do not
// have first-class configurability exposed in the CR.
"overlays": []map[string]interface{}{
{
"apiVersion": "apps/v1",
"kind": "Deployment",
"name": "sensor",
"patches": []map[string]interface{}{
{
"path": "spec.template.spec.initContainers[name:crs].resources.requests",
"value": `{"cpu":"80m", "memory": "150m"}`,
},
},
Comment on lines +762 to +767

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

Kubernetes resource quantity "m" suffix for memory

💡 Result:

In Kubernetes, the "m" suffix when applied to memory resource quantities denotes "millibytes," where 1m equals 1/1000 of a byte [1]. Because Kubernetes measures memory resources in whole bytes, the "m" suffix is not useful for specifying memory requirements [1]. Specifying memory with this suffix, such as "400m", results in a fractional value (e.g., 0.4 bytes), which is generally not a valid or intended configuration for memory requests or limits [1]. It is critical to distinguish between the case-sensitive suffixes: - "M" stands for megabytes (10^6 bytes) [1]. - "m" stands for millibytes (10^-3 bytes) [1]. For memory, users should typically use power-of-two suffixes (e.g., Mi, Gi) or decimal SI suffixes (e.g., M, G) to represent the intended integer number of bytes [1][2][3]. Using "m" in the context of memory is often a mistake by users who intended to specify a standard unit like mebibytes (Mi) or megabytes (M) [1].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the relevant section around the reported lines.
sed -n '730,780p' internal/deployer/deploy_via_operator.go | cat -n

# Find other occurrences of the same resource value or nearby resource patches.
rg -n '"150m"|"80m"|initContainers\[name:crs\]|resources.requests' internal/deployer/deploy_via_operator.go

Repository: stackrox/roxie

Length of output: 2138


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the resource profiles and the sensor resource definitions to see whether this is a request-only tweak.
rg -n 'securedClusterSensorResourcesTiny|securedClusterSensorResourcesSmall|resources:\s*securedClusterSensorResources' internal/deployer/deploy_via_operator.go
sed -n '1,140p' internal/deployer/deploy_via_operator.go | cat -n

Repository: stackrox/roxie

Length of output: 5477


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show the resource constants and any companion limits.
rg -n 'securedClusterSensorResourcesTiny|securedClusterSensorResourcesSmall|requests|limits' internal/deployer/deploy_via_operator.go
sed -n '1,140p' internal/deployer/deploy_via_operator.go | cat -n

Repository: stackrox/roxie

Length of output: 5564


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the tiny/small resource constants to see whether limits are set elsewhere.
sed -n '760,840p' internal/deployer/deploy_via_operator.go | cat -n
rg -n 'securedClusterSensorResourcesTiny|securedClusterSensorResourcesSmall' internal/deployer/deploy_via_operator.go

Repository: stackrox/roxie

Length of output: 2945


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Find the exact resource quantities used for the sensor and any related initContainer resources.
sed -n '780,860p' internal/deployer/deploy_via_operator.go | cat -n

Repository: stackrox/roxie

Length of output: 2769


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show the tiny/small resource definitions and the surrounding overlay patch in one slice.
sed -n '780,860p' internal/deployer/deploy_via_operator.go | cat -n

Repository: stackrox/roxie

Length of output: 2769


Use 150Mi for the initContainer memory request. m is millibytes for memory, so 150m is effectively zero and will skew scheduling for crs; 150Mi looks like the intended unit.

🐛 Proposed fix
-								"value": `{"cpu":"80m", "memory": "150m"}`,
+								"value": `{"cpu":"80m", "memory": "150Mi"}`,
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"patches": []map[string]interface{}{
{
"path": "spec.template.spec.initContainers[name:crs].resources.requests",
"value": `{"cpu":"80m", "memory": "150m"}`,
},
},
"patches": []map[string]interface{}{
{
"path": "spec.template.spec.initContainers[name:crs].resources.requests",
"value": `{"cpu":"80m", "memory": "150Mi"}`,
},
},
🤖 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 `@internal/deployer/deploy_via_operator.go` around lines 762 - 767, The
initContainer resource request in deploy_via_operator.go uses the wrong memory
unit for the crs init container. Update the patch value in the deploy logic that
targets spec.template.spec.initContainers[name:crs].resources.requests so the
memory request uses 150Mi instead of 150m, keeping the CPU request unchanged.

},
},
},
}
case types.ResourceProfileSmall:
return map[string]interface{}{
"spec": map[string]interface{}{
"admissionControl": map[string]interface{}{
"replicas": 1,
},
"sensor": map[string]interface{}{
"resources": securedClusterSensorResourcesSmall,
},
Expand Down
2 changes: 2 additions & 0 deletions internal/deployer/deployer.go
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,7 @@ func (d *Deployer) prepareCredentials() error {

func (d *Deployer) deployCentral(ctx context.Context) error {
d.logger.Infof("Deploying Central to namespace %s", d.config.Central.Namespace)
d.logger.Infof("Central resource profile: %s", d.config.Central.ResourceProfile)
if d.namespaceExists(d.config.Central.Namespace) {
d.logger.Info("Existing Central deployment found, tearing down...")
if err := d.teardownCentral(ctx); err != nil {
Expand All @@ -378,6 +379,7 @@ func (d *Deployer) deployCentral(ctx context.Context) error {

func (d *Deployer) deploySecuredCluster(ctx context.Context) error {
d.logger.Infof("Deploying SecuredCluster to namespace %s", d.config.SecuredCluster.Namespace)
d.logger.Infof("SecuredCluster resource profile: %s", d.config.SecuredCluster.ResourceProfile)
if d.namespaceExists(d.config.SecuredCluster.Namespace) {
d.logger.Info("Existing SecuredCluster deployment found, tearing down...")
if err := d.teardownSecuredCluster(ctx); err != nil {
Expand Down
34 changes: 31 additions & 3 deletions internal/helpers/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,16 +108,16 @@ func deepCopySlice(s []interface{}) []interface{} {
return result
}

// deepMerge recursively merges overlay into base
// DeepMerge recursively merges overlay into base.
func DeepMerge(base, overlay map[string]interface{}) error {
for k, v := range overlay {
if IsNil(v) {
continue
}
if baseVal, ok := base[k]; ok {
// Both are maps - merge recursively
if baseMap, baseIsMap := baseVal.(map[string]interface{}); baseIsMap {
if overlayMap, overlayIsMap := v.(map[string]interface{}); overlayIsMap {
// Both are maps - merge recursively.
if err := DeepMerge(baseMap, overlayMap); err != nil {
return err
}
Expand All @@ -126,13 +126,41 @@ func DeepMerge(base, overlay map[string]interface{}) error {
return fmt.Errorf("incompatible types in maps to merge (map vs. %T)", v)
}
}
if _, ok := v.(map[string]interface{}); ok {
return fmt.Errorf("incompatible types for key %q: %T vs. map", k, baseVal)
}

if baseSlice, ok := toSlice(baseVal); ok {
if overlaySlice, ok := toSlice(v); ok {
base[k] = append(baseSlice, overlaySlice...)
continue
}
return fmt.Errorf("incompatible types for key %q: slice vs. %T", k, v)
}
if _, ok := toSlice(v); ok {
return fmt.Errorf("incompatible types for key %q: %T vs. slice", k, baseVal)
}
}
// Override with overlay value

base[k] = v
}
return nil
}

func toSlice(v interface{}) ([]interface{}, bool) {
if s, ok := v.([]interface{}); ok {
return s, true
}
if s, ok := v.([]map[string]interface{}); ok {
out := make([]interface{}, len(s))
for i, e := range s {
out[i] = e
}
return out, true
}
return nil, false
}
Comment on lines +133 to +162

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify DeepMerge/MergeMaps call sites that may pass typed slices through map[string]interface{} values.
rg -n --type=go -C4 '\b(DeepMerge|MergeMaps)\s*\(' .
sed -n '133,162p' internal/helpers/helpers.go

Repository: stackrox/roxie

Length of output: 9429


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the merge callers and the data they feed into helpers.DeepMerge/MergeMaps.
for f in internal/deployer/feature_flags.go internal/deployer/config.go internal/helpers/helpers.go internal/helpers/helpers_test.go; do
  echo "===== $f ====="
  wc -l "$f"
done

echo "===== feature_flags.go outline ====="
ast-grep outline internal/deployer/feature_flags.go --view expanded || true

echo "===== config.go outline ====="
ast-grep outline internal/deployer/config.go --view expanded || true

echo "===== helpers.go outline ====="
ast-grep outline internal/helpers/helpers.go --view expanded || true

echo "===== featureFlagsToOverrides ====="
rg -n -C 30 'func featureFlagsToOverrides|ToUnstructuredConfig|DeepMerge|MergeMaps|toSlice|Unstructured' internal/deployer internal/helpers

echo "===== typed slice builders in repo ====="
rg -n -C 3 '(\[\]string|\[\]int|\[\]bool|\[\]float64|\[\]interface\{\}|\[\]map\[string\]interface\{\})' internal | sed -n '1,220p'

Repository: stackrox/roxie

Length of output: 50370


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Look for typed slices being inserted into map[string]interface{} values that can reach DeepMerge/MergeMaps.
rg -n -C 3 'map\[string\]interface\{\}\{[^}]*\[\][A-Za-z_][A-Za-z0-9_]*\{' internal || true
echo "-----"
rg -n -C 3 'featureFlagsToOverrides|ToUnstructuredConfig|ToUnstructured|UnstructuredConfig|mapstructure|yaml.Unmarshal|json.Unmarshal' internal || true
echo "-----"
sed -n '1,220p' internal/deployer/feature_flags.go
echo "-----"
sed -n '1,240p' internal/deployer/config.go

Repository: stackrox/roxie

Length of output: 23172


🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '1,160p' internal/types/exposure.go
echo "-----"
rg -n -C 2 'imagePullSecrets|labels": map\[string\]string|map\[string\]string|[]map\[string\]string' internal/deployer internal/types internal/helpers

Repository: stackrox/roxie

Length of output: 1972


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect every occurrence of imagePullSecrets and any DeepMerge tests around slice handling.
rg -n -C 3 'imagePullSecrets|DeepMergeAppendsSlices|DeepMergeSliceTypeMismatch|toSlice\(' internal/deployer internal/helpers internal -g '!**/*vendor*'

Repository: stackrox/roxie

Length of output: 8051


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show all imagePullSecrets occurrences and the exact slice handling tests.
rg -n -C 3 'imagePullSecrets|DeepMergeAppendsSlices|DeepMergeSliceTypeMismatch|func toSlice' internal/deployer internal/helpers internal

Repository: stackrox/roxie

Length of output: 6255


Broaden toSlice to accept typed slicesspec.imagePullSecrets is seeded as []map[string]string in internal/deployer/config.go, but DeepMerge only recognizes []interface{} and []map[string]interface{}. An overlay for that key will hit the slice mismatch path instead of appending.

🤖 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 `@internal/helpers/helpers.go` around lines 133 - 162, The DeepMerge helper
currently treats only []interface{} and []map[string]interface{} as slices, so
typed slices like spec.imagePullSecrets seeded from config can’t be merged and
fall into the mismatch error path. Update toSlice in helpers.go to recognize the
typed slice used by imagePullSecrets (and any equivalent typed map slice) by
converting it into []interface{} before merging, so DeepMerge can append
overlays instead of rejecting them. Use the existing DeepMerge and toSlice
symbols to keep the fix localized.


func MapToStruct(m map[string]interface{}, out interface{}) error {
bytes, err := yaml.Marshal(m)
if err != nil {
Expand Down
Loading
Loading