istio_ingress_route¶
Istio ingress route interface library.
This library provides the provider and requirer sides of the istio-ingress-route
relation interface for advanced ingress routing through the istio-ingress-k8s charm.
What is this library for?¶
The istio-ingress-k8s charm supports the standard ingress interface, but
that interface has limitations: it cannot open multiple ports, configure custom
path prefixes, apply URL rewrites or redirects, or set up gRPC routing.
The istio-ingress-route interface fills this gap. It allows requiring charms to
publish rich routing configurations — multi-port listeners, HTTP path matching,
gRPC method routing, URL rewrite filters, request redirect filters — that the
istio-ingress-k8s charm translates into Kubernetes Gateway API resources
(Gateway listeners, HTTPRoutes, and GRPCRoutes).
How it works¶
The requirer charm builds an
IstioIngressRouteConfigdescribing its listeners, HTTP routes, and gRPC routes, then callssubmit_config(config).The provider (istio-ingress-k8s) receives a
readyevent, reads the config viaget_config(relation), and creates the corresponding Gateway API resources.The provider publishes the external host and TLS status back to the requirer so it can construct its public URL.
Requirer usage:
from charmlibs.interfaces.istio_ingress_route import (
IstioIngressRouteRequirer,
IstioIngressRouteConfig,
Listener,
HTTPRoute,
GRPCRoute,
BackendRef,
ProtocolType,
HTTPMethod,
HTTPRouteMatch,
HTTPPathMatch,
HTTPPathMatchType,
GRPCMethodMatch,
GRPCRouteMatch,
to_gateway_protocol,
)
class MyCharm(CharmBase):
def __init__(self, *args):
super().__init__(*args)
self.ingress = IstioIngressRouteRequirer(
self,
relation_name="ingress",
)
self.framework.observe(
self.ingress.on.ready, self._on_ingress_ready
)
def _configure_ingress(self):
http_listener = Listener(port=3200, protocol=ProtocolType.HTTP)
grpc_listener = Listener(port=9096, protocol=ProtocolType.GRPC)
config = IstioIngressRouteConfig(
model=self.model.name,
listeners=[http_listener, grpc_listener],
http_routes=[
HTTPRoute(
name="http-route",
listener=http_listener,
matches=[
HTTPRouteMatch(
path=HTTPPathMatch(
type=HTTPPathMatchType.PathPrefix, value="/api"
),
method=HTTPMethod.GET,
)
],
backends=[BackendRef(service=self.app.name, port=3200)],
),
],
grpc_routes=[
GRPCRoute(
name="grpc-route",
listener=grpc_listener,
matches=[
GRPCRouteMatch(
method=GRPCMethodMatch(
service="myapp.MyService", method="GetData"
)
)
],
backends=[BackendRef(service=self.app.name, port=9096)],
),
],
)
self.ingress.submit_config(config)
def _on_ingress_ready(self, event):
scheme = "https" if self.ingress.tls_enabled else "http"
url = f"{scheme}://{self.ingress.external_host}"
Provider usage:
from charmlibs.interfaces.istio_ingress_route import (
IstioIngressRouteProvider,
to_gateway_protocol,
)
class IstioIngressCharm(CharmBase):
def __init__(self, *args):
super().__init__(*args)
self.istio_ingress_route = IstioIngressRouteProvider(
self,
external_host=self._external_host,
tls_enabled=self._is_tls_enabled(),
)
self.framework.observe(
self.istio_ingress_route.on.ready,
self._handle_istio_ingress_route_ready,
)
def _handle_istio_ingress_route_ready(self, event):
config = self.istio_ingress_route.get_config(event.relation)
if not config:
return
is_tls_enabled = self._is_tls_enabled()
for listener in config.listeners:
gateway_protocol = to_gateway_protocol(
listener.protocol, is_tls_enabled
)
- class BackendRef(
- *,
- service: str,
- port: Annotated[int, Ge(ge=1), Le(le=65535)],
- weight: Annotated[int | None, Ge(ge=1), Le(le=100)] = None,
Bases:
BaseModelReference to a backend service.
- class FilterType(*values)¶
-
Filter type values.
- URLRewrite = 'URLRewrite'¶
- RequestRedirect = 'RequestRedirect'¶
- class GRPCMethodMatch(*, service: str, method: str | None = None)¶
Bases:
BaseModelgRPC method matching configuration.
Matches gRPC methods in the format
/service/method.The
servicecan be a simple name (e.g.,"MyService") or package-qualified (e.g.,"package.MyService"). Themethodis the RPC method name; if omitted, all methods on the service are matched.Examples
>>> GRPCMethodMatch(service="com.example.UserService") # Matches all methods on /com.example.UserService
>>> GRPCMethodMatch(service="com.example.UserService", method="GetUser") # Matches only /com.example.UserService/GetUser
>>> GRPCMethodMatch(service="UserService", method="CreateUser") # Matches /UserService/CreateUser
- class GRPCRoute(
- *,
- name: str,
- listener: Listener,
- backends: list[BackendRef],
- hostnames: list[str] | None = None,
- matches: list[GRPCRouteMatch] | None = None,
- filters: list[RequestRedirectFilter] | None = None,
Bases:
_L7RoutegRPC route configuration.
- matches: list[GRPCRouteMatch] | None¶
- filters: list[RequestRedirectFilter] | None¶
- property protocol: ProtocolType¶
Protocol type for gRPC routes.
- class GRPCRouteMatch( )¶
Bases:
_RouteMatchMatch conditions for gRPC routes.
- method: GRPCMethodMatch | None¶
- class HTTPMethod(*values)¶
-
HTTP methods for route matching.
- GET = 'GET'¶
- POST = 'POST'¶
- PUT = 'PUT'¶
- DELETE = 'DELETE'¶
- PATCH = 'PATCH'¶
- HEAD = 'HEAD'¶
- OPTIONS = 'OPTIONS'¶
- CONNECT = 'CONNECT'¶
- TRACE = 'TRACE'¶
- class HTTPPathMatch(
- *,
- type: HTTPPathMatchType = HTTPPathMatchType.PathPrefix,
- value: str,
Bases:
BaseModelPath matching configuration for HTTP routes.
- type: HTTPPathMatchType¶
- class HTTPPathMatchType(*values)¶
-
Path match types for HTTP routes.
- Exact = 'Exact'¶
- PathPrefix = 'PathPrefix'¶
- RegularExpression = 'RegularExpression'¶
- class HTTPRoute(
- *,
- name: str,
- listener: Listener,
- backends: list[BackendRef],
- hostnames: list[str] | None = None,
- matches: list[HTTPRouteMatch] | None = None,
- filters: list[URLRewriteFilter | RequestRedirectFilter] | None = None,
Bases:
_L7RouteHTTP route configuration.
- matches: list[HTTPRouteMatch] | None¶
- filters: list[URLRewriteFilter | RequestRedirectFilter] | None¶
- property protocol: ProtocolType¶
Protocol type for HTTP routes.
- class HTTPRouteMatch(
- *,
- headers: dict[str, str] | None = None,
- path: HTTPPathMatch | None = None,
- method: HTTPMethod | None = None,
Bases:
_RouteMatchMatch conditions for HTTP routes.
- path: HTTPPathMatch | None¶
- method: HTTPMethod | None¶
- class IstioIngressRouteConfig(
- *,
- model: str,
- listeners: list[Listener] = <factory>,
- http_routes: list[HTTPRoute] = <factory>,
- grpc_routes: list[GRPCRoute] = <factory>,
Bases:
BaseModelComplete configuration for istio-ingress-route.
- exception IstioIngressRouteError¶
Bases:
RuntimeErrorBase class for exceptions raised by IstioIngressRoute.
- class IstioIngressRouteProvider(
- charm: CharmBase,
- relation_name: str = 'istio-ingress-route',
- external_host: str = '',
- *,
- tls_enabled: bool = False,
Bases:
ObjectImplementation of the provider of istio_ingress_route.
This will be owned by the istio-ingress charm. The main idea is that istio-ingress will observe the ready event and, upon receiving it, will fetch the config from the requirer’s application databag, apply it (create Gateway listeners and Routes), and update its own app databag to let the requirer know that the ingress is ready.
- on¶
Container for IstioIngressRouteProvider events.
- property relations¶
The list of Relation instances associated with this endpoint.
- update_ingress_address( )¶
Ensure that requirers know the external host for istio-ingress.
- wipe_ingress_data(relation: Relation)¶
Clear ingress data from relation.
This removes the external_host and tls_enabled fields from the provider’s application databag for the given relation. This is typically used when route conflicts are detected or when the ingress should no longer be available.
- Parameters:
relation – The relation to clear data from
- is_ready(relation: Relation) bool¶
Whether IstioIngressRoute is ready on this relation.
Returns True when the remote app shared the config; False otherwise.
- get_config(
- relation: Relation,
Retrieve the config published by the remote application.
- class IstioIngressRouteRequirer( )¶
Bases:
ObjectHandles the requirer side of the istio-ingress-route interface.
This class provides an API for publishing routing configurations to the istio-ingress charm through the istio-ingress-route relation.
- on¶
Container for IstioIngressRouteRequirer events.
- submit_config(
- config: IstioIngressRouteConfig,
Submit an ingress configuration to istio-ingress.
This method publishes routing configuration data to the istio-ingress-route relation.
- Parameters:
config – The IstioIngressRouteConfig to submit.
- Raises:
UnauthorizedError – If the unit is not the leader.
- class Listener(
- *,
- port: Annotated[int, Ge(ge=1), Le(le=65535)],
- protocol: ProtocolType,
Bases:
BaseModelGateway listener configuration.
Specify the application-level protocol (HTTP or GRPC). The istio-ingress charm will automatically upgrade to TLS (HTTPS/GRPCS) when certificates are available.
The listener name is automatically derived from port and protocol by the charm.
- protocol: ProtocolType¶
- class PathModifier(
- *,
- type: PathModifierType,
- value: str,
Bases:
BaseModelPath modification configuration.
- type: PathModifierType¶
- class PathModifierType(*values)¶
-
Path modifier types.
- ReplaceFullPath = 'ReplaceFullPath'¶
- ReplacePrefixMatch = 'ReplacePrefixMatch'¶
- class ProtocolType(*values)¶
-
Application-level protocol types.
Consumers specify the application protocol (HTTP or GRPC). The istio-ingress charm automatically applies TLS encryption based on certificate availability, upgrading HTTP to HTTPS and GRPC to GRPCS transparently.
The Gateway API doesn’t have GRPC as a distinct protocol type. GRPC uses HTTP/2, so it maps to “HTTP” or “HTTPS” in Gateway listeners. The difference between HTTP and gRPC traffic is expressed through the route type (HTTPRoute vs GRPCRoute).
- HTTP = 'HTTP'¶
- GRPC = 'GRPC'¶
- class RequestRedirectFilter(
- *,
- requestRedirect: RequestRedirectSpec,
Bases:
BaseModelRequest redirect filter for HTTP/gRPC redirects.
- requestRedirect: RequestRedirectSpec¶
- property type: FilterType¶
Filter type.
- class RequestRedirectSpec(
- *,
- scheme: str | None = None,
- hostname: str | None = None,
- path: PathModifier | None = None,
- port: Annotated[int | None, Ge(ge=1), Le(le=65535)] = None,
- statusCode: int = 301,
Bases:
BaseModelSpecification for request redirect configuration.
- path: PathModifier | None¶
- class URLRewriteFilter(
- *,
- urlRewrite: URLRewriteSpec,
Bases:
BaseModelURLRewrite filter for modifying request URL before proxying upstream.
- urlRewrite: URLRewriteSpec¶
- property type: FilterType¶
Filter type.
- class URLRewriteSpec(
- *,
- hostname: str | None = None,
- path: PathModifier | None = None,
Bases:
BaseModelSpecification for URL rewrite configuration.
At least one of hostname or path must be specified.
- path: PathModifier | None¶
- exception UnauthorizedError¶
Bases:
IstioIngressRouteErrorRaised when the unit needs the leader to perform some action.
- to_gateway_protocol(
- protocol: ProtocolType,
- tls_enabled: bool = False,
Map application protocol to Gateway API protocol.
The Gateway API doesn’t have separate HTTP/gRPC protocol types. Both use HTTP, with the difference being in the route type (HTTPRoute vs GRPCRoute).
- Parameters:
protocol – Application-level protocol (HTTP or GRPC)
tls_enabled – Whether TLS termination should be applied
- Returns:
Gateway API protocol string (“HTTP” or “HTTPS”)
Examples
>>> to_gateway_protocol(ProtocolType.HTTP, tls_enabled=False) 'HTTP' >>> to_gateway_protocol(ProtocolType.HTTP, tls_enabled=True) 'HTTPS' >>> to_gateway_protocol(ProtocolType.GRPC, tls_enabled=False) 'HTTP' >>> to_gateway_protocol(ProtocolType.GRPC, tls_enabled=True) 'HTTPS'