Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add pod log operation support #1

Merged
merged 1 commit into from
Jul 15, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions examples/log_openapi.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#[macro_use]
extern crate log;

use kube::{
api::{Api, Log, LogParams},
client::APIClient,
config,
};

fn main() -> Result<(), failure::Error> {
std::env::set_var("RUST_LOG", "info,kube=trace");
env_logger::init();
let config = config::load_kube_config().expect("failed to load kubeconfig");
let client = APIClient::new(config);

let mypod: &str = "mypod";

// Manage pods
let pods = Api::v1Pod(client);;
let lp = LogParams::default();
let plog = pods.within("default").log(mypod, &lp)?;
println!("Got pod {} log: {}", mypod, &plog);

Ok(())
}
4 changes: 3 additions & 1 deletion src/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ pub use raw::{
PatchParams,
DeleteParams,
PropagationPolicy,
PatchStrategy
PatchStrategy,
LogParams
};

mod typed;
Expand All @@ -33,6 +34,7 @@ pub use typed::{
Scale,
ScaleSpec,
ScaleStatus,
Log
};

mod resource;
Expand Down
3 changes: 3 additions & 0 deletions src/api/openapi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::api::{
RawApi,
Api,
Object,
Log
};
use crate::client::{
APIClient,
Expand Down Expand Up @@ -58,6 +59,8 @@ impl Api<Object<PodSpec, PodStatus>> {
}
}

impl Log for Api<Object<PodSpec, PodStatus>> {}

use k8s_openapi::api::core::v1::{ServiceSpec, ServiceStatus};
impl Api<Object<ServiceSpec, ServiceStatus>> {
pub fn v1Service(client: APIClient) -> Self {
Expand Down
66 changes: 66 additions & 0 deletions src/api/raw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,30 @@ pub enum PropagationPolicy {
Foreground,
}

#[derive(Default, Clone, Debug)]
pub struct LogParams {
/// The container for which to stream logs. Defaults to only container if there is one container in the pod.
pub container: Option<String>,
/// Follow the log stream of the pod. Defaults to false.
pub follow: bool,
/// If set, the number of bytes to read from the server before terminating the log output.
/// This may not display a complete final line of logging, and may return slightly more or slightly less than the specified limit.
pub limit_bytes: Option<i64>,
/// If 'true', then the output is pretty printed.
pub pretty: bool,
/// Return previous terminated container logs. Defaults to false.
pub previous: bool,
/// A relative time in seconds before the current time from which to show logs.
/// If this value precedes the time a pod was started, only logs since the pod start will be returned.
/// If this value is in the future, no logs will be returned. Only one of sinceSeconds or sinceTime may be specified.
pub since_seconds: Option<i64>,
/// If set, the number of lines from the end of the logs to show.
/// If not specified, logs are shown from the creation of the container or sinceSeconds or sinceTime
pub tail_lines: Option<i64>,
/// If true, add an RFC3339 or RFC3339Nano timestamp at the beginning of every line of log output. Defaults to false.
pub timestamps: bool,
}

/// Convenience methods found from API conventions
impl RawApi {
/// List a collection of a resource
Expand Down Expand Up @@ -553,6 +577,48 @@ impl RawApi {
Ok(req.body(data).context(ErrorKind::RequestBuild)?)
}

/// Get a pod logs
pub fn log(&self, name: &str, lp: &LogParams) -> Result<http::Request<Vec<u8>>> {
let base_url = self.make_url() + "/" + name + "/" + "log";
let mut qp = url::form_urlencoded::Serializer::new(base_url);

if let Some(container) = &lp.container {
qp.append_pair("container", &container);
}

if lp.follow {
qp.append_pair("follow", "true");
}

if let Some(limitBytes) = &lp.limit_bytes {
qp.append_pair("limitBytes", &limitBytes.to_string());
}

if lp.pretty {
qp.append_pair("pretty", "true");
}

if lp.previous {
qp.append_pair("previous", "true");
}

if let Some(sinceSeconds) = &lp.since_seconds {
qp.append_pair("sinceSeconds", &sinceSeconds.to_string());
}

if let Some(tailLines) = &lp.tail_lines {
qp.append_pair("tailLines", &tailLines.to_string());
}

if lp.timestamps {
qp.append_pair("timestamps", "true");
}

let urlstr = qp.finish();
let mut req = http::Request::get(urlstr);
Ok(req.body(vec![]).context(ErrorKind::RequestBuild)?)
}

}

#[test]
Expand Down
22 changes: 21 additions & 1 deletion src/api/typed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ use crate::api::{
PostParams,
DeleteParams,
ListParams,
PatchParams
PatchParams,
LogParams
};
use crate::api::resource::{
ObjectList, Object, WatchEvent, KubeObject,
Expand Down Expand Up @@ -41,6 +42,16 @@ pub struct Api<K> {
pub(in crate::api) phantom: PhantomData<K>,
}

pub trait LogOperation {
fn log_operation(&self, name: &str, lp: &LogParams) -> Result<String>;
}

pub trait Log: LogOperation {
fn log(&self, name: &str, lp: &LogParams) -> Result<String> {
Ok(self.log_operation(name, lp)?)
}
}

/// Expose same interface as Api for controlling scope/group/versions/ns
impl<K> Api<K> {
pub fn within(mut self, ns: &str) -> Self {
Expand Down Expand Up @@ -107,6 +118,15 @@ impl<K> Api<K> where
}
}

impl<K> LogOperation for Api<K> where
K: Clone + DeserializeOwned + KubeObject
{
fn log_operation(&self, name: &str, lp: &LogParams) -> Result<String> {
let req = self.api.log(name, lp)?;
self.client.request_text(req)
}
}

/// Scale spec from api::autoscaling::v1
#[derive(Deserialize, Serialize, Clone, Debug)]
pub struct ScaleSpec {
Expand Down
12 changes: 12 additions & 0 deletions src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,18 @@ impl APIClient {
})
}

pub fn request_text(&self, request: http::Request<Vec<u8>>) -> Result<String>
{
let mut res : reqwest::Response = self.send(request)?;
trace!("{} {}", res.status().as_str(), res.url());
//trace!("Response Headers: {:?}", res.headers());
let s = res.status();
let text = res.text().context(ErrorKind::RequestParse)?;
res.error_for_status().map_err(|e| make_api_error(&text, e, &s))?;

Ok(text)
}

pub fn request_status<T>(&self, request: http::Request<Vec<u8>>) -> Result<Either<T, Status>>
where
T: DeserializeOwned,
Expand Down