From 8aae18252de2fed74a02296cdadf8e610844f49c Mon Sep 17 00:00:00 2001 From: Colin Adler Date: Mon, 19 Apr 2021 12:58:04 -0500 Subject: [PATCH] Correctly pass TypeMeta through AdmissionReviews --- kube/src/api/admission.rs | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/kube/src/api/admission.rs b/kube/src/api/admission.rs index 07398bc67..9a513bd36 100644 --- a/kube/src/api/admission.rs +++ b/kube/src/api/admission.rs @@ -46,7 +46,10 @@ impl TryInto> for AdmissionReview { fn try_into(self) -> Result, Self::Error> { match self.request { - Some(req) => Ok(req), + Some(mut req) => { + req.types = self.types; + Ok(req) + } None => Err(Error::RequestValidation( "invalid AdmissionRequest. expected Some but got None".to_owned(), )), @@ -329,8 +332,10 @@ pub enum PatchType { mod test { const WEBHOOK_BODY: &'static str = r#"{"kind":"AdmissionReview","apiVersion":"admission.k8s.io/v1","request":{"uid":"0c9a8d74-9cb7-44dd-b98e-09fd62def2f4","kind":{"group":"","version":"v1","kind":"Pod"},"resource":{"group":"","version":"v1","resource":"pods"},"requestKind":{"group":"","version":"v1","kind":"Pod"},"requestResource":{"group":"","version":"v1","resource":"pods"},"name":"echo-pod","namespace":"colin-coder","operation":"CREATE","userInfo":{"username":"colin@coder.com","groups":["system:authenticated"],"extra":{"iam.gke.io/user-assertion":["REDACTED"],"user-assertion.cloud.google.com":["REDACTED"]}},"object":{"kind":"Pod","apiVersion":"v1","metadata":{"name":"echo-pod","namespace":"colin-coder","creationTimestamp":null,"labels":{"app":"echo-server"},"annotations":{"kubectl.kubernetes.io/last-applied-configuration":"{\"apiVersion\":\"v1\",\"kind\":\"Pod\",\"metadata\":{\"annotations\":{},\"labels\":{\"app\":\"echo-server\"},\"name\":\"echo-pod\",\"namespace\":\"colin-coder\"},\"spec\":{\"containers\":[{\"image\":\"jmalloc/echo-server\",\"name\":\"echo-server\",\"ports\":[{\"containerPort\":8080,\"name\":\"http-port\"}]}]}}\n"},"managedFields":[{"manager":"kubectl","operation":"Update","apiVersion":"v1","time":"2021-03-29T23:02:16Z","fieldsType":"FieldsV1","fieldsV1":{"f:metadata":{"f:annotations":{".":{},"f:kubectl.kubernetes.io/last-applied-configuration":{}},"f:labels":{".":{},"f:app":{}}},"f:spec":{"f:containers":{"k:{\"name\":\"echo-server\"}":{".":{},"f:image":{},"f:imagePullPolicy":{},"f:name":{},"f:ports":{".":{},"k:{\"containerPort\":8080,\"protocol\":\"TCP\"}":{".":{},"f:containerPort":{},"f:name":{},"f:protocol":{}}},"f:resources":{},"f:terminationMessagePath":{},"f:terminationMessagePolicy":{}}},"f:dnsPolicy":{},"f:enableServiceLinks":{},"f:restartPolicy":{},"f:schedulerName":{},"f:securityContext":{},"f:terminationGracePeriodSeconds":{}}}}]},"spec":{"volumes":[{"name":"default-token-rxbqq","secret":{"secretName":"default-token-rxbqq"}}],"containers":[{"name":"echo-server","image":"jmalloc/echo-server","ports":[{"name":"http-port","containerPort":8080,"protocol":"TCP"}],"resources":{},"volumeMounts":[{"name":"default-token-rxbqq","readOnly":true,"mountPath":"/var/run/secrets/kubernetes.io/serviceaccount"}],"terminationMessagePath":"/dev/termination-log","terminationMessagePolicy":"File","imagePullPolicy":"Always"}],"restartPolicy":"Always","terminationGracePeriodSeconds":30,"dnsPolicy":"ClusterFirst","serviceAccountName":"default","serviceAccount":"default","securityContext":{},"schedulerName":"default-scheduler","tolerations":[{"key":"node.kubernetes.io/not-ready","operator":"Exists","effect":"NoExecute","tolerationSeconds":300},{"key":"node.kubernetes.io/unreachable","operator":"Exists","effect":"NoExecute","tolerationSeconds":300}],"priority":0,"enableServiceLinks":true},"status":{}},"oldObject":null,"dryRun":false,"options":{"kind":"CreateOptions","apiVersion":"meta.k8s.io/v1"}}}"#; + use std::convert::TryInto; + use crate::{ - api::admission::{AdmissionReview, DynamicObject}, + api::admission::{AdmissionResponse, AdmissionReview, DynamicObject}, Result, }; @@ -339,4 +344,18 @@ mod test { serde_json::from_str::>(WEBHOOK_BODY)?; Ok(()) } + + #[test] + fn version_passes_through() -> Result<()> { + let rev = serde_json::from_str::>(WEBHOOK_BODY)?; + let rev_typ = rev.types.clone(); + let res = AdmissionResponse::from(&rev.try_into()?).into_review(); + + // Ensure TypeMeta was correctly deserialized. + assert_ne!(&rev_typ.api_version, ""); + // The TypeMeta should be correctly passed through from the incoming + // request. + assert_eq!(&rev_typ, &res.types); + Ok(()) + } }