Skip to content

chore(rest-api): Add ingress based TLS support for REST API#3351

Open
thossain-nv wants to merge 1 commit into
NVIDIA:mainfrom
thossain-nv:chore/rest-api-tls
Open

chore(rest-api): Add ingress based TLS support for REST API#3351
thossain-nv wants to merge 1 commit into
NVIDIA:mainfrom
thossain-nv:chore/rest-api-tls

Conversation

@thossain-nv

Copy link
Copy Markdown
Contributor

Currently we don't have a way to configure REST API to support TLS. Following K8s best practices, this PR introduces:

  • Ingress based TLS termination
  • Enhances Helm chart, installation and docs to enable TLS termination
  • Provides a quick option for cert-manager based self-signed TLS cert
  • Allows deeper configuration for adding FQDN if user wishes
  • TLS support is optional, it's not enabled by default to prevent breaking existing installations where users may be terminating TLS themselves

Related issues

#2587

Type of Change

  • Add - New feature or capability

Breaking Changes

  • This PR contains breaking changes

Testing

  • Unit tests added/updated

@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Summary by CodeRabbit

  • New Features

    • Added optional NGINX Ingress support for exposing the REST API through configurable host and path routing.
    • Added optional TLS certificate generation and integration with cert-manager.
    • Added setup options for installing the Ingress controller, including a command-line flag and environment setting.
    • Integrated Ingress LoadBalancer services with MetalLB-provided addresses.
  • Documentation

    • Added setup guidance, configuration examples, prerequisites, and TLS instructions.
  • Bug Fixes

    • Improved health checks and cleanup handling for optional Ingress components.

Walkthrough

Adds optional ingress-nginx installation and lifecycle management, plus configurable nico-rest-api Ingress and cert-manager TLS resources with Helm tests and setup documentation.

Changes

Ingress TLS exposure

Layer / File(s) Summary
Chart ingress and certificate rendering
helm/rest/nico-rest/charts/nico-rest-api/values.yaml, helm/rest/nico-rest/charts/nico-rest-api/templates/*, helm/rest/nico-rest/charts/nico-rest-api/tests/ingress_test.yaml
Adds disabled-by-default Ingress and certificate configuration, renders host/path routing and cert-manager Certificate resources, and tests enabled, disabled, TLS, and existing-secret scenarios.
Optional ingress-nginx installation
helm-prereqs/operators/values/ingress-nginx.yaml, helm-prereqs/helmfile.yaml, helm-prereqs/setup.sh
Adds the ingress-nginx Helm release and LoadBalancer configuration, with environment-variable and CLI controls, validation, installation, and readiness waiting.
Ingress lifecycle and health operations
helm-prereqs/health-check.sh, helm-prereqs/clean.sh
Detects and reports the optional controller, conditionally checks readiness, and removes its namespaces, cluster-scoped resources, and released persistent volumes during cleanup.
Ingress usage documentation
docs/getting-started/*, helm-prereqs/README.md, helm-prereqs/values/nico-rest.yaml
Documents optional ingress-nginx installation and TLS exposure for the REST API, including setup phases, prerequisites, configuration, and deployed components.

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

Sequence Diagram(s)

sequenceDiagram
  participant Operator
  participant setup.sh
  participant helmfile
  participant MetalLB
  participant ingress-nginx-controller
  participant nico-rest-api-Service
  Operator->>setup.sh: Enable ingress-nginx installation
  setup.sh->>helmfile: Sync ingress-nginx release
  helmfile->>ingress-nginx-controller: Create controller and LoadBalancer Service
  ingress-nginx-controller->>MetalLB: Request LoadBalancer address
  ingress-nginx-controller->>nico-rest-api-Service: Route configured Ingress traffic
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding optional ingress-based TLS support for the REST API.
Description check ✅ Passed The description is directly aligned with the PR and accurately describes the new TLS, ingress, cert-manager, and optional behavior.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@github-actions

Copy link
Copy Markdown

@github-actions

Copy link
Copy Markdown

🔐 TruffleHog Secret Scan

No secrets or credentials found!

Your code has been scanned for 700+ types of secrets and credentials. All clear! 🎉

🔗 View scan details

🕐 Last updated: 2026-07-10 01:48:51 UTC | Commit: b131a4b

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 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 `@helm-prereqs/clean.sh`:
- Line 245: Update the PV filtering logic in the cleanup script so it does not
automatically select every PV claimed in the ingress-nginx namespace; instead,
restrict deletion to explicitly stack-owned resources using ownership metadata
or known claim names, or remove ingress-nginx from the namespace allowlist
unless the script can verify it created and owns the namespace.
- Around line 157-164: Update the ingress-nginx cleanup logic in clean.sh to
delete resources only when this installation recorded ownership or the resources
have matching Helm ownership metadata; never unconditionally delete the global
nginx IngressClass, ingress-nginx ClusterRoles/ClusterRoleBindings, or
namespace. Preserve idempotency and safely skip shared or externally managed
resources, including the corresponding cleanup block around the namespace
deletion.

In `@helm-prereqs/health-check.sh`:
- Around line 109-112: Update the namespace discovery logic around
INGRESS_NGINX_NS to avoid selecting kubectl’s arbitrary .items[0]. Identify the
intended ingress-nginx-controller using Helm/release labels or a configured
namespace, and explicitly fail or report ambiguity when multiple matching
deployments remain; ensure the health-check lifecycle status is reliable.

In `@helm-prereqs/helmfile.yaml`:
- Around line 60-74: Ensure the optional ingress-nginx release cannot be
destroyed unless this setup explicitly installed it: update the helmfile and
related setup/cleanup logic around the ingress-nginx release so installation
ownership is tracked and clean.sh’s teardown is limited to owned releases, while
preserving idempotent lifecycle behavior.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: b618f86f-45cd-4c71-b3f9-1becb2b4b0cb

📥 Commits

Reviewing files that changed from the base of the PR and between 699951d and b131a4b.

📒 Files selected for processing (13)
  • docs/getting-started/installation-options/reference-install.md
  • docs/getting-started/quick-start.md
  • helm-prereqs/README.md
  • helm-prereqs/clean.sh
  • helm-prereqs/health-check.sh
  • helm-prereqs/helmfile.yaml
  • helm-prereqs/operators/values/ingress-nginx.yaml
  • helm-prereqs/setup.sh
  • helm-prereqs/values/nico-rest.yaml
  • helm/rest/nico-rest/charts/nico-rest-api/templates/ingress-certificate.yaml
  • helm/rest/nico-rest/charts/nico-rest-api/templates/ingress.yaml
  • helm/rest/nico-rest/charts/nico-rest-api/tests/ingress_test.yaml
  • helm/rest/nico-rest/charts/nico-rest-api/values.yaml

Comment thread helm-prereqs/clean.sh
Comment on lines +157 to +164
# ingress-nginx cluster-scoped resources are normally removed by helm uninstall,
# but remove stragglers so clean.sh can recover from partial installs.
echo "Removing ingress-nginx cluster-scoped resources..."
kubectl delete ingressclass nginx --ignore-not-found 2>/dev/null || true
kubectl get clusterrole,clusterrolebinding -o name \
| grep ingress-nginx \
| xargs kubectl delete --ignore-not-found 2>/dev/null || true

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.

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

Scope teardown to resources owned by this installation.

The setup flow explicitly allows operators to skip ingress-nginx when a controller already exists, but cleanup deletes the global IngressClass nginx, every matching ingress-nginx ClusterRole/ClusterRoleBinding, and the entire ingress-nginx namespace. This can remove another team’s ingress routing, RBAC, and workloads. Require recorded ownership or verify Helm ownership metadata before deleting these resources.

As per path instructions, helm-prereqs/** cleanup must be idempotent and must not remove shared cluster resources.

Also applies to: 205-210

🤖 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 `@helm-prereqs/clean.sh` around lines 157 - 164, Update the ingress-nginx
cleanup logic in clean.sh to delete resources only when this installation
recorded ownership or the resources have matching Helm ownership metadata; never
unconditionally delete the global nginx IngressClass, ingress-nginx
ClusterRoles/ClusterRoleBindings, or namespace. Preserve idempotency and safely
skip shared or externally managed resources, including the corresponding cleanup
block around the namespace deletion.

Source: Path instructions

Comment thread helm-prereqs/clean.sh
| jq -r '.items[] | select(
.spec.storageClassName == "local-path-persistent" and
(.spec.claimRef.namespace // "" | test("^(nico-system|cert-manager|vault|external-secrets|postgres|metallb-system|nico-rest|temporal)$"))
(.spec.claimRef.namespace // "" | test("^(nico-system|cert-manager|vault|external-secrets|postgres|ingress-nginx|metallb-system|nico-rest|temporal)$"))

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.

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Do not treat all ingress-nginx PVs as stack-owned.

This filter selects every local-path-persistent PV whose claim namespace is ingress-nginx. A pre-existing or shared namespace can contain unrelated retained volumes, so teardown may delete data outside this stack. Restrict deletion using ownership metadata or known claims, or exclude the namespace unless this script created and owns it.

As per path instructions, prerequisite teardown must avoid deleting resources outside its ownership boundary.

🤖 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 `@helm-prereqs/clean.sh` at line 245, Update the PV filtering logic in the
cleanup script so it does not automatically select every PV claimed in the
ingress-nginx namespace; instead, restrict deletion to explicitly stack-owned
resources using ownership metadata or known claim names, or remove ingress-nginx
from the namespace allowlist unless the script can verify it created and owns
the namespace.

Source: Path instructions

Comment on lines +109 to +112
if [[ -z "${INGRESS_NGINX_NS:-}" ]]; then
INGRESS_NGINX_NS=$(kubectl get deployment ingress-nginx-controller -A \
-o jsonpath='{.items[0].metadata.namespace}' 2>/dev/null || true)
fi

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.

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Do not select an arbitrary controller namespace.

If multiple namespaces contain ingress-nginx-controller, .items[0] can identify the wrong controller and produce misleading health results. Select the deployment using Helm/release labels or a known namespace, or explicitly report ambiguity when multiple matches exist.

As per path instructions, helm-prereqs/** health operations should provide reliable lifecycle status.

🤖 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 `@helm-prereqs/health-check.sh` around lines 109 - 112, Update the namespace
discovery logic around INGRESS_NGINX_NS to avoid selecting kubectl’s arbitrary
.items[0]. Identify the intended ingress-nginx-controller using Helm/release
labels or a configured namespace, and explicitly fail or report ambiguity when
multiple matching deployments remain; ensure the health-check lifecycle status
is reliable.

Source: Path instructions

Comment on lines +60 to +74
# ---------------------------------------------------------------------------
# ingress-nginx — optional Ingress controller for clusters that do not already
# provide one. setup.sh installs it only when requested; the controller Service
# uses type LoadBalancer and receives an address from MetalLB.
# ---------------------------------------------------------------------------
- name: ingress-nginx
namespace: ingress-nginx
createNamespace: true
chart: ingress-nginx/ingress-nginx
version: "4.12.1"
wait: true
timeout: 600
values:
- operators/values/ingress-nginx.yaml

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.

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

Prevent the optional release from broadening teardown scope.

setup.sh installs this release only when requested, but clean.sh runs helmfile destroy without a selector. A teardown can therefore target an existing ingress-nginx Helm release that this setup did not install. Track installation ownership or guard this release’s destruction explicitly.

As per path instructions, helm-prereqs/** lifecycle operations must be idempotent and must not remove resources outside their ownership boundary.

🤖 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 `@helm-prereqs/helmfile.yaml` around lines 60 - 74, Ensure the optional
ingress-nginx release cannot be destroyed unless this setup explicitly installed
it: update the helmfile and related setup/cleanup logic around the ingress-nginx
release so installation ownership is tracked and clean.sh’s teardown is limited
to owned releases, while preserving idempotent lifecycle behavior.

Source: Path instructions

@github-actions

github-actions Bot commented Jul 10, 2026

Copy link
Copy Markdown

🔍 Container Scan Summary

Service Total Critical High Medium Low Other
boot-artifacts-aarch64 3 0 0 3 0 0
boot-artifacts-x86_64 3 0 0 3 0 0
forge-admin-cli-x86_64 271 13 34 91 7 126
machine-validation-runner 800 37 234 291 43 195
machine_validation 800 37 234 291 43 195
machine_validation-aarch64 800 37 234 291 43 195
nvmetal-carbide 800 37 234 291 43 195
TOTAL 3477 161 970 1261 179 906

Per-CVE detail lives in the per-service grype-* artifacts (JSON + SARIF). Severity counts only — no CVE IDs published here.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant