Skip to content

Commit

Permalink
Add support for passing the fieldValidation query parameter on patch (#…
Browse files Browse the repository at this point in the history
…929)

* Add support for passing the fieldValidation query parameter on patch

The `fieldValidation` flag should be set to `Ignore` when doing a server-side
apply for a partial object. This introduces support to configure the
fieldValidation parameter to all the available options.

Signed-off-by: Leo Sjöberg <leo.sjoberg@gmail.com>

* cleanup doc blocks

Signed-off-by: Leo Sjöberg <leo.sjoberg@gmail.com>

* Update test to match current invalid usage of serializer

Signed-off-by: Leo Sjöberg <leo.sjoberg@gmail.com>

* Add shorthand functions for each validation directive

Signed-off-by: Leo Sjöberg <leo.sjoberg@gmail.com>

* Rename field_validation to validation and expose it

Signed-off-by: Leo Sjöberg <leo.sjoberg@gmail.com>

* fix cs

Signed-off-by: Leo Sjöberg <leo.sjoberg@gmail.com>
  • Loading branch information
phroggyy authored Jun 13, 2022
1 parent 12218ed commit c37d07b
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 2 deletions.
2 changes: 1 addition & 1 deletion kube-client/src/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ pub use kube_core::{
Resource, ResourceExt,
};
pub use params::{
DeleteParams, ListParams, Patch, PatchParams, PostParams, Preconditions, PropagationPolicy,
DeleteParams, ListParams, Patch, PatchParams, PostParams, Preconditions, PropagationPolicy, ValidationDirective,
};

use crate::Client;
Expand Down
89 changes: 88 additions & 1 deletion kube-core/src/params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,39 @@ impl ListParams {
}
}

/// The validation directive to use for `fieldValidation` when using server-side apply.
#[derive(Clone, Debug)]
pub enum ValidationDirective {
/// Strict mode will fail any invalid manifests.
///
/// This will fail the request with a BadRequest error if any unknown fields would be dropped from the
/// object, or if any duplicate fields are present. The error returned from the server will contain
/// all unknown and duplicate fields encountered.
Strict,
/// Warn mode will return a warning for invalid manifests.
///
/// This will send a warning via the standard warning response header for each unknown field that
/// is dropped from the object, and for each duplicate field that is encountered. The request will
/// still succeed if there are no other errors, and will only persist the last of any duplicate fields.
Warn,
/// Ignore mode will silently ignore any problems.
///
/// This will ignore any unknown fields that are silently dropped from the object, and will ignore
/// all but the last duplicate field that the decoder encounters.
Ignore,
}

impl ValidationDirective {
/// Returns the string format of the directive
pub fn as_str(self: &Self) -> &str {
match self {
Self::Strict => "Strict",
Self::Warn => "Warn",
Self::Ignore => "Ignore",
}
}
}

/// Common query parameters for put/post calls
#[derive(Default, Clone, Debug)]
pub struct PostParams {
Expand Down Expand Up @@ -270,6 +303,8 @@ pub struct PatchParams {
/// fieldManager is a name of the actor that is making changes. Required for [`Patch::Apply`]
/// optional for everything else.
pub field_manager: Option<String>,
/// The server-side validation directive to use. Applicable only to [`Patch::Apply`].
pub field_validation: Option<ValidationDirective>,
}

impl PatchParams {
Expand Down Expand Up @@ -301,6 +336,9 @@ impl PatchParams {
if let Some(ref fm) = self.field_manager {
qp.append_pair("fieldManager", fm);
}
if let Some(sv) = &self.field_validation {
qp.append_pair("fieldValidation", sv.as_str());
}
}

/// Construct `PatchParams` for server-side apply
Expand All @@ -327,6 +365,30 @@ impl PatchParams {
self.dry_run = true;
self
}

/// Set the validation directive for `fieldValidation` during server-side apply.
pub fn validation(mut self, vd: ValidationDirective) -> Self {
self.field_validation = Some(vd);
self
}

/// Set the validation directive to `Ignore`
#[must_use]
pub fn validation_ignore(self) -> Self {
self.validation(ValidationDirective::Ignore)
}

/// Set the validation directive to `Warn`
#[must_use]
pub fn validation_warn(self) -> Self {
self.validation(ValidationDirective::Warn)
}

/// Set the validation directive to `Strict`
#[must_use]
pub fn validation_strict(self) -> Self {
self.validation(ValidationDirective::Strict)
}
}

/// Common query parameters for delete calls
Expand Down Expand Up @@ -364,6 +426,7 @@ pub struct DeleteParams {

impl DeleteParams {
/// Construct `DeleteParams` with `PropagationPolicy::Background`.
///
/// This allows the garbage collector to delete the dependents in the background.
pub fn background() -> Self {
Self {
Expand All @@ -373,6 +436,7 @@ impl DeleteParams {
}

/// Construct `DeleteParams` with `PropagationPolicy::Foreground`.
///
/// This is a cascading policy that deletes all dependents in the foreground.
pub fn foreground() -> Self {
Self {
Expand All @@ -382,6 +446,8 @@ impl DeleteParams {
}

/// Construct `DeleteParams` with `PropagationPolicy::Orphan`.
///
///
/// This orpans the dependents.
pub fn orphan() -> Self {
Self {
Expand Down Expand Up @@ -435,7 +501,7 @@ where
}
#[cfg(test)]
mod test {
use super::DeleteParams;
use super::{DeleteParams, PatchParams, ValidationDirective};
#[test]
fn delete_param_serialize() {
let mut dp = DeleteParams::default();
Expand Down Expand Up @@ -463,6 +529,27 @@ mod test {
let ser = serde_json::to_value(&dp_orphan).unwrap();
assert_eq!(ser, serde_json::json!({"propagationPolicy": "Orphan"}));
}

#[test]
fn patch_param_serializes_field_validation() {
let pp = PatchParams::default().validation_ignore();
let mut qp = form_urlencoded::Serializer::new(String::from("some/resource?"));
pp.populate_qp(&mut qp);
let urlstr = qp.finish();
assert_eq!(String::from("some/resource?&fieldValidation=Ignore"), urlstr);

let pp = PatchParams::default().validation_warn();
let mut qp = form_urlencoded::Serializer::new(String::from("some/resource?"));
pp.populate_qp(&mut qp);
let urlstr = qp.finish();
assert_eq!(String::from("some/resource?&fieldValidation=Warn"), urlstr);

let pp = PatchParams::default().validation_strict();
let mut qp = form_urlencoded::Serializer::new(String::from("some/resource?"));
pp.populate_qp(&mut qp);
let urlstr = qp.finish();
assert_eq!(String::from("some/resource?&fieldValidation=Strict"), urlstr);
}
}

/// Preconditions must be fulfilled before an operation (update, delete, etc.) is carried out.
Expand Down

0 comments on commit c37d07b

Please sign in to comment.