Skip to content

Conversation

@mangelajo
Copy link
Member

@mangelajo mangelajo commented Oct 28, 2025

Summary by CodeRabbit

  • Refactor

    • Networking now uses NETWORKING_MODE instead of INGRESS_ENABLED to determine endpoint behavior; scripts set a sensible default and improved tracing.
  • New Features

    • Automatic creation of Ingress resources in ingress mode, with TLS passthrough and host extraction for gRPC.
    • ClusterIP services created when requested or required by Ingress/Route; labels/annotations from endpoint config are merged and respected.
    • gRPC endpoints use secure ports in ingress mode.
  • Tests

    • Added extensive ingress-focused tests covering creation, annotation/label merging, host parsing, TLS, and cleanup.

@mangelajo mangelajo requested a review from bennyz October 28, 2025 07:25
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 28, 2025

Walkthrough

Ingress reconciliation and creation were added for endpoints; service creation logic now considers Ingress/Route and merges labels/annotations via a new MergeMaps utility. Deployment scripts and env var usage switched from INGRESS_ENABLED to NETWORKING_MODE. Tests added for Ingress behavior and cleanup.

Changes

Cohort / File(s) Summary
Endpoints controller & ingress logic
deploy/operator/internal/controller/jumpstarter/endpoints/endpoints.go, deploy/operator/internal/controller/jumpstarter/endpoints/ingress.go
Added Ingress reconciliation (createOrUpdateIngress) and builder (createIngressForEndpoint), hostname extraction, default nginx/TLS annotations, and updated reconcile flows to create Ingress when applicable. Service creation now uses merged labels/annotations and ClusterIP creation conditions consider Ingress/Route.
Tests: ingress e2e and cleanup
deploy/operator/internal/controller/jumpstarter/endpoints/endpoints_test.go
Added tests verifying Ingress creation for controller and router endpoints (class handling, hostname extraction, TLS/rules/backends, annotation/label merge precedence). Expanded AfterEach cleanup to remove created Ingress and related services.
Utility: map merging
deploy/operator/internal/utils/utils.go
New MergeMaps(base, overrides map[string]string) map[string]string utility used to merge labels/annotations with overrides taking precedence.
Deployment scripts / env vars
hack/deploy_vars, hack/deploy_with_helm.sh, hack/deploy_with_operator.sh, hack/utils
Replaced INGRESS_ENABLED with NETWORKING_MODE (default nodeport), adjusted endpoint ports and ingress.class when NETWORKING_MODE=ingress, updated Helm/operator install branches to use NETWORKING_MODE, and enabled additional shell tracing in operator script.

Sequence Diagram(s)

sequenceDiagram
  participant Reconciler as EndpointReconciler
  participant API as K8s API
  participant Utils as utils.MergeMaps

  Note over Reconciler: ReconcileControllerEndpoint / ReconcileRouterReplicaEndpoint
  Reconciler->>API: ensure Service (ClusterIP/NodePort/LoadBalancer) with merged labels/annotations
  API-->>Reconciler: Service created/updated

  alt Ingress/Route enabled
    Reconciler->>Utils: Merge(defaultIngressAnnotations, userAnnotations)
    Utils-->>Reconciler: merged annotations
    Reconciler->>API: createOrUpdate Ingress (IngressClassName?, Rules, TLS) with ownerRef -> service backend
    API-->>Reconciler: Ingress created/updated
  else Ingress/Route not enabled
    Note right of Reconciler: Skip ingress creation
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Areas needing extra attention:
    • createOrUpdateIngress mutability and ownerReference logic in ingress.go
    • Hostname parsing edge cases in extractHostname (IPv6/brackets, ports)
    • Merge precedence and nil-safety when using utils.MergeMaps for labels/annotations
    • Tests in endpoints_test.go for flakiness and complete cleanup
    • Consistency of NETWORKING_MODE changes across scripts and defaults

"🐰
I stitched the maps and opened gates for hosts,
A hop, a merge, no more config ghosts,
Ingress hums softly, labels snug and true,
Tests tidy the garden, routing finds its view,
I nibble on bytes and celebrate this new."

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The pull request title "operator: ingress support" directly and accurately describes the primary change in this changeset. The PR comprehensively adds ingress support to the operator, including a new ingress reconciliation file with helper functions, modifications to endpoint handling to create and manage ingress resources, extensive test coverage for ingress functionality, and updates to deployment scripts to support ingress-based networking. The title is specific to the operator subsystem and the ingress feature, avoiding vague terms while remaining concise and clear enough for developers scanning the history to immediately understand the main purpose.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch operator-ingress

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
hack/deploy_with_operator.sh (1)

2-2: Consider if command tracing should remain enabled.

The -x flag enables command tracing, which increases log verbosity. This may be useful for debugging but could clutter logs. Note that hack/deploy_with_helm.sh still uses set -eo pipefail without tracing.

Consider either:

  • Removing the -x flag if it was added temporarily for debugging
  • Adding it consistently to other deployment scripts if it's intended to be permanent
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 37c64f8 and 96a270e.

📒 Files selected for processing (6)
  • deploy/operator/internal/controller/jumpstarter/endpoints/endpoints.go (7 hunks)
  • deploy/operator/internal/controller/jumpstarter/endpoints/endpoints_test.go (5 hunks)
  • hack/deploy_vars (1 hunks)
  • hack/deploy_with_helm.sh (1 hunks)
  • hack/deploy_with_operator.sh (2 hunks)
  • hack/utils (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
deploy/operator/internal/controller/jumpstarter/endpoints/endpoints_test.go (1)
deploy/operator/api/v1alpha1/jumpstarter_types.go (2)
  • Endpoint (380-414)
  • IngressConfig (433-451)
deploy/operator/internal/controller/jumpstarter/endpoints/endpoints.go (1)
deploy/helm/jumpstarter/charts/jumpstarter-controller/model.py (2)
  • Ingress (74-82)
  • Route (85-90)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: tests
  • GitHub Check: e2e-tests-release-0-7
  • GitHub Check: lint-go
  • GitHub Check: e2e-tests (ubuntu-24.04)
  • GitHub Check: e2e-tests (ubuntu-24.04-arm)
  • GitHub Check: deploy-with-operator
  • GitHub Check: deploy-kind
🔇 Additional comments (15)
hack/utils (1)

15-15: LGTM! Standardized networking mode configuration.

The transition from INGRESS_ENABLED to NETWORKING_MODE with a default of "nodeport" improves clarity and aligns with the broader refactoring across deployment scripts.

hack/deploy_with_operator.sh (1)

53-67: LGTM! Appropriate ingress class configuration.

Setting the ingress class to "nginx" for both controller and router endpoints aligns well with the nginx ingress installation performed earlier in the script. This ensures the ingress resources will be properly handled by the nginx ingress controller.

hack/deploy_with_helm.sh (1)

16-16: LGTM! Consistent networking mode check.

The update from INGRESS_ENABLED == "true" to NETWORKING_MODE == "ingress" maintains the same logic while aligning with the standardized configuration variable across all deployment scripts.

hack/deploy_vars (1)

11-18: LGTM! Clear endpoint configuration based on networking mode.

The port mappings are appropriate: 5443 for ingress (typically with TLS termination) and 8082/8083 for nodeport. The logic is consistent with the broader NETWORKING_MODE refactoring.

deploy/operator/internal/controller/jumpstarter/endpoints/endpoints.go (4)

157-171: LGTM! Proper ClusterIP service handling for Ingress/Route.

The logic correctly creates a ClusterIP service when needed by Ingress or Route configurations, while safely handling cases where ClusterIP config might be nil. This ensures the backend service exists for Ingress to route traffic.


174-185: LGTM! Proper default service logic.

The updated condition correctly avoids creating a default ClusterIP service when Ingress or Route are already enabled and handling service creation. This prevents resource duplication.


214-262: LGTM! Consistent router endpoint handling.

The router endpoint reconciliation follows the same patterns as the controller endpoint, ensuring consistency. The Ingress creation and ClusterIP service logic mirror the controller implementation appropriately.


290-291: The utils package referenced in the import does not exist in the codebase.

The code at line 291 calls utils.MergeMaps(baseLabels, extraLabels), but:

  • The package deploy/operator/internal/utils does not exist in the repository
  • The MergeMaps function is not defined anywhere in the codebase
  • This code would fail to compile

Either the utils package needs to be created with the MergeMaps function implementation, or the import path is incorrect. Cannot verify the precedence behavior without seeing the actual MergeMaps implementation.

deploy/operator/internal/controller/jumpstarter/endpoints/endpoints_test.go (7)

258-317: LGTM! Comprehensive Ingress test coverage.

This test thoroughly validates the Ingress creation flow, including:

  • ClusterIP service backend creation
  • IngressClassName assignment
  • Default nginx annotations for gRPC/TLS
  • Ingress rules and host configuration
  • TLS configuration

The test coverage is excellent for the Ingress-enabled endpoint scenario.


319-362: LGTM! Proper annotation and label merging validation.

This test confirms that user-provided annotations correctly override defaults while preserving non-conflicting default annotations. The label merging is also validated. This is important for ensuring flexibility in Ingress configuration.


364-406: LGTM! Thorough hostname extraction testing.

The test validates hostname extraction from various address formats (with and without ports), ensuring the Ingress host configuration is correct regardless of how the address is specified. The inline cleanup is appropriate for this iterative test.


408-436: LGTM! Validates default IngressClass behavior.

This test ensures that when no ingress class is specified, the IngressClassName is nil, allowing the cluster's default IngressClass to be used. This is the correct Kubernetes behavior.


440-461: LGTM! Proper test cleanup for Ingress resources.

The AfterEach block is correctly updated to clean up the newly created Ingress resources alongside their associated services. This prevents test pollution and resource leaks.


540-590: LGTM! Comprehensive router Ingress testing.

The router replica endpoint tests mirror the controller endpoint tests, validating Ingress creation, annotation merging, and proper service selection. The consistency between controller and router test patterns demonstrates good test design.


605-615: LGTM! Router Ingress cleanup.

The cleanup properly handles router-specific Ingress resources, maintaining consistency with the controller test cleanup patterns.

@mangelajo mangelajo force-pushed the operator-ingress branch 2 times, most recently from 823548d to d29516f Compare October 28, 2025 08:56
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (9)
hack/deploy_with_helm.sh (2)

16-20: Validate NETWORKING_MODE and fail fast on unknown values.

Add a guard to avoid silent misconfig when NETWORKING_MODE is unset or unexpected; default to nodeport or exit with a clear message.

-if [ "${NETWORKING_MODE}" == "ingress" ]; then
+case "${NETWORKING_MODE}" in
+  ingress) ;;
+  nodeport|"") NETWORKING_MODE="nodeport" ;;
+  *) echo "Unsupported NETWORKING_MODE=${NETWORKING_MODE} (expected: ingress|nodeport)"; exit 1 ;;
+esac
+
+if [ "${NETWORKING_MODE}" == "ingress" ]; then

Also applies to: 31-35


43-45: Use precise Helm release detection.

Avoid grep false positives; use helm status on the exact release/namespace.

-if helm list -A | grep jumpstarter > /dev/null; then
-  METHOD=upgrade
-fi
+if helm status jumpstarter -n jumpstarter-lab >/dev/null 2>&1; then
+  METHOD=upgrade
+fi
deploy/operator/internal/utils/utils.go (1)

5-19: Preallocate map capacity to reduce allocations.

Minor perf win and keeps semantics unchanged.

-func MergeMaps(base, overrides map[string]string) map[string]string {
-	merged := make(map[string]string)
+func MergeMaps(base, overrides map[string]string) map[string]string {
+	merged := make(map[string]string, len(base)+len(overrides))
deploy/operator/internal/controller/jumpstarter/endpoints/endpoints.go (2)

68-74: Preserve NodePort by port name, not index.

Index-based copy breaks if port order changes; match by Name to retain stable NodePorts.

-			if service.Spec.Type == corev1.ServiceTypeNodePort || service.Spec.Type == corev1.ServiceTypeLoadBalancer {
-				for i := range existingService.Spec.Ports {
-					if existingService.Spec.Ports[i].NodePort != 0 && i < len(service.Spec.Ports) {
-						service.Spec.Ports[i].NodePort = existingService.Spec.Ports[i].NodePort
-					}
-				}
-			}
+			if service.Spec.Type == corev1.ServiceTypeNodePort || service.Spec.Type == corev1.ServiceTypeLoadBalancer {
+				existingByName := make(map[string]int32, len(existingService.Spec.Ports))
+				for _, p := range existingService.Spec.Ports {
+					if p.NodePort != 0 && p.Name != "" {
+						existingByName[p.Name] = p.NodePort
+					}
+				}
+				for i := range service.Spec.Ports {
+					if np, ok := existingByName[service.Spec.Ports[i].Name]; ok {
+						service.Spec.Ports[i].NodePort = np
+					}
+				}
+			}

Also applies to: 84-90


131-138: Consider creating the ClusterIP service before the Ingress.

Minor ordering nit: reconciling the service first avoids brief ingress backends-not-found windows on first apply. Functionally OK either way.

Also applies to: 156-171

deploy/operator/internal/controller/jumpstarter/endpoints/endpoints_test.go (2)

364-407: Add IPv4 and IPv6 cases to hostname extraction tests.

Covers important formats declared in the CRD comments.

                 testCases := []struct {
                     address      string
                     expectedHost string
                 }{
                     {"grpc.example.com", "grpc.example.com"},
                     {"grpc.example.com:443", "grpc.example.com"},
                     {"grpc.example.com:8080", "grpc.example.com"},
+                    {"192.0.2.10:8443", "192.0.2.10"},
+                    {"[2001:db8::1]:8443", "2001:db8::1"},
                 }

258-317: Add a negative test: Ingress enabled but empty address → no Ingress created.

Verifies the “skip when no hostname” path.

deploy/operator/internal/controller/jumpstarter/endpoints/ingress.go (2)

106-116: Gate nginx-specific defaults by Ingress class.

Avoid applying nginx annotations when using another controller.

-	// Build default annotations for TLS passthrough with GRPC with nginx ingress
-	defaultAnnotations := map[string]string{
-		"nginx.ingress.kubernetes.io/ssl-redirect":       "true",
-		"nginx.ingress.kubernetes.io/backend-protocol":   "GRPC",
-		"nginx.ingress.kubernetes.io/proxy-read-timeout": "300",
-		"nginx.ingress.kubernetes.io/proxy-send-timeout": "300",
-		"nginx.ingress.kubernetes.io/ssl-passthrough":    "true",
-	}
+	defaultAnnotations := map[string]string{}
+	if endpoint.Ingress.Class == "" || endpoint.Ingress.Class == "nginx" {
+		defaultAnnotations = map[string]string{
+			"nginx.ingress.kubernetes.io/ssl-redirect":       "true",
+			"nginx.ingress.kubernetes.io/backend-protocol":   "GRPC",
+			"nginx.ingress.kubernetes.io/proxy-read-timeout": "300",
+			"nginx.ingress.kubernetes.io/proxy-send-timeout": "300",
+			"nginx.ingress.kubernetes.io/ssl-passthrough":    "true",
+		}
+	}

Also applies to: 121-126


70-90: Use net.SplitHostPort for robust parsing; keep IPv6 bracket handling.

Reduces edge-case bugs (e.g., bare IPv6 with port). Behavior stays backward‑compatible.

+import (
+    "context"
+    "net"
+    "strings"
+    ...
+)
@@
 func extractHostname(address string) string {
-	// Handle IPv6 addresses in brackets
-	if strings.HasPrefix(address, "[") {
-		// Find the closing bracket
-		if idx := strings.Index(address, "]"); idx != -1 {
-			return address[1:idx]
-		}
-		return address
-	}
-
-	// For hostname or IPv4, strip port if present
-	if idx := strings.LastIndex(address, ":"); idx != -1 {
-		// Check if this is part of an IPv6 address (no brackets)
-		// Count colons - if more than one, likely IPv6
-		if strings.Count(address, ":") > 1 {
-			return address
-		}
-		return address[:idx]
-	}
-
-	return address
+	if address == "" {
+		return ""
+	}
+	// Bracketed IPv6 with optional port
+	if strings.HasPrefix(address, "[") {
+		if host, _, err := net.SplitHostPort(address); err == nil {
+			return host
+		}
+		if idx := strings.Index(address, "]"); idx != -1 {
+			return address[1:idx]
+		}
+		return address
+	}
+	// Try host:port for hostname/IPv4
+	if host, _, err := net.SplitHostPort(address); err == nil {
+		return host
+	}
+	// Bare hostname, IPv4, or bare IPv6 without port
+	return address
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 96a270e and d29516f.

📒 Files selected for processing (8)
  • deploy/operator/internal/controller/jumpstarter/endpoints/endpoints.go (7 hunks)
  • deploy/operator/internal/controller/jumpstarter/endpoints/endpoints_test.go (5 hunks)
  • deploy/operator/internal/controller/jumpstarter/endpoints/ingress.go (1 hunks)
  • deploy/operator/internal/utils/utils.go (1 hunks)
  • hack/deploy_vars (1 hunks)
  • hack/deploy_with_helm.sh (1 hunks)
  • hack/deploy_with_operator.sh (2 hunks)
  • hack/utils (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • hack/deploy_vars
  • hack/deploy_with_operator.sh
  • hack/utils
🧰 Additional context used
🧬 Code graph analysis (3)
deploy/operator/internal/controller/jumpstarter/endpoints/endpoints.go (1)
deploy/operator/internal/utils/utils.go (1)
  • MergeMaps (5-19)
deploy/operator/internal/controller/jumpstarter/endpoints/endpoints_test.go (2)
deploy/operator/api/v1alpha1/jumpstarter_types.go (2)
  • Endpoint (380-414)
  • IngressConfig (433-451)
deploy/helm/jumpstarter/charts/jumpstarter-controller/model.py (2)
  • Ingress (74-82)
  • Port (70-71)
deploy/operator/internal/controller/jumpstarter/endpoints/ingress.go (2)
deploy/operator/internal/controller/jumpstarter/endpoints/endpoints.go (1)
  • Reconciler (35-38)
deploy/operator/internal/utils/utils.go (1)
  • MergeMaps (5-19)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: e2e-tests-release-0-7
  • GitHub Check: e2e-tests (ubuntu-24.04-arm)
  • GitHub Check: e2e-tests (ubuntu-24.04)
  • GitHub Check: deploy-with-operator
🔇 Additional comments (1)
deploy/operator/internal/controller/jumpstarter/endpoints/endpoints.go (1)

291-292: Nil-safe merge is fine; confirm extraLabels origin.

utils.MergeMaps handles nil. Ensure callers don’t pass huge maps unintentionally (labels copied per reconcile).

@mangelajo mangelajo changed the title Operator ingress operator: ingress support Oct 28, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
deploy/operator/internal/controller/jumpstarter/endpoints/ingress.go (1)

113-113: TODO documented for status condition propagation.

The TODO comment notes that invalid hostname errors should be propagated to status conditions in the future. This is good to track for improved observability.

Would you like me to open an issue to track implementing status condition propagation for invalid hostnames?

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d29516f and 3e595c8.

📒 Files selected for processing (8)
  • deploy/operator/internal/controller/jumpstarter/endpoints/endpoints.go (7 hunks)
  • deploy/operator/internal/controller/jumpstarter/endpoints/endpoints_test.go (5 hunks)
  • deploy/operator/internal/controller/jumpstarter/endpoints/ingress.go (1 hunks)
  • deploy/operator/internal/utils/utils.go (1 hunks)
  • hack/deploy_vars (1 hunks)
  • hack/deploy_with_helm.sh (1 hunks)
  • hack/deploy_with_operator.sh (2 hunks)
  • hack/utils (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • hack/deploy_with_helm.sh
  • hack/deploy_with_operator.sh
  • deploy/operator/internal/controller/jumpstarter/endpoints/endpoints.go
  • hack/deploy_vars
🧰 Additional context used
🧬 Code graph analysis (2)
deploy/operator/internal/controller/jumpstarter/endpoints/endpoints_test.go (1)
deploy/operator/api/v1alpha1/jumpstarter_types.go (2)
  • Endpoint (380-414)
  • IngressConfig (433-451)
deploy/operator/internal/controller/jumpstarter/endpoints/ingress.go (2)
deploy/operator/internal/controller/jumpstarter/endpoints/endpoints.go (1)
  • Reconciler (35-38)
deploy/operator/internal/utils/utils.go (1)
  • MergeMaps (5-19)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: tests
  • GitHub Check: deploy-with-operator
  • GitHub Check: deploy-kind
  • GitHub Check: e2e-tests (ubuntu-24.04)
  • GitHub Check: e2e-tests-release-0-7
  • GitHub Check: lint-go
🔇 Additional comments (9)
deploy/operator/internal/utils/utils.go (1)

5-19: LGTM! Clean and correct implementation.

The function correctly merges two maps with proper precedence (overrides take precedence over base). The implementation is safe for nil inputs since ranging over nil maps in Go is well-defined behavior.

hack/utils (1)

15-15: LGTM! Clean refactoring to mode-based configuration.

The change from INGRESS_ENABLED to NETWORKING_MODE with a default of "nodeport" provides better clarity and aligns with the PR's ingress support objectives.

deploy/operator/internal/controller/jumpstarter/endpoints/endpoints_test.go (4)

258-436: Excellent test coverage for Ingress functionality.

These tests comprehensively validate:

  • ClusterIP service creation with Ingress
  • Default nginx annotations for TLS passthrough and GRPC
  • User annotation/label merging with correct precedence
  • Hostname extraction from various address formats
  • IngressClassName handling (both specified and nil/default)
  • TLS configuration

The test structure is clear and follows existing patterns.


440-461: Proper cleanup of Ingress resources.

The AfterEach cleanup correctly includes the new ingress resources (controller-grpc-ing, test-svc-ing) alongside existing service cleanup.


540-590: Good coverage for router replica Ingress scenarios.

These tests properly validate Ingress creation for router replicas, including service creation, ingress configuration, annotation merging, and proper pod selector targeting.


605-615: Cleanup properly handles router ingress resources.

The router AfterEach correctly includes cleanup of router-grpc-ing alongside service resources.

deploy/operator/internal/controller/jumpstarter/endpoints/ingress.go (3)

34-67: LGTM! Follows controller-runtime best practices.

The function correctly uses CreateOrUpdate to reconcile Ingress resources, updates all mutable fields (Labels, Annotations, IngressClassName, Rules, TLS), sets owner references, and includes proper error handling and logging.


69-92: Hostname extraction logic handles multiple address formats correctly.

The function properly handles:

  • IPv6 addresses in brackets [IPv6] and [IPv6]:port
  • Hostnames and IPv4 addresses with optional ports
  • IPv6 addresses without brackets (multiple colons)

94-183: Well-structured ingress creation with proper validation.

The function includes several good practices:

  • Hostname extraction and validation using IsDNS1123Subdomain
  • Default nginx annotations for TLS passthrough and GRPC backend
  • Correct precedence when merging user annotations/labels with defaults using MergeMaps
  • Proper handling of optional IngressClassName (nil when empty)
  • TLS configuration for passthrough mode

Note: The past review comment regarding potential DNS1123 name length validation for the constructed ingress name (serviceName + "-ing") at line 143 remains relevant.

@mangelajo
Copy link
Member Author

github arm runners are down, that's why that shows up in red.

@mangelajo mangelajo merged commit c850a15 into main Oct 30, 2025
15 of 18 checks passed
@mangelajo mangelajo deleted the operator-ingress branch October 30, 2025 11:49
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.

4 participants