mirror of
https://github.com/NLnetLabs/krill.git
synced 2026-09-20 16:37:43 +02:00
Merge pull request #85 from NLnetLabs/issue71_cli_improvements
Issue71 cli improvements
This commit is contained in:
@@ -35,3 +35,7 @@ xml-rs = "0.8.0"
|
||||
|
||||
[build-dependencies]
|
||||
ignore = "^0.4"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
extra-debug = [ "rpki/extra-debug" ]
|
||||
+7
-2
@@ -1,10 +1,11 @@
|
||||
use std::io;
|
||||
use std::{env, io};
|
||||
|
||||
use serde::de::DeserializeOwned;
|
||||
use serde::Serialize;
|
||||
|
||||
use rpki::uri;
|
||||
|
||||
use crate::cli::options::KRILL_CLI_API_ENV;
|
||||
use crate::cli::options::{CaCommand, Command, Options, PublishersCommand, Rfc8181Command};
|
||||
use crate::cli::report::{ApiResponse, ReportError};
|
||||
use crate::commons::api::{
|
||||
@@ -43,6 +44,11 @@ impl KrillClient {
|
||||
server: options.server,
|
||||
token: options.token,
|
||||
};
|
||||
|
||||
if options.api {
|
||||
env::set_var(KRILL_CLI_API_ENV, "1") // this is safe here, because the CLI will exit
|
||||
}
|
||||
|
||||
match options.command {
|
||||
Command::Health => client.health(),
|
||||
Command::CertAuth(cmd) => client.certauth(cmd),
|
||||
@@ -79,7 +85,6 @@ impl KrillClient {
|
||||
httpclient::post_json(&uri, parent, Some(&self.token))?;
|
||||
Ok(ApiResponse::Empty)
|
||||
}
|
||||
|
||||
CaCommand::AddChild(handle, req) => {
|
||||
let uri = format!("api/v1/cas/{}/children", handle);
|
||||
let uri = self.resolve_uri(&uri);
|
||||
|
||||
+684
-532
File diff suppressed because it is too large
Load Diff
+11
-1
@@ -296,6 +296,12 @@ pub enum ErrorCode {
|
||||
#[display(fmt = "Child cannot have resources not held by parent")]
|
||||
ChildOverclaims,
|
||||
|
||||
#[display(fmt = "Parent with name exists")]
|
||||
DuplicateParent,
|
||||
|
||||
#[display(fmt = "Child unknown")]
|
||||
UnknownChild,
|
||||
|
||||
// 3000s General server errors
|
||||
#[display(fmt = "Cannot update internal state, issue with work_dir?")]
|
||||
Persistence,
|
||||
@@ -348,6 +354,8 @@ impl From<usize> for ErrorCode {
|
||||
2301 => ErrorCode::DuplicateChild,
|
||||
2302 => ErrorCode::ChildNeedsResources,
|
||||
2303 => ErrorCode::ChildOverclaims,
|
||||
2304 => ErrorCode::DuplicateParent,
|
||||
2305 => ErrorCode::UnknownChild,
|
||||
|
||||
// 3000s -> Server issues, bugs or operational issues
|
||||
3001 => ErrorCode::Persistence,
|
||||
@@ -391,6 +399,8 @@ impl Into<ErrorResponse> for ErrorCode {
|
||||
ErrorCode::DuplicateChild => 2301,
|
||||
ErrorCode::ChildNeedsResources => 2302,
|
||||
ErrorCode::ChildOverclaims => 2303,
|
||||
ErrorCode::DuplicateParent => 2304,
|
||||
ErrorCode::UnknownChild => 2305,
|
||||
|
||||
// server errors
|
||||
ErrorCode::Persistence => 3001,
|
||||
@@ -438,7 +448,7 @@ mod tests {
|
||||
test_code(n)
|
||||
}
|
||||
|
||||
for n in 2301..2304 {
|
||||
for n in 2301..2306 {
|
||||
test_code(n)
|
||||
}
|
||||
|
||||
|
||||
@@ -1040,10 +1040,8 @@ mod tests {
|
||||
let ncc_id_cer = include_bytes!("../../../test-resources/remote/ncc-id.der");
|
||||
let ncc_id_cer = IdCert::decode(ncc_id_cer.as_ref()).unwrap();
|
||||
|
||||
msg.validate_at(
|
||||
&ncc_id_cer,
|
||||
Time::utc(2019, 9, 14, 0, 0, 0)
|
||||
).unwrap();
|
||||
msg.validate_at(&ncc_id_cer, Time::utc(2019, 9, 27, 0, 0, 0))
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
//! Some helper functions for HTTP calls
|
||||
use std::io::Read;
|
||||
use std::time::Duration;
|
||||
use std::{env, fmt};
|
||||
|
||||
use bytes::Bytes;
|
||||
use reqwest::header::{HeaderMap, HeaderValue, InvalidHeaderValue, CONTENT_TYPE, USER_AGENT};
|
||||
@@ -8,14 +9,74 @@ use reqwest::{Client, Response, StatusCode};
|
||||
use serde::de::DeserializeOwned;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::cli::options::KRILL_CLI_API_ENV;
|
||||
use crate::commons::api::{ErrorResponse, Token};
|
||||
|
||||
const JSON_CONTENT: &str = "application/json";
|
||||
|
||||
fn report_get(uri: &str, content_type: Option<&str>, token: Option<&Token>) {
|
||||
if env::var(KRILL_CLI_API_ENV).is_ok() {
|
||||
println!("GET: {}", uri);
|
||||
if let Some(content_type) = content_type {
|
||||
println!("Headers: content-type: {}", content_type);
|
||||
}
|
||||
if let Some(token) = token {
|
||||
println!("Headers: Bearer: {}", token);
|
||||
}
|
||||
std::process::exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
enum PostBody<'a> {
|
||||
String(&'a String),
|
||||
Bytes(&'a Vec<u8>),
|
||||
}
|
||||
|
||||
impl<'a> fmt::Display for PostBody<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
PostBody::String(string) => write!(f, "{}", string),
|
||||
PostBody::Bytes(bytes) => {
|
||||
let base64 = base64::encode(bytes);
|
||||
write!(f, "<binary content, base64 encoded for display here> {}", base64)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn report_post(uri: &str, content_type: Option<&str>, token: Option<&Token>, body: PostBody) {
|
||||
if env::var(KRILL_CLI_API_ENV).is_ok() {
|
||||
println!("POST: {}", uri);
|
||||
if let Some(content_type) = content_type {
|
||||
println!("Headers: content-type: {}", content_type);
|
||||
}
|
||||
if let Some(token) = token {
|
||||
println!("Headers: Bearer: {}", token);
|
||||
}
|
||||
println!("Body: {}", body);
|
||||
std::process::exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
fn report_delete(uri: &str, content_type: Option<&str>, token: Option<&Token>) {
|
||||
if env::var(KRILL_CLI_API_ENV).is_ok() {
|
||||
println!("DELETE: {}", uri);
|
||||
if let Some(content_type) = content_type {
|
||||
println!("Headers: content-type: {}", content_type);
|
||||
}
|
||||
if let Some(token) = token {
|
||||
println!("Headers: Bearer: {}", token);
|
||||
}
|
||||
std::process::exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
/// Performs a GET request that expects a json response that can be
|
||||
/// deserialized into the an owned value of the expected type. Returns an error
|
||||
/// if nothing is returned.
|
||||
pub fn get_json<T: DeserializeOwned>(uri: &str, token: Option<&Token>) -> Result<T, Error> {
|
||||
report_get(uri, None, token);
|
||||
|
||||
let headers = headers(Some(JSON_CONTENT), token)?;
|
||||
let res = client(uri)?.get(uri).headers(headers).send()?;
|
||||
process_json_response(res)
|
||||
@@ -24,6 +85,8 @@ pub fn get_json<T: DeserializeOwned>(uri: &str, token: Option<&Token>) -> Result
|
||||
/// Performs a get request and expects a response that can be turned
|
||||
/// into a string (in particular, not a binary response).
|
||||
pub fn get_text(uri: &str, content_type: &str, token: Option<&Token>) -> Result<String, Error> {
|
||||
report_get(uri, Some(content_type), token);
|
||||
|
||||
let headers = headers(Some(content_type), token)?;
|
||||
let res = client(uri)?.get(uri).headers(headers).send()?;
|
||||
match opt_text_response(res)? {
|
||||
@@ -35,6 +98,8 @@ pub fn get_text(uri: &str, content_type: &str, token: Option<&Token>) -> Result<
|
||||
/// Checks that there is a 200 OK response at the given URI. Discards the
|
||||
/// response body.
|
||||
pub fn get_ok(uri: &str, token: Option<&Token>) -> Result<(), Error> {
|
||||
report_get(uri, None, token);
|
||||
|
||||
let headers = headers(None, token)?;
|
||||
let res = client(uri)?.get(uri).headers(headers).send()?;
|
||||
opt_text_response(res)?; // Will return nice errors with possible body.
|
||||
@@ -44,8 +109,11 @@ pub fn get_ok(uri: &str, token: Option<&Token>) -> Result<(), Error> {
|
||||
/// Performs a POST of data that can be serialized into json, and expects
|
||||
/// a 200 OK response, without a body.
|
||||
pub fn post_json(uri: &str, data: impl Serialize, token: Option<&Token>) -> Result<(), Error> {
|
||||
let headers = headers(Some(JSON_CONTENT), token)?;
|
||||
let body = serde_json::to_string(&data)?;
|
||||
report_post(uri, None, token, PostBody::String(&body));
|
||||
|
||||
let headers = headers(Some(JSON_CONTENT), token)?;
|
||||
|
||||
let res = client(uri)?.post(uri).headers(headers).body(body).send()?;
|
||||
if let Some(res) = opt_text_response(res)? {
|
||||
Err(Error::UnexpectedResponse(res))
|
||||
@@ -62,14 +130,18 @@ pub fn post_json_with_response<T: DeserializeOwned>(
|
||||
data: impl Serialize,
|
||||
token: Option<&Token>,
|
||||
) -> Result<T, Error> {
|
||||
let headers = headers(Some(JSON_CONTENT), token)?;
|
||||
let body = serde_json::to_string(&data)?;
|
||||
report_post(uri, None, token, PostBody::String(&body));
|
||||
|
||||
let headers = headers(Some(JSON_CONTENT), token)?;
|
||||
let res = client(uri)?.post(uri).headers(headers).body(body).send()?;
|
||||
process_json_response(res)
|
||||
}
|
||||
|
||||
/// Performs a POST with no data to the given URI and expects and empty 200 OK response.
|
||||
pub fn post_empty(uri: &str, token: Option<&Token>) -> Result<(), Error> {
|
||||
report_post(uri, None, token, PostBody::String(&"<empty>".to_string()));
|
||||
|
||||
let headers = headers(Some(JSON_CONTENT), token)?;
|
||||
let res = client(uri)?.post(uri).headers(headers).send()?;
|
||||
if let Some(res) = opt_text_response(res)? {
|
||||
@@ -84,9 +156,10 @@ pub fn post_empty(uri: &str, token: Option<&Token>) -> Result<(), Error> {
|
||||
/// Note: Bytes may be empty if the post was successful, but the response was
|
||||
/// empty.
|
||||
pub fn post_binary(uri: &str, data: &Bytes, content_type: &str) -> Result<Bytes, Error> {
|
||||
let headers = headers(Some(content_type), None)?;
|
||||
let body = data.to_vec();
|
||||
report_post(uri, None, None, PostBody::Bytes(&body));
|
||||
|
||||
let headers = headers(Some(content_type), None)?;
|
||||
let mut res = client(uri)?.post(uri).headers(headers).body(body).send()?;
|
||||
|
||||
match res.status() {
|
||||
@@ -111,6 +184,8 @@ pub fn post_binary(uri: &str, data: &Bytes, content_type: &str) -> Result<Bytes,
|
||||
|
||||
/// Sends a delete request to the specified url.
|
||||
pub fn delete(uri: &str, token: Option<&Token>) -> Result<(), Error> {
|
||||
report_delete(uri, None, token);
|
||||
|
||||
let headers = headers(None, token)?;
|
||||
client(uri)?.delete(uri).headers(headers).send()?;
|
||||
Ok(())
|
||||
|
||||
@@ -2,6 +2,7 @@ use std::fs::File;
|
||||
use std::io;
|
||||
use std::io::Read;
|
||||
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
use std::str::FromStr;
|
||||
|
||||
@@ -32,7 +33,7 @@ impl ConfigDefaults {
|
||||
3000
|
||||
}
|
||||
fn use_ta() -> bool {
|
||||
false
|
||||
env::var("KRILL_USE_TA").is_ok()
|
||||
}
|
||||
fn use_ssl() -> SslChoice {
|
||||
SslChoice::Test
|
||||
@@ -59,7 +60,6 @@ impl ConfigDefaults {
|
||||
PathBuf::from("./krill.log")
|
||||
}
|
||||
fn auth_token() -> Token {
|
||||
use std::env;
|
||||
|
||||
match env::var("KRILL_AUTH_TOKEN") {
|
||||
Ok(token) => Token::from(token),
|
||||
@@ -229,7 +229,7 @@ impl Config {
|
||||
|
||||
let config_file = matches
|
||||
.value_of("config")
|
||||
.unwrap_or("./daemon/defaults/krill.conf");
|
||||
.unwrap_or("./defaults/krill.conf");
|
||||
|
||||
let c = Self::read_config(config_file)?;
|
||||
c.init_logging()?;
|
||||
|
||||
@@ -535,6 +535,8 @@ impl ErrorToStatus for ca::ServerError<OpenSslSigner> {
|
||||
fn status(&self) -> StatusCode {
|
||||
match self {
|
||||
ca::ServerError::CertAuth(e) => e.status(),
|
||||
ca::ServerError::DuplicateCa(_) => StatusCode::BAD_REQUEST,
|
||||
ca::ServerError::UnknownCa(_) => StatusCode::BAD_REQUEST,
|
||||
_ => StatusCode::INTERNAL_SERVER_ERROR,
|
||||
}
|
||||
}
|
||||
@@ -620,6 +622,8 @@ impl ToErrorCode for ca::ServerError<OpenSslSigner> {
|
||||
fn code(&self) -> ErrorCode {
|
||||
match self {
|
||||
ca::ServerError::CertAuth(e) => e.code(),
|
||||
ca::ServerError::DuplicateCa(_) => ErrorCode::DuplicateChild,
|
||||
ca::ServerError::UnknownCa(_) => ErrorCode::UnknownChild,
|
||||
_ => ErrorCode::CaServerError,
|
||||
}
|
||||
}
|
||||
@@ -629,8 +633,10 @@ impl ToErrorCode for ca::Error {
|
||||
fn code(&self) -> ErrorCode {
|
||||
match self {
|
||||
ca::Error::DuplicateChild(_) => ErrorCode::DuplicateChild,
|
||||
ca::Error::UnknownChild(_) => ErrorCode::UnknownChild,
|
||||
ca::Error::MustHaveResources => ErrorCode::ChildNeedsResources,
|
||||
ca::Error::MissingResources => ErrorCode::ChildOverclaims,
|
||||
ca::Error::DuplicateParent(_) => ErrorCode::DuplicateParent,
|
||||
_ => ErrorCode::CaServerError,
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user