Files
google-apis-rs/gen/admin1_reports-cli/src/main.rs
Sebastian Thiel a328942033 feat(API): improved error handling
We are now able to decode detailed errors and pass them on. This allows
the CLI to provide more useful error responses.
Additionally, the CLI will only print debug responses in --debug mode.

Fixes #82
2015-04-25 09:49:57 +02:00

561 lines
22 KiB
Rust

// DO NOT EDIT !
// This file was generated automatically from 'src/mako/cli/main.rs.mako'
// DO NOT EDIT !
#![feature(plugin, exit_status)]
#![plugin(docopt_macros)]
#![allow(unused_variables, unused_imports, dead_code, unused_mut)]
extern crate docopt;
extern crate yup_oauth2 as oauth2;
extern crate yup_hyper_mock as mock;
extern crate rustc_serialize;
extern crate serde;
extern crate hyper;
extern crate mime;
extern crate google_admin1_reports as api;
use std::env;
use std::io::{self, Write};
docopt!(Options derive Debug, "
Usage:
admin1-reports [options] activities list <user-key> <application-name> [-p <v>]... [-o <out>]
admin1-reports [options] activities watch <user-key> <application-name> -r <kv>... [-p <v>]... [-o <out>]
admin1-reports [options] channels stop -r <kv>... [-p <v>]...
admin1-reports [options] customer-usage-reports get <date> [-p <v>]... [-o <out>]
admin1-reports [options] user-usage-report get <user-key> <date> [-p <v>]... [-o <out>]
admin1-reports --help
All documentation details can be found TODO: <URL to github.io docs here, see #51>
Configuration:
--scope <url>
Specify the authentication a method should be executed in. Each scope requires
the user to grant this application permission to use it.
If unset, it defaults to the shortest scope url for a particular method.
--config-dir <folder>
A directory into which we will store our persistent data. Defaults to a user-writable
directory that we will create during the first invocation.
[default: ~/.google-service-cli]
--debug
Output all server communication to standard error. `tx` and `rx` are placed into
the same stream.
--debug-auth
Output all communication related to authentication to standard error. `tx` and `rx` are placed into
the same stream.
");
mod cmn;
use cmn::{InvalidOptionsError, CLIError, JsonTokenStorage, arg_from_str, writer_from_opts, parse_kv_arg,
input_file_from_opts, input_mime_from_opts, FieldCursor, FieldError};
use std::default::Default;
use std::str::FromStr;
use oauth2::{Authenticator, DefaultAuthenticatorDelegate};
use rustc_serialize::json;
struct Engine {
opt: Options,
hub: api::Reports<hyper::Client, Authenticator<DefaultAuthenticatorDelegate, JsonTokenStorage, hyper::Client>>,
}
impl Engine {
fn _activities_list(&self, dry_run: bool, err: &mut InvalidOptionsError)
-> Option<api::Error> {
let mut call = self.hub.activities().list(&self.opt.arg_user_key, &self.opt.arg_application_name);
for parg in self.opt.arg_v.iter() {
let (key, value) = parse_kv_arg(&*parg, err, false);
match key {
"start-time" => {
call = call.start_time(value.unwrap_or(""));
},
"page-token" => {
call = call.page_token(value.unwrap_or(""));
},
"max-results" => {
call = call.max_results(arg_from_str(value.unwrap_or("-0"), err, "max-results", "integer"));
},
"filters" => {
call = call.filters(value.unwrap_or(""));
},
"event-name" => {
call = call.event_name(value.unwrap_or(""));
},
"end-time" => {
call = call.end_time(value.unwrap_or(""));
},
"customer-id" => {
call = call.customer_id(value.unwrap_or(""));
},
"actor-ip-address" => {
call = call.actor_ip_address(value.unwrap_or(""));
},
"alt"
|"fields"
|"key"
|"oauth-token"
|"pretty-print"
|"quota-user"
|"user-ip" => {
let map = [
("oauth-token", "oauth_token"),
("pretty-print", "prettyPrint"),
("quota-user", "quotaUser"),
("user-ip", "userIp"),
];
call = call.param(map.iter().find(|t| t.0 == key).unwrap_or(&("", key)).1, value.unwrap_or("unset"))
},
_ => err.issues.push(CLIError::UnknownParameter(key.to_string())),
}
}
let protocol = "standard-request";
if dry_run {
None
} else {
assert!(err.issues.len() == 0);
let mut ostream = writer_from_opts(self.opt.flag_o, &self.opt.arg_out);
match match protocol {
"standard-request" => call.doit(),
_ => unreachable!(),
} {
Err(api_err) => Some(api_err),
Ok((mut response, output_schema)) => {
serde::json::to_writer_pretty(&mut ostream, &output_schema).unwrap();
None
}
}
}
}
fn _activities_watch(&self, dry_run: bool, err: &mut InvalidOptionsError)
-> Option<api::Error> {
let mut request = api::Channel::default();
let mut call = self.hub.activities().watch(&request, &self.opt.arg_user_key, &self.opt.arg_application_name);
for parg in self.opt.arg_v.iter() {
let (key, value) = parse_kv_arg(&*parg, err, false);
match key {
"start-time" => {
call = call.start_time(value.unwrap_or(""));
},
"page-token" => {
call = call.page_token(value.unwrap_or(""));
},
"max-results" => {
call = call.max_results(arg_from_str(value.unwrap_or("-0"), err, "max-results", "integer"));
},
"filters" => {
call = call.filters(value.unwrap_or(""));
},
"event-name" => {
call = call.event_name(value.unwrap_or(""));
},
"end-time" => {
call = call.end_time(value.unwrap_or(""));
},
"customer-id" => {
call = call.customer_id(value.unwrap_or(""));
},
"actor-ip-address" => {
call = call.actor_ip_address(value.unwrap_or(""));
},
"alt"
|"fields"
|"key"
|"oauth-token"
|"pretty-print"
|"quota-user"
|"user-ip" => {
let map = [
("oauth-token", "oauth_token"),
("pretty-print", "prettyPrint"),
("quota-user", "quotaUser"),
("user-ip", "userIp"),
];
call = call.param(map.iter().find(|t| t.0 == key).unwrap_or(&("", key)).1, value.unwrap_or("unset"))
},
_ => err.issues.push(CLIError::UnknownParameter(key.to_string())),
}
}
let mut field_name = FieldCursor::default();
for kvarg in self.opt.arg_kv.iter() {
let (key, value) = parse_kv_arg(&*kvarg, err, false);
if let Err(field_err) = field_name.set(&*key) {
err.issues.push(field_err);
}
match &field_name.to_string()[..] {
"resource-uri" => {
request.resource_uri = Some(value.unwrap_or("").to_string());
},
"kind" => {
request.kind = Some(value.unwrap_or("").to_string());
},
"resource-id" => {
request.resource_id = Some(value.unwrap_or("").to_string());
},
"payload" => {
request.payload = Some(arg_from_str(value.unwrap_or("false"), err, "payload", "boolean"));
},
"token" => {
request.token = Some(value.unwrap_or("").to_string());
},
"params" => {
if request.params.is_none() {
request.params = Some(Default::default());
}
let (key, value) = parse_kv_arg(value.unwrap_or(""), err, true);
request.params.as_mut().unwrap().insert(key.to_string(), value.unwrap_or("").to_string());
},
"expiration" => {
request.expiration = Some(value.unwrap_or("").to_string());
},
"address" => {
request.address = Some(value.unwrap_or("").to_string());
},
"type" => {
request.type_ = Some(value.unwrap_or("").to_string());
},
"id" => {
request.id = Some(value.unwrap_or("").to_string());
},
_ => {
err.issues.push(CLIError::Field(FieldError::Unknown(field_name.to_string())));
}
}
}
let protocol = "standard-request";
if dry_run {
None
} else {
assert!(err.issues.len() == 0);
let mut ostream = writer_from_opts(self.opt.flag_o, &self.opt.arg_out);
match match protocol {
"standard-request" => call.doit(),
_ => unreachable!(),
} {
Err(api_err) => Some(api_err),
Ok((mut response, output_schema)) => {
serde::json::to_writer_pretty(&mut ostream, &output_schema).unwrap();
None
}
}
}
}
fn _channels_stop(&self, dry_run: bool, err: &mut InvalidOptionsError)
-> Option<api::Error> {
let mut request = api::Channel::default();
let mut call = self.hub.channels().stop(&request);
for parg in self.opt.arg_v.iter() {
let (key, value) = parse_kv_arg(&*parg, err, false);
match key {
"alt"
|"fields"
|"key"
|"oauth-token"
|"pretty-print"
|"quota-user"
|"user-ip" => {
let map = [
("oauth-token", "oauth_token"),
("pretty-print", "prettyPrint"),
("quota-user", "quotaUser"),
("user-ip", "userIp"),
];
call = call.param(map.iter().find(|t| t.0 == key).unwrap_or(&("", key)).1, value.unwrap_or("unset"))
},
_ => err.issues.push(CLIError::UnknownParameter(key.to_string())),
}
}
let mut field_name = FieldCursor::default();
for kvarg in self.opt.arg_kv.iter() {
let (key, value) = parse_kv_arg(&*kvarg, err, false);
if let Err(field_err) = field_name.set(&*key) {
err.issues.push(field_err);
}
match &field_name.to_string()[..] {
"resource-uri" => {
request.resource_uri = Some(value.unwrap_or("").to_string());
},
"kind" => {
request.kind = Some(value.unwrap_or("").to_string());
},
"resource-id" => {
request.resource_id = Some(value.unwrap_or("").to_string());
},
"payload" => {
request.payload = Some(arg_from_str(value.unwrap_or("false"), err, "payload", "boolean"));
},
"token" => {
request.token = Some(value.unwrap_or("").to_string());
},
"params" => {
if request.params.is_none() {
request.params = Some(Default::default());
}
let (key, value) = parse_kv_arg(value.unwrap_or(""), err, true);
request.params.as_mut().unwrap().insert(key.to_string(), value.unwrap_or("").to_string());
},
"expiration" => {
request.expiration = Some(value.unwrap_or("").to_string());
},
"address" => {
request.address = Some(value.unwrap_or("").to_string());
},
"type" => {
request.type_ = Some(value.unwrap_or("").to_string());
},
"id" => {
request.id = Some(value.unwrap_or("").to_string());
},
_ => {
err.issues.push(CLIError::Field(FieldError::Unknown(field_name.to_string())));
}
}
}
let protocol = "standard-request";
if dry_run {
None
} else {
assert!(err.issues.len() == 0);
match match protocol {
"standard-request" => call.doit(),
_ => unreachable!(),
} {
Err(api_err) => Some(api_err),
Ok(mut response) => {
None
}
}
}
}
fn _customer_usage_reports_get(&self, dry_run: bool, err: &mut InvalidOptionsError)
-> Option<api::Error> {
let mut call = self.hub.customer_usage_reports().get(&self.opt.arg_date);
for parg in self.opt.arg_v.iter() {
let (key, value) = parse_kv_arg(&*parg, err, false);
match key {
"parameters" => {
call = call.parameters(value.unwrap_or(""));
},
"page-token" => {
call = call.page_token(value.unwrap_or(""));
},
"customer-id" => {
call = call.customer_id(value.unwrap_or(""));
},
"alt"
|"fields"
|"key"
|"oauth-token"
|"pretty-print"
|"quota-user"
|"user-ip" => {
let map = [
("oauth-token", "oauth_token"),
("pretty-print", "prettyPrint"),
("quota-user", "quotaUser"),
("user-ip", "userIp"),
];
call = call.param(map.iter().find(|t| t.0 == key).unwrap_or(&("", key)).1, value.unwrap_or("unset"))
},
_ => err.issues.push(CLIError::UnknownParameter(key.to_string())),
}
}
let protocol = "standard-request";
if dry_run {
None
} else {
assert!(err.issues.len() == 0);
let mut ostream = writer_from_opts(self.opt.flag_o, &self.opt.arg_out);
match match protocol {
"standard-request" => call.doit(),
_ => unreachable!(),
} {
Err(api_err) => Some(api_err),
Ok((mut response, output_schema)) => {
serde::json::to_writer_pretty(&mut ostream, &output_schema).unwrap();
None
}
}
}
}
fn _user_usage_report_get(&self, dry_run: bool, err: &mut InvalidOptionsError)
-> Option<api::Error> {
let mut call = self.hub.user_usage_report().get(&self.opt.arg_user_key, &self.opt.arg_date);
for parg in self.opt.arg_v.iter() {
let (key, value) = parse_kv_arg(&*parg, err, false);
match key {
"parameters" => {
call = call.parameters(value.unwrap_or(""));
},
"page-token" => {
call = call.page_token(value.unwrap_or(""));
},
"max-results" => {
call = call.max_results(arg_from_str(value.unwrap_or("-0"), err, "max-results", "integer"));
},
"filters" => {
call = call.filters(value.unwrap_or(""));
},
"customer-id" => {
call = call.customer_id(value.unwrap_or(""));
},
"alt"
|"fields"
|"key"
|"oauth-token"
|"pretty-print"
|"quota-user"
|"user-ip" => {
let map = [
("oauth-token", "oauth_token"),
("pretty-print", "prettyPrint"),
("quota-user", "quotaUser"),
("user-ip", "userIp"),
];
call = call.param(map.iter().find(|t| t.0 == key).unwrap_or(&("", key)).1, value.unwrap_or("unset"))
},
_ => err.issues.push(CLIError::UnknownParameter(key.to_string())),
}
}
let protocol = "standard-request";
if dry_run {
None
} else {
assert!(err.issues.len() == 0);
let mut ostream = writer_from_opts(self.opt.flag_o, &self.opt.arg_out);
match match protocol {
"standard-request" => call.doit(),
_ => unreachable!(),
} {
Err(api_err) => Some(api_err),
Ok((mut response, output_schema)) => {
serde::json::to_writer_pretty(&mut ostream, &output_schema).unwrap();
None
}
}
}
}
fn _doit(&self, dry_run: bool) -> (Option<api::Error>, Option<InvalidOptionsError>) {
let mut err = InvalidOptionsError::new();
let mut call_result: Option<api::Error>;
let mut err_opt: Option<InvalidOptionsError> = None;
if self.opt.cmd_activities {
if self.opt.cmd_list {
call_result = self._activities_list(dry_run, &mut err);
} else if self.opt.cmd_watch {
call_result = self._activities_watch(dry_run, &mut err);
} else {
unreachable!();
}
}
else if self.opt.cmd_channels {
if self.opt.cmd_stop {
call_result = self._channels_stop(dry_run, &mut err);
} else {
unreachable!();
}
}
else if self.opt.cmd_customer_usage_reports {
if self.opt.cmd_get {
call_result = self._customer_usage_reports_get(dry_run, &mut err);
} else {
unreachable!();
}
}
else if self.opt.cmd_user_usage_report {
if self.opt.cmd_get {
call_result = self._user_usage_report_get(dry_run, &mut err);
} else {
unreachable!();
}
} else {
unreachable!();
}
if dry_run {
if err.issues.len() > 0 {
err_opt = Some(err);
}
}
(call_result, err_opt)
}
// Please note that this call will fail if any part of the opt can't be handled
fn new(opt: Options) -> Result<Engine, InvalidOptionsError> {
let (config_dir, secret) = {
let config_dir = match cmn::assure_config_dir_exists(&opt.flag_config_dir) {
Err(e) => return Err(InvalidOptionsError::single(e, 3)),
Ok(p) => p,
};
match cmn::application_secret_from_directory(&config_dir, "admin1-reports-secret.json",
"{\"installed\":{\"auth_uri\":\"https://accounts.google.com/o/oauth2/auth\",\"client_secret\":\"hCsslbCUyfehWMmbkG8vTYxG\",\"token_uri\":\"https://accounts.google.com/o/oauth2/token\",\"client_email\":\"\",\"redirect_uris\":[\"urn:ietf:wg:oauth:2.0:oob\",\"oob\"],\"client_x509_cert_url\":\"\",\"client_id\":\"620010449518-9ngf7o4dhs0dka470npqvor6dc5lqb9b.apps.googleusercontent.com\",\"auth_provider_x509_cert_url\":\"https://www.googleapis.com/oauth2/v1/certs\"}}") {
Ok(secret) => (config_dir, secret),
Err(e) => return Err(InvalidOptionsError::single(e, 4))
}
};
let auth = Authenticator::new( &secret, DefaultAuthenticatorDelegate,
if opt.flag_debug_auth {
hyper::Client::with_connector(mock::TeeConnector {
connector: hyper::net::HttpConnector(None)
})
} else {
hyper::Client::new()
},
JsonTokenStorage {
program_name: "admin1-reports",
db_dir: config_dir.clone(),
}, None);
let client =
if opt.flag_debug {
hyper::Client::with_connector(mock::TeeConnector {
connector: hyper::net::HttpConnector(None)
})
} else {
hyper::Client::new()
};
let engine = Engine {
opt: opt,
hub: api::Reports::new(client, auth),
};
match engine._doit(true) {
(_, Some(err)) => Err(err),
_ => Ok(engine),
}
}
// Execute the call with all the bells and whistles, informing the caller only if there was an error.
// The absense of one indicates success.
fn doit(&self) -> Option<api::Error> {
self._doit(false).0
}
}
fn main() {
let opts: Options = Options::docopt().decode().unwrap_or_else(|e| e.exit());
match Engine::new(opts) {
Err(err) => {
writeln!(io::stderr(), "{}", err).ok();
env::set_exit_status(err.exit_code);
},
Ok(engine) => {
if let Some(err) = engine.doit() {
writeln!(io::stderr(), "{:?}", err).ok();
writeln!(io::stderr(), "{}", err).ok();
env::set_exit_status(1);
}
}
}
}