Skip to content

Commit

Permalink
Use standard metav1.Status
Browse files Browse the repository at this point in the history
Signed-off-by: Mikail Bagishov <bagishov.mikail@yandex.ru>
  • Loading branch information
MikailBag committed Aug 29, 2022
1 parent d8dc65c commit 9a37d08
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 30 deletions.
7 changes: 5 additions & 2 deletions kube-client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,10 @@ mod test {
};
use futures::{StreamExt, TryStreamExt};
use k8s_openapi::api::core::v1::Pod;
use kube_core::params::{DeleteParams, Patch};
use kube_core::{
params::{DeleteParams, Patch},
response::StatusSummary,
};
use serde_json::json;
use tower::ServiceBuilder;

Expand Down Expand Up @@ -475,7 +478,7 @@ mod test {
let ep = EvictParams::default();
let eres = pods.evict("busybox-kube3", &ep).await?;
assert_eq!(eres.code, 201); // created
assert_eq!(eres.status, "Success");
assert_eq!(eres.status, Some(StatusSummary::Success));

Ok(())
}
Expand Down
11 changes: 6 additions & 5 deletions kube-core/src/conversion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ impl ConversionHandler {
request: None,
response: Some(ConversionResponse::error(
String::new(),
".request is unset in input".to_string(),
".request is unset in input",
"InvalidRequest",
)),
}
}
Expand All @@ -57,7 +58,7 @@ impl ConversionHandler {
return ConversionReview {
types: review.types.clone(),
request: None,
response: Some(ConversionResponse::error(req.uid, msg)),
response: Some(ConversionResponse::error(req.uid, &msg, "ConversionFailed")),
};
}
}
Expand Down Expand Up @@ -89,7 +90,7 @@ pub trait Converter {

#[cfg(test)]
mod tests {
use crate::conversion::low_level::ConversionStatus;
use crate::response::StatusSummary;

use super::{
low_level::{ConversionRequest, ConversionReview, META_API_VERSION_V1, META_KIND},
Expand Down Expand Up @@ -134,8 +135,8 @@ mod tests {
assert_eq!(output.types.api_version, META_API_VERSION_V1);
assert_eq!(output.types.kind, META_KIND);
let resp = output.response.unwrap();
assert!(matches!(resp.result.status, Some(ConversionStatus::Success)));
assert!(resp.result.message.is_none());
assert!(matches!(resp.result.status, Some(StatusSummary::Success)));
assert!(resp.result.message.is_empty());
assert_eq!(resp.converted_objects, Some(vec![obj1, obj2]));
}
}
18 changes: 6 additions & 12 deletions kube-core/src/conversion/low_level.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::TypeMeta;
use crate::{Status, TypeMeta};
use serde::{Deserialize, Serialize};

/// The `kind` field in [`TypeMeta`].
Expand Down Expand Up @@ -42,7 +42,7 @@ pub struct ConversionResponse {
/// Copy of .request.uid
pub uid: String,
/// Outcome of the conversion operation
pub result: ConversionResult,
pub result: Status,
/// Converted objects in the same order as in the request. Should be empty
/// if conversion failed.
#[serde(rename = "convertedObjects")]
Expand All @@ -57,24 +57,18 @@ impl ConversionResponse {
pub fn success(request_uid: String, converted_objects: Vec<serde_json::Value>) -> Self {
ConversionResponse {
uid: request_uid,
result: ConversionResult {
status: Some(ConversionStatus::Success),
message: None,
},
result: Status::success(),
converted_objects: Some(converted_objects),
}
}

/// Creates failed conversion response (discouraged).
/// `request_uid` must be equal to the `.uid` field in the request.
/// `message` will be returned to the apiserver.
pub fn error(request_uid: String, message: String) -> Self {
/// `message` and `reason` will be returned to the apiserver.
pub fn error(request_uid: String, message: &str, reason: &str) -> Self {
ConversionResponse {
uid: request_uid,
result: ConversionResult {
status: Some(ConversionStatus::Failed),
message: Some(message),
},
result: Status::failure(message, reason),
converted_objects: None,
}
}
Expand Down
75 changes: 64 additions & 11 deletions kube-core/src/response.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
//! Generic api response types
use serde::Deserialize;
use serde::{Deserialize, Serialize};

/// A Kubernetes status object
///
/// Equivalent to Status in k8s-openapi except we have have simplified options
#[derive(Deserialize, Debug)]
#[derive(Serialize, Deserialize, Debug)]
pub struct Status {
/// Suggested HTTP return code (0 if unset)
#[serde(default, skip_serializing_if = "num::Zero::is_zero")]
pub code: u16,

/// Status of the operation
///
/// One of: `Success` or `Failure` - [more info](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status)
#[serde(default, skip_serializing_if = "String::is_empty")]
pub status: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub status: Option<StatusSummary>,

/// Suggested HTTP return code (0 if unset)
#[serde(default, skip_serializing_if = "is_u16_zero")]
pub code: u16,

/// A human-readable description of the status of this operation
#[serde(default, skip_serializing_if = "String::is_empty")]
Expand All @@ -35,8 +35,53 @@ pub struct Status {
pub details: Option<StatusDetails>,
}

impl Status {
/// Returns a successful `Status`
pub fn success() -> Self {
Status {
status: Some(StatusSummary::Success),
code: 0,
message: String::new(),
reason: String::new(),
details: None,
}
}

/// Returns an unsuccessful `Status`
pub fn failure(message: &str, reason: &str) -> Self {
Status {
status: Some(StatusSummary::Failure),
code: 0,
message: message.to_string(),
reason: reason.to_string(),
details: None,
}
}

/// Sets an explicit HTTP status code
pub fn with_code(mut self, code: u16) -> Self {
self.code = code;
self
}

/// Adds details to the `Status`
pub fn with_details(mut self, details: StatusDetails) -> Self {
self.details = Some(details);
self
}
}

/// Overall status of the operation - whether it succeeded or not
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
pub enum StatusSummary {
/// Operation succeeded
Success,
/// Operation failed
Failure,
}

/// Status details object on the [`Status`] object
#[derive(Deserialize, Debug)]
#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct StatusDetails {
/// The name attribute of the resource associated with the status StatusReason (when there is a single name which can be described)
Expand Down Expand Up @@ -69,12 +114,12 @@ pub struct StatusDetails {
///
/// Some errors may indicate the client must take an alternate action -
/// for those errors this field may indicate how long to wait before taking the alternate action.
#[serde(default, skip_serializing_if = "num::Zero::is_zero")]
#[serde(default, skip_serializing_if = "is_u32_zero")]
pub retry_after_seconds: u32,
}

/// Status cause object on the [`StatusDetails`] object
#[derive(Deserialize, Debug)]
#[derive(Serialize, Deserialize, Debug)]
pub struct StatusCause {
/// A machine-readable description of the cause of the error. If this value is empty there is no information available.
#[serde(default, skip_serializing_if = "String::is_empty")]
Expand All @@ -92,6 +137,14 @@ pub struct StatusCause {
pub field: String,
}

fn is_u16_zero(&v: &u16) -> bool {
v == 0
}

fn is_u32_zero(&v: &u32) -> bool {
v == 0
}

#[cfg(test)]
mod test {
use super::Status;
Expand Down

0 comments on commit 9a37d08

Please sign in to comment.