Skip to content

DO-NOT-MERGE: static pod deployer#2345

Draft
tjungblu wants to merge 1 commit into
openshift:masterfrom
tjungblu:static_pod_kms_preflight
Draft

DO-NOT-MERGE: static pod deployer#2345
tjungblu wants to merge 1 commit into
openshift:masterfrom
tjungblu:static_pod_kms_preflight

Conversation

@tjungblu

@tjungblu tjungblu commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

This is just an e2e, not destined for review, we pull individual refactorings out.

Summary by CodeRabbit

  • New Features

    • Added support for running KMS preflight on control-plane nodes via a static-pod workflow.
    • Introduced a one-shot installer Pod to prepare and render the preflight pod manifest and encryption configuration resources.
    • Improved static-pod behavior with conditional spec changes (host networking, kubeconfig wiring, and static pod resource mounting).
  • Refactor

    • Streamlined KMS preflight pod template rendering to support both regular and static-pod variants, plus installer-pod templating.
  • Tests

    • Expanded unit tests for template generation, deploy/status/cleanup flows, kubeconfig sourcing (cluster vs fallback), and installer creation failure handling.

@openshift-ci

openshift-ci Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

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

@openshift-ci openshift-ci Bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jul 2, 2026
@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

This PR adds static-pod support for KMS preflight by introducing new pod templates, refactoring template rendering, and implementing a StaticPodPreflightDeployer with deploy, status, cleanup, and test coverage.

Changes

KMS preflight static-pod flow

Layer / File(s) Summary
Template model and static-pod rendering
pkg/operator/encryption/kms/preflight/pod_template.go, pkg/operator/encryption/kms/preflight/assets/kms-preflight-pod.yaml, pkg/operator/encryption/kms/preflight/deployer.go
The shared preflight template data model removes kubeconfig input, adds static-pod rendering, and renders the preflight pod template through named template parsing. The static-pod pod asset conditionally changes service account, host networking, kubeconfig arguments, security context, and the resource-dir mount.
Installer pod template
pkg/operator/encryption/kms/preflight/assets/kms-preflight-installer-pod.yaml, pkg/operator/encryption/kms/preflight/pod_template.go
The installer pod asset adds master-only scheduling, a cleanup init container, the installer container script, and pod-level volumes and execution settings. The template renderer adds a dedicated installer template path.
Static pod deployer
pkg/operator/encryption/kms/preflight/static_pod_deployer.go
The new deployer validates inputs, cleans up prior resources, creates the encryption config secret, renders and stores the static pod manifest and node kubeconfig, creates the installer pod, reports mirror-pod status, and deletes the managed resources during cleanup. It also includes mirror-pod name formatting and node kubeconfig sourcing with an embedded fallback.
Template and deployer tests
pkg/operator/encryption/kms/preflight/pod_template_test.go, pkg/operator/encryption/kms/preflight/static_pod_deployer_test.go
The tests update the existing pod template call, add semantic comparisons for static and installer pod YAML, and cover deploy, status, cleanup, failure, mirror naming, and kubeconfig fallback behavior for the static-pod deployer.

Estimated code review effort: 4 (Complex) | ~60 minutes


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error, 1 warning)

Check name Status Explanation Resolution
Container-Privileges ❌ Error PR adds privileged/root/static-pod networking in K8s manifests: kms-preflight-installer-pod.yaml sets privileged: true and runAsUser: 0; kms-preflight-pod.yaml sets hostNetwork: true and runAsUser: 0. Remove these fields or add a clear security justification and ensure no privileged/root/hostNetwork settings are shipped in the manifests.
Topology-Aware Scheduling Compatibility ⚠️ Warning Static-pod and installer templates unconditionally select node-role.kubernetes.io/master, with no ControlPlaneTopology gating in the KMS preflight path. Gate scheduling on infrastructure.Status.ControlPlaneTopology or avoid in-cluster CP selectors for External/HyperShift topologies; ensure arbiter handling is explicit.
✅ Passed checks (13 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the main change: adding a static pod deployer for KMS preflight.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
Stable And Deterministic Test Names ✅ Passed No dynamic data in test titles; the new tests use static function names and static t.Run scenario names only.
Test Structure And Quality ✅ Passed PASS: These are standard table-driven unit tests, not Ginkgo; they use fake clients, no cluster waits/timeouts, and assertions are specific with helpful failure messages.
Microshift Test Compatibility ✅ Passed Added tests are plain Go unit tests, not Ginkgo e2e tests, and no MicroShift-unsupported OpenShift APIs or tags appear.
Single Node Openshift (Sno) Test Compatibility ✅ Passed No new Ginkgo e2e tests were added; the changed tests are plain Go unit tests and don't make multi-node or HA assumptions.
Ote Binary Stdout Contract ✅ Passed No new stdout writes appear in main/init/TestMain/suite setup or top-level initializers; added klog usage is confined to command/runtime code, not process-level entrypoints.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed Only plain unit tests were added; no Ginkgo/e2e specs, IPv4-only parsing, or external-network calls were found.
No-Weak-Crypto ✅ Passed No weak-crypto primitives, custom crypto, or secret/token comparisons were added in the changed files.
No-Sensitive-Data-In-Logs ✅ Passed No new logging statements appear in the changed KMS preflight files; the added code only returns errors and the shell scripts don’t echo secret contents.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@openshift-ci

openshift-ci Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: tjungblu
Once this PR has been reviewed and has the lgtm label, please assign dgrisonnet for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@coderabbitai coderabbitai 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.

Actionable comments posted: 4

🧹 Nitpick comments (1)
pkg/operator/encryption/kms/preflight/static_pod_deployer_test.go (1)

244-253: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Assert rollback on installer-create failure.

This test would still pass if Deploy leaked the copied Secret or ConfigMap after Line 247’s forced failure. After adding rollback, assert the cleanup delete actions or absence of those created objects.

🤖 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 `@pkg/operator/encryption/kms/preflight/static_pod_deployer_test.go` around
lines 244 - 253, Update
TestStaticPodPreflightDeployer_Deploy_installerCreateFailure so it verifies
rollback, not just the create error. After forcing the pod create failure in
Deploy on StaticPodPreflightDeployer, assert that the copied Secret and
ConfigMap created earlier are cleaned up by checking the kubeClient actions for
delete calls or by confirming those objects no longer exist. Use the existing
helpers around newTestStaticPodDeployer, preflightInstallerPodName, and Deploy
to keep the test focused on the installer-create failure path.
🤖 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.

Inline comments:
In
`@pkg/operator/encryption/kms/preflight/assets/kms-preflight-installer-pod.yaml`:
- Around line 37-39: The pod spec is missing resource limits for both
containers, so update the container definitions for cleanup and installer in
kms-preflight-installer-pod.yaml to include cpu and memory limits alongside the
existing requests. Ensure the limit settings are added consistently to each
container block so both the init container and main container satisfy the
resource policy.
- Around line 33-35: The installer pod securityContext is still fully privileged
and runs as root without any additional hardening. Review the installer pod
manifest and the relevant securityContext block to either justify the required
elevated access or reduce it where possible; if privileged/root is unavoidable,
add the missing hardening settings in the same installer pod definition (for
example by tightening capabilities and related security options) so the elevated
privileges are explicitly scoped and documented.

In `@pkg/operator/encryption/kms/preflight/static_pod_deployer.go`:
- Around line 110-129: Cleanup in StaticPodPreflightDeployer.Cleanup only
removes Kubernetes resources and leaves the host-side static-pod manifest and
copied resources behind. Update the cleanup flow to also invoke the
installer/static-pod removal path that deletes the host manifest and
static-pod-resources before or alongside deleting the Secret, ConfigMap, and
installer Pod, so kubelet cannot keep a stale mirror pod running.
- Around line 50-95: The preflight deploy flow in static_pod_deployer.go leaves
partially created resources behind when later steps fail, especially after the
secret/configmap creation and before installer pod creation. Update the deploy
logic around the sequence in the deploy method that calls
generateStaticPodTemplate, pluginlifecycle.NewKMSPluginBuilder().Apply, and
d.coreClient.ConfigMaps(...).Create so it tracks created resources and rolls
them back on any subsequent error, including the installer pod creation failure.
Ensure cleanup covers the copied encryption config Secret and the manifest
ConfigMap, and return the original error after rollback.

---

Nitpick comments:
In `@pkg/operator/encryption/kms/preflight/static_pod_deployer_test.go`:
- Around line 244-253: Update
TestStaticPodPreflightDeployer_Deploy_installerCreateFailure so it verifies
rollback, not just the create error. After forcing the pod create failure in
Deploy on StaticPodPreflightDeployer, assert that the copied Secret and
ConfigMap created earlier are cleaned up by checking the kubeClient actions for
delete calls or by confirming those objects no longer exist. Use the existing
helpers around newTestStaticPodDeployer, preflightInstallerPodName, and Deploy
to keep the test focused on the installer-create failure path.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 75e22f92-226f-4837-864b-a606c55d3dfa

📥 Commits

Reviewing files that changed from the base of the PR and between 821faed and bd28e37.

📒 Files selected for processing (6)
  • pkg/operator/encryption/kms/preflight/assets/kms-preflight-installer-pod.yaml
  • pkg/operator/encryption/kms/preflight/assets/kms-preflight-pod.yaml
  • pkg/operator/encryption/kms/preflight/pod_template.go
  • pkg/operator/encryption/kms/preflight/pod_template_test.go
  • pkg/operator/encryption/kms/preflight/static_pod_deployer.go
  • pkg/operator/encryption/kms/preflight/static_pod_deployer_test.go

Comment on lines +33 to +35
securityContext:
privileged: true
runAsUser: 0

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

git ls-files | rg 'pkg/operator/encryption/kms/preflight/assets/kms-preflight-installer-pod.yaml|pkg/operator/encryption/kms/preflight|kms-preflight'
printf '\n--- manifest ---\n'
cat -n pkg/operator/encryption/kms/preflight/assets/kms-preflight-installer-pod.yaml | sed -n '1,220p'
printf '\n--- references ---\n'
rg -n "kms-preflight-installer-pod|privileged: true|runAsUser: 0|allowPrivilegeEscalation|readOnlyRootFilesystem|capabilities:" pkg/operator/encryption/kms/preflight -S
printf '\n--- surrounding code ---\n'
fd -a . pkg/operator/encryption/kms/preflight

Repository: openshift/library-go

Length of output: 5957


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n--- pod_template.go ---\n'
cat -n pkg/operator/encryption/kms/preflight/pod_template.go | sed -n '1,240p'

printf '\n--- deployer.go ---\n'
cat -n pkg/operator/encryption/kms/preflight/deployer.go | sed -n '1,240p'

printf '\n--- deployer_test.go ---\n'
cat -n pkg/operator/encryption/kms/preflight/deployer_test.go | sed -n '1,220p'

printf '\n--- installer pod template tests ---\n'
cat -n pkg/operator/encryption/kms/preflight/pod_template_test.go | sed -n '1,260p'

Repository: openshift/library-go

Length of output: 27824


Installer pod still runs as root with full privilege

These host-write containers likely need elevated access, but the manifest still leaves them as privileged: true and runAsUser: 0 without any clear justification or extra hardening. If that access is required, document why it cannot be reduced; otherwise scope it down and add the missing securityContext settings where compatible.

🤖 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
`@pkg/operator/encryption/kms/preflight/assets/kms-preflight-installer-pod.yaml`
around lines 33 - 35, The installer pod securityContext is still fully
privileged and runs as root without any additional hardening. Review the
installer pod manifest and the relevant securityContext block to either justify
the required elevated access or reduce it where possible; if privileged/root is
unavoidable, add the missing hardening settings in the same installer pod
definition (for example by tightening capabilities and related security options)
so the elevated privileges are explicitly scoped and documented.

Sources: Coding guidelines, Path instructions

Comment on lines +37 to +39
requests:
memory: 10Mi
cpu: 10m

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

Missing resource limits on both containers.

Only requests are defined; no limits are set for either the cleanup init container or the installer container.

As per path instructions, "Resource limits (cpu, memory) on every container."

🔧 Proposed fix
       resources:
         requests:
           memory: 10Mi
           cpu: 10m
+        limits:
+          memory: 10Mi
+          cpu: 10m

Also applies to: 69-71

🤖 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
`@pkg/operator/encryption/kms/preflight/assets/kms-preflight-installer-pod.yaml`
around lines 37 - 39, The pod spec is missing resource limits for both
containers, so update the container definitions for cleanup and installer in
kms-preflight-installer-pod.yaml to include cpu and memory limits alongside the
existing requests. Ensure the limit settings are added consistently to each
container block so both the init container and main container satisfy the
resource policy.

Source: Path instructions

Comment on lines +50 to +95
if _, err := d.coreClient.Secrets(d.namespace).Create(ctx, encryptionConfigSecret, metav1.CreateOptions{}); err != nil {
return fmt.Errorf("failed to create preflight encryption config secret: %w", err)
}

pod, err := generateStaticPodTemplate(
preflightPodName,
d.namespace,
configHash,
d.operatorImage,
d.operatorCommand,
d.kmsCallTimeout,
)
if err != nil {
return fmt.Errorf("failed to generate preflight pod template: %w", err)
}

err = pluginlifecycle.NewKMSPluginBuilder().
WithSecretRequired().
FromEncryptionConfigSecret(d.namespace, preflightEncryptionConfigSecretName, d.coreClient).
AsStaticPod().
Apply(ctx, &pod.Spec, preflightCheckContainerName)
if err != nil {
return fmt.Errorf("failed to apply preflight plugin: %w", err)
}

podManifest := resourceread.WritePodV1OrDie(pod)
if _, err = d.coreClient.ConfigMaps(d.namespace).Create(ctx, &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Namespace: d.namespace,
Name: preflightPodConfigMapPrefix,
Labels: labels,
},
Data: map[string]string{
"pod.yaml": podManifest,
},
}, metav1.CreateOptions{}); err != nil {
return fmt.Errorf("failed to create preflight pod configmap: %w", err)
}

installerPod, err := generateInstallerPodTemplate(d.namespace, d.operatorImage)
if err != nil {
return fmt.Errorf("failed to generate preflight installer pod: %w", err)
}

if _, err = d.coreClient.Pods(d.namespace).Create(ctx, installerPod, metav1.CreateOptions{}); err != nil {
return fmt.Errorf("failed to create preflight installer pod: %w", 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.

🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

Roll back resources created during partial deploy failures.

After the preflight Secret is created, later failures leave the copied encryption config Secret and possibly the manifest ConfigMap behind; Line 94’s installer-create failure path currently returns without cleanup.

🧹 Proposed rollback pattern
-func (d *StaticPodPreflightDeployer) Deploy(ctx context.Context, configHash string, encryptionConfigSecret *corev1.Secret) error {
+func (d *StaticPodPreflightDeployer) Deploy(ctx context.Context, configHash string, encryptionConfigSecret *corev1.Secret) (retErr error) {
@@
 	if _, err := d.coreClient.Secrets(d.namespace).Create(ctx, encryptionConfigSecret, metav1.CreateOptions{}); err != nil {
 		return fmt.Errorf("failed to create preflight encryption config secret: %w", err)
 	}
+	defer func() {
+		if retErr != nil {
+			if cleanupErr := d.Cleanup(ctx); cleanupErr != nil {
+				retErr = errors.Join(retErr, cleanupErr)
+			}
+		}
+	}()
📝 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
if _, err := d.coreClient.Secrets(d.namespace).Create(ctx, encryptionConfigSecret, metav1.CreateOptions{}); err != nil {
return fmt.Errorf("failed to create preflight encryption config secret: %w", err)
}
pod, err := generateStaticPodTemplate(
preflightPodName,
d.namespace,
configHash,
d.operatorImage,
d.operatorCommand,
d.kmsCallTimeout,
)
if err != nil {
return fmt.Errorf("failed to generate preflight pod template: %w", err)
}
err = pluginlifecycle.NewKMSPluginBuilder().
WithSecretRequired().
FromEncryptionConfigSecret(d.namespace, preflightEncryptionConfigSecretName, d.coreClient).
AsStaticPod().
Apply(ctx, &pod.Spec, preflightCheckContainerName)
if err != nil {
return fmt.Errorf("failed to apply preflight plugin: %w", err)
}
podManifest := resourceread.WritePodV1OrDie(pod)
if _, err = d.coreClient.ConfigMaps(d.namespace).Create(ctx, &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Namespace: d.namespace,
Name: preflightPodConfigMapPrefix,
Labels: labels,
},
Data: map[string]string{
"pod.yaml": podManifest,
},
}, metav1.CreateOptions{}); err != nil {
return fmt.Errorf("failed to create preflight pod configmap: %w", err)
}
installerPod, err := generateInstallerPodTemplate(d.namespace, d.operatorImage)
if err != nil {
return fmt.Errorf("failed to generate preflight installer pod: %w", err)
}
if _, err = d.coreClient.Pods(d.namespace).Create(ctx, installerPod, metav1.CreateOptions{}); err != nil {
return fmt.Errorf("failed to create preflight installer pod: %w", err)
func (d *StaticPodPreflightDeployer) Deploy(ctx context.Context, configHash string, encryptionConfigSecret *corev1.Secret) (retErr error) {
if _, err := d.coreClient.Secrets(d.namespace).Create(ctx, encryptionConfigSecret, metav1.CreateOptions{}); err != nil {
return fmt.Errorf("failed to create preflight encryption config secret: %w", err)
}
defer func() {
if retErr != nil {
if cleanupErr := d.Cleanup(ctx); cleanupErr != nil {
retErr = errors.Join(retErr, cleanupErr)
}
}
}()
pod, err := generateStaticPodTemplate(
preflightPodName,
d.namespace,
configHash,
d.operatorImage,
d.operatorCommand,
d.kmsCallTimeout,
)
if err != nil {
return fmt.Errorf("failed to generate preflight pod template: %w", err)
}
err = pluginlifecycle.NewKMSPluginBuilder().
WithSecretRequired().
FromEncryptionConfigSecret(d.namespace, preflightEncryptionConfigSecretName, d.coreClient).
AsStaticPod().
Apply(ctx, &pod.Spec, preflightCheckContainerName)
if err != nil {
return fmt.Errorf("failed to apply preflight plugin: %w", err)
}
podManifest := resourceread.WritePodV1OrDie(pod)
if _, err = d.coreClient.ConfigMaps(d.namespace).Create(ctx, &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Namespace: d.namespace,
Name: preflightPodConfigMapPrefix,
Labels: labels,
},
Data: map[string]string{
"pod.yaml": podManifest,
},
}, metav1.CreateOptions{}); err != nil {
return fmt.Errorf("failed to create preflight pod configmap: %w", err)
}
installerPod, err := generateInstallerPodTemplate(d.namespace, d.operatorImage)
if err != nil {
return fmt.Errorf("failed to generate preflight installer pod: %w", err)
}
if _, err = d.coreClient.Pods(d.namespace).Create(ctx, installerPod, metav1.CreateOptions{}); err != nil {
return fmt.Errorf("failed to create preflight installer pod: %w", err)
}
🤖 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 `@pkg/operator/encryption/kms/preflight/static_pod_deployer.go` around lines 50
- 95, The preflight deploy flow in static_pod_deployer.go leaves partially
created resources behind when later steps fail, especially after the
secret/configmap creation and before installer pod creation. Update the deploy
logic around the sequence in the deploy method that calls
generateStaticPodTemplate, pluginlifecycle.NewKMSPluginBuilder().Apply, and
d.coreClient.ConfigMaps(...).Create so it tracks created resources and rolls
them back on any subsequent error, including the installer pod creation failure.
Ensure cleanup covers the copied encryption config Secret and the manifest
ConfigMap, and return the original error after rollback.

Comment on lines +110 to +129
func (d *StaticPodPreflightDeployer) Cleanup(ctx context.Context) error {
var errs []error

installerPodName := preflightInstallerPodName
err := d.coreClient.Pods(d.namespace).Delete(ctx, installerPodName, metav1.DeleteOptions{})
if err != nil && !apierrors.IsNotFound(err) {
errs = append(errs, fmt.Errorf("failed to delete installer pod %s/%s: %w", d.namespace, installerPodName, err))
}

err = d.coreClient.Secrets(d.namespace).Delete(ctx, preflightEncryptionConfigSecretName, metav1.DeleteOptions{})
if err != nil && !apierrors.IsNotFound(err) {
errs = append(errs, fmt.Errorf("failed to delete secret %s/%s: %w", d.namespace, preflightEncryptionConfigSecretName, err))
}

err = d.coreClient.ConfigMaps(d.namespace).Delete(ctx, preflightPodConfigMapPrefix, metav1.DeleteOptions{})
if err != nil && !apierrors.IsNotFound(err) {
errs = append(errs, fmt.Errorf("failed to delete configmap %s/%s: %w", d.namespace, preflightPodConfigMapPrefix, err))
}

return errors.Join(errs...)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

Cleanup needs to remove the host static-pod artifacts.

The installer writes the manifest and supporting secret material onto the host, but Cleanup only deletes Kubernetes API objects. Deleting the ConfigMap/Secret does not remove the already-copied files, so kubelet can keep the mirror pod running with stale resources. Add a cleanup installer/static-pod removal path that deletes the host manifest and copied static-pod-resources before/while removing the API objects.

🤖 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 `@pkg/operator/encryption/kms/preflight/static_pod_deployer.go` around lines
110 - 129, Cleanup in StaticPodPreflightDeployer.Cleanup only removes Kubernetes
resources and leaves the host-side static-pod manifest and copied resources
behind. Update the cleanup flow to also invoke the installer/static-pod removal
path that deletes the host manifest and static-pod-resources before or alongside
deleting the Secret, ConfigMap, and installer Pod, so kubelet cannot keep a
stale mirror pod running.

@openshift-ci openshift-ci Bot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jul 2, 2026
@tjungblu tjungblu force-pushed the static_pod_kms_preflight branch from bd28e37 to 66565e6 Compare July 3, 2026 14:12
@openshift-ci openshift-ci Bot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jul 3, 2026

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 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.

Inline comments:
In `@pkg/operator/encryption/kms/preflight/assets/kms-preflight-pod.yaml`:
- Around line 27-29: The static-pod branch in kms-preflight-pod.yaml sets
hostNetwork: true without the required justification comment. Add an inline
manifest comment near the .StaticPod conditional that explains why hostNetwork
is necessary for the static-pod variant (for example, API server reachability
before CNI is ready) and explicitly notes that no lower-privilege alternative is
available. Keep the change scoped to the hostNetwork stanza and preserve the
existing .StaticPod gating.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 99932d52-d51d-4d52-8b86-5f368f6e7dd7

📥 Commits

Reviewing files that changed from the base of the PR and between bd28e37 and 66565e6.

📒 Files selected for processing (6)
  • pkg/operator/encryption/kms/preflight/assets/kms-preflight-installer-pod.yaml
  • pkg/operator/encryption/kms/preflight/assets/kms-preflight-pod.yaml
  • pkg/operator/encryption/kms/preflight/pod_template.go
  • pkg/operator/encryption/kms/preflight/pod_template_test.go
  • pkg/operator/encryption/kms/preflight/static_pod_deployer.go
  • pkg/operator/encryption/kms/preflight/static_pod_deployer_test.go
🚧 Files skipped from review as they are similar to previous changes (5)
  • pkg/operator/encryption/kms/preflight/pod_template_test.go
  • pkg/operator/encryption/kms/preflight/static_pod_deployer_test.go
  • pkg/operator/encryption/kms/preflight/assets/kms-preflight-installer-pod.yaml
  • pkg/operator/encryption/kms/preflight/pod_template.go
  • pkg/operator/encryption/kms/preflight/static_pod_deployer.go

Comment thread pkg/operator/encryption/kms/preflight/assets/kms-preflight-pod.yaml
@tjungblu tjungblu force-pushed the static_pod_kms_preflight branch from 66565e6 to 6e06658 Compare July 3, 2026 14:29

@coderabbitai coderabbitai 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.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 3a4c3cf6-200c-4ddc-abd8-70b38314f27a

📥 Commits

Reviewing files that changed from the base of the PR and between 66565e6 and 6e06658.

📒 Files selected for processing (7)
  • pkg/operator/encryption/kms/preflight/assets/kms-preflight-installer-pod.yaml
  • pkg/operator/encryption/kms/preflight/assets/kms-preflight-pod.yaml
  • pkg/operator/encryption/kms/preflight/deployer.go
  • pkg/operator/encryption/kms/preflight/pod_template.go
  • pkg/operator/encryption/kms/preflight/pod_template_test.go
  • pkg/operator/encryption/kms/preflight/static_pod_deployer.go
  • pkg/operator/encryption/kms/preflight/static_pod_deployer_test.go
💤 Files with no reviewable changes (1)
  • pkg/operator/encryption/kms/preflight/deployer.go
🚧 Files skipped from review as they are similar to previous changes (3)
  • pkg/operator/encryption/kms/preflight/static_pod_deployer_test.go
  • pkg/operator/encryption/kms/preflight/assets/kms-preflight-installer-pod.yaml
  • pkg/operator/encryption/kms/preflight/static_pod_deployer.go

Comment thread pkg/operator/encryption/kms/preflight/assets/kms-preflight-pod.yaml
@tjungblu tjungblu force-pushed the static_pod_kms_preflight branch from 6e06658 to 4497168 Compare July 3, 2026 14:59
# This is a one-shot preflight check, not a long-running pod.
# The operator creates it, waits for completion, and inspects the result.
restartPolicy: Never
{{- if not .StaticPod}}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This is just an e2e, not destined for review, we pull individual
refactorings out.

Signed-off-by: Thomas Jungblut <tjungblu@redhat.com>
@tjungblu tjungblu force-pushed the static_pod_kms_preflight branch from 4497168 to 8fe795e Compare July 3, 2026 15:05

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 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.

Inline comments:
In `@pkg/operator/encryption/kms/preflight/static_pod_deployer.go`:
- Around line 90-99: The ConfigMap created in static_pod_deployer.go is
incorrectly storing credential data from node-kubeconfigs alongside pod.yaml in
kms-preflight-pod. Update the preflight pod setup in the staticPodDeployer flow
so pod.yaml remains in the ConfigMap, but lb-int.kubeconfig is provided via a
Secret volume or by mounting node-kubeconfigs directly; use the existing
ConfigMap creation and pod manifest assembly points to separate non-sensitive
config from kubeconfig material.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 128c6559-8472-44e1-acc1-8197ed0e5bcb

📥 Commits

Reviewing files that changed from the base of the PR and between 6e06658 and 4497168.

📒 Files selected for processing (7)
  • pkg/operator/encryption/kms/preflight/assets/kms-preflight-installer-pod.yaml
  • pkg/operator/encryption/kms/preflight/assets/kms-preflight-pod.yaml
  • pkg/operator/encryption/kms/preflight/deployer.go
  • pkg/operator/encryption/kms/preflight/pod_template.go
  • pkg/operator/encryption/kms/preflight/pod_template_test.go
  • pkg/operator/encryption/kms/preflight/static_pod_deployer.go
  • pkg/operator/encryption/kms/preflight/static_pod_deployer_test.go
💤 Files with no reviewable changes (1)
  • pkg/operator/encryption/kms/preflight/deployer.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • pkg/operator/encryption/kms/preflight/pod_template.go

Comment thread pkg/operator/encryption/kms/preflight/static_pod_deployer.go

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 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.

Inline comments:
In `@pkg/operator/encryption/kms/preflight/static_pod_deployer.go`:
- Around line 193-207: The node kubeconfig fallback in nodeKubeconfigData is
broken because mustAsset("assets/lb-int.kubeconfig") references an asset that
does not exist, so a NotFound on node-kubeconfigs can panic the deploy flow.
Update StaticPodPreflightDeployer.nodeKubeconfigData to return a valid fallback
source that is actually present or otherwise handle the NotFound case without
using mustAsset, and keep the existing secret/error handling paths intact so the
function fails cleanly instead of crashing.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 0580546c-495d-4657-8378-afb604d30132

📥 Commits

Reviewing files that changed from the base of the PR and between 4497168 and 8fe795e.

📒 Files selected for processing (7)
  • pkg/operator/encryption/kms/preflight/assets/kms-preflight-installer-pod.yaml
  • pkg/operator/encryption/kms/preflight/assets/kms-preflight-pod.yaml
  • pkg/operator/encryption/kms/preflight/deployer.go
  • pkg/operator/encryption/kms/preflight/pod_template.go
  • pkg/operator/encryption/kms/preflight/pod_template_test.go
  • pkg/operator/encryption/kms/preflight/static_pod_deployer.go
  • pkg/operator/encryption/kms/preflight/static_pod_deployer_test.go
💤 Files with no reviewable changes (1)
  • pkg/operator/encryption/kms/preflight/deployer.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • pkg/operator/encryption/kms/preflight/pod_template_test.go
  • pkg/operator/encryption/kms/preflight/static_pod_deployer_test.go

Comment on lines +193 to +207
func (d *StaticPodPreflightDeployer) nodeKubeconfigData(ctx context.Context) ([]byte, error) {
secret, err := d.coreClient.Secrets(d.namespace).Get(ctx, nodeKubeconfigsSecretName, metav1.GetOptions{})
if err != nil {
if apierrors.IsNotFound(err) {
return mustAsset("assets/lb-int.kubeconfig"), nil
}
return nil, fmt.Errorf("failed to get %s/%s secret: %w", d.namespace, nodeKubeconfigsSecretName, err)
}

kubeconfig, ok := secret.Data[nodeKubeconfigSecretKey]
if !ok || len(kubeconfig) == 0 {
return nil, fmt.Errorf("secret %s/%s is missing %q data", d.namespace, nodeKubeconfigsSecretName, nodeKubeconfigSecretKey)
}
return kubeconfig, nil
}

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Inspect the embedded fallback asset and mustAsset resolution
fd -t f 'lb-int.kubeconfig' pkg/operator/encryption/kms/preflight
rg -nP '\bmustAsset\b' -C3 pkg/operator/encryption/kms/preflight
fd -t f 'lb-int.kubeconfig' pkg/operator/encryption/kms/preflight/assets --exec sed -n '1,40p' {}

Repository: openshift/library-go

Length of output: 2899


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== asset listing ==\n'
fd -t f 'lb-int.kubeconfig' pkg/operator/encryption/kms/preflight

printf '\n== asset contents ==\n'
sed -n '1,120p' pkg/operator/encryption/kms/preflight/assets/lb-int.kubeconfig

printf '\n== references to lb-int.kubeconfig ==\n'
rg -n 'lb-int\.kubeconfig|nodeKubeconfigsSecretName|nodeKubeconfigData\(' pkg/operator/encryption/kms/preflight -C 3

printf '\n== nearby deploy flow ==\n'
sed -n '1,260p' pkg/operator/encryption/kms/preflight/static_pod_deployer.go

Repository: openshift/library-go

Length of output: 307


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== locate asset file ==\n'
fd -a -t f 'lb-int.kubeconfig' .

printf '\n== locate assets directories under preflight ==\n'
fd -a -t d 'assets' pkg/operator/encryption/kms/preflight

printf '\n== search for fallback asset usage ==\n'
rg -n 'lb-int\.kubeconfig|mustAsset\(' pkg/operator/encryption/kms/preflight -C 3

printf '\n== file inventory around preflight ==\n'
git ls-files pkg/operator/encryption/kms/preflight

Repository: openshift/library-go

Length of output: 7868


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== nodeKubeconfigData call flow ==\n'
sed -n '1,260p' pkg/operator/encryption/kms/preflight/static_pod_deployer.go

printf '\n== tests around nodeKubeconfigData / missing secret ==\n'
rg -n 'nodeKubeconfigData|node-kubeconfigs|lb-int\.kubeconfig|NotFound|missing "lb-int\.kubeconfig"' pkg/operator/encryption/kms/preflight/*_test.go -C 4

printf '\n== static pod deployer tests ==\n'
sed -n '1,260p' pkg/operator/encryption/kms/preflight/static_pod_deployer_test.go

Repository: openshift/library-go

Length of output: 20401


Missing fallback asset will panic on NotFound. nodeKubeconfigData() calls mustAsset("assets/lb-int.kubeconfig"), but that file isn’t present under pkg/operator/encryption/kms/preflight/assets/. A missing node-kubeconfigs Secret will crash the deploy path instead of failing cleanly.

🤖 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 `@pkg/operator/encryption/kms/preflight/static_pod_deployer.go` around lines
193 - 207, The node kubeconfig fallback in nodeKubeconfigData is broken because
mustAsset("assets/lb-int.kubeconfig") references an asset that does not exist,
so a NotFound on node-kubeconfigs can panic the deploy flow. Update
StaticPodPreflightDeployer.nodeKubeconfigData to return a valid fallback source
that is actually present or otherwise handle the NotFound case without using
mustAsset, and keep the existing secret/error handling paths intact so the
function fails cleanly instead of crashing.

Source: Linters/SAST tools

openshift-merge-bot Bot pushed a commit that referenced this pull request Jul 8, 2026
to facilitate static pods, this is a spin-off from #2345.

Signed-off-by: Thomas Jungblut <tjungblu@redhat.com>
@openshift-ci openshift-ci Bot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jul 8, 2026
@openshift-ci

openshift-ci Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

PR needs rebase.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

tjungblu added a commit to tjungblu/library-go that referenced this pull request Jul 9, 2026
Alternative e2e to openshift#2345 that deploys the preflight static pod through
revision snapshots and the shared installerpod installer instead of a
custom shell-based installer pod.

Signed-off-by: Thomas Jungblut <tjungblu@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Signed-off-by: Thomas Jungblut <tjungblu@redhat.com>
tjungblu added a commit to tjungblu/library-go that referenced this pull request Jul 9, 2026
Alternative e2e to openshift#2345 that deploys the preflight static pod through
revision snapshots and the shared installerpod installer instead of a
custom shell-based installer pod.

Signed-off-by: Thomas Jungblut <tjungblu@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Signed-off-by: Thomas Jungblut <tjungblu@redhat.com>
tjungblu added a commit to tjungblu/library-go that referenced this pull request Jul 9, 2026
Alternative e2e to openshift#2345 that deploys the preflight static pod through
revision snapshots and the shared installerpod installer instead of a
custom shell-based installer pod.

Signed-off-by: Thomas Jungblut <tjungblu@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Signed-off-by: Thomas Jungblut <tjungblu@redhat.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant