diff --git a/Cargo.lock b/Cargo.lock index 14bca9c..6e8e764 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -216,20 +216,6 @@ dependencies = [ "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "core-foundation" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "core-foundation-sys" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "crc" version = "1.8.1" @@ -375,6 +361,14 @@ dependencies = [ "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ct-logs" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "sct 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "digest" version = "0.8.0" @@ -412,6 +406,15 @@ dependencies = [ "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "env_proxy" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "error-chain" version = "0.11.0" @@ -469,19 +472,6 @@ name = "fnv" version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "fuchsia-cprng" version = "0.1.1" @@ -604,15 +594,19 @@ dependencies = [ ] [[package]] -name = "hyper-tls" -version = "0.3.2" +name = "hyper-rustls" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "ct-logs 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.12.29 (registry+https://github.com/rust-lang/crates.io-index)", - "native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rustls 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-rustls 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", + "webpki 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)", + "webpki-roots 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -791,23 +785,6 @@ dependencies = [ "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "native-tls" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl 0.10.23 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.47 (registry+https://github.com/rust-lang/crates.io-index)", - "schannel 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", - "security-framework 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "security-framework-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tempfile 3.0.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "net2" version = "0.2.33" @@ -980,36 +957,6 @@ name = "opaque-debug" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "openssl" -version = "0.10.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.47 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "openssl-probe" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "openssl-sys" -version = "0.9.47" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", - "vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "owning_ref" version = "0.4.0" @@ -1133,11 +1080,6 @@ dependencies = [ "unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "pkg-config" -version = "0.3.14" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "proc-macro2" version = "0.4.30" @@ -1320,17 +1262,9 @@ dependencies = [ "ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "remove_dir_all" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "reqwest" -version = "0.9.18" +version = "0.9.19" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1342,11 +1276,11 @@ dependencies = [ "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", "http 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.12.29 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper-tls 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper-rustls 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "mime 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", "mime_guess 2.0.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)", - "native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rustls 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", "serde_urlencoded 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1354,10 +1288,26 @@ dependencies = [ "tokio 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-rustls 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-threadpool 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", + "webpki-roots 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winreg 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ring" +version = "0.14.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1390,41 +1340,35 @@ dependencies = [ ] [[package]] -name = "ryu" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "schannel" -version = "0.1.15" +name = "rustls" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)", + "sct 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "webpki 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "scopeguard" -version = "0.3.3" +name = "ryu" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "security-framework" -version = "0.3.1" +name = "scopeguard" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", - "core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", - "security-framework-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] -name = "security-framework-sys" -version = "0.3.1" +name = "sct" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)", + "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1526,6 +1470,25 @@ name = "smallvec" version = "0.6.10" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "snafu" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "backtrace 0.3.30 (registry+https://github.com/rust-lang/crates.io-index)", + "snafu-derive 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "snafu-derive" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.35 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "spectral" version = "0.6.0" @@ -1534,6 +1497,11 @@ dependencies = [ "num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "spin" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "stable_deref_trait" version = "1.1.1" @@ -1621,19 +1589,6 @@ dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "tempfile" -version = "3.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)", - "remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "termion" version = "1.5.2" @@ -1754,6 +1709,17 @@ dependencies = [ "tokio-sync 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "tokio-rustls" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", + "rustls 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "webpki 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "tokio-sync" version = "0.1.6" @@ -1891,6 +1857,11 @@ name = "unicode-xid" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "untrusted" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "url" version = "1.7.2" @@ -1914,11 +1885,6 @@ dependencies = [ "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "vcpkg" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "vec_map" version = "0.8.1" @@ -1939,6 +1905,24 @@ dependencies = [ "try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "webpki" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)", + "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "webpki-roots" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "webpki 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "winapi" version = "0.2.8" @@ -1968,16 +1952,26 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "winreg" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "woodchipper" version = "0.1.0" dependencies = [ "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "clipboard 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "crossterm 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "dtparse 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "env_proxy 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "jsonpath 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1985,12 +1979,13 @@ dependencies = [ "pest_derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "reqwest 0.9.18 (registry+https://github.com/rust-lang/crates.io-index)", + "reqwest 0.9.19 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", "serde_yaml 0.8.9 (registry+https://github.com/rust-lang/crates.io-index)", "shellexpand 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "simple-error 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "snafu 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "spectral 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "structopt 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", "subprocess 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2058,8 +2053,6 @@ dependencies = [ "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" "checksum cookie 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "888604f00b3db336d2af898ec3c1d5d0ddf5e6d462220f2ededc33a87ac4bbd5" "checksum cookie_store 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46750b3f362965f197996c4448e4a0935e791bf7d6631bfce9ee0af3d24c919c" -"checksum core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "25b9e03f145fd4f2bf705e07b900cd41fc636598fe5dc452fd0db1441c3f496d" -"checksum core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b" "checksum crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb" "checksum crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" "checksum crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b18cd2e169ad86297e6bc0ad9aa679aee9daa4f19e8163860faf7c164e4f5a71" @@ -2075,11 +2068,13 @@ dependencies = [ "checksum crossterm_terminal 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f1b61af4ef3ed3624994e8af7ac87b6a483c2936e63eebe38d9a2810cd4a6d44" "checksum crossterm_utils 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d26f24386ea91f9c55a85531dd3ee3673e4c82729e64567928665aca3a47c741" "checksum crossterm_winapi 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c061e4a1c47a53952ba0f2396c00a61cd7ab74482eba99b9c9cc77fdca71932" +"checksum ct-logs 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1b4660f8b07a560a88c02d76286edb9f0d5d64e495d2b0f233186155aa51be1f" "checksum digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05f47366984d3ad862010e22c7ce81a7dbcaebbdfb37241a620f8b6596ee135c" "checksum dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ea57b42383d091c85abcc2706240b94ab2a8fa1fc81c10ff23c4de06e2a90b5e" "checksum dtparse 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8205e3ae069632bf120c90c50db817d9200ba3719eb9384fd1a63a872602a2c5" "checksum either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5527cfe0d098f36e3f8839852688e63c8fff1c90b2b405aef730615f9a7bcf7b" "checksum encoding_rs 0.8.17 (registry+https://github.com/rust-lang/crates.io-index)" = "4155785c79f2f6701f185eb2e6b4caf0555ec03477cb4c70db67b465311620ed" +"checksum env_proxy 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "700798562fcbc0a4c89546df5dfa8586e82345026e3992242646d527dec948e4" "checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3" "checksum error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3ab49e9dcb602294bc42f9a7dfc9bc6e936fca4418ea300dbfb84fe16de0b7d9" "checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2" @@ -2087,8 +2082,6 @@ dependencies = [ "checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" "checksum flate2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f87e68aa82b2de08a6e037f1385455759df6e445a8df5e005b4297191dbf18aa" "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" -"checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -"checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" "checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" @@ -2101,7 +2094,7 @@ dependencies = [ "checksum http-body 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d" "checksum httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e8734b0cfd3bc3e101ec59100e101c2eecd19282202e87808b3037b442777a83" "checksum hyper 0.12.29 (registry+https://github.com/rust-lang/crates.io-index)" = "e2cd6adf83b3347d36e271f030621a8cf95fd1fd0760546b9fc5a24a0f1447c7" -"checksum hyper-tls 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3a800d6aa50af4b5850b2b0f659625ce9504df908e9733b635720483be26174f" +"checksum hyper-rustls 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)" = "15b66d1bd4864ef036adf2363409caa3acd63ebb4725957b66e621c8a36631a3" "checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" "checksum indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d" "checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" @@ -2124,7 +2117,6 @@ dependencies = [ "checksum miniz_oxide_c_api 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b7fe927a42e3807ef71defb191dc87d4e24479b221e67015fe38ae2b7b447bab" "checksum mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)" = "83f51996a3ed004ef184e16818edc51fadffe8e7ca68be67f9dee67d84d0ff23" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" -"checksum native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4b2df1a4c22fd44a62147fd8f13dd0f95c9d8ca7b2610299b2a2f9cf8964274e" "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" "checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" "checksum num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "4703ad64153382334aa8db57c637364c322d3372e097840c72000dabdcf6156e" @@ -2144,9 +2136,6 @@ dependencies = [ "checksum objc-foundation 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" "checksum objc_id 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" "checksum opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "93f5bb2e8e8dec81642920ccff6b61f1eb94fa3020c5a325c9851ff604152409" -"checksum openssl 0.10.23 (registry+https://github.com/rust-lang/crates.io-index)" = "97c140cbb82f3b3468193dd14c1b88def39f341f68257f8a7fe8ed9ed3f628a5" -"checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" -"checksum openssl-sys 0.9.47 (registry+https://github.com/rust-lang/crates.io-index)" = "75bdd6dbbb4958d38e47a1d2348847ad1eb4dc205dc5d37473ae504391865acc" "checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13" "checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337" "checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9" @@ -2161,7 +2150,6 @@ dependencies = [ "checksum phf_codegen 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "b03e85129e324ad4166b06b2c7491ae27fe3ec353af72e72cd1654c7225d517e" "checksum phf_generator 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "09364cc93c159b8b06b1f4dd8a4398984503483891b0c26b867cf431fb132662" "checksum phf_shared 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "234f71a15de2288bcb7e3b6515828d22af7ec8598ee6d24c3b526fa0a80b67a0" -"checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c" "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" "checksum publicsuffix 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5afecba86dcf1e4fd610246f89899d1924fe12e1e89f555eb7c7f710f3c5ad1d" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" @@ -2182,17 +2170,16 @@ dependencies = [ "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" "checksum regex 1.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "0b2f0808e7d7e4fb1cb07feb6ff2f4bc827938f24f8c2e6a3beb7370af544bdd" "checksum regex-syntax 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9d76410686f9e3a17f06128962e0ecc5755870bb890c34820c7af7f1db2e1d48" -"checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" -"checksum reqwest 0.9.18 (registry+https://github.com/rust-lang/crates.io-index)" = "00eb63f212df0e358b427f0f40aa13aaea010b470be642ad422bcbca2feff2e4" +"checksum reqwest 0.9.19 (registry+https://github.com/rust-lang/crates.io-index)" = "1d0777154c2c3eb54f5c480db01de845652d941e47191277cc673634c3853939" +"checksum ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)" = "426bc186e3e95cac1e4a4be125a4aca7e84c2d616ffc02244eef36e2a60a093c" "checksum rust_decimal 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a93c95e3d5c1d997e6e4ba9bda898f4e1d73934cd05510c972f10087d0ef00c1" "checksum rustc-demangle 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "a7f4dccf6f4891ebcc0c39f9b6eb1a83b9bf5d747cb439ec6fba4f3b977038af" "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +"checksum rustls 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f271e3552cd835fa28c541c34a7e8fdd8cdff09d77fe4eb8f6c42e87a11b096e" "checksum ryu 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "b96a9549dc8d48f2c283938303c4b5a77aa29bfbc5b54b084fb1630408899a8f" -"checksum schannel 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "f2f6abf258d99c3c1c5c2131d99d064e94b7b3dd5f416483057f308fea253339" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" -"checksum security-framework 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eee63d0f4a9ec776eeb30e220f0bc1e092c3ad744b2a379e3993070364d3adc2" -"checksum security-framework-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9636f8989cbf61385ae4824b98c1aaa54c994d7d8b41f11c601ed799f0549a56" +"checksum sct 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f5adf8fbd58e1b1b52699dc8bed2630faecb6d8c7bee77d009d6bbe4af569b9" "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" "checksum serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)" = "32746bf0f26eab52f06af0d0aa1984f641341d06d8d673c693871da2d188c9be" @@ -2206,7 +2193,10 @@ dependencies = [ "checksum siphasher 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac" "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" "checksum smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ab606a9c5e214920bb66c458cd7be8ef094f813f20fe77a54cc7dbfff220d4b7" +"checksum snafu 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5712353226e5ccb06c8f9b1cab819654b25514479523755ffa94703ceeb00e4f" +"checksum snafu-derive 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "78178fb0042da2d70bba6e3fb26b6412c4824a22b7fe434f5e082d2ca0b894ee" "checksum spectral 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ae3c15181f4b14e52eeaac3efaeec4d2764716ce9c86da0c934c3e318649c5ba" +"checksum spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44363f6f51401c34e7be73db0db371c04705d35efbe9f7d6082e03a921a32c55" "checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" "checksum string 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0bbfb8937e38e34c3444ff00afb28b0811d9554f15c5ad64d12b0308d1d1995" "checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" @@ -2217,7 +2207,6 @@ dependencies = [ "checksum syn 0.15.35 (registry+https://github.com/rust-lang/crates.io-index)" = "641e117d55514d6d918490e47102f7e08d096fdde360247e4a10f7a91a8478d3" "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" "checksum synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f" -"checksum tempfile 3.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7dc4738f2e68ed2855de5ac9cdbe05c9216773ecde4739b2f095002ab03a13ef" "checksum termion 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dde0593aeb8d47accea5392b39350015b5eccb12c0d98044d856983d89548dea" "checksum termios 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "72b620c5ea021d75a735c943269bb07d30c9b77d6ac6b236bc8b5c496ef05625" "checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" @@ -2229,6 +2218,7 @@ dependencies = [ "checksum tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "83ea44c6c0773cc034771693711c35c677b4b5a4b21b9e7071704c54de7d555e" "checksum tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "5090db468dad16e1a7a54c8c67280c5e4b544f3d3e018f0b913b400261f85926" "checksum tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6af16bfac7e112bea8b0442542161bfc41cbfa4466b580bdda7d18cb88b911ce" +"checksum tokio-rustls 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1600e90b2602df28ff54ae842519b408fbb25378c3c5aee1b795593e9263dc80" "checksum tokio-sync 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2162248ff317e2bc713b261f242b69dbb838b85248ed20bb21df56d60ea4cae7" "checksum tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1d14b10654be682ac43efee27401d792507e30fd8d26389e1da3b185de2e4119" "checksum tokio-threadpool 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "72558af20be886ea124595ea0f806dd5703b8958e4705429dd58b3d8231f72f2" @@ -2247,18 +2237,21 @@ dependencies = [ "checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" "checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" +"checksum untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "55cd1f4b4e96b46aeb8d4855db4a7a9bd96eeeb5c6a1ab54593328761642ce2f" "checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" "checksum utf8-ranges 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9d50aa7650df78abf942826607c62468ce18d9019673d4a2ebe1865dbb96ffde" "checksum uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "90dbc611eb48397705a6b0f6e917da23ae517e4d127123d2cf7674206627d32a" -"checksum vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "def296d3eb3b12371b2c7d0e83bfe1403e4db2d7a0bba324a12b21c4ee13143d" "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" "checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" "checksum want 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "797464475f30ddb8830cc529aaaae648d581f99e2036a928877dfde027ddf6b3" +"checksum webpki 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4f7e1cd7900a3a6b65a3e8780c51a3e6b59c0e2c55c6dc69578c288d69f7d082" +"checksum webpki-roots 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c10fa4212003ba19a564f25cd8ab572c6791f99a03cc219c13ed35ccab00de0e" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" "checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770" "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +"checksum winreg 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73f1f3c6c4d3cab118551b96c476a2caab920701e28875b64a458f2ecb96ec9d" "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" "checksum x11-clipboard 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3a77356335a1398267e15a7c1d5fa1c8d3fdb3e5ba2e381407d74482c29587d3" "checksum xcb 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5e917a3f24142e9ff8be2414e36c649d47d6cc2ba81f16201cdef96e533e02de" diff --git a/Cargo.toml b/Cargo.toml index a5dfe12..27bf20c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,11 +33,14 @@ ansi_term = "0.11.0" shellexpand = "1.0.0" atty = "0.2.11" jsonpath = "0.1.1" -reqwest = "0.9" +reqwest = { version = "0.9", features = ["rustls-tls"], default-features = false } rand = "0.6" subprocess = "0.1" pest = "2.1" pest_derive = "2.1" +env_proxy = "0.3" +snafu = "0.4" +base64 = "0.10" [target.'cfg(not(target_env = "musl"))'.dependencies] clipboard = "0.5.0" diff --git a/src/reader/kubernetes/kubeconfig.rs b/src/reader/kubernetes/kubeconfig.rs new file mode 100644 index 0000000..c8a898a --- /dev/null +++ b/src/reader/kubernetes/kubeconfig.rs @@ -0,0 +1,750 @@ +// (C) Copyright 2019 Hewlett Packard Enterprise Development LP + +use std::collections::HashMap; +use std::fmt; +use std::fs::File; +use std::io::{BufReader, Read}; +use std::ops::Deref; +use std::path::{Path, PathBuf}; + +use base64; +use chrono::{DateTime, offset::Utc}; +use reqwest::{ + Certificate, Client, ClientBuilder, RequestBuilder, Identity, IntoUrl, + header::{AUTHORIZATION, HeaderValue, HeaderMap} +}; +use serde::Deserialize; +use serde::de::{self, Visitor, Deserializer}; +use serde_json::Value; +use snafu::{ensure, ResultExt, Snafu}; +use subprocess; + +#[derive(Debug, Snafu)] +pub enum Error { + #[snafu(display( + "unable to read kubeconfig at {}: {}", + path.display(), source + ))] + ConfigRead { + path: PathBuf, + source: std::io::Error + }, + + #[snafu(display( + "unable to deserialize kubeconfig at {}: {}", + path.display(), source + ))] + ConfigDeserialize { + path: PathBuf, + source: serde_yaml::Error + }, + + #[snafu(display( + "context missing in kubeconfig at {}: {:?}", + path.display(), context + ))] + ContextNotFound { + path: PathBuf, + context: Option + }, + + #[snafu(display( + "could not add auth header: {}", message + ))] + InvalidAuthHeader { + message: String + }, + + #[snafu(display( + "client certificate is invalid: {}", source + ))] + InvalidIdentity { + source: reqwest::Error + }, + + #[snafu(display( + "unable to initialize reqwest client: {}", source + ))] + ReqwestInit { + source: reqwest::Error + }, + + #[snafu(display( + "error executing auth plugin {}: {}", + command, source + ))] + AuthPluginExecError { + command: String, + source: subprocess::PopenError + }, + + #[snafu(display( + "error from auth plugin {}: {}", + command, message + ))] + AuthPluginError { + command: String, + message: String + }, + + #[snafu(display( + "error deserializing result from auth plugin {}: {}", + command, source + ))] + AuthPluginDeserialize { + command: String, + source: serde_yaml::Error + }, + + #[snafu(display( + "error converting pem to der" + ))] + CertificateConversionError { + message: String + }, + + #[snafu(display( + "certificate could not be parsed from {}: {}", + context, source + ))] + InvalidCertificate { + context: String, + source: reqwest::Error + } +} + +/// "Alias" for Vec to avoid puking raw cert data on Debug +#[derive(Clone)] +pub struct Bytes(Vec); + +impl Deref for Bytes { + type Target = [u8]; + + fn deref(&self) -> &[u8] { + &self.0 + } +} + +impl fmt::Debug for Bytes { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "&u8[{}]", self.0.len()) + } +} + +type Result = std::result::Result; + +struct BytesFromPathStr; + +impl<'de> Visitor<'de> for BytesFromPathStr { + type Value = Bytes; + + fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("a string containing a path to an existing file") + } + + fn visit_str(self, s: &str) -> Result + where + E: de::Error + { + match File::open(s) { + Ok(mut file) => { + let mut data = Vec::new(); + + match file.read_to_end(&mut data) { + Ok(_) => Ok(Bytes(data)), + Err(e) => Err(de::Error::custom(format!( + "error reading file at {}: {:?}", s, e + ))) + } + }, + Err(e) => Err(de::Error::custom(format!( + "unable to open file at {}: {:?}", s, e + ))) + } + } +} + +fn de_path_bytes<'de, D>(deserializer: D) -> Result +where + D: Deserializer<'de> +{ + deserializer.deserialize_str(BytesFromPathStr) +} + +struct BytesFromBase64; + +impl<'de> Visitor<'de> for BytesFromBase64 { + type Value = Bytes; + + fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("a string containing base64 data") + } + + fn visit_str(self, s: &str) -> Result + where + E: de::Error + { + match base64::decode(s) { + Ok(data) => { + Ok(Bytes(data)) + }, + Err(e) => Err(de::Error::custom(format!( + "unable to decode base64 string: {:?}", e + ))) + } + } +} + +fn de_base64_bytes<'de, D>(deserializer: D) -> Result +where + D: Deserializer<'de> +{ + deserializer.deserialize_str(BytesFromBase64) +} + +struct BytesFromStr; + +impl<'de> Visitor<'de> for BytesFromStr { + type Value = Bytes; + + fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("a string containing data") + } + + fn visit_str(self, s: &str) -> Result + where + E: de::Error + { + Ok(Bytes(s.bytes().collect())) + } +} + +fn de_str_bytes<'de, D>(deserializer: D) -> Result +where + D: Deserializer<'de> +{ + deserializer.deserialize_str(BytesFromStr) +} + +// https://github.com/vityafx/serde-aux/blob/574574cbb3d38568454707846edd2387bf4b0e48/src/field_attributes.rs#L360-L366 +// (MIT) +fn de_default_from_null<'de, D, T>(deserializer: D) -> Result +where + D: Deserializer<'de>, + T: Deserialize<'de> + Default, +{ + Ok(Option::deserialize(deserializer)?.unwrap_or_default()) +} + +#[derive(Debug, Deserialize, Clone)] +pub struct ClusterCAFile { + #[serde(rename = "certificate-authority", deserialize_with = "de_path_bytes")] + certificate: Bytes +} + +#[derive(Debug, Deserialize, Clone)] +pub struct ClusterCAEmbedded { + #[serde( + rename = "certificate-authority-data", + deserialize_with = "de_base64_bytes" + )] + certificate: Bytes +} + +#[derive(Debug, Deserialize, Clone)] +#[serde(untagged)] +pub enum ClusterCA { + File(ClusterCAFile), + Embedded(ClusterCAEmbedded) +} + +fn default_skip_tls_verify() -> bool { + false +} + +#[serde(rename_all = "kebab-case")] +#[derive(Debug, Deserialize, Clone)] +pub struct Cluster { + server: String, + + #[serde(default = "default_skip_tls_verify")] + insecure_skip_tls_verify: bool, + + #[serde(flatten)] + certificate_authority: Option +} + +#[derive(Debug, Deserialize)] +pub struct ClusterContainer { + pub name: String, + pub cluster: Cluster +} + +#[derive(Debug, Deserialize)] +pub struct Context { + pub cluster: String, + pub namespace: Option, + pub user: String +} + +#[derive(Debug)] +pub struct ResolvedContext<'a> { + pub namespace: &'a str, + pub auth: &'a Auth, + pub cluster: &'a Cluster +} + +#[derive(Debug, Deserialize)] +pub struct ContextContainer { + pub name: String, + pub context: Context +} + +#[derive(Debug, Deserialize, Clone)] +pub struct ExecAuth { + #[serde(rename = "apiVersion")] + pub api_version: String, + pub command: String, + + #[serde(default)] + pub args: Vec, + + #[serde(deserialize_with = "de_default_from_null")] + pub env: HashMap +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct ExecCredentialToken { + token: String, + expiration_timestamp: Option> +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct ExecCredentialCertificateEmbedded { + #[serde(rename = "clientCertificateData", deserialize_with = "de_str_bytes")] + certificate: Bytes, + + #[serde(rename = "clientKeyData", deserialize_with = "de_str_bytes")] + key: Bytes, + + expiration_timestamp: Option> +} + +#[derive(Debug, Deserialize)] +#[serde(untagged)] +pub enum ExecCredentialStatus { + Token(ExecCredentialToken), + CertificateEmbedded(ExecCredentialCertificateEmbedded) +} + +impl ExecCredentialStatus { + pub fn expiration(&self) -> Option> { + match self { + ExecCredentialStatus::CertificateEmbedded(cred) => cred.expiration_timestamp, + ExecCredentialStatus::Token(cred) => cred.expiration_timestamp + } + } +} + +#[derive(Debug, Deserialize)] +pub struct ExecCredential { + #[serde(rename = "apiVersion")] + pub api_version: String, + + pub kind: String, + pub status: ExecCredentialStatus +} + +#[derive(Debug, Deserialize, Clone)] +pub struct AuthPlain { + username: String, + password: String +} + +#[derive(Debug, Deserialize, Clone)] +pub struct AuthToken { + token: String +} + +#[derive(Debug, Deserialize, Clone)] +#[serde(rename_all = "kebab-case")] +pub struct AuthCertificateFile { + #[serde(rename = "client-certificate", deserialize_with = "de_path_bytes")] + certificate: Bytes, + + #[serde(rename = "client-key", deserialize_with = "de_path_bytes")] + key: Bytes +} + +#[derive(Debug, Deserialize, Clone)] +#[serde(rename_all = "kebab-case")] +pub struct AuthCertificateEmbedded { + #[serde( + rename = "client-certificate-data", + deserialize_with = "de_base64_bytes" + )] + certificate: Bytes, + + #[serde( + rename = "client-key-data", + deserialize_with = "de_base64_bytes" + )] + key: Bytes +} + +#[derive(Debug, Deserialize, Clone)] +pub struct AuthExec { + exec: ExecAuth +} + +#[derive(Debug, Deserialize, Clone)] +#[serde(untagged)] +pub enum Auth { + Plain(AuthPlain), + Token(AuthToken), + CertificateFile(AuthCertificateFile), + CertificateEmbedded(AuthCertificateEmbedded), + Exec(AuthExec), + Null +} + +impl Auth { + /// Attempts to retrieve an ExecCredential if this is an Auth::Exec, otherwise + /// returns Some(None) + pub fn exec(&self) -> Result> { + let exec = if let Auth::Exec(exec) = self { + &exec.exec + } else { + return Ok(None); + }; + + let env: Vec<(&str, &str)> = exec.env.iter() + .map(|(k, v)| (k.as_str(), v.as_str())) + .collect(); + + let capture = subprocess::Exec::cmd(&exec.command) + .args(&exec.args) + .env_extend(&env) + .stdout(subprocess::Redirection::Pipe) + .stderr(subprocess::Redirection::Pipe) + .capture() + .context(AuthPluginExecError { command: exec.command.clone() })?; + + if capture.success() { + let creds: ExecCredential = serde_yaml::from_slice(&capture.stdout) + .context(AuthPluginDeserialize { + command: exec.command.clone() + })?; + + Ok(Some(creds)) + } else { + Err(Error::AuthPluginError { + command: exec.command.clone(), + message: capture.stderr_str() + }) + } + } + + /// Attempts to create a reqwest client Identity using the configured auth, + /// if any exists. + pub fn identity(&self) -> Result> { + let (cert, key) = match self { + Auth::CertificateFile(auth) => { + (&auth.certificate, &auth.key) + }, + Auth::CertificateEmbedded(auth) => { + (&auth.certificate, &auth.key) + }, + _ => return Ok(None) + }; + + // reqwest wants these cat'd together + let mut concat = Vec::with_capacity(cert.len() + key.len()); + concat.extend_from_slice(&cert); + concat.extend_from_slice(&key); + + // rustls doesn't support ip address hosts + // - https://github.com/ctz/hyper-rustls/issues/56 + // - https://github.com/ctz/rustls/issues/184 + // - https://github.com/briansmith/webpki/issues/54 + // + // also, native-tls doesn't support PEMs, or at least if it does, reqwest + // doesn't expose that functionality + // + // I think we'll need to keep the kubectl subprocess workaround handy for + // this case since it affects basically all non-cloud kubernetes apis + + Identity::from_pem(&concat).context(InvalidIdentity {}).map(Some) + } + + pub fn token(&self) -> Option<&str> { + match self { + Auth::Token(auth) => { + Some(&auth.token) + }, + _ => None + } + } + + pub fn basic(&self) -> Option { + match self { + Auth::Plain(auth) => { + let bytes: Vec = format!("{}:{}", &auth.username, &auth.password) + .bytes() + .collect(); + + Some(base64::encode(&bytes)) + }, + _ => None + } + } +} + +impl Default for Auth { + fn default() -> Self { + Auth::Null {} + } +} + +impl From for Auth { + fn from(exec: ExecCredential) -> Self { + match exec.status { + ExecCredentialStatus::Token(cred) => { + Auth::Token(AuthToken { token: cred.token }) + }, + ExecCredentialStatus::CertificateEmbedded(cred) => { + Auth::CertificateEmbedded(AuthCertificateEmbedded { + certificate: cred.certificate, + key: cred.key + }) + } + } + } +} + +#[derive(Debug, Deserialize)] +pub struct User { + #[serde(flatten, default)] + pub auth: Auth +} + +impl Default for User { + fn default() -> Self { + User { + auth: Auth::Null {} + } + } +} + +#[derive(Debug, Deserialize)] +pub struct UserContainer { + pub name: String, + + #[serde(default)] + pub user: User +} + +#[derive(Debug, Deserialize)] +pub struct KubernetesConfig { + #[serde(rename = "apiVersion")] + pub api_version: String, + pub kind: String, + + pub clusters: Vec, + pub contexts: Vec, + pub users: Vec, + + #[serde(rename = "current-context")] + pub current_context: Option, + + pub preferences: HashMap +} + +impl KubernetesConfig { + pub fn current_context(&self) -> Option { + let current_context: &str = match &self.current_context { + Some(c) => c, + None => return None + }; + + let context = match self.contexts.iter().find(|c| c.name == current_context) { + Some(c) => &c.context, + None => return None + }; + + let auth = match self.users.iter().find(|u| u.name == context.user) { + Some(u) => &u.user.auth, + None => return None + }; + + let cluster = match self.clusters.iter().find(|c| c.name == context.cluster) { + Some(c) => &c.cluster, + None => return None + }; + + Some(ResolvedContext { + auth, cluster, + + namespace: context.namespace.as_ref().map(String::as_str).unwrap_or("default") + }) + } + + pub fn load

(path: P) -> Result + where + P: AsRef + { + let path = path.as_ref(); + let file = File::open(path).context(ConfigRead { path })?; + let reader = BufReader::new(file); + + serde_yaml::from_reader(reader).context(ConfigDeserialize { path }) + } +} + +#[derive(Debug)] +pub struct KubernetesClient { + server: String, + cluster: Cluster, + auth: Auth, + pub namespace: String, + + client: Client, + + pub auth_expiration: Option> +} + +impl KubernetesClient { + pub fn new( + cluster: Cluster, + auth: Auth, + namespace: &str + ) -> Result { + let mut builder = Client::builder() + .use_rustls_tls() + .use_sys_proxy(); + + if cluster.insecure_skip_tls_verify { + builder = builder.danger_accept_invalid_certs(true); + } + + // do some basic cleanup of the server, the k8s api likes to reject calls + // with extra slashes + let server = cluster.server.trim_end_matches('/').to_string(); + + let mut auth_expiration = None; + let runtime_auth = if let Some(exec) = auth.exec()? { + auth_expiration = exec.status.expiration(); + exec.into() + } else { + auth.clone() + }; + + let mut headers = HeaderMap::new(); + if let Some(token) = runtime_auth.token() { + headers.insert( + AUTHORIZATION, + HeaderValue::from_str(&format!("Bearer {}", token)).map_err(|e| { + Error::InvalidAuthHeader { + message: e.to_string() + } + })? + ); + } else if let Some(basic) = runtime_auth.basic() { + headers.insert( + AUTHORIZATION, + HeaderValue::from_str(&format!("Basic {}", basic)).map_err(|e| { + Error::InvalidAuthHeader { + message: e.to_string() + } + })? + ); + } + + builder = builder.default_headers(headers); + + if let Some(identity) = runtime_auth.identity()? { + builder = builder.identity(identity); + } + + match &cluster.certificate_authority { + Some(ClusterCA::File(ca)) => { + let cert = Certificate::from_pem(&ca.certificate) + .context(InvalidCertificate { + context: "certificate-authority".to_owned() + })?; + + builder = builder.add_root_certificate(cert); + }, + Some(ClusterCA::Embedded(ca)) => { + let cert = Certificate::from_pem(&ca.certificate) + .context(InvalidCertificate { + context: "certificate-authority-data".to_owned() + })?; + + builder = builder.add_root_certificate(cert); + }, + _ => () + }; + + // initialize the client with the original auth (possibly exec) so we can + // re-auth later if necessary (expired token, etc) + let client = KubernetesClient { + server, cluster, auth, auth_expiration, + namespace: namespace.to_owned(), + client: builder.build().context(ReqwestInit {})? + }; + + Ok(client) + } + + /// Creates a new KubernetesClient from a ResolvedContext + pub fn from_context(context: &ResolvedContext) -> Result { + KubernetesClient::new( + context.cluster.clone(), + context.auth.clone(), + context.namespace + ) + } + + /// If the current auth method has some expiration timestamp, returns true if + /// the current credentials have expired. + /// + /// New credentials can be acquired using `KubernetesClient::reauth()`. At the + /// moment, only Exec credentials can expire. + pub fn is_expired(&self) -> bool { + if let Some(expiration) = self.auth_expiration { + expiration < Utc::now() + } else { + false + } + } + + /// Consumes this KubernetesClient to create a new client instance, + /// potentially refreshing expired credentials depending on the auth type. + /// + /// `KubernetesClient::is_expired()` may be used to check if the current set + /// of credentials has expired. + pub fn reauthenticate(self) -> Result { + KubernetesClient::new( + self.cluster, + self.auth, + &self.namespace + ) + } + + pub fn get>(&self, path: S) -> RequestBuilder { + self.client.get(&format!( + "{}/{}", + self.server, path.into().trim_start_matches('/') + )) + } + + pub fn post>(&self, path: S) -> RequestBuilder { + self.client.post(&format!( + "{}/{}", + self.server, path.into().trim_start_matches('/') + )) + } +} diff --git a/src/reader/kubernetes.rs b/src/reader/kubernetes/kubernetes.rs similarity index 100% rename from src/reader/kubernetes.rs rename to src/reader/kubernetes/kubernetes.rs diff --git a/src/reader/kubernetes/mod.rs b/src/reader/kubernetes/mod.rs new file mode 100644 index 0000000..f13935f --- /dev/null +++ b/src/reader/kubernetes/mod.rs @@ -0,0 +1,5 @@ +// (C) Copyright 2019 Hewlett Packard Enterprise Development LP +mod kubernetes; +pub mod kubeconfig; + +pub use kubernetes::*;