Skip to content

Conversation

@safoinme
Copy link
Contributor

@safoinme safoinme commented Nov 21, 2025

Describe changes

I implemented improved URL discovery and preference handling for Kubernetes deployments to achieve better control over which URL is returned when multiple endpoint types are available (Gateway API, Ingress, LoadBalancer, NodePort, ClusterIP).

Key changes:

  • Added url_preference setting to explicitly select URL type
  • Refactored URL discovery into focused helper methods
  • Added comprehensive test coverage for URL selection logic
  • Updated documentation with URL preference guidance
  • All discovered URLs are stored in deployment metadata

This allows users to explicitly request specific URL types (e.g., url_preference="ingress") and raises clear errors if the requested type is unavailable, preventing accidental fallback to unexpected endpoints.

Pre-requisites

  • I have read the CONTRIBUTING.md document.
  • I have added tests to cover my changes.
  • I have based my new branch on develop and the open PR is targeting develop.
  • Documentation has been updated in the Kubernetes deployer guide

Types of changes

  • New feature (non-breaking change which adds functionality)

@github-actions github-actions bot added the internal To filter out internal PRs and issues label Nov 21, 2025
@htahir1
Copy link
Contributor

htahir1 commented Nov 21, 2025

@claude full-review

@claude

This comment was marked as outdated.

@safoinme
Copy link
Contributor Author

@claude full-review

@zenml-io zenml-io deleted a comment from claude bot Nov 24, 2025
@claude

This comment was marked as outdated.

@safoinme safoinme requested a review from stefannica December 3, 2025 10:30
@safoinme safoinme marked this pull request as ready for review December 3, 2025 10:30
@github-actions
Copy link
Contributor

github-actions bot commented Dec 3, 2025

Classification template updates in examples/mlops_starter have been pushed.

@htahir1
Copy link
Contributor

htahir1 commented Dec 4, 2025

@claude full-review

@claude

This comment was marked as resolved.

@github-actions
Copy link
Contributor

github-actions bot commented Dec 4, 2025

Documentation Link Check Results

Absolute links check failed
There are broken absolute links in the documentation. See workflow logs for details
Relative links check passed
Last checked: 2025-12-11 10:38:00 UTC

@safoinme safoinme linked an issue Dec 4, 2025 that may be closed by this pull request
1 task
Copy link
Contributor

@stefannica stefannica left a comment

Choose a reason for hiding this comment

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

I love this idea of collecting all possible URLs and leaving it to the user to decide which one to use.

I like it so much in fact, that I think we should formalize it and allow ALL deployments to have one or more URLs in the main DeploymentResponse model, one default and some alternative ones.

Comment on lines +559 to +569
class KubernetesUrlPreference(StrEnum):
"""URL preference for Kubernetes deployer when multiple URL types are available."""

GATEWAY_API = "gateway_api"
INGRESS = "ingress"
LOAD_BALANCER = "load_balancer"
NODE_PORT = "node_port"
CLUSTER_IP = "cluster_ip"
AUTO = "auto"


Copy link
Contributor

Choose a reason for hiding this comment

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

I think this belongs in a file somewhere under the kubernetes integration, not here.


Tip: When using Ingress or Gateway API, combine `service_type="ClusterIP"` with the matching `url_preference` so the returned URL matches the routing layer you manage (and you avoid paying for an extra LoadBalancer).

- Strict preference behavior: If you set `url_preference` to a specific type and that URL can't be discovered (for example, LoadBalancer is still pending), the deployer raises an error instead of returning another URL type. This helps avoid accidental exposure paths.
Copy link
Contributor

Choose a reason for hiding this comment

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

Love this neat little insight!

Comment on lines +1361 to +1362
gateway: Union[Dict[str, Any], Any],
httproute: Union[Dict[str, Any], Any],
Copy link
Contributor

Choose a reason for hiding this comment

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

I know there are no typed objects in the kubernetes client library for things like gateway and httproute, but using dictionaries is really error prone and difficult to read/understand. I suggest you define some simple pydantic objects that map to the attributes that you're using from these objects instead of using these unpredictable .get calls. Generally speaking, when it feels like you're using a lot of .get, hasattr and getattr calls, this is a sign that you're not using Python typing features correctly.

name=httproute_item.name,
namespace=httproute_namespace,
kind="HTTPRoute",
api_version="gateway.networking.k8s.io/v1beta1",
Copy link
Contributor

Choose a reason for hiding this comment

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

how likely is it that these versions will change or have changed ? shouldn't you try to cover all the relevant versions, past and future ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is a great insight, this is probably changing sometime soon once this get's more stable, hmmm but what would be the right way to handle this? let user pass the api version?

name=gateway_item.name,
namespace=gateway_item_namespace,
kind="Gateway",
api_version="gateway.networking.k8s.io/v1beta1",
Copy link
Contributor

Choose a reason for hiding this comment

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

Same here: how likely is it that these versions will change or have changed ? shouldn't you try to cover all the relevant versions, past and future ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

same as above

Comment on lines 1178 to 1182
inventory, "Gateway", "gateway.networking.k8s.io/v1beta1"
)
httproute_items = _filter_inventory(
inventory, "HTTPRoute", "gateway.networking.k8s.io/v1beta1"
)
Copy link
Contributor

Choose a reason for hiding this comment

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

what about previous/future versions of these resources? can you check and make sure that this code is also valid on other kubernetes versions, past and (preferably) future?

Comment on lines 1265 to 1282
httproute_spec = httproute_dict.get("spec", {})
httproute_rules = httproute_spec.get("rules", [])

routes_to_service = False
for rule in httproute_rules:
backend_refs = rule.get("backendRefs", [])
for backend_ref in backend_refs:
backend_service_name = backend_ref.get("name")
backend_namespace = (
backend_ref.get("namespace") or httproute_namespace
)

if (
backend_service_name == service_item.name
and backend_namespace == service_namespace
):
routes_to_service = True
break
Copy link
Contributor

Choose a reason for hiding this comment

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

Same comment here: prefer typed objects to these interminable and opaque .get calls.

@github-actions
Copy link
Contributor

⚠️ This PR has been inactive for 2 weeks and has been marked as stale.
Timeline:

  • Week 2 (now): First reminder - PR marked as stale
  • Week 4: PR will be automatically closed if no activity
    Please update this PR or leave a comment to keep it active. Any activity will reset the timer and remove the stale label.

@github-actions github-actions bot added the stale label Dec 26, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

internal To filter out internal PRs and issues stale

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Kubernetes Deployer URL extraction

5 participants