Skip to content

feat(STONEINTG-1661): validate Component for NudgeConfig nudges#1607

Open
Josh-Everett wants to merge 1 commit into
konflux-ci:mainfrom
Josh-Everett:1661
Open

feat(STONEINTG-1661): validate Component for NudgeConfig nudges#1607
Josh-Everett wants to merge 1 commit into
konflux-ci:mainfrom
Josh-Everett:1661

Conversation

@Josh-Everett

Copy link
Copy Markdown
Contributor

Add a Go ValidatingWebhook that rejects NudgeConfig CREATE/UPDATE when spec.nudges[].from or spec.nudges[].to references a Component that does not exist in the namespace. Pre-existing entries are not re-validated on update (staleness is the stale-reference controller's responsibility).

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request introduces validation logic to ensure that components referenced in a NudgeConfig actually exist in the namespace during creation and update operations, along with comprehensive unit tests. Feedback points out that the added webhook 'vnudgeconfig.kb.io' in 'dist/chart/templates/webhook/webhooks.yaml' is a duplicate of an existing definition, which is invalid in Kubernetes and should be consolidated.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +132 to +156
- name: vnudgeconfig.kb.io
clientConfig:
service:
name: integration-service-webhook-service
namespace: {{ .Values.namespace | default .Release.Namespace }}
path: /validate-appstudio-redhat-com-v1beta2-nudgeconfig
failurePolicy: Fail
sideEffects: None
admissionReviewVersions:
- v1
namespaceSelector:
matchExpressions:
- key: kubernetes.io/metadata.name
operator: NotIn
values: [kube-system, kube-public, kube-node-lease]
rules:
- operations:
- CREATE
- UPDATE
apiGroups:
- appstudio.redhat.com
apiVersions:
- v1beta2
resources:
- nudgeconfigs

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

The webhook vnudgeconfig.kb.io is already defined at lines 50-69 in this file. Defining two webhooks with the same name in a single ValidatingWebhookConfiguration is invalid in Kubernetes and will cause deployment failures or one definition to silently overwrite the other.

Please remove this duplicate entry and instead update the existing webhook definition at lines 50-69 to include the namespaceSelector block.

@fullsend-ai-review

fullsend-ai-review Bot commented Jun 26, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 2:37 PM UTC · Completed 2:51 PM UTC
Commit: ec21706 · View workflow run →

@qodo-app-for-konflux-ci

Copy link
Copy Markdown

PR Summary by Qodo

Validate NudgeConfig nudge Component references via admission webhook
✨ Enhancement 🧪 Tests ⚙️ Configuration changes 🕐 40+ Minutes

Grey Divider

Description

• Add validating webhook to block NudgeConfig with missing Component references.
• Validate only newly-added (from,to) pairs on update; leave staleness to controller.
• Extend webhook deployment config and add coverage for existence validation scenarios.
Diagram

graph TD
  A["NudgeConfig CREATE/UPDATE"] --> B(["Admission Webhook"]) --> C["NudgeConfig validator"] --> F{"Components exist?"} --> G["Admit request"]
  C --> D[("Kubernetes API")] --> E["Component CRs (namespace)"]
  F --> H["Reject w/ details"]

  subgraph Legend
    direction LR
    _cr["Custom Resource"] ~~~ _svc(["Webhook service"]) ~~~ _api[("K8s API")] ~~~ _dec{"Decision"}
  end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. GET each referenced Component (per from/to) instead of listing
  • ➕ Potentially less memory/time when namespace has many Components
  • ➕ Avoids scanning unrelated Components
  • ➖ More API calls (2 per nudge) and higher admission latency for large nudge sets
  • ➖ Harder to aggregate missing references efficiently without extra bookkeeping
2. Use controller reconciliation to enforce references (no webhook)
  • ➕ Avoids admission-time API calls and webhook operational overhead
  • ➕ Fits eventual-consistency patterns
  • ➖ Does not prevent bad configs from being persisted
  • ➖ Users see delayed failures and downstream behavior becomes harder to reason about
3. CRD CEL/OpenAPI validation rules
  • ➕ No webhook deployment/maintenance
  • ➕ Validation runs natively in the API server
  • ➖ Cannot reliably validate cross-resource existence (Component) via schema-only checks
  • ➖ Limited expressiveness for aggregation and namespace-scoped lookups

Recommendation: Keep the webhook approach: cross-resource existence checks require admission-time logic. The current single-list aggregation is efficient for typical nudge sizes and produces actionable error messages; if namespaces can contain very large Component counts, consider switching to per-name GETs or an indexed cache later.

Files changed (5) +339 / -4

Enhancement (1) +82 / -2
nudgeconfig_webhook.goValidate referenced Components exist for NudgeConfig nudges +82/-2

Validate referenced Components exist for NudgeConfig nudges

• Introduces admission-time validation that spec.nudges[].from/to names correspond to existing Component CRs in the same namespace. On update, only newly-added (from,to) pairs are checked while cycle detection still revalidates the full nudge graph when nudges change; missing references are aggregated into a single error message.

internal/webhook/v1beta2/nudgeconfig_webhook.go

Tests (2) +229 / -2
nudgeconfig_webhook_test.goAdd test coverage for Component existence validation semantics +225/-2

Add test coverage for Component existence validation semantics

• Adds helpers to create Component and NudgeConfig objects and introduces a dedicated test suite for existence validation. Covers create-time rejection for missing from/to, aggregation of missing refs, update-only validation for newly-added pairs, and allowing updates when pre-existing refs become stale.

internal/webhook/v1beta2/nudgeconfig_webhook_test.go

webhook_suite_test.goRegister core Kubernetes scheme for webhook envtest +4/-0

Register core Kubernetes scheme for webhook envtest

• Adds client-go scheme registration to support creating Namespaces and other core resources in webhook tests.

internal/webhook/v1beta2/webhook_suite_test.go

Other (2) +28 / -0
kustomization.yamlApply namespace selector patch for webhook manifests +3/-0

Apply namespace selector patch for webhook manifests

• Adds a kustomize patch entry to apply the NudgeConfig namespace selector configuration when generating webhook resources.

config/webhook/kustomization.yaml

webhooks.yamlRegister ValidatingWebhook for NudgeConfig +25/-0

Register ValidatingWebhook for NudgeConfig

• Adds a new ValidatingWebhookConfiguration entry for NudgeConfig CREATE/UPDATE routed to the webhook service path. Includes a namespaceSelector excluding core Kubernetes namespaces.

dist/chart/templates/webhook/webhooks.yaml

@codecov-commenter

codecov-commenter commented Jun 26, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 45 lines in your changes missing coverage. Please review.
✅ Project coverage is 39.67%. Comparing base (3e5f7eb) to head (fe53f4a).

Files with missing lines Patch % Lines
internal/webhook/v1beta2/nudgeconfig_webhook.go 0.00% 45 Missing ⚠️

❗ There is a different number of reports uploaded between BASE (3e5f7eb) and HEAD (fe53f4a). Click for more details.

HEAD has 1 upload less than BASE
Flag BASE (3e5f7eb) HEAD (fe53f4a)
unit-tests 1 0
Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##             main    #1607       +/-   ##
===========================================
- Coverage   67.00%   39.67%   -27.34%     
===========================================
  Files          71       70        -1     
  Lines        9533     9231      -302     
===========================================
- Hits         6388     3662     -2726     
- Misses       2416     5011     +2595     
+ Partials      729      558      -171     
Flag Coverage Δ
e2e-tests 39.67% <0.00%> (?)
unit-tests ?

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

Files with missing lines Coverage Δ
internal/webhook/v1beta2/nudgeconfig_webhook.go 6.84% <0.00%> (-93.16%) ⬇️

... and 65 files with indirect coverage changes


Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 3e5f7eb...fe53f4a. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@qodo-app-for-konflux-ci

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (2) 📜 Skill insights (0)

Context used
✅ Compliance rules (platform): 10 rules

Grey Divider


Action required

1. Duplicate chart webhook 🐞 Bug ≡ Correctness
Description
dist/chart/templates/webhook/webhooks.yaml defines vnudgeconfig.kb.io twice in the same
ValidatingWebhookConfiguration, causing redundant admission calls and leaving the earlier entry
unscoped (so system namespaces are still matched). This can increase admission latency and defeats
the intended namespaceSelector restriction.
Code

dist/chart/templates/webhook/webhooks.yaml[R132-156]

+  - name: vnudgeconfig.kb.io
+    clientConfig:
+      service:
+        name: integration-service-webhook-service
+        namespace: {{ .Values.namespace | default .Release.Namespace }}
+        path: /validate-appstudio-redhat-com-v1beta2-nudgeconfig
+    failurePolicy: Fail
+    sideEffects: None
+    admissionReviewVersions:
+      - v1
+    namespaceSelector:
+      matchExpressions:
+        - key: kubernetes.io/metadata.name
+          operator: NotIn
+          values: [kube-system, kube-public, kube-node-lease]
+    rules:
+      - operations:
+          - CREATE
+          - UPDATE
+        apiGroups:
+          - appstudio.redhat.com
+        apiVersions:
+          - v1beta2
+        resources:
+          - nudgeconfigs
Relevance

⭐⭐⭐ High

Chart webhook config is actively maintained; likely to remove duplicate webhook (webhooks.yaml
touched in PRs 1594/1154).

PR-#1594
PR-#1154

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The chart template already contains a vnudgeconfig.kb.io webhook entry, and the PR adds another
vnudgeconfig.kb.io entry with the same clientConfig/rules but different namespaceSelector,
resulting in two matching webhooks for the same resource.

dist/chart/templates/webhook/webhooks.yaml[49-69]
dist/chart/templates/webhook/webhooks.yaml[132-156]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The Helm chart template renders two `webhooks` entries with `name: vnudgeconfig.kb.io`. The earlier one has no `namespaceSelector`, so the webhook still applies to system namespaces and also results in duplicate webhook invocations for normal namespaces.

### Issue Context
There is already an existing `vnudgeconfig.kb.io` entry earlier in the same `webhooks:` list. The PR added a second one with a `namespaceSelector` instead of updating the original.

### Fix Focus Areas
- dist/chart/templates/webhook/webhooks.yaml[49-156]

### What to change
- Remove the newly-added duplicate `vnudgeconfig.kb.io` block.
- Add the `namespaceSelector` stanza to the original `vnudgeconfig.kb.io` webhook entry (the one already present near the top of the validating webhook list).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Direct v.Client.List used 📘 Rule violation ⌂ Architecture
Description
The webhook validator fetches Component resources via the raw controller-runtime client
(v.Client.List) instead of going through loader.ObjectLoader. This bypasses the required
fetching abstraction and violates the repository’s Kubernetes access policy.
Code

internal/webhook/v1beta2/nudgeconfig_webhook.go[R126-129]

+	componentList := &applicationapiv1alpha1.ComponentList{}
+	if err := v.Client.List(ctx, componentList, client.InNamespace(namespace)); err != nil {
+		return fmt.Errorf("failed to list Components in namespace %q: %w", namespace, err)
+	}
Relevance

⭐⭐ Medium

No evidence of enforced ObjectLoader-only access in webhooks; prior webhook work uses raw client
patterns (PR #1594).

PR-#1594

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
PR Compliance ID 510 requires Kubernetes resource fetching to be performed via
loader.ObjectLoader. The added validator code lists Component objects using
v.Client.List(...), which is a direct client fetch rather than ObjectLoader-mediated access.

Rule 510: Use loader.ObjectLoader for all Kubernetes resource fetching
internal/webhook/v1beta2/nudgeconfig_webhook.go[126-129]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
New code fetches Kubernetes resources using `v.Client.List(...)` directly. Per compliance, all Kubernetes resource fetching must go through `loader.ObjectLoader` (or an injected abstraction that wraps it).

## Issue Context
This was introduced in the new `validateComponentsExist(...)` logic for `NudgeConfig` validation.

## Fix Focus Areas
- internal/webhook/v1beta2/nudgeconfig_webhook.go[121-134]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Missing kustomize patch 🐞 Bug ☼ Reliability
Description
config/webhook/kustomization.yaml references patches/nudgeconfig_namespace_selector.yaml, but
that file is not present in the PR branch, so kustomize build config/webhook (and
config/default) fails. This breaks deployment pipelines that use the kustomize manifests.
Code

config/webhook/kustomization.yaml[R8-9]

+patches:
+- path: patches/nudgeconfig_namespace_selector.yaml
Relevance

⭐⭐ Medium

No similar historical evidence; likely fixed if CI breaks, but no precedent found.

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The kustomization now references a patch file under patches/, but the repository branch does not
contain that path, so kustomize cannot load it.

config/webhook/kustomization.yaml[1-9]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`config/webhook/kustomization.yaml` includes a patch file path that does not exist in the repository. This causes kustomize to error out when building the webhook manifests.

### Issue Context
The PR adds:
- `patches: - path: patches/nudgeconfig_namespace_selector.yaml`
…but there is no `config/webhook/patches/nudgeconfig_namespace_selector.yaml` in the branch.

### Fix Focus Areas
- config/webhook/kustomization.yaml[1-9]

### What to change
- Create the missing file at `config/webhook/patches/nudgeconfig_namespace_selector.yaml` (and the `config/webhook/patches/` directory).
- The patch should add the intended `namespaceSelector` to the `ValidatingWebhookConfiguration` webhook with `name: vnudgeconfig.kb.io` (metadata.name is `validating-webhook-configuration` in `config/webhook/manifests.yaml`).

Example (strategic-merge) patch content:
```yaml
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
 name: validating-webhook-configuration
webhooks:
 - name: vnudgeconfig.kb.io
   namespaceSelector:
     matchExpressions:
       - key: kubernetes.io/metadata.name
         operator: NotIn
         values:
           - kube-system
           - kube-public
           - kube-node-lease
```

(Alternatively: remove the `patches:` entry if you decide not to apply a namespaceSelector for the kustomize deployment path.)

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Informational

4. Webhook code outside internal/webhooks/ 📘 Rule violation ⌂ Architecture
Description
The modified webhook implementation resides under internal/webhook/v1beta2/ rather than
internal/webhooks/<resource>/ as required. This breaks the mandated repository layout for webhook
implementations.
Code

internal/webhook/v1beta2/nudgeconfig_webhook.go[R121-166]

+func (v *NudgeConfigCustomValidator) validateComponentsExist(ctx context.Context, namespace string, nudges []v1beta2.NudgeRelationship) error {
+	if len(nudges) == 0 {
+		return nil
+	}
+
+	componentList := &applicationapiv1alpha1.ComponentList{}
+	if err := v.Client.List(ctx, componentList, client.InNamespace(namespace)); err != nil {
+		return fmt.Errorf("failed to list Components in namespace %q: %w", namespace, err)
+	}
+
+	existing := make(map[string]struct{}, len(componentList.Items))
+	for i := range componentList.Items {
+		existing[componentList.Items[i].Name] = struct{}{}
+	}
+
+	var missingFrom, missingTo []string
+	seenFrom, seenTo := map[string]struct{}{}, map[string]struct{}{}
+	for _, n := range nudges {
+		if _, ok := existing[n.From]; !ok {
+			if _, dup := seenFrom[n.From]; !dup {
+				seenFrom[n.From] = struct{}{}
+				missingFrom = append(missingFrom, n.From)
+			}
+		}
+		if _, ok := existing[n.To]; !ok {
+			if _, dup := seenTo[n.To]; !dup {
+				seenTo[n.To] = struct{}{}
+				missingTo = append(missingTo, n.To)
+			}
+		}
+	}
+
+	if len(missingFrom) == 0 && len(missingTo) == 0 {
+		return nil
+	}
+
+	msg := fmt.Sprintf("NudgeConfig references non-existent Component(s) in namespace %q", namespace)
+	if len(missingFrom) > 0 {
+		msg += fmt.Sprintf("; missing 'from' component(s): %s", strings.Join(missingFrom, ", "))
+	}
+	if len(missingTo) > 0 {
+		msg += fmt.Sprintf("; missing 'to' component(s): %s", strings.Join(missingTo, ", "))
+	}
+	nudgeconfiglog.Info(msg)
+	return fmt.Errorf("%s", msg)
+}
Relevance

⭐ Low

Repo convention is internal/webhook/v1beta2 (singular); same path used/added in PR #1594.

PR-#1594

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
PR Compliance ID 509 requires new or modified webhook implementations to be located under
internal/webhooks/<resource>/. The PR adds substantial webhook validation logic in
internal/webhook/v1beta2/nudgeconfig_webhook.go, which is outside the required path.

Rule 509: Place webhook implementations under internal/webhooks/<resource>/
internal/webhook/v1beta2/nudgeconfig_webhook.go[121-166]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Webhook implementation changes were made in `internal/webhook/v1beta2/nudgeconfig_webhook.go`, but compliance requires webhook implementations to live under `internal/webhooks/<resource>/`.

## Issue Context
This PR adds/extends the NudgeConfig validating webhook logic (e.g., `validateComponentsExist(...)`). The implementation location does not match the required directory structure.

## Fix Focus Areas
- internal/webhook/v1beta2/nudgeconfig_webhook.go[65-176]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment on lines +126 to +129
componentList := &applicationapiv1alpha1.ComponentList{}
if err := v.Client.List(ctx, componentList, client.InNamespace(namespace)); err != nil {
return fmt.Errorf("failed to list Components in namespace %q: %w", namespace, err)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

1. Direct v.client.list used 📘 Rule violation ⌂ Architecture

The webhook validator fetches Component resources via the raw controller-runtime client
(v.Client.List) instead of going through loader.ObjectLoader. This bypasses the required
fetching abstraction and violates the repository’s Kubernetes access policy.
Agent Prompt
## Issue description
New code fetches Kubernetes resources using `v.Client.List(...)` directly. Per compliance, all Kubernetes resource fetching must go through `loader.ObjectLoader` (or an injected abstraction that wraps it).

## Issue Context
This was introduced in the new `validateComponentsExist(...)` logic for `NudgeConfig` validation.

## Fix Focus Areas
- internal/webhook/v1beta2/nudgeconfig_webhook.go[121-134]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +132 to +156
- name: vnudgeconfig.kb.io
clientConfig:
service:
name: integration-service-webhook-service
namespace: {{ .Values.namespace | default .Release.Namespace }}
path: /validate-appstudio-redhat-com-v1beta2-nudgeconfig
failurePolicy: Fail
sideEffects: None
admissionReviewVersions:
- v1
namespaceSelector:
matchExpressions:
- key: kubernetes.io/metadata.name
operator: NotIn
values: [kube-system, kube-public, kube-node-lease]
rules:
- operations:
- CREATE
- UPDATE
apiGroups:
- appstudio.redhat.com
apiVersions:
- v1beta2
resources:
- nudgeconfigs

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

3. Duplicate chart webhook 🐞 Bug ≡ Correctness

dist/chart/templates/webhook/webhooks.yaml defines vnudgeconfig.kb.io twice in the same
ValidatingWebhookConfiguration, causing redundant admission calls and leaving the earlier entry
unscoped (so system namespaces are still matched). This can increase admission latency and defeats
the intended namespaceSelector restriction.
Agent Prompt
### Issue description
The Helm chart template renders two `webhooks` entries with `name: vnudgeconfig.kb.io`. The earlier one has no `namespaceSelector`, so the webhook still applies to system namespaces and also results in duplicate webhook invocations for normal namespaces.

### Issue Context
There is already an existing `vnudgeconfig.kb.io` entry earlier in the same `webhooks:` list. The PR added a second one with a `namespaceSelector` instead of updating the original.

### Fix Focus Areas
- dist/chart/templates/webhook/webhooks.yaml[49-156]

### What to change
- Remove the newly-added duplicate `vnudgeconfig.kb.io` block.
- Add the `namespaceSelector` stanza to the original `vnudgeconfig.kb.io` webhook entry (the one already present near the top of the validating webhook list).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +8 to +9
patches:
- path: patches/nudgeconfig_namespace_selector.yaml

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

4. Missing kustomize patch 🐞 Bug ☼ Reliability

config/webhook/kustomization.yaml references patches/nudgeconfig_namespace_selector.yaml, but
that file is not present in the PR branch, so kustomize build config/webhook (and
config/default) fails. This breaks deployment pipelines that use the kustomize manifests.
Agent Prompt
### Issue description
`config/webhook/kustomization.yaml` includes a patch file path that does not exist in the repository. This causes kustomize to error out when building the webhook manifests.

### Issue Context
The PR adds:
- `patches: - path: patches/nudgeconfig_namespace_selector.yaml`
…but there is no `config/webhook/patches/nudgeconfig_namespace_selector.yaml` in the branch.

### Fix Focus Areas
- config/webhook/kustomization.yaml[1-9]

### What to change
- Create the missing file at `config/webhook/patches/nudgeconfig_namespace_selector.yaml` (and the `config/webhook/patches/` directory).
- The patch should add the intended `namespaceSelector` to the `ValidatingWebhookConfiguration` webhook with `name: vnudgeconfig.kb.io` (metadata.name is `validating-webhook-configuration` in `config/webhook/manifests.yaml`).

Example (strategic-merge) patch content:
```yaml
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
  name: validating-webhook-configuration
webhooks:
  - name: vnudgeconfig.kb.io
    namespaceSelector:
      matchExpressions:
        - key: kubernetes.io/metadata.name
          operator: NotIn
          values:
            - kube-system
            - kube-public
            - kube-node-lease
```

(Alternatively: remove the `patches:` entry if you decide not to apply a namespaceSelector for the kustomize deployment path.)

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@fullsend-ai-review

Copy link
Copy Markdown

Review

Findings

Critical

  • [missing file / build breakage] config/webhook/kustomization.yaml:9 — The kustomization.yaml references patches/nudgeconfig_namespace_selector.yaml, but neither the config/webhook/patches/ directory nor the patch file exist in the repository or in the PR diff. Running kustomize build on this path will fail with a file-not-found error.
    Remediation: Add the missing config/webhook/patches/nudgeconfig_namespace_selector.yaml file to the PR, or remove the patches: stanza from kustomization.yaml if the namespace selector is being applied through another mechanism.

High

  • [duplicate resource / API contract violation] dist/chart/templates/webhook/webhooks.yaml:132 — The existing webhooks.yaml already contains a vnudgeconfig.kb.io webhook entry at lines 50–69 (without a namespaceSelector). The diff appends a second entry with the same name (with a namespaceSelector). Two webhooks with the same name in a single ValidatingWebhookConfiguration is invalid — Kubernetes will reject it or last-one-wins behavior will silently drop the original.
    Remediation: Replace the existing vnudgeconfig.kb.io block (lines 50–69) with the new version that includes the namespaceSelector, instead of appending a duplicate.

Medium

  • [architectural_misalignment] api/v1beta2/nudgeconfig_types.go:96 — The NudgeConfig CRD documentation states "Validation rules are enforced stateless by the API server via CEL expressions with no webhook overhead." This PR introduces a stateful webhook that performs K8s API calls to validate Component existence, contradicting the documented design principle. The CEL-based validations remain stateless; the webhook adds a complementary stateful check for what CEL cannot handle (cross-resource existence).
    Remediation: Update the documentation comment in nudgeconfig_types.go to acknowledge that Component existence validation requires stateful webhook checks alongside the CEL-based validations.

Low

  • [scope_creep] internal/webhook/v1beta2/nudgeconfig_webhook.go — The PR description and code comments reference a "stale-reference controller" that does not exist in the codebase. This is acknowledged as future work — the webhook validates at admission time and intentionally skips re-validation of pre-existing pairs on update. Consider linking to or creating a tracking issue for the stale-reference controller.

  • [error handling / availability] internal/webhook/v1beta2/nudgeconfig_webhook.go:113 — If client.List fails (e.g., RBAC issue, API server transient error), the webhook returns an error and rejects the NudgeConfig CREATE/UPDATE. Combined with failurePolicy: Fail, any Component API unavailability blocks all NudgeConfig mutations. This is a deliberate fail-closed design trade-off.

  • [inconsistent namespace scoping] config/webhook/manifests.yaml:95 — The kubebuilder-generated manifests define vnudgeconfig.kb.io without a namespaceSelector, while the Helm chart attempts to add one via a duplicate entry. The kustomize and Helm deployments may diverge in namespace scoping behavior. This is partially a consequence of the missing kustomize patch file (see Critical finding above).

@fullsend-ai-review fullsend-ai-review Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

See the review comment for full details.

Comment thread config/webhook/kustomization.yaml
Comment thread dist/chart/templates/webhook/webhooks.yaml Outdated
Comment thread internal/webhook/v1beta2/nudgeconfig_webhook.go
@fullsend-ai-review

fullsend-ai-review Bot commented Jun 30, 2026

Copy link
Copy Markdown

🤖 Review · ⚠️ Cancelled · Started 6:50 PM UTC · Ended 6:51 PM UTC
Commit: ec21706 · View workflow run →

Add a Go ValidatingWebhook that rejects NudgeConfig CREATE/UPDATE when
spec.nudges[].from or spec.nudges[].to references a Component that does
not exist in the namespace. Pre-existing entries are not re-validated on
update (staleness is the stale-reference controller's responsibility).

Signed-off-by: Josh Everett <jeverett@redhat.com>
Assisted-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@fullsend-ai-review

fullsend-ai-review Bot commented Jun 30, 2026

Copy link
Copy Markdown

🤖 Finished Review · ❌ Failure · Started 6:54 PM UTC · Completed 7:00 PM UTC
Commit: ec21706 · View workflow run →

if len(missingFrom) > 0 {
msg += fmt.Sprintf("; missing 'from' component(s): %s", strings.Join(missingFrom, ", "))
}
if len(missingTo) > 0 {

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.

nit: This logs the full rejection message at Info level, but the admission framework also logs returned errors on rejection — so every rejected NudgeConfig produces two log entries with near-identical
content. Consider either removing this explicit log or dropping it to debug level (nudgeconfiglog.V(1).Info(msg)).

msg += fmt.Sprintf("; missing 'from' component(s): %s", strings.Join(missingFrom, ", "))
}
if len(missingTo) > 0 {
msg += fmt.Sprintf("; missing 'to' component(s): %s", strings.Join(missingTo, ", "))

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.

nit: No format substitution here —errors.New(msg)is slightly more idiomatic than fmt.Errorf("%s", msg)

@kasemAlem

Copy link
Copy Markdown
Contributor

in general PR is good, beside two minor nits and fixes proposed by AI agents, make sure comments not hallucinations :)

Great work @Josh-Everett

@jencull

jencull commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

@Josh-Everett just FYI there is a flaky test that fails about 40% of the time when run on local. Ticket created to address it, 1694. https://github.com/konflux-ci/integration-service/actions/runs/28600938718/job/84808668695 <- my PR has same issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants