fix(policy): allow gateway api httproutes as authorizationpolicy target type (#13962)

AuthorizationPolicies may have HTTPRoutes as targetRefs.  However, the validation admission controller webhook for AuthorizationPolicies rejects any which have a httproutes.gateway.networking.k8s.io target (as opposed to httproutes.policy.linkerd.io which are accepted).  

We allow httproutes.gateway.networking.k8s.io as a target ref by removing this overly restrictive validation.  This validation was, in fact, completely redundant since the target type is checked during conversion and validated that it is a supported target (including httproutes.gateway.networking.k8s.io).

Validated by running through https://linkerd.io/2-edge/tasks/configuring-per-route-policy/ and replacing the httproutes.policy.linkerd.io with httproutes.gateway.networking.io (including targetRefs).

Signed-off-by: Alex Leong <alex@buoyant.io>
This commit is contained in:
Alex Leong 2025-04-30 15:54:54 -07:00 committed by GitHub
parent 9bc75640a1
commit cdff9e2f68
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 4 additions and 26 deletions

View File

@ -1,7 +1,7 @@
use super::validation;
use crate::k8s::policy::{
httproute, AuthorizationPolicy, AuthorizationPolicySpec, EgressNetwork, EgressNetworkSpec,
HttpLocalRateLimitPolicy, HttpRoute, HttpRouteSpec, LocalTargetRef, MeshTLSAuthentication,
HttpLocalRateLimitPolicy, HttpRoute, HttpRouteSpec, MeshTLSAuthentication,
MeshTLSAuthenticationSpec, NamespacedTargetRef, Network, NetworkAuthentication,
NetworkAuthenticationSpec, RateLimitPolicySpec, Server, ServerAuthorization,
ServerAuthorizationSpec, ServerSpec,
@ -228,30 +228,6 @@ fn parse_spec<T: DeserializeOwned>(req: AdmissionRequest) -> Result<(DynamicObje
Ok((obj, spec))
}
/// Validates the target of an `AuthorizationPolicy`.
fn validate_policy_target(ns: &str, tgt: &LocalTargetRef) -> Result<()> {
if tgt.targets_kind::<Server>() {
return Ok(());
}
if tgt.targets_kind::<HttpRoute>() {
return Ok(());
}
if tgt.targets_kind::<gateway::GRPCRoute>() {
return Ok(());
}
if tgt.targets_kind::<Namespace>() {
if tgt.name != ns {
bail!("cannot target another namespace: {}", tgt.name);
}
return Ok(());
}
bail!("invalid targetRef kind: {}", tgt.canonical_kind());
}
#[async_trait::async_trait]
impl Validate<AuthorizationPolicySpec> for Admission {
async fn validate(
@ -261,7 +237,9 @@ impl Validate<AuthorizationPolicySpec> for Admission {
_annotations: &BTreeMap<String, String>,
spec: AuthorizationPolicySpec,
) -> Result<()> {
validate_policy_target(ns, &spec.target_ref)?;
if spec.target_ref.targets_kind::<Namespace>() && spec.target_ref.name != ns {
bail!("cannot target another namespace: {}", &spec.target_ref.name);
}
let mtls_authns_count = spec
.required_authentication_refs