Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refector(policy): Prepare for Gateway API type binding library switch #13654

Draft
wants to merge 11 commits into
base: main
Choose a base branch
from
92 changes: 91 additions & 1 deletion policy-controller/k8s/api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ pub mod labels;
pub mod policy;

pub use self::labels::Labels;
pub use k8s_gateway_api as gateway;
pub use k8s_openapi::{
api::{
self,
Expand All @@ -32,3 +31,94 @@ pub use kube::{
runtime::watcher::Event as WatchEvent,
Client, Error,
};

pub mod gateway {
pub use k8s_gateway_api::*;

pub type HTTPRoute = HttpRoute;
pub type HTTPRouteSpec = HttpRouteSpec;
pub type HTTPRouteParentRefs = ParentReference;
pub type HTTPRouteRules = HttpRouteRule;
pub type HTTPRouteRulesMatches = HttpRouteMatch;
pub type HTTPRouteRulesFilters = HttpRouteFilter;
pub type HTTPRouteRulesBackendRefs = HttpBackendRef;
pub type HTTPRouteRulesBackendRefsFilters = HttpRouteFilter;
pub type HTTPRouteStatus = HttpRouteStatus;
pub type HTTPRouteStatusParents = RouteParentStatus;
pub type HTTPRouteStatusParentsParentRef = ParentReference;
pub type HTTPRouteRulesFiltersRequestHeaderModifier = HttpRequestHeaderFilter;
pub type HTTPRouteRulesFiltersResponseHeaderModifier = HttpRequestHeaderFilter;
pub type HTTPRouteRulesBackendRefsFiltersRequestHeaderModifier = HttpRequestHeaderFilter;
pub type HTTPRouteRulesBackendRefsFiltersResponseHeaderModifier = HttpRequestHeaderFilter;
pub type HTTPRouteRulesFiltersRequestHeaderModifierAdd = HttpHeader;
pub type HTTPRouteRulesFiltersRequestHeaderModifierSet = HttpHeader;
pub type HTTPRouteRulesFiltersResponseHeaderModifierAdd = HttpHeader;
pub type HTTPRouteRulesFiltersResponseHeaderModifierSet = HttpHeader;
pub type HTTPRouteRulesBackendRefsFiltersRequestHeaderModifierAdd = HttpHeader;
pub type HTTPRouteRulesBackendRefsFiltersRequestHeaderModifierSet = HttpHeader;
pub type HTTPRouteRulesBackendRefsFiltersResponseHeaderModifierAdd = HttpHeader;
pub type HTTPRouteRulesBackendRefsFiltersResponseHeaderModifierSet = HttpHeader;
pub type HTTPRouteRulesFiltersRequestRedirect = HttpRequestRedirectFilter;
pub type HTTPRouteRulesBackendRefsFiltersRequestRedirect = HttpRequestRedirectFilter;
pub type HTTPRouteRulesFiltersRequestRedirectPath = HttpPathModifier;
pub type HTTPRouteRulesBackendRefsFiltersRequestRedirectPath = HttpPathModifier;

pub mod http_method {
pub const GET: &str = "GET";
pub const POST: &str = "POST";
pub const PUT: &str = "PUT";
pub const DELETE: &str = "DELETE";
pub const PATCH: &str = "PATCH";
pub const HEAD: &str = "HEAD";
pub const OPTIONS: &str = "OPTIONS";
pub const CONNECT: &str = "CONNECT";
pub const TRACE: &str = "TRACE";
}

pub mod http_scheme {
pub const HTTP: &str = "http";
pub const HTTPS: &str = "https";
}

pub type GRPCRoute = GrpcRoute;
pub type GRPCRouteSpec = GrpcRouteSpec;
pub type GRPCRouteParentRefs = ParentReference;
pub type GRPCRouteRules = GrpcRouteRule;
pub type GRPCRouteRulesMatches = GrpcRouteMatch;
pub type GRPCRouteRulesFilters = GrpcRouteFilter;
pub type GRPCRouteRulesBackendRefs = GrpcRouteBackendRef;
pub type GRPCRouteRulesBackendRefsFilters = GrpcRouteFilter;
pub type GRPCRouteStatus = GrpcRouteStatus;
pub type GRPCRouteStatusParents = RouteParentStatus;
pub type GRPCRouteStatusParentsParentRef = ParentReference;
pub type GRPCRouteRulesFiltersRequestHeaderModifier = HttpRequestHeaderFilter;
pub type GRPCRouteRulesFiltersResponseHeaderModifier = HttpRequestHeaderFilter;
pub type GRPCRouteRulesBackendRefsFiltersRequestHeaderModifier = HttpRequestHeaderFilter;
pub type GRPCRouteRulesBackendRefsFiltersResponseHeaderModifier = HttpRequestHeaderFilter;
pub type GRPCRouteRulesFiltersRequestHeaderModifierAdd = HttpHeader;
pub type GRPCRouteRulesFiltersRequestHeaderModifierSet = HttpHeader;
pub type GRPCRouteRulesFiltersResponseHeaderModifierAdd = HttpHeader;
pub type GRPCRouteRulesFiltersResponseHeaderModifierSet = HttpHeader;
pub type GRPCRouteRulesBackendRefsFiltersRequestHeaderModifierAdd = HttpHeader;
pub type GRPCRouteRulesBackendRefsFiltersRequestHeaderModifierSet = HttpHeader;
pub type GRPCRouteRulesBackendRefsFiltersResponseHeaderModifierAdd = HttpHeader;
pub type GRPCRouteRulesBackendRefsFiltersResponseHeaderModifierSet = HttpHeader;

pub type TLSRoute = TlsRoute;
pub type TLSRouteSpec = TlsRouteSpec;
pub type TLSRouteParentRefs = ParentReference;
pub type TLSRouteRules = TlsRouteRule;
pub type TLSRouteRulesBackendRefs = BackendRef;
pub type TLSRouteStatus = TlsRouteStatus;
pub type TLSRouteStatusParents = RouteParentStatus;
pub type TLSRouteStatusParentsParentRef = ParentReference;

pub type TCPRoute = TcpRoute;
pub type TCPRouteSpec = TcpRouteSpec;
pub type TCPRouteParentRefs = ParentReference;
pub type TCPRouteRules = TcpRouteRule;
pub type TCPRouteRulesBackendRefs = BackendRef;
pub type TCPRouteStatus = TcpRouteStatus;
pub type TCPRouteStatusParents = RouteParentStatus;
pub type TCPRouteStatusParentsParentRef = ParentReference;
}
3 changes: 3 additions & 0 deletions policy-controller/k8s/api/src/policy.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub mod authorization_policy;
pub mod egress_network;
pub mod grpcroute;
pub mod httproute;
pub mod meshtls_authentication;
mod network;
Expand All @@ -8,6 +9,8 @@ pub mod ratelimit_policy;
pub mod server;
pub mod server_authorization;
pub mod target_ref;
pub mod tcproute;
pub mod tlsroute;

pub use self::{
authorization_policy::{AuthorizationPolicy, AuthorizationPolicySpec},
Expand Down
26 changes: 26 additions & 0 deletions policy-controller/k8s/api/src/policy/grpcroute.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
use crate::gateway;

pub fn parent_ref_targets_kind<T>(parent_ref: &gateway::GRPCRouteParentRefs) -> bool
where
T: kube::Resource,
T::DynamicType: Default,
{
let kind = match parent_ref.kind {
Some(ref kind) => kind,
None => return false,
};

super::targets_kind::<T>(parent_ref.group.as_deref(), kind)
}

pub fn backend_ref_targets_kind<T>(backend_ref: &gateway::GRPCRouteRulesBackendRefs) -> bool
where
T: kube::Resource,
T::DynamicType: Default,
{
// Default kind is assumed to be service for backend ref objects
super::targets_kind::<T>(
backend_ref.inner.group.as_deref(),
backend_ref.inner.kind.as_deref().unwrap_or("Service"),
)
}
60 changes: 27 additions & 33 deletions policy-controller/k8s/api/src/policy/httproute.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
pub use k8s_gateway_api::{
BackendObjectReference, CommonRouteSpec, Hostname, HttpBackendRef, HttpHeader, HttpHeaderMatch,
HttpHeaderName, HttpMethod, HttpPathMatch, HttpPathModifier, HttpQueryParamMatch,
HttpRequestHeaderFilter, HttpRequestRedirectFilter, HttpRouteMatch, LocalObjectReference,
ParentReference, RouteStatus,
};
use crate::gateway::{self, HTTPRouteStatus};

/// HTTPRoute provides a way to route HTTP requests. This includes the
/// capability to match requests by hostname, path, header, or query param.
Expand All @@ -23,13 +18,17 @@ pub use k8s_gateway_api::{
version = "v1beta3",
kind = "HTTPRoute",
root = "HttpRoute",
status = "HttpRouteStatus",
status = "HTTPRouteStatus",
namespaced
)]
pub struct HttpRouteSpec {
/// Common route information.
#[serde(flatten)]
pub inner: CommonRouteSpec,
#[serde(
default,
skip_serializing_if = "Option::is_none",
rename = "parentRefs"
)]
pub parent_refs: Option<Vec<gateway::HTTPRouteParentRefs>>,

/// Hostnames defines a set of hostname that should match against the HTTP
/// Host header to select a HTTPRoute to process the request. This matches
Expand All @@ -38,7 +37,7 @@ pub struct HttpRouteSpec {
/// 1. IPs are not allowed.
/// 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard
/// label must appear by itself as the first label.
pub hostnames: Option<Vec<Hostname>>,
pub hostnames: Option<Vec<String>>,

/// Rules are a list of HTTP matchers, filters and actions.
pub rules: Option<Vec<HttpRouteRule>>,
Expand All @@ -47,9 +46,7 @@ pub struct HttpRouteSpec {
/// HTTPRouteRule defines semantics for matching an HTTP request based on
/// conditions (matches), processing it (filters), and forwarding the request to
/// an API object (backendRefs).
#[derive(
Clone, Debug, PartialEq, Eq, serde::Deserialize, serde::Serialize, schemars::JsonSchema,
)]
#[derive(Clone, Debug, PartialEq, serde::Deserialize, serde::Serialize, schemars::JsonSchema)]
#[serde(rename_all = "camelCase")]
pub struct HttpRouteRule {
/// Matches define conditions used for matching the rule against incoming
Expand Down Expand Up @@ -105,7 +102,7 @@ pub struct HttpRouteRule {
///
/// When no rules matching a request have been successfully attached to the
/// parent a request is coming from, a HTTP 404 status code MUST be returned.
pub matches: Option<Vec<HttpRouteMatch>>,
pub matches: Option<Vec<gateway::HTTPRouteRulesMatches>>,

/// Filters define the filters that are applied to requests that match this
/// rule.
Expand Down Expand Up @@ -153,7 +150,7 @@ pub struct HttpRouteRule {
/// Support: Custom for any other resource
///
/// Support for weight: Core
pub backend_refs: Option<Vec<HttpBackendRef>>,
pub backend_refs: Option<Vec<gateway::HTTPRouteRulesBackendRefs>>,

/// Timeouts defines the timeouts that can be configured for an HTTP request.
///
Expand All @@ -167,9 +164,7 @@ pub struct HttpRouteRule {
/// Some examples include request or response modification, implementing
/// authentication strategies, rate-limiting, and traffic shaping. API
/// guarantee/conformance is defined based on the type of the filter.
#[derive(
Clone, Debug, PartialEq, Eq, serde::Deserialize, serde::Serialize, schemars::JsonSchema,
)]
#[derive(Clone, Debug, PartialEq, serde::Deserialize, serde::Serialize, schemars::JsonSchema)]
#[serde(tag = "type", rename_all = "PascalCase")]
pub enum HttpRouteFilter {
/// RequestHeaderModifier defines a schema for a filter that modifies request
Expand All @@ -178,7 +173,7 @@ pub enum HttpRouteFilter {
/// Support: Core
#[serde(rename_all = "camelCase")]
RequestHeaderModifier {
request_header_modifier: HttpRequestHeaderFilter,
request_header_modifier: gateway::HTTPRouteRulesFiltersRequestHeaderModifier,
},

/// ResponseHeaderModifier defines a schema for a filter that modifies response
Expand All @@ -187,7 +182,7 @@ pub enum HttpRouteFilter {
/// Support: Extended
#[serde(rename_all = "camelCase")]
ResponseHeaderModifier {
response_header_modifier: HttpRequestHeaderFilter,
response_header_modifier: gateway::HTTPRouteRulesFiltersResponseHeaderModifier,
},

/// RequestRedirect defines a schema for a filter that responds to the
Expand All @@ -196,18 +191,10 @@ pub enum HttpRouteFilter {
/// Support: Core
#[serde(rename_all = "camelCase")]
RequestRedirect {
request_redirect: HttpRequestRedirectFilter,
request_redirect: gateway::HTTPRouteRulesFiltersRequestRedirect,
},
}

/// HTTPRouteStatus defines the observed state of HTTPRoute.
#[derive(Clone, Debug, PartialEq, serde::Deserialize, serde::Serialize, schemars::JsonSchema)]
pub struct HttpRouteStatus {
/// Common route status information.
#[serde(flatten)]
pub inner: RouteStatus,
}

/// HTTPRouteTimeouts defines timeouts that can be configured for an HTTPRoute.
/// Timeout values are formatted like 1h/1m/1s/1ms as parsed by Golang time.ParseDuration
/// and MUST BE >= 1ms.
Expand Down Expand Up @@ -238,7 +225,7 @@ pub struct HttpRouteTimeouts {
pub backend_request: Option<crate::duration::K8sDuration>,
}

pub fn parent_ref_targets_kind<T>(parent_ref: &ParentReference) -> bool
pub fn parent_ref_targets_kind<T>(parent_ref: &gateway::HTTPRouteParentRefs) -> bool
where
T: kube::Resource,
T::DynamicType: Default,
Expand All @@ -251,14 +238,21 @@ where
super::targets_kind::<T>(parent_ref.group.as_deref(), kind)
}

pub fn backend_ref_targets_kind<T>(backend_ref: &BackendObjectReference) -> bool
pub fn backend_ref_targets_kind<T>(backend_ref: &gateway::HTTPRouteRulesBackendRefs) -> bool
where
T: kube::Resource,
T::DynamicType: Default,
{
// Default kind is assumed to be service for backend ref objects
super::targets_kind::<T>(
backend_ref.group.as_deref(),
backend_ref.kind.as_deref().unwrap_or("Service"),
backend_ref
.backend_ref
.as_ref()
.and_then(|br| br.inner.group.as_deref()),
backend_ref
.backend_ref
.as_ref()
.and_then(|br| br.inner.kind.as_deref())
.unwrap_or("Service"),
)
}
26 changes: 26 additions & 0 deletions policy-controller/k8s/api/src/policy/tcproute.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
use crate::gateway;

pub fn parent_ref_targets_kind<T>(parent_ref: &gateway::TCPRouteParentRefs) -> bool
where
T: kube::Resource,
T::DynamicType: Default,
{
let kind = match parent_ref.kind {
Some(ref kind) => kind,
None => return false,
};

super::targets_kind::<T>(parent_ref.group.as_deref(), kind)
}

pub fn backend_ref_targets_kind<T>(backend_ref: &gateway::TCPRouteRulesBackendRefs) -> bool
where
T: kube::Resource,
T::DynamicType: Default,
{
// Default kind is assumed to be service for backend ref objects
super::targets_kind::<T>(
backend_ref.inner.group.as_deref(),
backend_ref.inner.kind.as_deref().unwrap_or("Service"),
)
}
26 changes: 26 additions & 0 deletions policy-controller/k8s/api/src/policy/tlsroute.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
use crate::gateway;

pub fn parent_ref_targets_kind<T>(parent_ref: &gateway::TLSRouteParentRefs) -> bool
where
T: kube::Resource,
T::DynamicType: Default,
{
let kind = match parent_ref.kind {
Some(ref kind) => kind,
None => return false,
};

super::targets_kind::<T>(parent_ref.group.as_deref(), kind)
}

pub fn backend_ref_targets_kind<T>(backend_ref: &gateway::TLSRouteRulesBackendRefs) -> bool
where
T: kube::Resource,
T::DynamicType: Default,
{
// Default kind is assumed to be service for backend ref objects
super::targets_kind::<T>(
backend_ref.inner.group.as_deref(),
backend_ref.inner.kind.as_deref().unwrap_or("Service"),
)
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use anyhow::Result;
use linkerd_policy_controller_core::routes::GroupKindName;
use linkerd_policy_controller_k8s_api::{
self as k8s, gateway as k8s_gateway_api,
self as k8s, gateway,
policy::{LocalTargetRef, NamespacedTargetRef},
ServiceAccount,
};
Expand Down Expand Up @@ -66,21 +66,19 @@ fn target(t: LocalTargetRef) -> Result<Target> {
t if t.targets_kind::<k8s::policy::Server>() => Ok(Target::Server(t.name)),
t if t.targets_kind::<k8s::Namespace>() => Ok(Target::Namespace),
t if t.targets_kind::<k8s::policy::HttpRoute>()
|| t.targets_kind::<k8s_gateway_api::HttpRoute>() =>
|| t.targets_kind::<gateway::HTTPRoute>() =>
{
Ok(Target::HttpRoute(GroupKindName {
group: t.group.unwrap_or_default().into(),
kind: t.kind.into(),
name: t.name.into(),
}))
}
t if t.targets_kind::<k8s_gateway_api::GrpcRoute>() => {
Ok(Target::GrpcRoute(GroupKindName {
group: t.group.unwrap_or_default().into(),
kind: t.kind.into(),
name: t.name.into(),
}))
}
t if t.targets_kind::<gateway::GRPCRoute>() => Ok(Target::GrpcRoute(GroupKindName {
group: t.group.unwrap_or_default().into(),
kind: t.kind.into(),
name: t.name.into(),
})),
_ => anyhow::bail!(
"unsupported authorization target type: {}",
t.canonical_kind()
Expand Down
Loading
Loading