@@ -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,54 @@ 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
+ /// let pp = &PatchParams::apply("controller").force();
411
+ /// // Perform an apply patch on the resource
412
+ /// client.patch(pod, pp, &Patch::Apply(&pod), &Default::default()).await?;
413
+ /// // Perform an apply patch on the resource status
414
+ /// client.patch(pod, pp, &Patch::Apply(&pod), &Subresource::Status).await?;
415
+ /// # Ok(())
416
+ /// # }
417
+ /// ```
418
+ pub async fn patch < K , P : Serialize + Debug > (
419
+ & self ,
420
+ resource : & K ,
421
+ pp : & PatchParams ,
422
+ patch : & Patch < P > ,
423
+ subresource : & Subresource ,
424
+ ) -> Result < K >
425
+ where
426
+ K : ResourceExt + Serialize + DeserializeOwned + Clone + Debug ,
427
+ <K as Resource >:: DynamicType : Default ,
428
+ {
429
+ let name = resource. meta ( ) . name . as_ref ( ) . ok_or ( Error :: NameResolve ) ?;
430
+ let url = K :: url_path ( & Default :: default ( ) , resource. meta ( ) . namespace . as_deref ( ) ) ;
431
+ let req = Request :: new ( url) ;
432
+ let req = match subresource {
433
+ Subresource :: Core => req. patch ( name, pp, patch) . map_err ( Error :: BuildRequest ) ?,
434
+ Subresource :: Status => req
435
+ . patch_subresource ( "status" , name, pp, patch)
436
+ . map_err ( Error :: BuildRequest ) ?,
437
+ Subresource :: Scale => req
438
+ . patch_subresource ( "scale" , name, pp, patch)
439
+ . map_err ( Error :: BuildRequest ) ?,
440
+ Subresource :: Custom ( subresource) => req
441
+ . patch_subresource ( subresource, name, pp, patch)
442
+ . map_err ( Error :: BuildRequest ) ?,
443
+ } ;
444
+ self . request :: < K > ( req) . await
445
+ }
388
446
}
389
447
390
448
// Resource url_path resolver
0 commit comments