From e6bda30e6f1c39b0b908af589e947531819cbfa3 Mon Sep 17 00:00:00 2001 From: Arnavion Date: Sat, 23 Jun 2018 13:24:18 -0700 Subject: [PATCH] Special-case readCoreV1NamespacedPodLog to return an Iterator. Fixes #10 --- k8s-openapi-tests/src/logs.rs | 8 ++- k8s-openapi/src/v1_10/api/core/v1/pod.rs | 6 +- .../src/v1_7/kubernetes/pkg/api/v1/pod.rs | 6 +- k8s-openapi/src/v1_8/api/core/v1/pod.rs | 6 +- k8s-openapi/src/v1_9/api/core/v1/pod.rs | 6 +- src/main.rs | 71 +++++++++++++------ 6 files changed, 62 insertions(+), 41 deletions(-) diff --git a/k8s-openapi-tests/src/logs.rs b/k8s-openapi-tests/src/logs.rs index 5e31b83961..d77fbbc37b 100644 --- a/k8s-openapi-tests/src/logs.rs +++ b/k8s-openapi-tests/src/logs.rs @@ -42,9 +42,13 @@ fn get() { &client, addon_manager_pod_name, "kube-system", Some("kube-addon-manager"), None, Some(4096), None, None, None, None, None) .expect("couldn't get addon-manager pod logs"); - let addon_manager_logs = match addon_manager_logs { + let mut addon_manager_logs = match addon_manager_logs { api::ReadCoreV1NamespacedPodLogResponse::Ok(logs) => logs, other => panic!("couldn't get addon-manager pod logs: {:?}", other), }; - assert!(addon_manager_logs.contains("INFO: == Kubernetes addon manager started at")); + let addon_manager_logs_first_line = + addon_manager_logs + .next().expect("addon-manager pod has no logs") + .expect("couldn't get first line of addon-manager pod logs"); + assert!(addon_manager_logs_first_line.contains("INFO: == Kubernetes addon manager started at"), "{}", addon_manager_logs_first_line); } diff --git a/k8s-openapi/src/v1_10/api/core/v1/pod.rs b/k8s-openapi/src/v1_10/api/core/v1/pod.rs index aab6f81174..39c88b9eb0 100644 --- a/k8s-openapi/src/v1_10/api/core/v1/pod.rs +++ b/k8s-openapi/src/v1_10/api/core/v1/pod.rs @@ -1295,7 +1295,7 @@ impl Pod { #[derive(Debug)] pub enum ReadCoreV1NamespacedPodLogResponse where R: ::std::io::Read { - Ok(String), + Ok(::std::io::Lines<::std::io::BufReader>), Unauthorized(R), Other(::http::StatusCode, R), } @@ -1358,9 +1358,7 @@ impl Pod { Ok(match ::Response::status_code(&response) { ::http::StatusCode::OK => { - let mut response = response; - let mut result = String::new(); - ::std::io::Read::read_to_string(&mut response, &mut result).map_err(::Error::IO)?; + let result = ::std::io::BufRead::lines(::std::io::BufReader::new(response)); ReadCoreV1NamespacedPodLogResponse::Ok(result) }, ::http::StatusCode::UNAUTHORIZED => ReadCoreV1NamespacedPodLogResponse::Unauthorized(response), diff --git a/k8s-openapi/src/v1_7/kubernetes/pkg/api/v1/pod.rs b/k8s-openapi/src/v1_7/kubernetes/pkg/api/v1/pod.rs index a4a5f977ed..2b3801a253 100644 --- a/k8s-openapi/src/v1_7/kubernetes/pkg/api/v1/pod.rs +++ b/k8s-openapi/src/v1_7/kubernetes/pkg/api/v1/pod.rs @@ -1609,7 +1609,7 @@ impl Pod { #[derive(Debug)] pub enum ReadCoreV1NamespacedPodLogResponse where R: ::std::io::Read { - Ok(String), + Ok(::std::io::Lines<::std::io::BufReader>), Unauthorized(R), Other(::http::StatusCode, R), } @@ -1672,9 +1672,7 @@ impl Pod { Ok(match ::Response::status_code(&response) { ::http::StatusCode::OK => { - let mut response = response; - let mut result = String::new(); - ::std::io::Read::read_to_string(&mut response, &mut result).map_err(::Error::IO)?; + let result = ::std::io::BufRead::lines(::std::io::BufReader::new(response)); ReadCoreV1NamespacedPodLogResponse::Ok(result) }, ::http::StatusCode::UNAUTHORIZED => ReadCoreV1NamespacedPodLogResponse::Unauthorized(response), diff --git a/k8s-openapi/src/v1_8/api/core/v1/pod.rs b/k8s-openapi/src/v1_8/api/core/v1/pod.rs index 43fd193156..a212a28c7d 100644 --- a/k8s-openapi/src/v1_8/api/core/v1/pod.rs +++ b/k8s-openapi/src/v1_8/api/core/v1/pod.rs @@ -1645,7 +1645,7 @@ impl Pod { #[derive(Debug)] pub enum ReadCoreV1NamespacedPodLogResponse where R: ::std::io::Read { - Ok(String), + Ok(::std::io::Lines<::std::io::BufReader>), Unauthorized(R), Other(::http::StatusCode, R), } @@ -1708,9 +1708,7 @@ impl Pod { Ok(match ::Response::status_code(&response) { ::http::StatusCode::OK => { - let mut response = response; - let mut result = String::new(); - ::std::io::Read::read_to_string(&mut response, &mut result).map_err(::Error::IO)?; + let result = ::std::io::BufRead::lines(::std::io::BufReader::new(response)); ReadCoreV1NamespacedPodLogResponse::Ok(result) }, ::http::StatusCode::UNAUTHORIZED => ReadCoreV1NamespacedPodLogResponse::Unauthorized(response), diff --git a/k8s-openapi/src/v1_9/api/core/v1/pod.rs b/k8s-openapi/src/v1_9/api/core/v1/pod.rs index 7af644f977..120ab9e940 100644 --- a/k8s-openapi/src/v1_9/api/core/v1/pod.rs +++ b/k8s-openapi/src/v1_9/api/core/v1/pod.rs @@ -1655,7 +1655,7 @@ impl Pod { #[derive(Debug)] pub enum ReadCoreV1NamespacedPodLogResponse where R: ::std::io::Read { - Ok(String), + Ok(::std::io::Lines<::std::io::BufReader>), Unauthorized(R), Other(::http::StatusCode, R), } @@ -1718,9 +1718,7 @@ impl Pod { Ok(match ::Response::status_code(&response) { ::http::StatusCode::OK => { - let mut response = response; - let mut result = String::new(); - ::std::io::Read::read_to_string(&mut response, &mut result).map_err(::Error::IO)?; + let result = ::std::io::BufRead::lines(::std::io::BufReader::new(response)); ReadCoreV1NamespacedPodLogResponse::Ok(result) }, ::http::StatusCode::UNAUTHORIZED => ReadCoreV1NamespacedPodLogResponse::Unauthorized(response), diff --git a/src/main.rs b/src/main.rs index aed4b663bd..79569080f7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -765,6 +765,24 @@ fn get_rust_type(schema_kind: &swagger20::SchemaKind, replace_namespaces: &[(Vec } } +fn is_read_pod_log_operation_ok_response( + operation: &swagger20::Operation, + status_code: reqwest::StatusCode, + schema: &swagger20::Schema, +) -> Result { + if operation.id == "readCoreV1NamespacedPodLog" && status_code == reqwest::StatusCode::Ok { + if let swagger20::SchemaKind::Ty(swagger20::Type::String { format: None }) = schema.kind { + Ok(true) + } + else { + Err(format!("expected operation {} to have String type for status code 200", operation.id).into()) + } + } + else { + Ok(false) + } +} + fn replace_namespace<'a, I>(parts: I, replace_namespaces: &[(Vec<&str>, Vec)]) -> Vec where I: IntoIterator { let parts: Vec<_> = parts.into_iter().collect(); @@ -806,7 +824,7 @@ fn write_operation( let operation_responses: Result, _> = operation.responses.iter() - .map(|(status_code, schema)| { + .map(|(&status_code, schema)| { let http_status_code = match status_code { reqwest::StatusCode::Accepted => "ACCEPTED", reqwest::StatusCode::Created => "CREATED", @@ -823,7 +841,7 @@ fn write_operation( _ => return Err(format!("unrecognized status code {}", status_code)), }; - Ok((http_status_code, variant_name, schema)) + Ok((status_code, http_status_code, variant_name, schema)) }) .collect(); let operation_responses = operation_responses?; @@ -833,7 +851,7 @@ fn write_operation( writeln!(file, "#[derive(Debug)]")?; } writeln!(file, "pub enum {} where R: ::std::io::Read {{", operation_result_name)?; - for (_, variant_name, schema) in &operation_responses { + for &(status_code, _, variant_name, schema) in &operation_responses { if let Some(schema) = schema { if is_watch { writeln!( @@ -841,6 +859,9 @@ fn write_operation( " {}(::serde_json::StreamDeserializer<'static, ::serde_json::de::IoRead, {}>),", variant_name, get_rust_type(&schema.kind, replace_namespaces, mod_root))?; } + else if is_read_pod_log_operation_ok_response(operation, status_code, schema)? { + writeln!(file, " {}(::std::io::Lines<::std::io::BufReader>),", variant_name)?; + } else { writeln!(file, " {}({}),", variant_name, get_rust_type(&schema.kind, replace_namespaces, mod_root))?; } @@ -1019,31 +1040,35 @@ fn write_operation( writeln!(file)?; writeln!(file, "{} Ok(match ::Response::status_code(&response) {{", indent)?; - for (http_status_code, variant_name, schema) in &operation_responses { + for &(status_code, http_status_code, variant_name, schema) in &operation_responses { write!(file, "{} ::http::StatusCode::{} => ", indent, http_status_code)?; if let Some(schema) = schema { writeln!(file, "{{")?; - match &schema.kind { - swagger20::SchemaKind::Ty(swagger20::Type::String { .. }) => { - writeln!(file, "{} let mut response = response;", indent)?; - writeln!(file, "{} let mut result = String::new();", indent)?; - // TODO: Better to return a Read rather than buffer up a whole String? `pods/{}/log` can get quite large... - writeln!(file, "{} ::std::io::Read::read_to_string(&mut response, &mut result).map_err(::Error::IO)?;", indent)?; - }, - - swagger20::SchemaKind::Ty(swagger20::Type::Boolean { .. }) | - swagger20::SchemaKind::Ty(swagger20::Type::Integer { .. }) | - swagger20::SchemaKind::Ty(swagger20::Type::Number { .. }) => { - return Err(format!("unsupported response type {:?}", schema.kind).into()); - }, - - _ => if is_watch { - writeln!(file, "{} let result = ::serde_json::Deserializer::from_reader(response).into_iter();", indent)?; + if is_read_pod_log_operation_ok_response(operation, status_code, schema)? { + writeln!(file, "{} let result = ::std::io::BufRead::lines(::std::io::BufReader::new(response));", indent)?; + } + else { + match &schema.kind { + swagger20::SchemaKind::Ty(swagger20::Type::String { .. }) => { + writeln!(file, "{} let mut response = response;", indent)?; + writeln!(file, "{} let mut result = String::new();", indent)?; + writeln!(file, "{} ::std::io::Read::read_to_string(&mut response, &mut result).map_err(::Error::IO)?;", indent)?; + }, + + swagger20::SchemaKind::Ty(swagger20::Type::Boolean { .. }) | + swagger20::SchemaKind::Ty(swagger20::Type::Integer { .. }) | + swagger20::SchemaKind::Ty(swagger20::Type::Number { .. }) => { + return Err(format!("unsupported response type {:?}", schema.kind).into()); + }, + + _ => if is_watch { + writeln!(file, "{} let result = ::serde_json::Deserializer::from_reader(response).into_iter();", indent)?; + } + else { + writeln!(file, "{} let result = ::serde_json::from_reader(response).map_err(::Error::JSON)?;", indent)?; + }, } - else { - writeln!(file, "{} let result = ::serde_json::from_reader(response).map_err(::Error::JSON)?;", indent)?; - }, } writeln!(file, " {}::{}(result)", operation_result_name, variant_name)?;