Skip to content

CM-716: Add HTTP01 Challenge Proxy controller#398

Open
sebrandon1 wants to merge 1 commit into
openshift:masterfrom
sebrandon1:cm-716-http01-proxy
Open

CM-716: Add HTTP01 Challenge Proxy controller#398
sebrandon1 wants to merge 1 commit into
openshift:masterfrom
sebrandon1:cm-716-http01-proxy

Conversation

@sebrandon1

@sebrandon1 sebrandon1 commented Apr 6, 2026

Copy link
Copy Markdown
Member

Summary

Adds the HTTP01 Challenge Proxy controller to cert-manager-operator, enabling cert-manager to complete HTTP01 ACME challenges for the API endpoint (api.cluster.example.com) on baremetal platforms where the API VIP is not exposed via OpenShift Ingress.

This follows the enhancement proposal in openshift/enhancements#1929 and the existing IstioCSR/TrustManager controller pattern.

How It Works

When a user creates an HTTP01Proxy CR with mode: DefaultDeployment, the operator:

  1. Validates the platform is BareMetal with distinct API and Ingress VIPs
  2. Deploys a DaemonSet on control plane nodes running a reverse proxy
  3. The proxy uses nftables to redirect HTTP traffic from API_VIP:80 to a local proxy port (default 8888)
  4. Only /.well-known/acme-challenge/* requests are forwarded to the Ingress VIP — all other requests are rejected
  5. This allows cert-manager's ACME HTTP01 solver to complete challenges for API endpoint certificates

On unsupported platforms (non-BareMetal, missing VIPs, or equal API/Ingress VIPs), the controller sets Degraded=True with a descriptive message and does not deploy any workloads.

New CRD

apiVersion: operator.openshift.io/v1alpha1
kind: HTTP01Proxy
metadata:
  name: default
  namespace: cert-manager-operator
spec:
  mode: DefaultDeployment  # or CustomDeployment with customDeployment.internalPort

Feature Gate

HTTP01Proxy — Alpha, disabled by default. Enable via --unsupported-addon-features=HTTP01Proxy=true.

Deployed Resources

When the HTTP01Proxy CR is created, the controller deploys:

  • DaemonSet (cert-manager-http01-proxy) on control plane nodes with hostNetwork: true and NET_ADMIN capability
  • ServiceAccount (cert-manager-http01-proxy)
  • ClusterRole and ClusterRoleBindings (including privileged SCC binding)
  • NetworkPolicies (deny-all ingress + allow egress on ports 80, 443, 6443)

All resources are cleaned up via a finalizer when the CR is deleted.

Testing & Deployment Guide

A how-to guide with pre-built images and step-by-step deployment instructions is available for reviewers:

Deployment & Testing Guide

The guide covers:

  • Pre-built test images (no build required)
  • Local-run and in-cluster deployment paths
  • Verification script (hack/verify-http01proxy.sh)
  • End-to-end certificate issuance with Let's Encrypt staging
  • Troubleshooting common issues

Pre-built Images

Image Tag Description
quay.io/bapalm/cert-manager-operator http01proxy Operator built from this PR (multi-arch)
quay.io/bapalm/cert-mgr-http01-proxy v0.2.0 / latest HTTP01 proxy (multi-arch, OCP 4.17+ and 5.x)

Verified On

  • CRC (SNO) — controller correctly sets Degraded with "platform type None is not supported" and creates no workloads
  • Baremetal MNO (cnfdt16, OCP 5.0) — DaemonSet deployed on all 3 master nodes, proxy running and forwarding challenges, all verification checks pass
  • All existing unit tests pass (654 tests in 28 packages)
  • make verify passes

Proxy Image

The proxy image (quay.io/bapalm/cert-mgr-http01-proxy) is a temporary development image used for initial development and testing. It will be replaced with an official OpenShift-built image before the feature graduates from alpha. Source: sebrandon1/cert-mgr-http01-proxy (forked from mvazquezc/cert-mgr-http01-proxy).

Tracking

Summary by CodeRabbit

  • New Features
    • Added an HTTP01Proxy custom resource (CRD) with singleton validation, plus a sample manifest.
    • Introduced an operator feature gate and new reconciler to manage the HTTP-01 proxy deployment.
    • Added the proxy DaemonSet, required RBAC/SCC bindings, and network policies; also extended operator manifests/related images for the proxy.
    • Added a cluster verification script for the HTTP-01 proxy rollout.
  • Bug Fixes
    • Expanded operator and controller RBAC/runtime settings (including operand image environment variables) so the proxy can be deployed and reconciled correctly.
  • Documentation
    • Added repository guidance and cleanup task tracking.

@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Apr 6, 2026
@openshift-ci-robot

openshift-ci-robot commented Apr 6, 2026

Copy link
Copy Markdown

@sebrandon1: This pull request references CM-716 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the task to target the "4.22.0" version, but no target version was set.

Details

In response to this:

Summary

Adds the HTTP01 Challenge Proxy controller to cert-manager-operator, enabling cert-manager to complete HTTP01 ACME challenges for the API endpoint (api.cluster.example.com) on baremetal platforms where the API VIP is not exposed via OpenShift Ingress.

This follows the enhancement proposal in openshift/enhancements#1929 and the existing IstioCSR/TrustManager controller pattern.

What it does

When a user creates an HTTP01Proxy CR with mode: DefaultDeployment, the operator:

  1. Validates the platform is BareMetal with distinct API and Ingress VIPs
  2. Deploys a DaemonSet on control plane nodes running a reverse proxy
  3. The proxy uses nftables to redirect HTTP traffic from API_VIP:80 to a local proxy port (default 8888)
  4. Only /.well-known/acme-challenge/* requests are forwarded to the Ingress VIP — all other requests are rejected
  5. This allows cert-manager's ACME HTTP01 solver to complete challenges for API endpoint certificates

On unsupported platforms (non-BareMetal, missing VIPs, or equal API/Ingress VIPs), the controller sets Degraded=True with a descriptive message and does not deploy any workloads.

New CRD

apiVersion: operator.openshift.io/v1alpha1
kind: HTTP01Proxy
metadata:
 name: default
 namespace: cert-manager-operator
spec:
 mode: DefaultDeployment  # or CustomDeployment with customDeployment.internalPort

Feature Gate

HTTP01Proxy — Alpha, disabled by default. Enable via --unsupported-addon-features=HTTP01Proxy=true.

Testing

  • Verified on CRC (SNO) — controller correctly sets Degraded with "platform type None is not supported" and creates no workloads
  • Verified on baremetal MNO cluster (cnfdt16) — DaemonSet deployed on all 3 master nodes, proxy running and forwarding challenges with nftables rules applied
  • All existing unit tests pass, feature gate tests updated

Tracking

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 openshift-eng/jira-lifecycle-plugin repository.

@coderabbitai

coderabbitai Bot commented Apr 6, 2026

Copy link
Copy Markdown

Caution

Review failed

An error occurred during the review process. Please try again later.

Walkthrough

Adds the HTTP01Proxy API, CRD, generated clients and apply configurations, embedded manifests and RBAC, a new controller with platform validation, manager wiring, and supporting docs, lint, and scripts.

Changes

HTTP01Proxy feature rollout

Layer / File(s) Summary
API and CRD contract
api/operator/v1alpha1/*, config/crd/bases/operator.openshift.io_http01proxies.yaml, config/crd/kustomization.yaml, config/samples/operator.openshift.io_v1alpha1_http01proxy.yaml, bundle/manifests/operator.openshift.io_http01proxies.yaml, pkg/features/features_test.go, pkg/operator/applyconfigurations/internal/internal.go
Adds the HTTP01Proxy feature gate, API types, deepcopy methods, CRD schemas, sample resource, generated type metadata, and feature coverage updates.
Generated clients and accessors
pkg/operator/applyconfigurations/operator/v1alpha1/*, pkg/operator/clientset/versioned/typed/operator/v1alpha1/*, pkg/operator/informers/externalversions/*, pkg/operator/listers/operator/v1alpha1/*
Adds apply-configuration builders, typed client/fake client surfaces, informer wiring, listers, and generic resource registration for HTTP01Proxy.
Embedded manifests and bundle wiring
bindata/http01-proxy/*, bindata/networkpolicies/*, pkg/operator/assets/bindata.go, bundle/manifests/cert-manager-operator.clusterserviceversion.yaml, config/manager/manager.yaml, config/rbac/role.yaml, Makefile
Embeds HTTP01Proxy workload and network-policy assets and wires them into the bundle, RBAC, manager env, and local run target.
HTTP01Proxy reconciler
pkg/controller/http01proxy/*.go
Adds controller constants, platform discovery, reconciliation, resource apply/delete helpers, finalizer and status handling, and cleanup logic for HTTP01Proxy-managed resources.
Manager and feature-gate wiring
pkg/operator/setup_manager.go, pkg/operator/starter.go
Adds the HTTP01Proxy enablement flag, startup gating, controller registration, cache selection, and metrics server binding changes.
Docs, lint config, and scripts
.golangci.bck.yaml, CLAUDE.md, TODO-cleanup.md, hack/verify-http01proxy.sh, rebase_all.sh
Adds repository guidance, lint configuration, cleanup notes, a verification script, and a rebase automation script.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

@openshift-ci

openshift-ci Bot commented Apr 6, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: sebrandon1
Once this PR has been reviewed and has the lgtm label, please assign mytreya-rh 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: 8

🧹 Nitpick comments (1)
pkg/controller/http01proxy/controller.go (1)

40-42: Context should be passed through, not stored in struct.

The ctx field is initialized to context.Background() and stored in the Reconciler. Helper methods (e.g., deleteDaemonSet, deleteServiceAccount) use r.ctx instead of the context passed to Reconcile(). This means operations won't be cancelled if the reconcile request is cancelled, potentially causing reliability issues with long-running cleanup operations.

♻️ Recommended approach

Pass the context from Reconcile(ctx, req) down to helper methods rather than storing it:

 type Reconciler struct {
 	common.CtrlClient
 
-	ctx           context.Context
 	eventRecorder record.EventRecorder
 	log           logr.Logger
 	scheme        *runtime.Scheme
 }

Then update helper method signatures to accept context and pass it from Reconcile:

func (r *Reconciler) deleteDaemonSet(ctx context.Context, proxy *v1alpha1.HTTP01Proxy) error {
    return r.deleteIfExists(ctx, &appsv1.DaemonSet{}, ...)
}

Also applies to: 62-62

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/controller/http01proxy/controller.go` around lines 40 - 42, The struct
field ctx should not be stored or initialized to context.Background(); remove
the ctx field from Reconciler and stop using r.ctx. Update Reconcile(ctx, req)
to pass its ctx into all helper calls (e.g., deleteDaemonSet,
deleteServiceAccount and any other helpers) and change those helper signatures
to accept ctx context.Context as their first parameter (for example func (r
*Reconciler) deleteDaemonSet(ctx context.Context, proxy *v1alpha1.HTTP01Proxy)
error) and ensure internal calls like deleteIfExists use the passed ctx instead
of r.ctx. Search for uses of r.ctx across the file (and functions like
deleteIfExists) and replace them to use the ctx parameter propagated from
Reconcile.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@bindata/http01-proxy/cert-manager-http01-proxy-clusterrole.yaml`:
- Around line 26-34: The ClusterRole block granting verbs ["create","update"] on
the cluster-scoped resource "machineconfigs" is too broad; remove the "create"
and "update" verbs from the cluster-wide ClusterRole in
cert-manager-http01-proxy-clusterrole.yaml and instead either (a) move necessary
write privileges into a namespaced Role bound to a dedicated controller
ServiceAccount, or (b) if cluster-scoped writes are unavoidable, replace the
ClusterRole entry with a more restrictive rule using "resourceNames" limited to
the specific deterministic MachineConfig names and bind it only to the dedicated
controller identity; update any RoleBinding/ClusterRoleBinding to target that
controller ServiceAccount accordingly.

In `@bindata/http01-proxy/cert-manager-http01-proxy-daemonset.yaml`:
- Around line 45-52: The securityContext for the proxy container currently
grants NET_ADMIN and runs as root but does not prevent privilege escalation;
update the proxy container's securityContext (the block containing capabilities:
add: - NET_ADMIN / drop: - ALL and runAsNonRoot: false) to include
allowPrivilegeEscalation: false so escalation is explicitly blocked while
keeping the existing capabilities intact.

In `@config/manager/manager.yaml`:
- Around line 89-90: The RELATED_IMAGE_CERT_MANAGER_HTTP01PROXY env var is using
an unpinned image tag ("quay.io/bapalm/cert-mgr-http01-proxy:latest"); change it
to a fixed version tag or digest (for example
"quay.io/bapalm/cert-mgr-http01-proxy:v0.1.0" or a sha256@digest) to match other
operand pins and ensure reproducibility and verifiability—update the value for
RELATED_IMAGE_CERT_MANAGER_HTTP01PROXY accordingly and confirm the chosen
tag/digest matches the tested/released HTTP01Proxy version.

In `@Makefile`:
- Around line 325-330: The RELATED_IMAGE_CERT_MANAGER_HTTP01PROXY value
currently uses the mutable tag ":latest" while HTTP01PROXY_OPERAND_IMAGE_VERSION
is set to "0.1.0"; change RELATED_IMAGE_CERT_MANAGER_HTTP01PROXY to use a fixed
tag or digest that matches HTTP01PROXY_OPERAND_IMAGE_VERSION (or derive the tag
from HTTP01PROXY_OPERAND_IMAGE_VERSION) so both variables are aligned and the
image is pinned for reproducible, reviewable runs; update any
documentation/comments to reflect the pinning.

In `@pkg/controller/http01proxy/infrastructure.go`:
- Around line 67-68: The current check only compares info.apiVIPs[0] and
info.ingressVIPs[0]; update the validation to ensure no VIP appears in both
slices anywhere by checking the full lists (e.g., build a set from info.apiVIPs
and test each entry of info.ingressVIPs or vice versa) and if any overlap exists
return a clear error message referencing the duplicated VIP(s). Modify the
comparison around the block that currently uses info.apiVIPs[0] and
info.ingressVIPs[0] to perform this full-list intersection check and return the
same formatted message (including the conflicting VIP(s)) when overlaps are
found.
- Around line 33-44: The code is ignoring errors from unstructured.NestedString
and NestedStringSlice which can mask malformed Infrastructure status; update the
extraction around platformType (using unstructured.NestedString) and the VIP
slices (using unstructured.NestedStringSlice) to capture and check the returned
ok/err values, and handle failures explicitly (e.g., return an error from the
function or log and fail fast) instead of silently treating them as unsupported;
specifically modify the block that builds platformInfo (referencing variables
infra.Object, platformType, platformInfo, platformBareMetal, apiVIPs,
ingressVIPs) to validate the extraction results and propagate a clear error when
parsing fails.

In `@pkg/controller/http01proxy/utils.go`:
- Around line 115-137: The daemonSetSpecModified function currently only checks
a few fields and misses many important pod and controller settings; update it to
detect any meaningful drift by comparing the full managed DaemonSet spec (or at
minimum the full PodTemplateSpec and controller-level fields) rather than only
selector/template labels and container[0] subsets—specifically include
Template.Annotations, Template.Spec (hostNetwork, tolerations, volumes,
securityContext, affinity, dnsPolicy, imagePullSecrets, init containers and all
containers with their names/images/env/ports/resources), and top-level Spec
fields like Strategy; easiest fix: replace the ad-hoc checks in
daemonSetSpecModified with a deep equality comparison between desired.Spec and
fetched.Spec (or between desired.Spec.Template and fetched.Spec.Template) or
switch to server-side apply (SSA) for this resource so any difference in those
fields triggers an update.
- Around line 141-145: The status-update error handling currently discards the
original reconcile error (prependErr) by aggregating only err and errUpdate;
change the aggregation inside the if block that follows r.updateStatus(r.ctx,
proxy) to include prependErr as well (use utilerrors.NewAggregate with
prependErr, err, and errUpdate or otherwise append prependErr into the errors
slice) so the returned aggregate preserves the original reconcile error and the
update failure; modify the code paths around r.updateStatus, prependErr,
errUpdate, and utilerrors.NewAggregate accordingly.

---

Nitpick comments:
In `@pkg/controller/http01proxy/controller.go`:
- Around line 40-42: The struct field ctx should not be stored or initialized to
context.Background(); remove the ctx field from Reconciler and stop using r.ctx.
Update Reconcile(ctx, req) to pass its ctx into all helper calls (e.g.,
deleteDaemonSet, deleteServiceAccount and any other helpers) and change those
helper signatures to accept ctx context.Context as their first parameter (for
example func (r *Reconciler) deleteDaemonSet(ctx context.Context, proxy
*v1alpha1.HTTP01Proxy) error) and ensure internal calls like deleteIfExists use
the passed ctx instead of r.ctx. Search for uses of r.ctx across the file (and
functions like deleteIfExists) and replace them to use the ctx parameter
propagated from Reconcile.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9c15de22-9f29-499f-b07d-8f12c902ce3e

📥 Commits

Reviewing files that changed from the base of the PR and between 2beb5f9 and 28e765b.

📒 Files selected for processing (44)
  • Makefile
  • api/operator/v1alpha1/features.go
  • api/operator/v1alpha1/http01proxy_types.go
  • api/operator/v1alpha1/zz_generated.deepcopy.go
  • bindata/http01-proxy/cert-manager-http01-proxy-clusterrole.yaml
  • bindata/http01-proxy/cert-manager-http01-proxy-clusterrolebinding.yaml
  • bindata/http01-proxy/cert-manager-http01-proxy-daemonset.yaml
  • bindata/http01-proxy/cert-manager-http01-proxy-scc-rolebinding.yaml
  • bindata/http01-proxy/cert-manager-http01-proxy-serviceaccount.yaml
  • bindata/networkpolicies/http01-proxy-allow-egress-networkpolicy.yaml
  • bindata/networkpolicies/http01-proxy-deny-all-networkpolicy.yaml
  • config/crd/bases/operator.openshift.io_http01proxies.yaml
  • config/manager/manager.yaml
  • config/rbac/role.yaml
  • config/samples/operator.openshift.io_v1alpha1_http01proxy.yaml
  • pkg/controller/http01proxy/constants.go
  • pkg/controller/http01proxy/controller.go
  • pkg/controller/http01proxy/daemonsets.go
  • pkg/controller/http01proxy/infrastructure.go
  • pkg/controller/http01proxy/install_http01proxy.go
  • pkg/controller/http01proxy/networkpolicies.go
  • pkg/controller/http01proxy/rbacs.go
  • pkg/controller/http01proxy/serviceaccounts.go
  • pkg/controller/http01proxy/utils.go
  • pkg/features/features_test.go
  • pkg/operator/applyconfigurations/internal/internal.go
  • pkg/operator/applyconfigurations/operator/v1alpha1/http01proxy.go
  • pkg/operator/applyconfigurations/operator/v1alpha1/http01proxycustomdeploymentspec.go
  • pkg/operator/applyconfigurations/operator/v1alpha1/http01proxyspec.go
  • pkg/operator/applyconfigurations/operator/v1alpha1/http01proxystatus.go
  • pkg/operator/applyconfigurations/utils.go
  • pkg/operator/assets/bindata.go
  • pkg/operator/clientset/versioned/typed/operator/v1alpha1/fake/fake_http01proxy.go
  • pkg/operator/clientset/versioned/typed/operator/v1alpha1/fake/fake_operator_client.go
  • pkg/operator/clientset/versioned/typed/operator/v1alpha1/generated_expansion.go
  • pkg/operator/clientset/versioned/typed/operator/v1alpha1/http01proxy.go
  • pkg/operator/clientset/versioned/typed/operator/v1alpha1/operator_client.go
  • pkg/operator/informers/externalversions/generic.go
  • pkg/operator/informers/externalversions/operator/v1alpha1/http01proxy.go
  • pkg/operator/informers/externalversions/operator/v1alpha1/interface.go
  • pkg/operator/listers/operator/v1alpha1/expansion_generated.go
  • pkg/operator/listers/operator/v1alpha1/http01proxy.go
  • pkg/operator/setup_manager.go
  • pkg/operator/starter.go

Comment thread bindata/http01-proxy/cert-manager-http01-proxy-clusterrole.yaml Outdated
Comment thread bindata/http01-proxy/cert-manager-http01-proxy-daemonset.yaml
Comment thread config/manager/manager.yaml
Comment thread Makefile
Comment thread pkg/controller/http01proxy/infrastructure.go Outdated
Comment thread pkg/controller/http01proxy/infrastructure.go Outdated
Comment thread pkg/controller/http01proxy/utils.go
Comment thread pkg/controller/http01proxy/utils.go Outdated
@sebrandon1 sebrandon1 force-pushed the cm-716-http01-proxy branch from 28e765b to baa4972 Compare April 6, 2026 20:30

@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: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
bundle/manifests/cert-manager-operator.clusterserviceversion.yaml (1)

347-399: ⚠️ Potential issue | 🟠 Major

Declare HTTP01Proxy as an owned CRD in the CSV.

This PR now exposes http01proxies in CSV RBAC, but spec.customresourcedefinitions.owned still doesn't list http01proxies.operator.openshift.io. OLM metadata for the new API stays incomplete until that entry is added.

Suggested patch
     - description: CertManager is the Schema for the certmanagers API
       displayName: CertManager
       kind: CertManager
       name: certmanagers.operator.openshift.io
       version: v1alpha1
+    - description: HTTP01Proxy describes the configuration for the managed HTTP-01 challenge proxy.
+      displayName: HTTP01Proxy
+      kind: HTTP01Proxy
+      name: http01proxies.operator.openshift.io
+      version: v1alpha1
     - description: Challenge is a type to represent a Challenge request with an ACME
         server

As per coding guidelines, "-Focus on major issues impacting performance, readability, maintainability and security. Avoid nitpicks and avoid verbosity."

Also applies to: 657-658

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@bundle/manifests/cert-manager-operator.clusterserviceversion.yaml` around
lines 347 - 399, The CSV is missing an owned CRD entry for the new HTTP01Proxy
API: add an entry under spec.customresourcedefinitions.owned with displayName
"HTTP01Proxy", kind "HTTP01Proxy", name "http01proxies.operator.openshift.io"
and the appropriate version (e.g., v1alpha1) so OLM recognizes the CRD as owned;
update the list near the other owned CRDs (similar to entries for
IstioCSR/TrustManager) to match the RBAC exposure of http01proxies.
♻️ Duplicate comments (5)
bindata/http01-proxy/cert-manager-http01-proxy-daemonset.yaml (1)

45-51: ⚠️ Potential issue | 🟠 Major

Set allowPrivilegeEscalation: false on the proxy container.

This pod already runs with hostNetwork, root, and NET_ADMIN; leaving privilege escalation implicit keeps the attack surface wider than necessary for a very privileged workload.

Suggested patch
           securityContext:
+            allowPrivilegeEscalation: false
             capabilities:
               add:
                 - NET_ADMIN
               drop:
                 - ALL
             runAsNonRoot: false

As per coding guidelines, "-Focus on major issues impacting performance, readability, maintainability and security. Avoid nitpicks and avoid verbosity."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@bindata/http01-proxy/cert-manager-http01-proxy-daemonset.yaml` around lines
45 - 51, The container securityContext is missing allowPrivilegeEscalation
explicitly and currently runAsNonRoot is false while adding NET_ADMIN and
hostNetwork increases risk; update the container's securityContext for the proxy
(the block where "securityContext:", "capabilities: add: - NET_ADMIN", and
"runAsNonRoot: false" are defined) to set allowPrivilegeEscalation: false so
privilege escalation is explicitly denied for the privileged workload, keeping
other capability and runAsNonRoot settings as intended.
pkg/controller/http01proxy/infrastructure.go (2)

66-68: ⚠️ Potential issue | 🟠 Major

Check the full VIP sets for overlap, not just index 0.

This only compares the first API/ingress VIP. Multi-VIP baremetal clusters can still overlap on later entries, which would wrongly let the proxy deploy onto an unsupported topology.

Suggested patch
-	// If API VIP == Ingress VIP, proxy is not needed
-	if info.apiVIPs[0] == info.ingressVIPs[0] {
-		return fmt.Sprintf("API VIP (%s) and ingress VIP (%s) are the same; HTTP01 proxy is not needed", info.apiVIPs[0], info.ingressVIPs[0])
-	}
+	// If any API VIP overlaps any ingress VIP, the proxy is not needed.
+	apiVIPSet := make(map[string]struct{}, len(info.apiVIPs))
+	for _, vip := range info.apiVIPs {
+		apiVIPSet[vip] = struct{}{}
+	}
+	for _, vip := range info.ingressVIPs {
+		if _, found := apiVIPSet[vip]; found {
+			return fmt.Sprintf("API VIP (%s) and ingress VIP (%s) are the same; HTTP01 proxy is not needed", vip, vip)
+		}
+	}

As per coding guidelines, "-Focus on major issues impacting performance, readability, maintainability and security. Avoid nitpicks and avoid verbosity."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/controller/http01proxy/infrastructure.go` around lines 66 - 68, The
current check only compares info.apiVIPs[0] and info.ingressVIPs[0]; change it
to detect any overlap between the two slices instead. Replace the single-index
comparison with a proper intersection test (e.g., build a set from info.apiVIPs
and check each entry of info.ingressVIPs for membership, or vice versa) and
return the same message when any VIP exists in both sets; update the conditional
that uses info.apiVIPs and info.ingressVIPs accordingly so multi-VIP clusters
with any shared VIP are handled correctly.

33-43: ⚠️ Potential issue | 🟠 Major

Propagate Infrastructure parse failures instead of masking them.

If any of these unstructured.NestedString* calls fail, validatePlatform falls back to generic "unsupported" messages and hides the real problem. Please check found/err and return a parse error here.

Suggested patch
-	platformType, _, _ := unstructured.NestedString(infra.Object, "status", "platformStatus", "type")
+	platformType, found, err := unstructured.NestedString(infra.Object, "status", "platformStatus", "type")
+	if err != nil {
+		return nil, fmt.Errorf("failed to parse infrastructure status.platformStatus.type: %w", err)
+	}
+	if !found {
+		return nil, fmt.Errorf("infrastructure status.platformStatus.type not found")
+	}
@@
 	switch platformType {
 	case platformBareMetal:
-		apiVIPs, _, _ := unstructured.NestedStringSlice(infra.Object, "status", "platformStatus", "baremetal", "apiServerInternalIPs")
-		ingressVIPs, _, _ := unstructured.NestedStringSlice(infra.Object, "status", "platformStatus", "baremetal", "ingressIPs")
+		apiVIPs, _, err := unstructured.NestedStringSlice(infra.Object, "status", "platformStatus", "baremetal", "apiServerInternalIPs")
+		if err != nil {
+			return nil, fmt.Errorf("failed to parse baremetal.apiServerInternalIPs: %w", err)
+		}
+		ingressVIPs, _, err := unstructured.NestedStringSlice(infra.Object, "status", "platformStatus", "baremetal", "ingressIPs")
+		if err != nil {
+			return nil, fmt.Errorf("failed to parse baremetal.ingressIPs: %w", err)
+		}
 		info.apiVIPs = apiVIPs
 		info.ingressVIPs = ingressVIPs
 	}

As per coding guidelines, "-Focus on major issues impacting performance, readability, maintainability and security. Avoid nitpicks and avoid verbosity."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/controller/http01proxy/infrastructure.go` around lines 33 - 43, The
current infrastructure parsing uses unstructured.NestedString and
unstructured.NestedStringSlice but ignores the found and err values, which masks
parse failures and causes validatePlatform to return generic "unsupported"
messages; update the parsing in pkg/controller/http01proxy/infrastructure.go
(around platformInfo construction and the switch handling platformBareMetal) to
check the returned (found, err) for each
unstructured.NestedString/NestedStringSlice call and, on error or missing
expected fields, return a clear parse error (propagate instead of swallowing) so
callers like validatePlatform receive and can report the real parsing failure;
reference the platformInfo struct, platformBareMetal constant, and the
unstructured.NestedString/NestedStringSlice calls when making the changes.
pkg/controller/http01proxy/utils.go (2)

115-137: ⚠️ Potential issue | 🟠 Major

DaemonSet drift detection is still too narrow.

This only checks a small subset of DaemonSetSpec, so changes to hostNetwork, tolerations, volumes, security context, template annotations, strategy, or any non-zero-index container will not trigger an update. That can leave the live proxy on stale networking or privilege settings after an upgrade. Please compare the full managed spec/template here or move this resource to SSA.


141-145: ⚠️ Potential issue | 🟠 Major

Keep the original reconcile error in the aggregate.

This branch still returns the status-update failure twice and drops prependErr, which hides the root cause and can change requeue behavior.

Suggested fix
 		errUpdate := fmt.Errorf("failed to update %s/%s status: %w", proxy.GetNamespace(), proxy.GetName(), err)
 		if prependErr != nil {
-			return utilerrors.NewAggregate([]error{err, errUpdate})
+			return utilerrors.NewAggregate([]error{prependErr, errUpdate})
 		}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/controller/http01proxy/utils.go` around lines 141 - 145, The
status-update error branch currently aggregates the update error and the
update-creation error (err and errUpdate) and drops the original reconcile error
stored in prependErr; change the logic in the block that calls r.updateStatus so
that when prependErr != nil you return
utilerrors.NewAggregate([]error{prependErr, errUpdate}) (i.e., include the
original reconcile error), and when prependErr == nil return errUpdate (or the
single update error), ensuring you reference the existing symbols updateStatus,
prependErr, errUpdate and utilerrors.NewAggregate and avoid duplicating the same
error twice.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@bundle/manifests/cert-manager-operator.clusterserviceversion.yaml`:
- Around line 797-798: The RELATED_IMAGE_CERT_MANAGER_HTTP01PROXY entry is using
an immutably-tagged image (quay.io/...:latest) which should be pinned; replace
the :latest tag with the immutable release reference used by the operator (use
the same value as HTTP01PROXY_OPERAND_IMAGE_VERSION or hardcode that version,
e.g. :0.1.0) so the bundle is reproducible, and apply the same change to the
other RELATED_IMAGE_CERT_MANAGER_HTTP01PROXY occurrences noted in the file (the
other RELATED_IMAGE entries mentioned). Ensure the RELATED_IMAGE value exactly
matches the operand version the operator publishes
(HTTP01PROXY_OPERAND_IMAGE_VERSION).

In `@pkg/controller/http01proxy/utils.go`:
- Around line 140-141: The updateCondition function currently uses the stored
background context r.ctx which can ignore reconcile cancellation; change the
signature of updateCondition to accept a context parameter (ctx
context.Context), propagate that ctx into the call to r.updateStatus (replace
r.ctx with ctx), and update all callers (notably Reconciler.Reconcile) to pass
the incoming request context instead of relying on r.ctx; ensure any other
internal uses of updateCondition are updated similarly and remove reliance on
r.ctx for status updates so status updates respect deadlines/cancellations.

In `@pkg/features/features_test.go`:
- Around line 114-117: The current assertion compares isPreGA to !spec.Default
(using assert.Equal), which forces GA features to be default-enabled; change the
test to only assert that pre-GA features are disabled by making the check
conditional: compute isPreGA (as you already do using spec.PreRelease,
featuregate.Alpha and featuregate.Beta) and then if isPreGA assert that
spec.Default is false (e.g., assert.False on spec.Default with the same message
referencing feat and spec.PreRelease); do not assert anything for non-pre-GA
features so GA features can be intentionally default-off.

---

Outside diff comments:
In `@bundle/manifests/cert-manager-operator.clusterserviceversion.yaml`:
- Around line 347-399: The CSV is missing an owned CRD entry for the new
HTTP01Proxy API: add an entry under spec.customresourcedefinitions.owned with
displayName "HTTP01Proxy", kind "HTTP01Proxy", name
"http01proxies.operator.openshift.io" and the appropriate version (e.g.,
v1alpha1) so OLM recognizes the CRD as owned; update the list near the other
owned CRDs (similar to entries for IstioCSR/TrustManager) to match the RBAC
exposure of http01proxies.

---

Duplicate comments:
In `@bindata/http01-proxy/cert-manager-http01-proxy-daemonset.yaml`:
- Around line 45-51: The container securityContext is missing
allowPrivilegeEscalation explicitly and currently runAsNonRoot is false while
adding NET_ADMIN and hostNetwork increases risk; update the container's
securityContext for the proxy (the block where "securityContext:",
"capabilities: add: - NET_ADMIN", and "runAsNonRoot: false" are defined) to set
allowPrivilegeEscalation: false so privilege escalation is explicitly denied for
the privileged workload, keeping other capability and runAsNonRoot settings as
intended.

In `@pkg/controller/http01proxy/infrastructure.go`:
- Around line 66-68: The current check only compares info.apiVIPs[0] and
info.ingressVIPs[0]; change it to detect any overlap between the two slices
instead. Replace the single-index comparison with a proper intersection test
(e.g., build a set from info.apiVIPs and check each entry of info.ingressVIPs
for membership, or vice versa) and return the same message when any VIP exists
in both sets; update the conditional that uses info.apiVIPs and info.ingressVIPs
accordingly so multi-VIP clusters with any shared VIP are handled correctly.
- Around line 33-43: The current infrastructure parsing uses
unstructured.NestedString and unstructured.NestedStringSlice but ignores the
found and err values, which masks parse failures and causes validatePlatform to
return generic "unsupported" messages; update the parsing in
pkg/controller/http01proxy/infrastructure.go (around platformInfo construction
and the switch handling platformBareMetal) to check the returned (found, err)
for each unstructured.NestedString/NestedStringSlice call and, on error or
missing expected fields, return a clear parse error (propagate instead of
swallowing) so callers like validatePlatform receive and can report the real
parsing failure; reference the platformInfo struct, platformBareMetal constant,
and the unstructured.NestedString/NestedStringSlice calls when making the
changes.

In `@pkg/controller/http01proxy/utils.go`:
- Around line 141-145: The status-update error branch currently aggregates the
update error and the update-creation error (err and errUpdate) and drops the
original reconcile error stored in prependErr; change the logic in the block
that calls r.updateStatus so that when prependErr != nil you return
utilerrors.NewAggregate([]error{prependErr, errUpdate}) (i.e., include the
original reconcile error), and when prependErr == nil return errUpdate (or the
single update error), ensuring you reference the existing symbols updateStatus,
prependErr, errUpdate and utilerrors.NewAggregate and avoid duplicating the same
error twice.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5f8af34a-6eb0-4edc-86ac-c64d16215328

📥 Commits

Reviewing files that changed from the base of the PR and between 28e765b and baa4972.

📒 Files selected for processing (45)
  • Makefile
  • api/operator/v1alpha1/features.go
  • api/operator/v1alpha1/http01proxy_types.go
  • api/operator/v1alpha1/zz_generated.deepcopy.go
  • bindata/http01-proxy/cert-manager-http01-proxy-clusterrole.yaml
  • bindata/http01-proxy/cert-manager-http01-proxy-clusterrolebinding.yaml
  • bindata/http01-proxy/cert-manager-http01-proxy-daemonset.yaml
  • bindata/http01-proxy/cert-manager-http01-proxy-scc-rolebinding.yaml
  • bindata/http01-proxy/cert-manager-http01-proxy-serviceaccount.yaml
  • bindata/networkpolicies/http01-proxy-allow-egress-networkpolicy.yaml
  • bindata/networkpolicies/http01-proxy-deny-all-networkpolicy.yaml
  • bundle/manifests/cert-manager-operator.clusterserviceversion.yaml
  • config/crd/bases/operator.openshift.io_http01proxies.yaml
  • config/manager/manager.yaml
  • config/rbac/role.yaml
  • config/samples/operator.openshift.io_v1alpha1_http01proxy.yaml
  • pkg/controller/http01proxy/constants.go
  • pkg/controller/http01proxy/controller.go
  • pkg/controller/http01proxy/daemonsets.go
  • pkg/controller/http01proxy/infrastructure.go
  • pkg/controller/http01proxy/install_http01proxy.go
  • pkg/controller/http01proxy/networkpolicies.go
  • pkg/controller/http01proxy/rbacs.go
  • pkg/controller/http01proxy/serviceaccounts.go
  • pkg/controller/http01proxy/utils.go
  • pkg/features/features_test.go
  • pkg/operator/applyconfigurations/internal/internal.go
  • pkg/operator/applyconfigurations/operator/v1alpha1/http01proxy.go
  • pkg/operator/applyconfigurations/operator/v1alpha1/http01proxycustomdeploymentspec.go
  • pkg/operator/applyconfigurations/operator/v1alpha1/http01proxyspec.go
  • pkg/operator/applyconfigurations/operator/v1alpha1/http01proxystatus.go
  • pkg/operator/applyconfigurations/utils.go
  • pkg/operator/assets/bindata.go
  • pkg/operator/clientset/versioned/typed/operator/v1alpha1/fake/fake_http01proxy.go
  • pkg/operator/clientset/versioned/typed/operator/v1alpha1/fake/fake_operator_client.go
  • pkg/operator/clientset/versioned/typed/operator/v1alpha1/generated_expansion.go
  • pkg/operator/clientset/versioned/typed/operator/v1alpha1/http01proxy.go
  • pkg/operator/clientset/versioned/typed/operator/v1alpha1/operator_client.go
  • pkg/operator/informers/externalversions/generic.go
  • pkg/operator/informers/externalversions/operator/v1alpha1/http01proxy.go
  • pkg/operator/informers/externalversions/operator/v1alpha1/interface.go
  • pkg/operator/listers/operator/v1alpha1/expansion_generated.go
  • pkg/operator/listers/operator/v1alpha1/http01proxy.go
  • pkg/operator/setup_manager.go
  • pkg/operator/starter.go
✅ Files skipped from review due to trivial changes (18)
  • pkg/operator/applyconfigurations/utils.go
  • bindata/http01-proxy/cert-manager-http01-proxy-serviceaccount.yaml
  • pkg/operator/clientset/versioned/typed/operator/v1alpha1/generated_expansion.go
  • bindata/http01-proxy/cert-manager-http01-proxy-scc-rolebinding.yaml
  • bindata/networkpolicies/http01-proxy-allow-egress-networkpolicy.yaml
  • config/samples/operator.openshift.io_v1alpha1_http01proxy.yaml
  • bindata/networkpolicies/http01-proxy-deny-all-networkpolicy.yaml
  • pkg/operator/applyconfigurations/internal/internal.go
  • pkg/operator/listers/operator/v1alpha1/expansion_generated.go
  • pkg/operator/informers/externalversions/generic.go
  • bindata/http01-proxy/cert-manager-http01-proxy-clusterrolebinding.yaml
  • config/manager/manager.yaml
  • pkg/operator/applyconfigurations/operator/v1alpha1/http01proxyspec.go
  • pkg/operator/clientset/versioned/typed/operator/v1alpha1/fake/fake_http01proxy.go
  • pkg/operator/applyconfigurations/operator/v1alpha1/http01proxystatus.go
  • config/crd/bases/operator.openshift.io_http01proxies.yaml
  • pkg/controller/http01proxy/networkpolicies.go
  • pkg/operator/clientset/versioned/typed/operator/v1alpha1/http01proxy.go
🚧 Files skipped from review as they are similar to previous changes (16)
  • api/operator/v1alpha1/features.go
  • pkg/operator/clientset/versioned/typed/operator/v1alpha1/fake/fake_operator_client.go
  • bindata/http01-proxy/cert-manager-http01-proxy-clusterrole.yaml
  • pkg/operator/starter.go
  • Makefile
  • pkg/controller/http01proxy/serviceaccounts.go
  • config/rbac/role.yaml
  • pkg/operator/applyconfigurations/operator/v1alpha1/http01proxycustomdeploymentspec.go
  • pkg/operator/informers/externalversions/operator/v1alpha1/interface.go
  • pkg/controller/http01proxy/rbacs.go
  • pkg/controller/http01proxy/install_http01proxy.go
  • pkg/operator/informers/externalversions/operator/v1alpha1/http01proxy.go
  • api/operator/v1alpha1/http01proxy_types.go
  • pkg/controller/http01proxy/daemonsets.go
  • pkg/controller/http01proxy/controller.go
  • pkg/operator/assets/bindata.go

Comment thread bundle/manifests/cert-manager-operator.clusterserviceversion.yaml
Comment thread pkg/controller/http01proxy/utils.go Outdated
Comment thread pkg/features/features_test.go
@sebrandon1 sebrandon1 force-pushed the cm-716-http01-proxy branch from baa4972 to 8fc4aa5 Compare April 7, 2026 15:42

@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: 3

♻️ Duplicate comments (1)
pkg/controller/http01proxy/utils.go (1)

115-137: ⚠️ Potential issue | 🟠 Major

DaemonSet drift detection still misses networking and privilege changes.

This comparator only checks labels, first-container image/env/ports, serviceAccountName, and nodeSelector. Hardening or rollout changes in the current manifest—hostNetwork, tolerations, allowPrivilegeEscalation, capabilities, resources, priorityClassName, and most of the pod template—won't update existing clusters.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/controller/http01proxy/utils.go` around lines 115 - 137, The
daemonSetSpecModified comparator currently only checks a few fields and misses
important pod/podTemplate changes (networking, security, resources, scheduling)
— update daemonSetSpecModified to compare the full pod template spec (or
explicitly include the missing fields) instead of only labels/first container
basics: ensure you compare desired.Spec.Template.Spec vs
fetched.Spec.Template.Spec (or at minimum include hostNetwork, tolerations,
securityContext (containers[].securityContext and podSecurityContext),
allowPrivilegeEscalation, capabilities, resources, volume/volumeMounts,
affinity/nodeAffinity, tolerations, priorityClassName, dnsPolicy, restartPolicy,
and any other container-level fields) so drift detection triggers updates when
those values diverge.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@pkg/controller/http01proxy/controller.go`:
- Around line 101-109: The controller currently never watches the cluster
Infrastructure resource, so platform changes discovered by discoverPlatform()
(in pkg/controller/http01proxy/infrastructure.go) won't trigger reconciles for
HTTP01Proxy; add a Watch for the cluster Infrastructure object
(configv1.Infrastructure) to the controller builder—e.g. add
Watches(&configv1.Infrastructure{}, handler.EnqueueRequestsFromMapFunc(mapFunc),
controllerManagedResourcePredicates) (and import configv1) so changes to the
Infrastructure/cluster resource enqueue the HTTP01Proxy reconcile via the
existing mapFunc and predicates.

In `@pkg/controller/http01proxy/install_http01proxy.go`:
- Around line 18-20: validatePlatform returning unsupported currently bails out
without cleaning up already-deployed proxy resources; change the branch so that
before returning the irrecoverable error you invoke the same teardown used in
the deletion path (e.g., call the deletion/cleanup routine used for HTTP01 proxy
such as r.deleteHTTP01ProxyResources or the function(s) that remove the
DaemonSet, ServiceAccount, RBAC, NetworkPolicies and any nftables redirection),
ensure the cleanup is idempotent and ignores NotFound errors, then log and
return common.NewIrrecoverableError(fmt.Errorf("platform validation failed"),
"%s", reason) as before; keep references to validatePlatform and the
NewIrrecoverableError return path.

In `@pkg/operator/assets/bindata.go`:
- Around line 2299-2325: The ClusterRole in
bindata/http01-proxy/cert-manager-http01-proxy-clusterrole.yaml grants
unnecessary MCO write permissions: remove the entire rule block that targets
apiGroups: ["operator.openshift.io"] with resources: ["machineconfigurations"]
and verbs: ["update"] and the rule block that targets apiGroups:
["machineconfiguration.openshift.io"] with resources: ["machineconfigs"] and
verbs: ["get","list","create","update"]; then regenerate the bindata so
pkg/operator/assets/bindata.go is updated accordingly and verify http01-proxy
DaemonSet/service account no longer receives machineconfig write rights.

---

Duplicate comments:
In `@pkg/controller/http01proxy/utils.go`:
- Around line 115-137: The daemonSetSpecModified comparator currently only
checks a few fields and misses important pod/podTemplate changes (networking,
security, resources, scheduling) — update daemonSetSpecModified to compare the
full pod template spec (or explicitly include the missing fields) instead of
only labels/first container basics: ensure you compare
desired.Spec.Template.Spec vs fetched.Spec.Template.Spec (or at minimum include
hostNetwork, tolerations, securityContext (containers[].securityContext and
podSecurityContext), allowPrivilegeEscalation, capabilities, resources,
volume/volumeMounts, affinity/nodeAffinity, tolerations, priorityClassName,
dnsPolicy, restartPolicy, and any other container-level fields) so drift
detection triggers updates when those values diverge.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e8402571-bb33-4ef5-9165-93da089dc08e

📥 Commits

Reviewing files that changed from the base of the PR and between baa4972 and 8fc4aa5.

📒 Files selected for processing (45)
  • Makefile
  • api/operator/v1alpha1/features.go
  • api/operator/v1alpha1/http01proxy_types.go
  • api/operator/v1alpha1/zz_generated.deepcopy.go
  • bindata/http01-proxy/cert-manager-http01-proxy-clusterrole.yaml
  • bindata/http01-proxy/cert-manager-http01-proxy-clusterrolebinding.yaml
  • bindata/http01-proxy/cert-manager-http01-proxy-daemonset.yaml
  • bindata/http01-proxy/cert-manager-http01-proxy-scc-rolebinding.yaml
  • bindata/http01-proxy/cert-manager-http01-proxy-serviceaccount.yaml
  • bindata/networkpolicies/http01-proxy-allow-egress-networkpolicy.yaml
  • bindata/networkpolicies/http01-proxy-deny-all-networkpolicy.yaml
  • bundle/manifests/cert-manager-operator.clusterserviceversion.yaml
  • config/crd/bases/operator.openshift.io_http01proxies.yaml
  • config/manager/manager.yaml
  • config/rbac/role.yaml
  • config/samples/operator.openshift.io_v1alpha1_http01proxy.yaml
  • pkg/controller/http01proxy/constants.go
  • pkg/controller/http01proxy/controller.go
  • pkg/controller/http01proxy/daemonsets.go
  • pkg/controller/http01proxy/infrastructure.go
  • pkg/controller/http01proxy/install_http01proxy.go
  • pkg/controller/http01proxy/networkpolicies.go
  • pkg/controller/http01proxy/rbacs.go
  • pkg/controller/http01proxy/serviceaccounts.go
  • pkg/controller/http01proxy/utils.go
  • pkg/features/features_test.go
  • pkg/operator/applyconfigurations/internal/internal.go
  • pkg/operator/applyconfigurations/operator/v1alpha1/http01proxy.go
  • pkg/operator/applyconfigurations/operator/v1alpha1/http01proxycustomdeploymentspec.go
  • pkg/operator/applyconfigurations/operator/v1alpha1/http01proxyspec.go
  • pkg/operator/applyconfigurations/operator/v1alpha1/http01proxystatus.go
  • pkg/operator/applyconfigurations/utils.go
  • pkg/operator/assets/bindata.go
  • pkg/operator/clientset/versioned/typed/operator/v1alpha1/fake/fake_http01proxy.go
  • pkg/operator/clientset/versioned/typed/operator/v1alpha1/fake/fake_operator_client.go
  • pkg/operator/clientset/versioned/typed/operator/v1alpha1/generated_expansion.go
  • pkg/operator/clientset/versioned/typed/operator/v1alpha1/http01proxy.go
  • pkg/operator/clientset/versioned/typed/operator/v1alpha1/operator_client.go
  • pkg/operator/informers/externalversions/generic.go
  • pkg/operator/informers/externalversions/operator/v1alpha1/http01proxy.go
  • pkg/operator/informers/externalversions/operator/v1alpha1/interface.go
  • pkg/operator/listers/operator/v1alpha1/expansion_generated.go
  • pkg/operator/listers/operator/v1alpha1/http01proxy.go
  • pkg/operator/setup_manager.go
  • pkg/operator/starter.go
✅ Files skipped from review due to trivial changes (21)
  • pkg/operator/clientset/versioned/typed/operator/v1alpha1/generated_expansion.go
  • pkg/operator/applyconfigurations/internal/internal.go
  • bindata/networkpolicies/http01-proxy-allow-egress-networkpolicy.yaml
  • config/samples/operator.openshift.io_v1alpha1_http01proxy.yaml
  • bindata/networkpolicies/http01-proxy-deny-all-networkpolicy.yaml
  • bindata/http01-proxy/cert-manager-http01-proxy-clusterrolebinding.yaml
  • pkg/operator/informers/externalversions/generic.go
  • Makefile
  • bindata/http01-proxy/cert-manager-http01-proxy-serviceaccount.yaml
  • pkg/operator/applyconfigurations/operator/v1alpha1/http01proxycustomdeploymentspec.go
  • bindata/http01-proxy/cert-manager-http01-proxy-clusterrole.yaml
  • bindata/http01-proxy/cert-manager-http01-proxy-scc-rolebinding.yaml
  • pkg/operator/informers/externalversions/operator/v1alpha1/interface.go
  • config/rbac/role.yaml
  • pkg/operator/applyconfigurations/operator/v1alpha1/http01proxystatus.go
  • pkg/controller/http01proxy/networkpolicies.go
  • pkg/operator/applyconfigurations/operator/v1alpha1/http01proxyspec.go
  • pkg/operator/listers/operator/v1alpha1/http01proxy.go
  • pkg/operator/informers/externalversions/operator/v1alpha1/http01proxy.go
  • pkg/controller/http01proxy/daemonsets.go
  • pkg/operator/applyconfigurations/operator/v1alpha1/http01proxy.go
🚧 Files skipped from review as they are similar to previous changes (14)
  • pkg/operator/applyconfigurations/utils.go
  • pkg/operator/listers/operator/v1alpha1/expansion_generated.go
  • pkg/operator/starter.go
  • config/manager/manager.yaml
  • api/operator/v1alpha1/features.go
  • pkg/operator/clientset/versioned/typed/operator/v1alpha1/fake/fake_operator_client.go
  • pkg/features/features_test.go
  • pkg/controller/http01proxy/serviceaccounts.go
  • pkg/operator/setup_manager.go
  • pkg/controller/http01proxy/constants.go
  • pkg/operator/clientset/versioned/typed/operator/v1alpha1/fake/fake_http01proxy.go
  • bundle/manifests/cert-manager-operator.clusterserviceversion.yaml
  • api/operator/v1alpha1/http01proxy_types.go
  • config/crd/bases/operator.openshift.io_http01proxies.yaml

Comment thread pkg/controller/http01proxy/controller.go
Comment thread pkg/controller/http01proxy/install_http01proxy.go
Comment thread pkg/operator/assets/bindata.go
@sebrandon1 sebrandon1 force-pushed the cm-716-http01-proxy branch from 8fc4aa5 to b1138fe Compare April 17, 2026 15:26
@openshift-ci-robot

openshift-ci-robot commented Apr 17, 2026

Copy link
Copy Markdown

@sebrandon1: This pull request references CM-716 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the task to target the "5.0.0" version, but no target version was set.

Details

In response to this:

Summary

Adds the HTTP01 Challenge Proxy controller to cert-manager-operator, enabling cert-manager to complete HTTP01 ACME challenges for the API endpoint (api.cluster.example.com) on baremetal platforms where the API VIP is not exposed via OpenShift Ingress.

This follows the enhancement proposal in openshift/enhancements#1929 and the existing IstioCSR/TrustManager controller pattern.

What it does

When a user creates an HTTP01Proxy CR with mode: DefaultDeployment, the operator:

  1. Validates the platform is BareMetal with distinct API and Ingress VIPs
  2. Deploys a DaemonSet on control plane nodes running a reverse proxy
  3. The proxy uses nftables to redirect HTTP traffic from API_VIP:80 to a local proxy port (default 8888)
  4. Only /.well-known/acme-challenge/* requests are forwarded to the Ingress VIP — all other requests are rejected
  5. This allows cert-manager's ACME HTTP01 solver to complete challenges for API endpoint certificates

On unsupported platforms (non-BareMetal, missing VIPs, or equal API/Ingress VIPs), the controller sets Degraded=True with a descriptive message and does not deploy any workloads.

New CRD

apiVersion: operator.openshift.io/v1alpha1
kind: HTTP01Proxy
metadata:
 name: default
 namespace: cert-manager-operator
spec:
 mode: DefaultDeployment  # or CustomDeployment with customDeployment.internalPort

Feature Gate

HTTP01Proxy — Alpha, disabled by default. Enable via --unsupported-addon-features=HTTP01Proxy=true.

Testing

  • Verified on CRC (SNO) — controller correctly sets Degraded with "platform type None is not supported" and creates no workloads
  • Verified on baremetal MNO cluster (cnfdt16) — DaemonSet deployed on all 3 master nodes, proxy running and forwarding challenges with nftables rules applied
  • All existing unit tests pass, feature gate tests updated

Tracking

Summary by CodeRabbit

  • New Features

  • Added HTTP01Proxy custom resource for managing HTTP-01 proxy deployments across cluster nodes.

  • Introduced HTTP01Proxy feature gate (disabled by default, alpha status) to control the new capability.

  • Supports two deployment modes: DefaultDeployment and CustomDeployment with configurable port settings.

  • Chores

  • Updated operator configuration and RBAC permissions to support HTTP01 proxy management.

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 openshift-eng/jira-lifecycle-plugin repository.

@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: 3

♻️ Duplicate comments (3)
bundle/manifests/cert-manager-operator.clusterserviceversion.yaml (1)

797-798: ⚠️ Potential issue | 🟠 Major

Pin the HTTP01 proxy image to the release tag.

RELATED_IMAGE_CERT_MANAGER_HTTP01PROXY and spec.relatedImages still point at :latest, while HTTP01PROXY_OPERAND_IMAGE_VERSION says 0.1.0. That makes the bundle non-reproducible and lets the reported operand version drift from what clusters actually deploy. Use the same immutable tag in all three places.

Also applies to: 805-806, 923-924

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@bundle/manifests/cert-manager-operator.clusterserviceversion.yaml` around
lines 797 - 798, The RELATED_IMAGE_CERT_MANAGER_HTTP01PROXY environment var and
spec.relatedImages entries are using :latest while
HTTP01PROXY_OPERAND_IMAGE_VERSION is 0.1.0; update
RELATED_IMAGE_CERT_MANAGER_HTTP01PROXY and the corresponding spec.relatedImages
entries to use the immutable release tag (e.g.,
quay.io/bapalm/cert-mgr-http01-proxy:0.1.0) so all three places
(RELATED_IMAGE_CERT_MANAGER_HTTP01PROXY, spec.relatedImages, and
HTTP01PROXY_OPERAND_IMAGE_VERSION) reference the same pinned tag and eliminate
the :latest drift.
pkg/controller/http01proxy/controller.go (1)

104-112: ⚠️ Potential issue | 🟠 Major

Watch Infrastructure/cluster as a reconciliation trigger.

discoverPlatform() depends on Infrastructure/cluster, but this controller never watches that object. Because unsupported platform failures are treated as irrecoverable, later VIP/platform fixes will not enqueue a new reconcile unless someone touches the HTTP01Proxy manually.

#!/bin/bash
sed -n '72,112p' pkg/controller/http01proxy/controller.go
printf '\n---\n'
sed -n '37,74p' pkg/controller/http01proxy/infrastructure.go
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/controller/http01proxy/controller.go` around lines 104 - 112, The
controller never watches the Infrastructure/cluster object that
discoverPlatform() relies on, so platform/VIP fixes won't requeue reconciles;
update the controller setup in NewControllerManagedBy(...) (the chain that
For(&v1alpha1.HTTP01Proxy{}, ...) and subsequent Watches(...)) to add a watch
for the Infrastructure resource (e.g. &configv1.Infrastructure{}) using the same
mapFunc enqueuer (handler.EnqueueRequestsFromMapFunc(mapFunc)) and appropriate
predicates (controllerManagedResourcePredicates or the existing
withIgnoreStatusUpdatePredicates as needed) so changes to Infrastructure/cluster
trigger reconciles that call discoverPlatform().
pkg/controller/http01proxy/install_http01proxy.go (1)

18-20: ⚠️ Potential issue | 🟠 Major

Tear down existing resources before returning unsupported.

This branch only blocks future applies. If the proxy was already deployed, the DaemonSet, RBAC, ServiceAccount, and NetworkPolicies remain until the CR is deleted, which leaves the old datapath in place after the controller has declared the platform unsupported. Call the same cleanup path used in cleanUp() before returning the irrecoverable error.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/controller/http01proxy/install_http01proxy.go` around lines 18 - 20, The
platform-validation branch returns an irrecoverable error but doesn't remove
existing resources; before returning from the validatePlatform check in
install_http01proxy.go, call the same cleanup path used by cleanUp() to delete
the DaemonSet, RBAC, ServiceAccount and NetworkPolicies (e.g., invoke
r.cleanUp(...) or the existing cleanUp helper used elsewhere), handle/propagate
any cleanup errors appropriately (log them with r.log and include them in the
returned error if needed), then return
common.NewIrrecoverableError(fmt.Errorf("platform validation failed"), "%s",
reason) as before.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@bindata/http01-proxy/cert-manager-http01-proxy-daemonset.yaml`:
- Around line 23-24: The DaemonSet currently sets hostNetwork: true which
prevents Kubernetes NetworkPolicies from applying; edit the
cert-manager-http01-proxy DaemonSet spec to remove or set hostNetwork to false
(i.e., stop joining the node network namespace) and instead expose required
ports via container hostPort or a NodePort/HostPort + proper selector, or
enforce node-level firewall rules if node networking is required; update the pod
spec (where serviceAccountName: cert-manager-http01-proxy appears) to use
hostPort or a Service-backed approach and verify NetworkPolicy rules now target
the podSelector so least-privilege egress works as intended.

In `@pkg/controller/http01proxy/controller.go`:
- Around line 40-46: The reconciler currently holds a long-lived context (ctx)
on the struct; remove the ctx field (and any initialization using
context.Background()) from the controller struct and any place it is set, then
propagate the context parameter from Reconcile through all helper methods
(cleanUp, reconcileHTTP01ProxyDeployment and any nested calls) so every
downstream API call uses the Reconcile-scoped ctx for cancellation and
deadlines; update signatures to accept ctx where needed, replace r.ctx uses with
the passed ctx, and ensure no code uses a long-lived background context or a
reconciler-level ctx variable.

In `@pkg/controller/http01proxy/infrastructure.go`:
- Around line 25-34: The current getOrDiscoverPlatform caches platformInfo in
r.cachedPlatform forever; change this so the controller doesn't use stale
Infrastructure data by invalidating the cache before each reconcile or on
Infrastructure change. Concretely: either set r.cachedPlatform = nil at the
start of Reconciler.Reconcile (so getOrDiscoverPlatform always re-reads
per-reconcile), or implement an Infrastructure watch/event handler that clears
r.cachedPlatform when the Infrastructure/cluster resource changes; update
getOrDiscoverPlatform/discoverPlatform usage accordingly to avoid permanent
caching.

---

Duplicate comments:
In `@bundle/manifests/cert-manager-operator.clusterserviceversion.yaml`:
- Around line 797-798: The RELATED_IMAGE_CERT_MANAGER_HTTP01PROXY environment
var and spec.relatedImages entries are using :latest while
HTTP01PROXY_OPERAND_IMAGE_VERSION is 0.1.0; update
RELATED_IMAGE_CERT_MANAGER_HTTP01PROXY and the corresponding spec.relatedImages
entries to use the immutable release tag (e.g.,
quay.io/bapalm/cert-mgr-http01-proxy:0.1.0) so all three places
(RELATED_IMAGE_CERT_MANAGER_HTTP01PROXY, spec.relatedImages, and
HTTP01PROXY_OPERAND_IMAGE_VERSION) reference the same pinned tag and eliminate
the :latest drift.

In `@pkg/controller/http01proxy/controller.go`:
- Around line 104-112: The controller never watches the Infrastructure/cluster
object that discoverPlatform() relies on, so platform/VIP fixes won't requeue
reconciles; update the controller setup in NewControllerManagedBy(...) (the
chain that For(&v1alpha1.HTTP01Proxy{}, ...) and subsequent Watches(...)) to add
a watch for the Infrastructure resource (e.g. &configv1.Infrastructure{}) using
the same mapFunc enqueuer (handler.EnqueueRequestsFromMapFunc(mapFunc)) and
appropriate predicates (controllerManagedResourcePredicates or the existing
withIgnoreStatusUpdatePredicates as needed) so changes to Infrastructure/cluster
trigger reconciles that call discoverPlatform().

In `@pkg/controller/http01proxy/install_http01proxy.go`:
- Around line 18-20: The platform-validation branch returns an irrecoverable
error but doesn't remove existing resources; before returning from the
validatePlatform check in install_http01proxy.go, call the same cleanup path
used by cleanUp() to delete the DaemonSet, RBAC, ServiceAccount and
NetworkPolicies (e.g., invoke r.cleanUp(...) or the existing cleanUp helper used
elsewhere), handle/propagate any cleanup errors appropriately (log them with
r.log and include them in the returned error if needed), then return
common.NewIrrecoverableError(fmt.Errorf("platform validation failed"), "%s",
reason) as before.
🪄 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: Pro Plus

Run ID: 2127a61f-e15f-4258-bef3-d76f89e91141

📥 Commits

Reviewing files that changed from the base of the PR and between 8fc4aa5 and b1138fe.

⛔ Files ignored due to path filters (1)
  • api/operator/v1alpha1/zz_generated.deepcopy.go is excluded by !**/zz_generated*
📒 Files selected for processing (44)
  • Makefile
  • api/operator/v1alpha1/features.go
  • api/operator/v1alpha1/http01proxy_types.go
  • bindata/http01-proxy/cert-manager-http01-proxy-clusterrole.yaml
  • bindata/http01-proxy/cert-manager-http01-proxy-clusterrolebinding.yaml
  • bindata/http01-proxy/cert-manager-http01-proxy-daemonset.yaml
  • bindata/http01-proxy/cert-manager-http01-proxy-scc-rolebinding.yaml
  • bindata/http01-proxy/cert-manager-http01-proxy-serviceaccount.yaml
  • bindata/networkpolicies/http01-proxy-allow-egress-networkpolicy.yaml
  • bindata/networkpolicies/http01-proxy-deny-all-networkpolicy.yaml
  • bundle/manifests/cert-manager-operator.clusterserviceversion.yaml
  • config/crd/bases/operator.openshift.io_http01proxies.yaml
  • config/manager/manager.yaml
  • config/rbac/role.yaml
  • config/samples/operator.openshift.io_v1alpha1_http01proxy.yaml
  • pkg/controller/http01proxy/constants.go
  • pkg/controller/http01proxy/controller.go
  • pkg/controller/http01proxy/daemonsets.go
  • pkg/controller/http01proxy/infrastructure.go
  • pkg/controller/http01proxy/install_http01proxy.go
  • pkg/controller/http01proxy/networkpolicies.go
  • pkg/controller/http01proxy/rbacs.go
  • pkg/controller/http01proxy/serviceaccounts.go
  • pkg/controller/http01proxy/utils.go
  • pkg/features/features_test.go
  • pkg/operator/applyconfigurations/internal/internal.go
  • pkg/operator/applyconfigurations/operator/v1alpha1/http01proxy.go
  • pkg/operator/applyconfigurations/operator/v1alpha1/http01proxycustomdeploymentspec.go
  • pkg/operator/applyconfigurations/operator/v1alpha1/http01proxyspec.go
  • pkg/operator/applyconfigurations/operator/v1alpha1/http01proxystatus.go
  • pkg/operator/applyconfigurations/utils.go
  • pkg/operator/assets/bindata.go
  • pkg/operator/clientset/versioned/typed/operator/v1alpha1/fake/fake_http01proxy.go
  • pkg/operator/clientset/versioned/typed/operator/v1alpha1/fake/fake_operator_client.go
  • pkg/operator/clientset/versioned/typed/operator/v1alpha1/generated_expansion.go
  • pkg/operator/clientset/versioned/typed/operator/v1alpha1/http01proxy.go
  • pkg/operator/clientset/versioned/typed/operator/v1alpha1/operator_client.go
  • pkg/operator/informers/externalversions/generic.go
  • pkg/operator/informers/externalversions/operator/v1alpha1/http01proxy.go
  • pkg/operator/informers/externalversions/operator/v1alpha1/interface.go
  • pkg/operator/listers/operator/v1alpha1/expansion_generated.go
  • pkg/operator/listers/operator/v1alpha1/http01proxy.go
  • pkg/operator/setup_manager.go
  • pkg/operator/starter.go
✅ Files skipped from review due to trivial changes (25)
  • pkg/operator/clientset/versioned/typed/operator/v1alpha1/generated_expansion.go
  • pkg/operator/applyconfigurations/internal/internal.go
  • bindata/networkpolicies/http01-proxy-deny-all-networkpolicy.yaml
  • bindata/networkpolicies/http01-proxy-allow-egress-networkpolicy.yaml
  • pkg/operator/listers/operator/v1alpha1/expansion_generated.go
  • bindata/http01-proxy/cert-manager-http01-proxy-serviceaccount.yaml
  • bindata/http01-proxy/cert-manager-http01-proxy-clusterrolebinding.yaml
  • pkg/controller/http01proxy/serviceaccounts.go
  • pkg/operator/informers/externalversions/operator/v1alpha1/interface.go
  • pkg/features/features_test.go
  • bindata/http01-proxy/cert-manager-http01-proxy-scc-rolebinding.yaml
  • pkg/operator/clientset/versioned/typed/operator/v1alpha1/operator_client.go
  • pkg/operator/informers/externalversions/generic.go
  • pkg/operator/applyconfigurations/operator/v1alpha1/http01proxycustomdeploymentspec.go
  • bindata/http01-proxy/cert-manager-http01-proxy-clusterrole.yaml
  • pkg/operator/applyconfigurations/operator/v1alpha1/http01proxyspec.go
  • pkg/operator/applyconfigurations/operator/v1alpha1/http01proxystatus.go
  • api/operator/v1alpha1/http01proxy_types.go
  • pkg/operator/informers/externalversions/operator/v1alpha1/http01proxy.go
  • pkg/operator/listers/operator/v1alpha1/http01proxy.go
  • pkg/controller/http01proxy/utils.go
  • pkg/operator/assets/bindata.go
  • pkg/operator/clientset/versioned/typed/operator/v1alpha1/http01proxy.go
  • config/samples/operator.openshift.io_v1alpha1_http01proxy.yaml
  • pkg/operator/applyconfigurations/operator/v1alpha1/http01proxy.go
🚧 Files skipped from review as they are similar to previous changes (12)
  • config/manager/manager.yaml
  • api/operator/v1alpha1/features.go
  • pkg/operator/clientset/versioned/typed/operator/v1alpha1/fake/fake_operator_client.go
  • pkg/operator/applyconfigurations/utils.go
  • config/rbac/role.yaml
  • Makefile
  • pkg/controller/http01proxy/networkpolicies.go
  • config/crd/bases/operator.openshift.io_http01proxies.yaml
  • pkg/operator/clientset/versioned/typed/operator/v1alpha1/fake/fake_http01proxy.go
  • pkg/controller/http01proxy/daemonsets.go
  • pkg/operator/setup_manager.go
  • pkg/operator/starter.go

Comment thread bindata/http01-proxy/cert-manager-http01-proxy-daemonset.yaml
Comment thread pkg/controller/http01proxy/controller.go Outdated
Comment thread pkg/controller/http01proxy/infrastructure.go
@sebrandon1 sebrandon1 force-pushed the cm-716-http01-proxy branch from b1138fe to 6bf13d6 Compare May 5, 2026 22:37

@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: 2

♻️ Duplicate comments (4)
bindata/http01-proxy/cert-manager-http01-proxy-daemonset.yaml (1)

23-24: ⚠️ Potential issue | 🟠 Major

hostNetwork makes the added NetworkPolicies effectively non-enforcing.

This pod joins the node network namespace, so the HTTP01Proxy NetworkPolicies won't reliably constrain it. If host networking is required here, isolation needs to move to a host-scoped mechanism instead of Kubernetes NetworkPolicies.

Do Kubernetes NetworkPolicies apply to Pods with `hostNetwork: true`? Please verify using the official Kubernetes documentation, and include any caveats called out there.
🤖 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 `@bindata/http01-proxy/cert-manager-http01-proxy-daemonset.yaml` around lines
23 - 24, The manifest sets hostNetwork: true for the cert-manager-http01-proxy
pod which makes Kubernetes NetworkPolicies ineffective for it; verify the
official Kubernetes docs on NetworkPolicy (Pods using hostNetwork bypass
namespace/pod isolation) and either remove hostNetwork if not required or move
isolation to a host-scoped mechanism (e.g., host firewall, Node-level
iptables/iptables-restore, or hostNetwork-aware CNI policy) and document the
caveat next to serviceAccountName: cert-manager-http01-proxy so reviewers know
why NetworkPolicies won’t apply.
pkg/controller/http01proxy/infrastructure.go (1)

24-35: ⚠️ Potential issue | 🟠 Major

Don't cache Infrastructure/cluster forever.

cachedPlatform is written once and never invalidated, so later API/ingress VIP changes are ignored for the lifetime of the controller process. Re-discover on each reconcile, or clear the cache when Infrastructure/cluster changes.

🤖 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/controller/http01proxy/infrastructure.go` around lines 24 - 35, The
getOrDiscoverPlatform method currently caches platform info in
Reconciler.cachedPlatform and never invalidates it, causing VIP changes to be
ignored; update this by either removing the long-lived cache so
getOrDiscoverPlatform always calls discoverPlatform(ctx) on each reconcile, or
add logic to invalidate/update cachedPlatform when the cluster Infrastructure
resource changes (e.g., detect changes to the Infrastructure/cluster resource
and clear cachedPlatform), modifying getOrDiscoverPlatform,
Reconciler.cachedPlatform usage, and discoverPlatform accordingly so the
controller re-discovers platform info when Infrastructure/cluster is updated.
pkg/controller/http01proxy/install_http01proxy.go (1)

18-20: ⚠️ Potential issue | 🟠 Major

Clean up existing proxy resources before returning unsupported.

This branch only stops future applies. If the proxy was already deployed, the DaemonSet/RBAC/NetworkPolicies/ServiceAccount stay behind, so the redirect path can remain active after the controller reports Degraded. Run the same teardown used in the deletion path before returning the irrecoverable error.

🤖 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/controller/http01proxy/install_http01proxy.go` around lines 18 - 20, When
validatePlatform(info) returns a non-empty reason, run the same teardown used by
the deletion path to remove any existing proxy resources (DaemonSet, RBAC,
NetworkPolicies, ServiceAccount) before returning the irrecoverable error;
locate the deletion/teardown helper used elsewhere in this package (the function
that removes the proxy resources) and invoke it here, handle/log any teardown
errors but proceed to return common.NewIrrecoverableError(fmt.Errorf("platform
validation failed"), "%s", reason) after cleanup so no stale redirect resources
remain; keep the existing log r.log.V(1).Info("platform not supported for HTTP01
proxy", ...) around the operation.
pkg/operator/assets/bindata.go (1)

2310-2324: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Remove unnecessary MachineConfig write permissions from the HTTP01 proxy ClusterRole.

The embedded ClusterRole still grants update on operator.openshift.io/machineconfigurations and create/update on machineconfiguration.openshift.io/machineconfigs. This is excessive for the proxy workload and expands privilege scope unnecessarily.

Suggested manifest change (source YAML, then regenerate bindata)
 rules:
   - apiGroups:
       - config.openshift.io
     resources:
       - clusterversions
       - infrastructures
       - ingresses
     verbs:
       - get
       - list
       - watch
-  - apiGroups:
-      - operator.openshift.io
-    resources:
-      - machineconfigurations
-    verbs:
-      - update
-  - apiGroups:
-      - machineconfiguration.openshift.io
-    resources:
-      - machineconfigs
-    verbs:
-      - get
-      - list
-      - create
-      - update
🤖 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/assets/bindata.go` around lines 2310 - 2324, Remove the
unnecessary MachineConfig write permissions from the embedded ClusterRole by
locating the ClusterRole manifest in pkg/operator/assets/bindata.go that
contains apiGroups operator.openshift.io with resources machineconfigurations
and machineconfiguration.openshift.io with resources machineconfigs, and delete
the rule blocks granting "update" and "create/update" respectively; after
editing the source ClusterRole YAML (the manifest embedded into bindata via
Generate/asset tooling) regenerate the bindata assets so the compiled bindata.go
reflects the removed rules.
🤖 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/controller/http01proxy/controller.go`:
- Around line 104-105: Remove the GenerationChangedPredicate from the primary
watch so deletions (which only set metadata.deletionTimestamp) still trigger
reconciliation: in the controller setup where
ctrl.NewControllerManagedBy(mgr).For(&v1alpha1.HTTP01Proxy{},
builder.WithPredicates(predicate.GenerationChangedPredicate{})) is defined, drop
the builder.WithPredicates(predicate.GenerationChangedPredicate{}) argument and
call For(&v1alpha1.HTTP01Proxy{}) so the reconciler (and the HTTP01Proxy cleanup
path) runs on deletion events.

In `@pkg/controller/http01proxy/daemonsets.go`:
- Around line 35-37: The Pod template labels are being overwritten by
ds.Spec.Template.Labels = resourceLabels which can remove required selector
labels (e.g., app: cert-manager-http01-proxy); instead merge resourceLabels into
the existing ds.Spec.Template.Labels (preserving existing keys) after calling
common.UpdateResourceLabels(ds, resourceLabels). Locate the assignment to
ds.Spec.Template.Labels and replace it with logic that iterates/merges keys from
resourceLabels into ds.Spec.Template.Labels (initializing the map if nil) so
existing selector-required labels remain alongside the new ones.

---

Duplicate comments:
In `@bindata/http01-proxy/cert-manager-http01-proxy-daemonset.yaml`:
- Around line 23-24: The manifest sets hostNetwork: true for the
cert-manager-http01-proxy pod which makes Kubernetes NetworkPolicies ineffective
for it; verify the official Kubernetes docs on NetworkPolicy (Pods using
hostNetwork bypass namespace/pod isolation) and either remove hostNetwork if not
required or move isolation to a host-scoped mechanism (e.g., host firewall,
Node-level iptables/iptables-restore, or hostNetwork-aware CNI policy) and
document the caveat next to serviceAccountName: cert-manager-http01-proxy so
reviewers know why NetworkPolicies won’t apply.

In `@pkg/controller/http01proxy/infrastructure.go`:
- Around line 24-35: The getOrDiscoverPlatform method currently caches platform
info in Reconciler.cachedPlatform and never invalidates it, causing VIP changes
to be ignored; update this by either removing the long-lived cache so
getOrDiscoverPlatform always calls discoverPlatform(ctx) on each reconcile, or
add logic to invalidate/update cachedPlatform when the cluster Infrastructure
resource changes (e.g., detect changes to the Infrastructure/cluster resource
and clear cachedPlatform), modifying getOrDiscoverPlatform,
Reconciler.cachedPlatform usage, and discoverPlatform accordingly so the
controller re-discovers platform info when Infrastructure/cluster is updated.

In `@pkg/controller/http01proxy/install_http01proxy.go`:
- Around line 18-20: When validatePlatform(info) returns a non-empty reason, run
the same teardown used by the deletion path to remove any existing proxy
resources (DaemonSet, RBAC, NetworkPolicies, ServiceAccount) before returning
the irrecoverable error; locate the deletion/teardown helper used elsewhere in
this package (the function that removes the proxy resources) and invoke it here,
handle/log any teardown errors but proceed to return
common.NewIrrecoverableError(fmt.Errorf("platform validation failed"), "%s",
reason) after cleanup so no stale redirect resources remain; keep the existing
log r.log.V(1).Info("platform not supported for HTTP01 proxy", ...) around the
operation.

In `@pkg/operator/assets/bindata.go`:
- Around line 2310-2324: Remove the unnecessary MachineConfig write permissions
from the embedded ClusterRole by locating the ClusterRole manifest in
pkg/operator/assets/bindata.go that contains apiGroups operator.openshift.io
with resources machineconfigurations and machineconfiguration.openshift.io with
resources machineconfigs, and delete the rule blocks granting "update" and
"create/update" respectively; after editing the source ClusterRole YAML (the
manifest embedded into bindata via Generate/asset tooling) regenerate the
bindata assets so the compiled bindata.go reflects the removed rules.
🪄 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: 91a83d88-ebc2-4246-a600-9d1356a77dfe

📥 Commits

Reviewing files that changed from the base of the PR and between b1138fe and 6bf13d6.

⛔ Files ignored due to path filters (1)
  • api/operator/v1alpha1/zz_generated.deepcopy.go is excluded by !**/zz_generated*
📒 Files selected for processing (44)
  • Makefile
  • api/operator/v1alpha1/features.go
  • api/operator/v1alpha1/http01proxy_types.go
  • bindata/http01-proxy/cert-manager-http01-proxy-clusterrole.yaml
  • bindata/http01-proxy/cert-manager-http01-proxy-clusterrolebinding.yaml
  • bindata/http01-proxy/cert-manager-http01-proxy-daemonset.yaml
  • bindata/http01-proxy/cert-manager-http01-proxy-scc-rolebinding.yaml
  • bindata/http01-proxy/cert-manager-http01-proxy-serviceaccount.yaml
  • bindata/networkpolicies/http01-proxy-allow-egress-networkpolicy.yaml
  • bindata/networkpolicies/http01-proxy-deny-all-networkpolicy.yaml
  • bundle/manifests/cert-manager-operator.clusterserviceversion.yaml
  • config/crd/bases/operator.openshift.io_http01proxies.yaml
  • config/manager/manager.yaml
  • config/rbac/role.yaml
  • config/samples/operator.openshift.io_v1alpha1_http01proxy.yaml
  • pkg/controller/http01proxy/constants.go
  • pkg/controller/http01proxy/controller.go
  • pkg/controller/http01proxy/daemonsets.go
  • pkg/controller/http01proxy/infrastructure.go
  • pkg/controller/http01proxy/install_http01proxy.go
  • pkg/controller/http01proxy/networkpolicies.go
  • pkg/controller/http01proxy/rbacs.go
  • pkg/controller/http01proxy/serviceaccounts.go
  • pkg/controller/http01proxy/utils.go
  • pkg/features/features_test.go
  • pkg/operator/applyconfigurations/internal/internal.go
  • pkg/operator/applyconfigurations/operator/v1alpha1/http01proxy.go
  • pkg/operator/applyconfigurations/operator/v1alpha1/http01proxycustomdeploymentspec.go
  • pkg/operator/applyconfigurations/operator/v1alpha1/http01proxyspec.go
  • pkg/operator/applyconfigurations/operator/v1alpha1/http01proxystatus.go
  • pkg/operator/applyconfigurations/utils.go
  • pkg/operator/assets/bindata.go
  • pkg/operator/clientset/versioned/typed/operator/v1alpha1/fake/fake_http01proxy.go
  • pkg/operator/clientset/versioned/typed/operator/v1alpha1/fake/fake_operator_client.go
  • pkg/operator/clientset/versioned/typed/operator/v1alpha1/generated_expansion.go
  • pkg/operator/clientset/versioned/typed/operator/v1alpha1/http01proxy.go
  • pkg/operator/clientset/versioned/typed/operator/v1alpha1/operator_client.go
  • pkg/operator/informers/externalversions/generic.go
  • pkg/operator/informers/externalversions/operator/v1alpha1/http01proxy.go
  • pkg/operator/informers/externalversions/operator/v1alpha1/interface.go
  • pkg/operator/listers/operator/v1alpha1/expansion_generated.go
  • pkg/operator/listers/operator/v1alpha1/http01proxy.go
  • pkg/operator/setup_manager.go
  • pkg/operator/starter.go
🚧 Files skipped from review as they are similar to previous changes (7)
  • bindata/networkpolicies/http01-proxy-allow-egress-networkpolicy.yaml
  • bindata/networkpolicies/http01-proxy-deny-all-networkpolicy.yaml
  • pkg/operator/listers/operator/v1alpha1/http01proxy.go
  • config/crd/bases/operator.openshift.io_http01proxies.yaml
  • api/operator/v1alpha1/features.go
  • pkg/operator/clientset/versioned/typed/operator/v1alpha1/fake/fake_operator_client.go
  • pkg/operator/informers/externalversions/operator/v1alpha1/http01proxy.go

Comment thread pkg/controller/http01proxy/controller.go Outdated
Comment thread pkg/controller/http01proxy/daemonsets.go
@sebrandon1 sebrandon1 force-pushed the cm-716-http01-proxy branch from 3510c2b to 69a74fd Compare May 6, 2026 15:24
@sebrandon1 sebrandon1 force-pushed the cm-716-http01-proxy branch from 69a74fd to 77ed50a Compare May 14, 2026 19:07
@sebrandon1

Copy link
Copy Markdown
Member Author

/retest

Comment thread pkg/controller/http01proxy/controller.go Outdated
Comment thread pkg/controller/http01proxy/daemonsets.go
@sebrandon1 sebrandon1 force-pushed the cm-716-http01-proxy branch 2 times, most recently from 7ada5c9 to 716a848 Compare May 29, 2026 18:54
Comment thread pkg/controller/http01proxy/infrastructure.go
Comment thread api/operator/v1alpha1/http01proxy_types.go
@sebrandon1 sebrandon1 force-pushed the cm-716-http01-proxy branch 2 times, most recently from c2125f1 to 34d01f7 Compare June 8, 2026 18:35
@sebrandon1 sebrandon1 force-pushed the cm-716-http01-proxy branch from 34d01f7 to d6922d2 Compare June 15, 2026 16:25
@sebrandon1 sebrandon1 force-pushed the cm-716-http01-proxy branch from d6922d2 to e4f1d04 Compare June 24, 2026 19:10
@sebrandon1 sebrandon1 force-pushed the cm-716-http01-proxy branch from e4f1d04 to 5d76782 Compare June 25, 2026 16:35
@openshift-ci openshift-ci Bot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jun 25, 2026
@sebrandon1 sebrandon1 force-pushed the cm-716-http01-proxy branch from 5d76782 to 71c2a12 Compare June 25, 2026 17:26
@openshift-ci openshift-ci Bot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jun 25, 2026
@sebrandon1 sebrandon1 force-pushed the cm-716-http01-proxy branch 2 times, most recently from d8b102d to 2a8621d Compare June 25, 2026 17:50
@sebrandon1

Copy link
Copy Markdown
Member Author

/retest

@sebrandon1

Copy link
Copy Markdown
Member Author

Testing & deployment guide for reviewers: https://gist.github.com/sebrandon1/457d18741c33a5eef5adf77a0c973106

@sebrandon1

Copy link
Copy Markdown
Member Author

/retest ci/prow/e2e-operator

@sebrandon1

Copy link
Copy Markdown
Member Author

/test e2e-operator

- name: RELATED_IMAGE_CERT_MANAGER_TRUST_MANAGER
value: quay.io/jetstack/trust-manager:v0.20.3
- name: RELATED_IMAGE_CERT_MANAGER_HTTP01PROXY
value: quay.io/bapalm/cert-mgr-http01-proxy:latest

@anandkuma77 anandkuma77 Jul 1, 2026

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.

Image from personal quay.io can not be accepted.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Correct - I have that in my top level comment under "proxy image".

@sebrandon1 sebrandon1 force-pushed the cm-716-http01-proxy branch from 2a8621d to 3140cbf Compare July 6, 2026 16:17
@sebrandon1

Copy link
Copy Markdown
Member Author

@coderabbitai resume

@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown
✅ Action performed

Reviews resumed.

@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: 2

🧹 Nitpick comments (3)
bindata/http01-proxy/cert-manager-http01-proxy-daemonset.yaml (1)

34-60: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

No liveness/readiness probes defined.

The proxy container has no health checks, so a hung or crashed nftables/proxy process won't be automatically detected or restarted by the kubelet.

As per path instructions, "Liveness + readiness probes defined" for Kubernetes/OpenShift manifests.

🤖 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 `@bindata/http01-proxy/cert-manager-http01-proxy-daemonset.yaml` around lines
34 - 60, The http01-proxy container in cert-manager-http01-proxy-daemonset.yaml
is missing health checks, so add both liveness and readiness probes to the
http01-proxy container spec. Use the existing container settings like name
http01-proxy and PROXY_PORT to wire the probes to the proxy process endpoint,
and keep the probes aligned with Kubernetes/OpenShift manifest requirements so
kubelet can detect hung or unhealthy proxy instances.

Source: Path instructions

.golangci.bck.yaml (1)

1-71: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Remove the stray .golangci.bck.yaml backup. Makefile points golangci-lint at .golangci.yaml, so this duplicate config is dead weight and can confuse future changes.

🤖 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 @.golangci.bck.yaml around lines 1 - 71, The repository contains a stray
backup golangci-lint config that duplicates the active settings and can cause
confusion. Remove the .golangci.bck.yaml file entirely, and make sure any future
lint configuration changes are applied only to the main .golangci.yaml
referenced by Makefile, keeping this backup out of the tree.
bundle/manifests/cert-manager-operator.clusterserviceversion.yaml (1)

368-370: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add description/displayName and an alm-example for HTTP01Proxy.

Every other owned CRD has description/displayName; this new entry has neither, and there's no corresponding alm-examples sample CR (unlike IstioCSR/TrustManager, which this feature follows).

♻️ Suggested fix
-    - kind: HTTP01Proxy
+    - description: HTTP01Proxy is the Schema for configuring the HTTP-01 challenge
+        proxy used to complete ACME challenges for the API endpoint on platforms
+        without an exposed API VIP.
+      displayName: HTTP01 Challenge Proxy
+      kind: HTTP01Proxy
       name: http01proxies.operator.openshift.io
       version: v1alpha1
🤖 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 `@bundle/manifests/cert-manager-operator.clusterserviceversion.yaml` around
lines 368 - 370, The new HTTP01Proxy CR entry in the CSV is missing the same
metadata used by the other owned CRDs. Update the HTTP01Proxy resource block to
include both description and displayName, and add a matching sample to the
alm-examples payload so it follows the existing IstioCSR/TrustManager pattern.
Use the HTTP01Proxy section in cert-manager-operator.clusterserviceversion.yaml
to keep the new CRD entry consistent with the rest of the manifest.
🤖 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 `@bindata/http01-proxy/cert-manager-http01-proxy-daemonset.yaml`:
- Around line 45-52: The container securityContext in
cert-manager-http01-proxy-daemonset should be tightened to follow the manifest
policy: change the explicit root allowance and declare a minimal filesystem
posture. Update the securityContext block used by the daemonset container to set
runAsNonRoot to true where possible, add readOnlyRootFilesystem, and keep
allowPrivilegeEscalation disabled; if root is still required for
NET_ADMIN/nftables behavior, document that exception in a nearby comment and
keep the scope as narrow as possible.

In `@rebase_all.sh`:
- Around line 19-31: The branch iteration in rebase_all.sh is not fully guarded,
so a failed git checkout in the loop can still terminate the script under set
-e. Update the loop around the branch handling logic to treat git checkout
"$branch" like the existing git pull --rebase upstream "$MAIN_BRANCH" step:
detect checkout failures, log a warning for that branch, optionally clean up any
partial state, and continue to the next branch instead of exiting the whole
script.

---

Nitpick comments:
In @.golangci.bck.yaml:
- Around line 1-71: The repository contains a stray backup golangci-lint config
that duplicates the active settings and can cause confusion. Remove the
.golangci.bck.yaml file entirely, and make sure any future lint configuration
changes are applied only to the main .golangci.yaml referenced by Makefile,
keeping this backup out of the tree.

In `@bindata/http01-proxy/cert-manager-http01-proxy-daemonset.yaml`:
- Around line 34-60: The http01-proxy container in
cert-manager-http01-proxy-daemonset.yaml is missing health checks, so add both
liveness and readiness probes to the http01-proxy container spec. Use the
existing container settings like name http01-proxy and PROXY_PORT to wire the
probes to the proxy process endpoint, and keep the probes aligned with
Kubernetes/OpenShift manifest requirements so kubelet can detect hung or
unhealthy proxy instances.

In `@bundle/manifests/cert-manager-operator.clusterserviceversion.yaml`:
- Around line 368-370: The new HTTP01Proxy CR entry in the CSV is missing the
same metadata used by the other owned CRDs. Update the HTTP01Proxy resource
block to include both description and displayName, and add a matching sample to
the alm-examples payload so it follows the existing IstioCSR/TrustManager
pattern. Use the HTTP01Proxy section in
cert-manager-operator.clusterserviceversion.yaml to keep the new CRD entry
consistent with the rest of the manifest.
🪄 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: 9d7e102b-df28-4a4f-936b-b9479ef464c4

📥 Commits

Reviewing files that changed from the base of the PR and between b1138fe and 3140cbf.

⛔ Files ignored due to path filters (1)
  • api/operator/v1alpha1/zz_generated.deepcopy.go is excluded by !**/zz_generated*
📒 Files selected for processing (51)
  • .golangci.bck.yaml
  • CLAUDE.md
  • Makefile
  • TODO-cleanup.md
  • api/operator/v1alpha1/features.go
  • api/operator/v1alpha1/http01proxy_types.go
  • bindata/http01-proxy/cert-manager-http01-proxy-clusterrole.yaml
  • bindata/http01-proxy/cert-manager-http01-proxy-clusterrolebinding.yaml
  • bindata/http01-proxy/cert-manager-http01-proxy-daemonset.yaml
  • bindata/http01-proxy/cert-manager-http01-proxy-scc-rolebinding.yaml
  • bindata/http01-proxy/cert-manager-http01-proxy-serviceaccount.yaml
  • bindata/networkpolicies/http01-proxy-allow-egress-networkpolicy.yaml
  • bindata/networkpolicies/http01-proxy-deny-all-networkpolicy.yaml
  • bundle/manifests/cert-manager-operator.clusterserviceversion.yaml
  • bundle/manifests/operator.openshift.io_http01proxies.yaml
  • config/crd/bases/operator.openshift.io_http01proxies.yaml
  • config/crd/kustomization.yaml
  • config/manager/manager.yaml
  • config/rbac/role.yaml
  • config/samples/operator.openshift.io_v1alpha1_http01proxy.yaml
  • hack/verify-http01proxy.sh
  • pkg/controller/http01proxy/constants.go
  • pkg/controller/http01proxy/controller.go
  • pkg/controller/http01proxy/daemonsets.go
  • pkg/controller/http01proxy/infrastructure.go
  • pkg/controller/http01proxy/install_http01proxy.go
  • pkg/controller/http01proxy/networkpolicies.go
  • pkg/controller/http01proxy/rbacs.go
  • pkg/controller/http01proxy/serviceaccounts.go
  • pkg/controller/http01proxy/utils.go
  • pkg/features/features_test.go
  • pkg/operator/applyconfigurations/internal/internal.go
  • pkg/operator/applyconfigurations/operator/v1alpha1/http01proxy.go
  • pkg/operator/applyconfigurations/operator/v1alpha1/http01proxycustomdeploymentspec.go
  • pkg/operator/applyconfigurations/operator/v1alpha1/http01proxyspec.go
  • pkg/operator/applyconfigurations/operator/v1alpha1/http01proxystatus.go
  • pkg/operator/applyconfigurations/utils.go
  • pkg/operator/assets/bindata.go
  • pkg/operator/clientset/versioned/typed/operator/v1alpha1/fake/fake_http01proxy.go
  • pkg/operator/clientset/versioned/typed/operator/v1alpha1/fake/fake_operator_client.go
  • pkg/operator/clientset/versioned/typed/operator/v1alpha1/generated_expansion.go
  • pkg/operator/clientset/versioned/typed/operator/v1alpha1/http01proxy.go
  • pkg/operator/clientset/versioned/typed/operator/v1alpha1/operator_client.go
  • pkg/operator/informers/externalversions/generic.go
  • pkg/operator/informers/externalversions/operator/v1alpha1/http01proxy.go
  • pkg/operator/informers/externalversions/operator/v1alpha1/interface.go
  • pkg/operator/listers/operator/v1alpha1/expansion_generated.go
  • pkg/operator/listers/operator/v1alpha1/http01proxy.go
  • pkg/operator/setup_manager.go
  • pkg/operator/starter.go
  • rebase_all.sh
✅ Files skipped from review due to trivial changes (14)
  • CLAUDE.md
  • pkg/operator/applyconfigurations/operator/v1alpha1/http01proxycustomdeploymentspec.go
  • pkg/operator/applyconfigurations/internal/internal.go
  • pkg/operator/clientset/versioned/typed/operator/v1alpha1/fake/fake_operator_client.go
  • TODO-cleanup.md
  • pkg/operator/listers/operator/v1alpha1/expansion_generated.go
  • bundle/manifests/operator.openshift.io_http01proxies.yaml
  • pkg/operator/informers/externalversions/generic.go
  • pkg/operator/informers/externalversions/operator/v1alpha1/http01proxy.go
  • pkg/operator/clientset/versioned/typed/operator/v1alpha1/fake/fake_http01proxy.go
  • pkg/operator/applyconfigurations/operator/v1alpha1/http01proxyspec.go
  • pkg/operator/clientset/versioned/typed/operator/v1alpha1/generated_expansion.go
  • pkg/operator/applyconfigurations/operator/v1alpha1/http01proxystatus.go
  • config/samples/operator.openshift.io_v1alpha1_http01proxy.yaml
🚧 Files skipped from review as they are similar to previous changes (22)
  • bindata/http01-proxy/cert-manager-http01-proxy-serviceaccount.yaml
  • bindata/http01-proxy/cert-manager-http01-proxy-scc-rolebinding.yaml
  • bindata/networkpolicies/http01-proxy-deny-all-networkpolicy.yaml
  • bindata/networkpolicies/http01-proxy-allow-egress-networkpolicy.yaml
  • pkg/operator/applyconfigurations/utils.go
  • pkg/features/features_test.go
  • pkg/controller/http01proxy/serviceaccounts.go
  • api/operator/v1alpha1/features.go
  • pkg/operator/clientset/versioned/typed/operator/v1alpha1/operator_client.go
  • config/manager/manager.yaml
  • pkg/operator/informers/externalversions/operator/v1alpha1/interface.go
  • pkg/operator/starter.go
  • bindata/http01-proxy/cert-manager-http01-proxy-clusterrolebinding.yaml
  • pkg/controller/http01proxy/rbacs.go
  • pkg/controller/http01proxy/constants.go
  • pkg/operator/clientset/versioned/typed/operator/v1alpha1/http01proxy.go
  • api/operator/v1alpha1/http01proxy_types.go
  • pkg/controller/http01proxy/infrastructure.go
  • Makefile
  • pkg/operator/setup_manager.go
  • pkg/operator/assets/bindata.go
  • config/crd/bases/operator.openshift.io_http01proxies.yaml

Comment on lines +45 to +52
securityContext:
allowPrivilegeEscalation: false
capabilities:
add:
- NET_ADMIN
drop:
- ALL
runAsNonRoot: false

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

Root filesystem and non-root user not enforced.

runAsNonRoot: false explicitly permits root, and readOnlyRootFilesystem is unset (defaults to writable). Even with NET_ADMIN requirements for nftables manipulation, the container should still declare an explicit, minimal-writable root filesystem where feasible and only run as root if strictly required with justification in a comment.

🛡️ Suggested tightening
           securityContext:
             allowPrivilegeEscalation: false
             capabilities:
               add:
                 - NET_ADMIN
               drop:
                 - ALL
+            readOnlyRootFilesystem: true
             runAsNonRoot: false

As per path instructions, "securityContext: runAsNonRoot, readOnlyRootFilesystem, allowPrivilegeEscalation: false" for Kubernetes/OpenShift manifests.

🤖 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 `@bindata/http01-proxy/cert-manager-http01-proxy-daemonset.yaml` around lines
45 - 52, The container securityContext in cert-manager-http01-proxy-daemonset
should be tightened to follow the manifest policy: change the explicit root
allowance and declare a minimal filesystem posture. Update the securityContext
block used by the daemonset container to set runAsNonRoot to true where
possible, add readOnlyRootFilesystem, and keep allowPrivilegeEscalation
disabled; if root is still required for NET_ADMIN/nftables behavior, document
that exception in a nearby comment and keep the scope as narrow as possible.

Source: Path instructions

Comment thread rebase_all.sh
Comment on lines +19 to +31
for branch in $(git branch --format='%(refname:short)' | grep -v "^${MAIN_BRANCH}$"); do
echo ""
echo "=== Rebasing $branch ==="
git checkout "$branch"

if git pull --rebase upstream "$MAIN_BRANCH"; then
echo "Pushing $branch to origin..."
git push origin "$branch" --force-with-lease
else
echo "WARNING: Rebase failed for $branch, skipping push."
git rebase --abort 2>/dev/null || true
fi
done

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 | 🟡 Minor | ⚡ Quick win

Unguarded git checkout will abort the whole loop under set -e.

Only the rebase step is wrapped in an if; a failed git checkout "$branch" (e.g., dirty tree, uncommitted changes) will trigger set -e and terminate the script for all remaining branches instead of skipping just that one, defeating the intended per-branch resilience.

🐛 Proposed fix
     echo "=== Rebasing $branch ==="
-    git checkout "$branch"
+    if ! git checkout "$branch"; then
+        echo "WARNING: Could not checkout $branch, skipping."
+        continue
+    fi
 
     if git pull --rebase upstream "$MAIN_BRANCH"; then
📝 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
for branch in $(git branch --format='%(refname:short)' | grep -v "^${MAIN_BRANCH}$"); do
echo ""
echo "=== Rebasing $branch ==="
git checkout "$branch"
if git pull --rebase upstream "$MAIN_BRANCH"; then
echo "Pushing $branch to origin..."
git push origin "$branch" --force-with-lease
else
echo "WARNING: Rebase failed for $branch, skipping push."
git rebase --abort 2>/dev/null || true
fi
done
for branch in $(git branch --format='%(refname:short)' | grep -v "^${MAIN_BRANCH}$"); do
echo ""
echo "=== Rebasing $branch ==="
if ! git checkout "$branch"; then
echo "WARNING: Could not checkout $branch, skipping."
continue
fi
if git pull --rebase upstream "$MAIN_BRANCH"; then
echo "Pushing $branch to origin..."
git push origin "$branch" --force-with-lease
else
echo "WARNING: Rebase failed for $branch, skipping push."
git rebase --abort 2>/dev/null || true
fi
done
🤖 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 `@rebase_all.sh` around lines 19 - 31, The branch iteration in rebase_all.sh is
not fully guarded, so a failed git checkout in the loop can still terminate the
script under set -e. Update the loop around the branch handling logic to treat
git checkout "$branch" like the existing git pull --rebase upstream
"$MAIN_BRANCH" step: detect checkout failures, log a warning for that branch,
optionally clean up any partial state, and continue to the next branch instead
of exiting the whole script.

@sebrandon1

Copy link
Copy Markdown
Member Author

CodeRabbit Feedback - Status Update

Thank you for the comprehensive review! I've addressed the actionable feedback:

✅ Already Fixed (in earlier commits)

  • Context threading: Controller properly threads context from Reconcile through all helpers
  • GenerationChangedPredicate: Removed from HTTP01Proxy watch to handle deletions
  • Pod template labels: Merge logic preserves existing selector labels
  • Unstructured extraction: Proper error handling for Infrastructure parsing
  • VIP validation: Full list comparison (nested loops) to catch all overlaps
  • updateCondition context: Takes context parameter and threads it through
  • Error aggregation: prependErr properly included in aggregate
  • MachineConfig permissions: Removed unused MCO API permissions
  • allowPrivilegeEscalation: Set to false in DaemonSet securityContext
  • features_test assertion: Only checks pre-GA features are default-disabled
  • Platform validation cleanup: Calls cleanUp() before returning unsupported error

✅ Just Fixed (commit 5323304)

  • Infrastructure watch: Added watch on Infrastructure/cluster that invalidates platform cache and triggers reconcile when platform changes
  • DaemonSet drift detection: Replaced partial field comparison with DeepEqual on full PodTemplateSpec to catch all drift (hostNetwork, tolerations, volumes, securityContext, etc.)

📝 Deferred (acknowledged design decisions)

  • :latest image tags: Using :latest during dev/preview phase while image not yet in official OpenShift build pipeline (acknowledged by CodeRabbit)
  • hostNetwork + NetworkPolicy: Known limitation - NetworkPolicies don't reliably apply to hostNetwork pods across CNIs, but hostNetwork is required for the proxy's nftables manipulation on the node

Summary

All critical CodeRabbit feedback has been addressed. The controller now properly handles platform changes, has comprehensive drift detection, and follows all best practices for context threading, error handling, and least-privilege RBAC.

Tests pass, linter clean. Ready for human review.

Implements a new HTTP01Proxy controller that enables HTTP-01 ACME challenges
for baremetal clusters where API and Ingress VIPs differ. The proxy runs as
a DaemonSet with hostNetwork, intercepts HTTP-01 challenge traffic on port 80,
and forwards it to the ingress VIP.

Features:
- Platform detection via Infrastructure/cluster resource
- Validates baremetal platform with distinct API/Ingress VIPs
- Deploys DaemonSet with nftables-based traffic redirection
- Includes RBAC, NetworkPolicies, and ServiceAccount resources
- Feature-gated with HTTP01Proxy TechPreview gate
- Watches Infrastructure for platform changes and invalidates cache
- Comprehensive DaemonSet drift detection for safe upgrades
- Automatic cleanup on deletion or platform validation failure

Architecture:
- Controller reconciles HTTP01Proxy singleton in operator namespace
- Platform validation runs on each reconcile with caching
- Infrastructure watch invalidates cache when cluster config changes
- Finalizer ensures cleanup of all managed resources
- Status conditions track deployment state

Security:
- Least-privilege RBAC (removed unused MCO permissions)
- allowPrivilegeEscalation: false in securityContext
- NET_ADMIN capability required for nftables manipulation
- NetworkPolicies restrict egress (though limited with hostNetwork)
- Runs as root for node-level network configuration

Implementation details:
- Uses Server-Side Apply where appropriate
- Full PodTemplateSpec comparison for drift detection
- Context properly threaded from Reconcile through all helpers
- Proper error handling for Infrastructure resource parsing
- Full VIP list validation (all combinations checked)

Closes: CM-716
@sebrandon1 sebrandon1 force-pushed the cm-716-http01-proxy branch from 5323304 to e7b9069 Compare July 7, 2026 17:17
@sebrandon1

Copy link
Copy Markdown
Member Author

Squashed commits into a single atomic commit (e7b9069) with comprehensive commit message that includes:

  • Feature implementation details
  • CodeRabbit fixes (Infrastructure watch, DaemonSet drift detection)
  • Architecture overview
  • Security considerations
  • All implementation details

PR now has clean single-commit history ready for review.

@openshift-ci

openshift-ci Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

@sebrandon1: all tests passed!

Full PR test history. Your PR dashboard.

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. I understand the commands that are listed here.

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

Labels

jira/valid-reference Indicates that this PR references a valid Jira ticket of any type.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants