@@ -5,9 +5,10 @@ use k8s_openapi::{
5
5
} ;
6
6
use kube_core:: {
7
7
object:: ObjectList ,
8
- params:: { GetParams , ListParams } ,
8
+ params:: { GetParams , ListParams , Patch , PatchParams } ,
9
9
request:: Request ,
10
- ApiResource , ClusterResourceScope , DynamicResourceScope , NamespaceResourceScope , Resource ,
10
+ ApiResource , ClusterResourceScope , DynamicResourceScope , NamespaceResourceScope , ObjectMeta , Resource ,
11
+ ResourceExt ,
11
12
} ;
12
13
use serde:: { de:: DeserializeOwned , Serialize } ;
13
14
use std:: fmt:: Debug ;
@@ -149,7 +150,7 @@ where
149
150
150
151
/// Scopes for `unstable-client` [`Client#impl-Client`] extension methods
151
152
pub mod scope {
152
- pub use super :: { Cluster , Namespace , NamespacedRef } ;
153
+ pub use super :: { Cluster , Namespace , NamespacedRef , Subresource } ;
153
154
}
154
155
155
156
// All objects can be listed cluster-wide
@@ -230,6 +231,15 @@ pub enum NamespaceError {
230
231
MissingName ,
231
232
}
232
233
234
+ #[ derive( Default ) ]
235
+ pub enum Subresource {
236
+ #[ default]
237
+ Core ,
238
+ Status ,
239
+ Scale ,
240
+ Custom ( String ) ,
241
+ }
242
+
233
243
/// Generic client extensions for the `unstable-client` feature
234
244
///
235
245
/// These methods allow users to query across a wide-array of resources without needing
@@ -385,6 +395,53 @@ impl Client {
385
395
req. extensions_mut ( ) . insert ( "list" ) ;
386
396
self . request :: < ObjectList < K > > ( req) . await
387
397
}
398
+
399
+ /// Patch provided `Resource` implementing type `K`
400
+ ///
401
+ /// ```no_run
402
+ /// # use k8s_openapi::api::core::v1::Pod;
403
+ /// # use k8s_openapi::api::core::v1::Service;
404
+ /// # use kube::client::scope::{Namespace, Subresource};
405
+ /// # use kube::prelude::*;
406
+ /// # use kube::api::{PatchParams, Patch};
407
+ /// # async fn wrapper() -> Result<(), Box<dyn std::error::Error>> {
408
+ /// # let client: kube::Client = todo!();
409
+ /// let pod: Pod = client.get("some_pod", &Namespace::from("default")).await?;
410
+ /// // Perform an apply patch on the resource
411
+ /// client.patch(pod, &PatchParams::apply("controller").force(), &Patch::Apply(&pod), &Default::default()).await?;
412
+ /// // Perform an apply patch on the resource status
413
+ /// client.patch(pod, &PatchParams::apply("controller").force(), &Patch::Apply(&pod), &Subresource::Status).await?;
414
+ /// # Ok(())
415
+ /// # }
416
+ /// ```
417
+ pub async fn patch < K , P : Serialize + Debug > (
418
+ & self ,
419
+ resource : & K ,
420
+ pp : & PatchParams ,
421
+ patch : & Patch < P > ,
422
+ subresource : & Subresource ,
423
+ ) -> Result < K >
424
+ where
425
+ K : ResourceExt + Serialize + DeserializeOwned + Clone + Debug ,
426
+ <K as Resource >:: DynamicType : Default ,
427
+ {
428
+ let name = resource. meta ( ) . name . as_ref ( ) . ok_or ( Error :: NameResolve ) ?;
429
+ let url = K :: url_path ( & Default :: default ( ) , resource. meta ( ) . namespace . as_deref ( ) ) ;
430
+ let req = Request :: new ( url) ;
431
+ let req = match subresource {
432
+ Subresource :: Core => req. patch ( name, pp, patch) . map_err ( Error :: BuildRequest ) ?,
433
+ Subresource :: Status => req
434
+ . patch_subresource ( "status" , name, pp, patch)
435
+ . map_err ( Error :: BuildRequest ) ?,
436
+ Subresource :: Scale => req
437
+ . patch_subresource ( "scale" , name, pp, patch)
438
+ . map_err ( Error :: BuildRequest ) ?,
439
+ Subresource :: Custom ( subresource) => req
440
+ . patch_subresource ( subresource, name, pp, patch)
441
+ . map_err ( Error :: BuildRequest ) ?,
442
+ } ;
443
+ self . request :: < K > ( req) . await
444
+ }
388
445
}
389
446
390
447
// Resource url_path resolver
0 commit comments