├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── Makefile ├── NOTICE ├── README.markdown ├── docs └── diplomat-internals.graffle ├── etc └── test.config.normal.toml ├── scripts ├── generate-api-mod ├── install-openssl-linux └── install-protobuf-linux └── src ├── config.rs ├── config_test.rs ├── consul ├── catalog.rs ├── errors.rs ├── kv.rs ├── mod.rs └── request.rs ├── main.rs └── server ├── eds.rs └── mod.rs /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | **/*.rs.bk 3 | .DS_Store 4 | vendor 5 | Cargo.lock 6 | src/api/*.rs 7 | diplomat 8 | *.tar.gz 9 | *.zip 10 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | [root] 2 | name = "diplomat" 3 | version = "0.1.0" 4 | dependencies = [ 5 | "cargo-watch 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 6 | "clap 2.26.2 (registry+https://github.com/rust-lang/crates.io-index)", 7 | "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", 8 | "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", 9 | "futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", 10 | "futures-cpupool 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 11 | "grpcio 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 12 | "grpcio-compiler 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 13 | "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 14 | "lru_time_cache 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 15 | "md5 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", 16 | "protobuf 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", 17 | "reqwest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", 18 | "serde 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)", 19 | "serde_derive 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)", 20 | "serde_json 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", 21 | "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", 22 | "url 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 23 | ] 24 | 25 | [[package]] 26 | name = "adler32" 27 | version = "1.0.2" 28 | source = "registry+https://github.com/rust-lang/crates.io-index" 29 | 30 | [[package]] 31 | name = "advapi32-sys" 32 | version = "0.2.0" 33 | source = "registry+https://github.com/rust-lang/crates.io-index" 34 | dependencies = [ 35 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 36 | "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 37 | ] 38 | 39 | [[package]] 40 | name = "aho-corasick" 41 | version = "0.6.3" 42 | source = "registry+https://github.com/rust-lang/crates.io-index" 43 | dependencies = [ 44 | "memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 45 | ] 46 | 47 | [[package]] 48 | name = "ansi_term" 49 | version = "0.9.0" 50 | source = "registry+https://github.com/rust-lang/crates.io-index" 51 | 52 | [[package]] 53 | name = "atty" 54 | version = "0.2.3" 55 | source = "registry+https://github.com/rust-lang/crates.io-index" 56 | dependencies = [ 57 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 58 | "libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", 59 | "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 60 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 61 | ] 62 | 63 | [[package]] 64 | name = "backtrace" 65 | version = "0.3.3" 66 | source = "registry+https://github.com/rust-lang/crates.io-index" 67 | dependencies = [ 68 | "backtrace-sys 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", 69 | "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 70 | "dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 71 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 72 | "libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", 73 | "rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 74 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 75 | ] 76 | 77 | [[package]] 78 | name = "backtrace-sys" 79 | version = "0.1.14" 80 | source = "registry+https://github.com/rust-lang/crates.io-index" 81 | dependencies = [ 82 | "cc 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 83 | "libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", 84 | ] 85 | 86 | [[package]] 87 | name = "base64" 88 | version = "0.6.0" 89 | source = "registry+https://github.com/rust-lang/crates.io-index" 90 | dependencies = [ 91 | "byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 92 | "safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 93 | ] 94 | 95 | [[package]] 96 | name = "bitflags" 97 | version = "0.4.0" 98 | source = "registry+https://github.com/rust-lang/crates.io-index" 99 | 100 | [[package]] 101 | name = "bitflags" 102 | version = "0.7.0" 103 | source = "registry+https://github.com/rust-lang/crates.io-index" 104 | 105 | [[package]] 106 | name = "bitflags" 107 | version = "0.9.1" 108 | source = "registry+https://github.com/rust-lang/crates.io-index" 109 | 110 | [[package]] 111 | name = "byteorder" 112 | version = "1.1.0" 113 | source = "registry+https://github.com/rust-lang/crates.io-index" 114 | 115 | [[package]] 116 | name = "bytes" 117 | version = "0.3.0" 118 | source = "registry+https://github.com/rust-lang/crates.io-index" 119 | 120 | [[package]] 121 | name = "bytes" 122 | version = "0.4.5" 123 | source = "registry+https://github.com/rust-lang/crates.io-index" 124 | dependencies = [ 125 | "byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 126 | "iovec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 127 | ] 128 | 129 | [[package]] 130 | name = "cargo-watch" 131 | version = "6.0.0" 132 | source = "registry+https://github.com/rust-lang/crates.io-index" 133 | dependencies = [ 134 | "clap 2.26.2 (registry+https://github.com/rust-lang/crates.io-index)", 135 | "watchexec 1.8.5 (registry+https://github.com/rust-lang/crates.io-index)", 136 | ] 137 | 138 | [[package]] 139 | name = "cc" 140 | version = "1.0.0" 141 | source = "registry+https://github.com/rust-lang/crates.io-index" 142 | 143 | [[package]] 144 | name = "cfg-if" 145 | version = "0.1.2" 146 | source = "registry+https://github.com/rust-lang/crates.io-index" 147 | 148 | [[package]] 149 | name = "clap" 150 | version = "2.26.2" 151 | source = "registry+https://github.com/rust-lang/crates.io-index" 152 | dependencies = [ 153 | "ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", 154 | "atty 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 155 | "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", 156 | "strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", 157 | "term_size 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 158 | "textwrap 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", 159 | "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 160 | "vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", 161 | ] 162 | 163 | [[package]] 164 | name = "cmake" 165 | version = "0.1.26" 166 | source = "registry+https://github.com/rust-lang/crates.io-index" 167 | dependencies = [ 168 | "cc 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 169 | ] 170 | 171 | [[package]] 172 | name = "conv" 173 | version = "0.3.3" 174 | source = "registry+https://github.com/rust-lang/crates.io-index" 175 | dependencies = [ 176 | "custom_derive 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", 177 | ] 178 | 179 | [[package]] 180 | name = "core-foundation" 181 | version = "0.2.3" 182 | source = "registry+https://github.com/rust-lang/crates.io-index" 183 | dependencies = [ 184 | "core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 185 | "libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", 186 | ] 187 | 188 | [[package]] 189 | name = "core-foundation-sys" 190 | version = "0.2.3" 191 | source = "registry+https://github.com/rust-lang/crates.io-index" 192 | dependencies = [ 193 | "libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", 194 | ] 195 | 196 | [[package]] 197 | name = "crypt32-sys" 198 | version = "0.2.0" 199 | source = "registry+https://github.com/rust-lang/crates.io-index" 200 | dependencies = [ 201 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 202 | "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 203 | ] 204 | 205 | [[package]] 206 | name = "custom_derive" 207 | version = "0.1.7" 208 | source = "registry+https://github.com/rust-lang/crates.io-index" 209 | 210 | [[package]] 211 | name = "dbghelp-sys" 212 | version = "0.2.0" 213 | source = "registry+https://github.com/rust-lang/crates.io-index" 214 | dependencies = [ 215 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 216 | "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 217 | ] 218 | 219 | [[package]] 220 | name = "dtoa" 221 | version = "0.4.2" 222 | source = "registry+https://github.com/rust-lang/crates.io-index" 223 | 224 | [[package]] 225 | name = "env_logger" 226 | version = "0.4.3" 227 | source = "registry+https://github.com/rust-lang/crates.io-index" 228 | dependencies = [ 229 | "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 230 | "regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 231 | ] 232 | 233 | [[package]] 234 | name = "error-chain" 235 | version = "0.11.0" 236 | source = "registry+https://github.com/rust-lang/crates.io-index" 237 | dependencies = [ 238 | "backtrace 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 239 | ] 240 | 241 | [[package]] 242 | name = "filetime" 243 | version = "0.1.12" 244 | source = "registry+https://github.com/rust-lang/crates.io-index" 245 | dependencies = [ 246 | "libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", 247 | "redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", 248 | ] 249 | 250 | [[package]] 251 | name = "fnv" 252 | version = "1.0.5" 253 | source = "registry+https://github.com/rust-lang/crates.io-index" 254 | 255 | [[package]] 256 | name = "foreign-types" 257 | version = "0.2.0" 258 | source = "registry+https://github.com/rust-lang/crates.io-index" 259 | 260 | [[package]] 261 | name = "fsevent" 262 | version = "0.2.16" 263 | source = "registry+https://github.com/rust-lang/crates.io-index" 264 | dependencies = [ 265 | "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 266 | "fsevent-sys 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 267 | "libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", 268 | ] 269 | 270 | [[package]] 271 | name = "fsevent-sys" 272 | version = "0.1.6" 273 | source = "registry+https://github.com/rust-lang/crates.io-index" 274 | dependencies = [ 275 | "libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", 276 | ] 277 | 278 | [[package]] 279 | name = "futures" 280 | version = "0.1.16" 281 | source = "registry+https://github.com/rust-lang/crates.io-index" 282 | 283 | [[package]] 284 | name = "futures-cpupool" 285 | version = "0.1.6" 286 | source = "registry+https://github.com/rust-lang/crates.io-index" 287 | dependencies = [ 288 | "futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", 289 | "num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 290 | ] 291 | 292 | [[package]] 293 | name = "gcc" 294 | version = "0.3.54" 295 | source = "registry+https://github.com/rust-lang/crates.io-index" 296 | 297 | [[package]] 298 | name = "glob" 299 | version = "0.2.11" 300 | source = "registry+https://github.com/rust-lang/crates.io-index" 301 | 302 | [[package]] 303 | name = "globset" 304 | version = "0.2.0" 305 | source = "registry+https://github.com/rust-lang/crates.io-index" 306 | dependencies = [ 307 | "aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", 308 | "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", 309 | "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 310 | "memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 311 | "regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 312 | ] 313 | 314 | [[package]] 315 | name = "grpcio" 316 | version = "0.1.1" 317 | source = "registry+https://github.com/rust-lang/crates.io-index" 318 | dependencies = [ 319 | "futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", 320 | "grpcio-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 321 | "libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", 322 | "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 323 | "protobuf 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", 324 | ] 325 | 326 | [[package]] 327 | name = "grpcio-compiler" 328 | version = "0.1.0" 329 | source = "registry+https://github.com/rust-lang/crates.io-index" 330 | dependencies = [ 331 | "protobuf 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", 332 | ] 333 | 334 | [[package]] 335 | name = "grpcio-sys" 336 | version = "0.1.1" 337 | source = "registry+https://github.com/rust-lang/crates.io-index" 338 | dependencies = [ 339 | "cmake 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", 340 | "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", 341 | "libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", 342 | "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", 343 | ] 344 | 345 | [[package]] 346 | name = "httparse" 347 | version = "1.2.3" 348 | source = "registry+https://github.com/rust-lang/crates.io-index" 349 | 350 | [[package]] 351 | name = "hyper" 352 | version = "0.11.6" 353 | source = "registry+https://github.com/rust-lang/crates.io-index" 354 | dependencies = [ 355 | "base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", 356 | "bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", 357 | "futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", 358 | "futures-cpupool 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 359 | "httparse 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 360 | "language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 361 | "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 362 | "mime 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", 363 | "percent-encoding 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 364 | "relay 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 365 | "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", 366 | "tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 367 | "tokio-io 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 368 | "tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 369 | "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 370 | "unicase 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 371 | ] 372 | 373 | [[package]] 374 | name = "hyper-tls" 375 | version = "0.1.2" 376 | source = "registry+https://github.com/rust-lang/crates.io-index" 377 | dependencies = [ 378 | "futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", 379 | "hyper 0.11.6 (registry+https://github.com/rust-lang/crates.io-index)", 380 | "native-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 381 | "tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 382 | "tokio-io 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 383 | "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 384 | "tokio-tls 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 385 | ] 386 | 387 | [[package]] 388 | name = "idna" 389 | version = "0.1.4" 390 | source = "registry+https://github.com/rust-lang/crates.io-index" 391 | dependencies = [ 392 | "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 393 | "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", 394 | "unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 395 | ] 396 | 397 | [[package]] 398 | name = "inotify" 399 | version = "0.3.0" 400 | source = "registry+https://github.com/rust-lang/crates.io-index" 401 | dependencies = [ 402 | "libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", 403 | ] 404 | 405 | [[package]] 406 | name = "iovec" 407 | version = "0.1.1" 408 | source = "registry+https://github.com/rust-lang/crates.io-index" 409 | dependencies = [ 410 | "libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", 411 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 412 | ] 413 | 414 | [[package]] 415 | name = "itoa" 416 | version = "0.3.4" 417 | source = "registry+https://github.com/rust-lang/crates.io-index" 418 | 419 | [[package]] 420 | name = "kernel32-sys" 421 | version = "0.2.2" 422 | source = "registry+https://github.com/rust-lang/crates.io-index" 423 | dependencies = [ 424 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 425 | "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 426 | ] 427 | 428 | [[package]] 429 | name = "language-tags" 430 | version = "0.2.2" 431 | source = "registry+https://github.com/rust-lang/crates.io-index" 432 | 433 | [[package]] 434 | name = "lazy_static" 435 | version = "0.2.9" 436 | source = "registry+https://github.com/rust-lang/crates.io-index" 437 | 438 | [[package]] 439 | name = "lazycell" 440 | version = "0.5.1" 441 | source = "registry+https://github.com/rust-lang/crates.io-index" 442 | 443 | [[package]] 444 | name = "libc" 445 | version = "0.2.32" 446 | source = "registry+https://github.com/rust-lang/crates.io-index" 447 | 448 | [[package]] 449 | name = "libflate" 450 | version = "0.1.11" 451 | source = "registry+https://github.com/rust-lang/crates.io-index" 452 | dependencies = [ 453 | "adler32 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 454 | "byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 455 | ] 456 | 457 | [[package]] 458 | name = "log" 459 | version = "0.3.8" 460 | source = "registry+https://github.com/rust-lang/crates.io-index" 461 | 462 | [[package]] 463 | name = "lru_time_cache" 464 | version = "0.7.0" 465 | source = "registry+https://github.com/rust-lang/crates.io-index" 466 | 467 | [[package]] 468 | name = "magenta" 469 | version = "0.1.1" 470 | source = "registry+https://github.com/rust-lang/crates.io-index" 471 | dependencies = [ 472 | "conv 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 473 | "magenta-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 474 | ] 475 | 476 | [[package]] 477 | name = "magenta-sys" 478 | version = "0.1.1" 479 | source = "registry+https://github.com/rust-lang/crates.io-index" 480 | dependencies = [ 481 | "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 482 | ] 483 | 484 | [[package]] 485 | name = "matches" 486 | version = "0.1.6" 487 | source = "registry+https://github.com/rust-lang/crates.io-index" 488 | 489 | [[package]] 490 | name = "md5" 491 | version = "0.3.5" 492 | source = "registry+https://github.com/rust-lang/crates.io-index" 493 | 494 | [[package]] 495 | name = "memchr" 496 | version = "1.0.1" 497 | source = "registry+https://github.com/rust-lang/crates.io-index" 498 | dependencies = [ 499 | "libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", 500 | ] 501 | 502 | [[package]] 503 | name = "mime" 504 | version = "0.3.4" 505 | source = "registry+https://github.com/rust-lang/crates.io-index" 506 | dependencies = [ 507 | "unicase 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 508 | ] 509 | 510 | [[package]] 511 | name = "mime_guess" 512 | version = "2.0.0-alpha.2" 513 | source = "registry+https://github.com/rust-lang/crates.io-index" 514 | dependencies = [ 515 | "mime 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", 516 | "phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", 517 | "phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", 518 | "unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 519 | ] 520 | 521 | [[package]] 522 | name = "mio" 523 | version = "0.5.1" 524 | source = "registry+https://github.com/rust-lang/crates.io-index" 525 | dependencies = [ 526 | "bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 527 | "libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", 528 | "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 529 | "miow 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 530 | "net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", 531 | "nix 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 532 | "slab 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 533 | "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", 534 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 535 | ] 536 | 537 | [[package]] 538 | name = "mio" 539 | version = "0.6.10" 540 | source = "registry+https://github.com/rust-lang/crates.io-index" 541 | dependencies = [ 542 | "iovec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 543 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 544 | "lazycell 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 545 | "libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", 546 | "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 547 | "magenta 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 548 | "magenta-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 549 | "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 550 | "net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", 551 | "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 552 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 553 | ] 554 | 555 | [[package]] 556 | name = "miow" 557 | version = "0.1.5" 558 | source = "registry+https://github.com/rust-lang/crates.io-index" 559 | dependencies = [ 560 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 561 | "net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", 562 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 563 | "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 564 | ] 565 | 566 | [[package]] 567 | name = "miow" 568 | version = "0.2.1" 569 | source = "registry+https://github.com/rust-lang/crates.io-index" 570 | dependencies = [ 571 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 572 | "net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", 573 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 574 | "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 575 | ] 576 | 577 | [[package]] 578 | name = "native-tls" 579 | version = "0.1.4" 580 | source = "registry+https://github.com/rust-lang/crates.io-index" 581 | dependencies = [ 582 | "openssl 0.9.19 (registry+https://github.com/rust-lang/crates.io-index)", 583 | "schannel 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 584 | "security-framework 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", 585 | "security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", 586 | "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", 587 | ] 588 | 589 | [[package]] 590 | name = "net2" 591 | version = "0.2.31" 592 | source = "registry+https://github.com/rust-lang/crates.io-index" 593 | dependencies = [ 594 | "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 595 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 596 | "libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", 597 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 598 | "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 599 | ] 600 | 601 | [[package]] 602 | name = "nix" 603 | version = "0.5.1" 604 | source = "registry+https://github.com/rust-lang/crates.io-index" 605 | dependencies = [ 606 | "bitflags 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 607 | "libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", 608 | ] 609 | 610 | [[package]] 611 | name = "nix" 612 | version = "0.9.0" 613 | source = "registry+https://github.com/rust-lang/crates.io-index" 614 | dependencies = [ 615 | "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", 616 | "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 617 | "libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", 618 | "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 619 | ] 620 | 621 | [[package]] 622 | name = "notify" 623 | version = "4.0.1" 624 | source = "registry+https://github.com/rust-lang/crates.io-index" 625 | dependencies = [ 626 | "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 627 | "filetime 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", 628 | "fsevent 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", 629 | "fsevent-sys 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 630 | "inotify 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 631 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 632 | "libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", 633 | "mio 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 634 | "walkdir 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 635 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 636 | ] 637 | 638 | [[package]] 639 | name = "num-traits" 640 | version = "0.1.40" 641 | source = "registry+https://github.com/rust-lang/crates.io-index" 642 | 643 | [[package]] 644 | name = "num_cpus" 645 | version = "1.7.0" 646 | source = "registry+https://github.com/rust-lang/crates.io-index" 647 | dependencies = [ 648 | "libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", 649 | ] 650 | 651 | [[package]] 652 | name = "openssl" 653 | version = "0.9.19" 654 | source = "registry+https://github.com/rust-lang/crates.io-index" 655 | dependencies = [ 656 | "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", 657 | "foreign-types 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 658 | "lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", 659 | "libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", 660 | "openssl-sys 0.9.19 (registry+https://github.com/rust-lang/crates.io-index)", 661 | ] 662 | 663 | [[package]] 664 | name = "openssl-sys" 665 | version = "0.9.19" 666 | source = "registry+https://github.com/rust-lang/crates.io-index" 667 | dependencies = [ 668 | "cc 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 669 | "libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", 670 | "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", 671 | "vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 672 | ] 673 | 674 | [[package]] 675 | name = "percent-encoding" 676 | version = "1.0.0" 677 | source = "registry+https://github.com/rust-lang/crates.io-index" 678 | 679 | [[package]] 680 | name = "phf" 681 | version = "0.7.21" 682 | source = "registry+https://github.com/rust-lang/crates.io-index" 683 | dependencies = [ 684 | "phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", 685 | ] 686 | 687 | [[package]] 688 | name = "phf_codegen" 689 | version = "0.7.21" 690 | source = "registry+https://github.com/rust-lang/crates.io-index" 691 | dependencies = [ 692 | "phf_generator 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", 693 | "phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", 694 | ] 695 | 696 | [[package]] 697 | name = "phf_generator" 698 | version = "0.7.21" 699 | source = "registry+https://github.com/rust-lang/crates.io-index" 700 | dependencies = [ 701 | "phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", 702 | "rand 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", 703 | ] 704 | 705 | [[package]] 706 | name = "phf_shared" 707 | version = "0.7.21" 708 | source = "registry+https://github.com/rust-lang/crates.io-index" 709 | dependencies = [ 710 | "siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 711 | "unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 712 | ] 713 | 714 | [[package]] 715 | name = "pkg-config" 716 | version = "0.3.9" 717 | source = "registry+https://github.com/rust-lang/crates.io-index" 718 | 719 | [[package]] 720 | name = "protobuf" 721 | version = "1.4.1" 722 | source = "registry+https://github.com/rust-lang/crates.io-index" 723 | 724 | [[package]] 725 | name = "quote" 726 | version = "0.3.15" 727 | source = "registry+https://github.com/rust-lang/crates.io-index" 728 | 729 | [[package]] 730 | name = "rand" 731 | version = "0.3.16" 732 | source = "registry+https://github.com/rust-lang/crates.io-index" 733 | dependencies = [ 734 | "libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", 735 | "magenta 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 736 | ] 737 | 738 | [[package]] 739 | name = "redox_syscall" 740 | version = "0.1.31" 741 | source = "registry+https://github.com/rust-lang/crates.io-index" 742 | 743 | [[package]] 744 | name = "redox_termios" 745 | version = "0.1.1" 746 | source = "registry+https://github.com/rust-lang/crates.io-index" 747 | dependencies = [ 748 | "redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", 749 | ] 750 | 751 | [[package]] 752 | name = "regex" 753 | version = "0.2.2" 754 | source = "registry+https://github.com/rust-lang/crates.io-index" 755 | dependencies = [ 756 | "aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", 757 | "memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 758 | "regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", 759 | "thread_local 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", 760 | "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 761 | ] 762 | 763 | [[package]] 764 | name = "regex-syntax" 765 | version = "0.4.1" 766 | source = "registry+https://github.com/rust-lang/crates.io-index" 767 | 768 | [[package]] 769 | name = "relay" 770 | version = "0.1.0" 771 | source = "registry+https://github.com/rust-lang/crates.io-index" 772 | dependencies = [ 773 | "futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", 774 | ] 775 | 776 | [[package]] 777 | name = "reqwest" 778 | version = "0.8.0" 779 | source = "registry+https://github.com/rust-lang/crates.io-index" 780 | dependencies = [ 781 | "bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", 782 | "futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", 783 | "hyper 0.11.6 (registry+https://github.com/rust-lang/crates.io-index)", 784 | "hyper-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 785 | "libflate 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", 786 | "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 787 | "mime_guess 2.0.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)", 788 | "native-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 789 | "serde 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)", 790 | "serde_json 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", 791 | "serde_urlencoded 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 792 | "tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 793 | "tokio-io 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 794 | "tokio-tls 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 795 | "url 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 796 | "uuid 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 797 | ] 798 | 799 | [[package]] 800 | name = "rustc-demangle" 801 | version = "0.1.5" 802 | source = "registry+https://github.com/rust-lang/crates.io-index" 803 | 804 | [[package]] 805 | name = "rustc_version" 806 | version = "0.1.7" 807 | source = "registry+https://github.com/rust-lang/crates.io-index" 808 | dependencies = [ 809 | "semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", 810 | ] 811 | 812 | [[package]] 813 | name = "safemem" 814 | version = "0.2.0" 815 | source = "registry+https://github.com/rust-lang/crates.io-index" 816 | 817 | [[package]] 818 | name = "schannel" 819 | version = "0.1.8" 820 | source = "registry+https://github.com/rust-lang/crates.io-index" 821 | dependencies = [ 822 | "advapi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 823 | "crypt32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 824 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 825 | "lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", 826 | "secur32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 827 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 828 | "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 829 | ] 830 | 831 | [[package]] 832 | name = "scoped-tls" 833 | version = "0.1.0" 834 | source = "registry+https://github.com/rust-lang/crates.io-index" 835 | 836 | [[package]] 837 | name = "secur32-sys" 838 | version = "0.2.0" 839 | source = "registry+https://github.com/rust-lang/crates.io-index" 840 | dependencies = [ 841 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 842 | "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 843 | ] 844 | 845 | [[package]] 846 | name = "security-framework" 847 | version = "0.1.16" 848 | source = "registry+https://github.com/rust-lang/crates.io-index" 849 | dependencies = [ 850 | "core-foundation 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 851 | "core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 852 | "libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", 853 | "security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", 854 | ] 855 | 856 | [[package]] 857 | name = "security-framework-sys" 858 | version = "0.1.16" 859 | source = "registry+https://github.com/rust-lang/crates.io-index" 860 | dependencies = [ 861 | "core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 862 | "libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", 863 | ] 864 | 865 | [[package]] 866 | name = "semver" 867 | version = "0.1.20" 868 | source = "registry+https://github.com/rust-lang/crates.io-index" 869 | 870 | [[package]] 871 | name = "serde" 872 | version = "1.0.15" 873 | source = "registry+https://github.com/rust-lang/crates.io-index" 874 | 875 | [[package]] 876 | name = "serde_derive" 877 | version = "1.0.15" 878 | source = "registry+https://github.com/rust-lang/crates.io-index" 879 | dependencies = [ 880 | "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", 881 | "serde_derive_internals 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", 882 | "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", 883 | ] 884 | 885 | [[package]] 886 | name = "serde_derive_internals" 887 | version = "0.16.0" 888 | source = "registry+https://github.com/rust-lang/crates.io-index" 889 | dependencies = [ 890 | "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", 891 | "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", 892 | ] 893 | 894 | [[package]] 895 | name = "serde_json" 896 | version = "1.0.3" 897 | source = "registry+https://github.com/rust-lang/crates.io-index" 898 | dependencies = [ 899 | "dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 900 | "itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", 901 | "num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", 902 | "serde 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)", 903 | ] 904 | 905 | [[package]] 906 | name = "serde_urlencoded" 907 | version = "0.5.1" 908 | source = "registry+https://github.com/rust-lang/crates.io-index" 909 | dependencies = [ 910 | "dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 911 | "itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", 912 | "serde 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)", 913 | "url 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 914 | ] 915 | 916 | [[package]] 917 | name = "siphasher" 918 | version = "0.2.2" 919 | source = "registry+https://github.com/rust-lang/crates.io-index" 920 | 921 | [[package]] 922 | name = "slab" 923 | version = "0.1.3" 924 | source = "registry+https://github.com/rust-lang/crates.io-index" 925 | 926 | [[package]] 927 | name = "slab" 928 | version = "0.3.0" 929 | source = "registry+https://github.com/rust-lang/crates.io-index" 930 | 931 | [[package]] 932 | name = "slab" 933 | version = "0.4.0" 934 | source = "registry+https://github.com/rust-lang/crates.io-index" 935 | 936 | [[package]] 937 | name = "smallvec" 938 | version = "0.2.1" 939 | source = "registry+https://github.com/rust-lang/crates.io-index" 940 | 941 | [[package]] 942 | name = "strsim" 943 | version = "0.6.0" 944 | source = "registry+https://github.com/rust-lang/crates.io-index" 945 | 946 | [[package]] 947 | name = "syn" 948 | version = "0.11.11" 949 | source = "registry+https://github.com/rust-lang/crates.io-index" 950 | dependencies = [ 951 | "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", 952 | "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", 953 | "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 954 | ] 955 | 956 | [[package]] 957 | name = "synom" 958 | version = "0.11.3" 959 | source = "registry+https://github.com/rust-lang/crates.io-index" 960 | dependencies = [ 961 | "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 962 | ] 963 | 964 | [[package]] 965 | name = "take" 966 | version = "0.1.0" 967 | source = "registry+https://github.com/rust-lang/crates.io-index" 968 | 969 | [[package]] 970 | name = "tempdir" 971 | version = "0.3.5" 972 | source = "registry+https://github.com/rust-lang/crates.io-index" 973 | dependencies = [ 974 | "rand 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", 975 | ] 976 | 977 | [[package]] 978 | name = "term_size" 979 | version = "0.3.0" 980 | source = "registry+https://github.com/rust-lang/crates.io-index" 981 | dependencies = [ 982 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 983 | "libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", 984 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 985 | ] 986 | 987 | [[package]] 988 | name = "termion" 989 | version = "1.5.1" 990 | source = "registry+https://github.com/rust-lang/crates.io-index" 991 | dependencies = [ 992 | "libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", 993 | "redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", 994 | "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 995 | ] 996 | 997 | [[package]] 998 | name = "textwrap" 999 | version = "0.8.0" 1000 | source = "registry+https://github.com/rust-lang/crates.io-index" 1001 | dependencies = [ 1002 | "term_size 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 1003 | "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 1004 | ] 1005 | 1006 | [[package]] 1007 | name = "thread_local" 1008 | version = "0.3.4" 1009 | source = "registry+https://github.com/rust-lang/crates.io-index" 1010 | dependencies = [ 1011 | "lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", 1012 | "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 1013 | ] 1014 | 1015 | [[package]] 1016 | name = "time" 1017 | version = "0.1.38" 1018 | source = "registry+https://github.com/rust-lang/crates.io-index" 1019 | dependencies = [ 1020 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 1021 | "libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", 1022 | "redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", 1023 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 1024 | ] 1025 | 1026 | [[package]] 1027 | name = "tokio-core" 1028 | version = "0.1.10" 1029 | source = "registry+https://github.com/rust-lang/crates.io-index" 1030 | dependencies = [ 1031 | "bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", 1032 | "futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", 1033 | "iovec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 1034 | "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 1035 | "mio 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", 1036 | "scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 1037 | "slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 1038 | "tokio-io 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 1039 | ] 1040 | 1041 | [[package]] 1042 | name = "tokio-io" 1043 | version = "0.1.3" 1044 | source = "registry+https://github.com/rust-lang/crates.io-index" 1045 | dependencies = [ 1046 | "bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", 1047 | "futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", 1048 | "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 1049 | ] 1050 | 1051 | [[package]] 1052 | name = "tokio-proto" 1053 | version = "0.1.1" 1054 | source = "registry+https://github.com/rust-lang/crates.io-index" 1055 | dependencies = [ 1056 | "futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", 1057 | "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 1058 | "net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", 1059 | "rand 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", 1060 | "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 1061 | "smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 1062 | "take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 1063 | "tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 1064 | "tokio-io 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 1065 | "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 1066 | ] 1067 | 1068 | [[package]] 1069 | name = "tokio-service" 1070 | version = "0.1.0" 1071 | source = "registry+https://github.com/rust-lang/crates.io-index" 1072 | dependencies = [ 1073 | "futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", 1074 | ] 1075 | 1076 | [[package]] 1077 | name = "tokio-tls" 1078 | version = "0.1.3" 1079 | source = "registry+https://github.com/rust-lang/crates.io-index" 1080 | dependencies = [ 1081 | "futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", 1082 | "native-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 1083 | "tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 1084 | "tokio-io 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 1085 | ] 1086 | 1087 | [[package]] 1088 | name = "toml" 1089 | version = "0.4.5" 1090 | source = "registry+https://github.com/rust-lang/crates.io-index" 1091 | dependencies = [ 1092 | "serde 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)", 1093 | ] 1094 | 1095 | [[package]] 1096 | name = "unicase" 1097 | version = "1.4.2" 1098 | source = "registry+https://github.com/rust-lang/crates.io-index" 1099 | dependencies = [ 1100 | "version_check 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 1101 | ] 1102 | 1103 | [[package]] 1104 | name = "unicase" 1105 | version = "2.0.0" 1106 | source = "registry+https://github.com/rust-lang/crates.io-index" 1107 | dependencies = [ 1108 | "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", 1109 | ] 1110 | 1111 | [[package]] 1112 | name = "unicode-bidi" 1113 | version = "0.3.4" 1114 | source = "registry+https://github.com/rust-lang/crates.io-index" 1115 | dependencies = [ 1116 | "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 1117 | ] 1118 | 1119 | [[package]] 1120 | name = "unicode-normalization" 1121 | version = "0.1.5" 1122 | source = "registry+https://github.com/rust-lang/crates.io-index" 1123 | 1124 | [[package]] 1125 | name = "unicode-width" 1126 | version = "0.1.4" 1127 | source = "registry+https://github.com/rust-lang/crates.io-index" 1128 | 1129 | [[package]] 1130 | name = "unicode-xid" 1131 | version = "0.0.4" 1132 | source = "registry+https://github.com/rust-lang/crates.io-index" 1133 | 1134 | [[package]] 1135 | name = "unreachable" 1136 | version = "1.0.0" 1137 | source = "registry+https://github.com/rust-lang/crates.io-index" 1138 | dependencies = [ 1139 | "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 1140 | ] 1141 | 1142 | [[package]] 1143 | name = "url" 1144 | version = "1.5.1" 1145 | source = "registry+https://github.com/rust-lang/crates.io-index" 1146 | dependencies = [ 1147 | "idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 1148 | "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 1149 | "percent-encoding 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 1150 | ] 1151 | 1152 | [[package]] 1153 | name = "utf8-ranges" 1154 | version = "1.0.0" 1155 | source = "registry+https://github.com/rust-lang/crates.io-index" 1156 | 1157 | [[package]] 1158 | name = "uuid" 1159 | version = "0.5.1" 1160 | source = "registry+https://github.com/rust-lang/crates.io-index" 1161 | dependencies = [ 1162 | "rand 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", 1163 | ] 1164 | 1165 | [[package]] 1166 | name = "vcpkg" 1167 | version = "0.2.2" 1168 | source = "registry+https://github.com/rust-lang/crates.io-index" 1169 | 1170 | [[package]] 1171 | name = "vec_map" 1172 | version = "0.8.0" 1173 | source = "registry+https://github.com/rust-lang/crates.io-index" 1174 | 1175 | [[package]] 1176 | name = "version_check" 1177 | version = "0.1.3" 1178 | source = "registry+https://github.com/rust-lang/crates.io-index" 1179 | 1180 | [[package]] 1181 | name = "void" 1182 | version = "1.0.2" 1183 | source = "registry+https://github.com/rust-lang/crates.io-index" 1184 | 1185 | [[package]] 1186 | name = "walkdir" 1187 | version = "0.1.8" 1188 | source = "registry+https://github.com/rust-lang/crates.io-index" 1189 | dependencies = [ 1190 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 1191 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 1192 | ] 1193 | 1194 | [[package]] 1195 | name = "watchexec" 1196 | version = "1.8.5" 1197 | source = "registry+https://github.com/rust-lang/crates.io-index" 1198 | dependencies = [ 1199 | "clap 2.26.2 (registry+https://github.com/rust-lang/crates.io-index)", 1200 | "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", 1201 | "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", 1202 | "globset 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 1203 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 1204 | "lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", 1205 | "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 1206 | "nix 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", 1207 | "notify 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 1208 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 1209 | ] 1210 | 1211 | [[package]] 1212 | name = "winapi" 1213 | version = "0.2.8" 1214 | source = "registry+https://github.com/rust-lang/crates.io-index" 1215 | 1216 | [[package]] 1217 | name = "winapi-build" 1218 | version = "0.1.1" 1219 | source = "registry+https://github.com/rust-lang/crates.io-index" 1220 | 1221 | [[package]] 1222 | name = "ws2_32-sys" 1223 | version = "0.2.1" 1224 | source = "registry+https://github.com/rust-lang/crates.io-index" 1225 | dependencies = [ 1226 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 1227 | "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 1228 | ] 1229 | 1230 | [metadata] 1231 | "checksum adler32 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6cbd0b9af8587c72beadc9f72d35b9fbb070982c9e6203e46e93f10df25f8f45" 1232 | "checksum advapi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e06588080cb19d0acb6739808aafa5f26bfb2ca015b2b6370028b44cf7cb8a9a" 1233 | "checksum aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "500909c4f87a9e52355b26626d890833e9e1d53ac566db76c36faa984b889699" 1234 | "checksum ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6" 1235 | "checksum atty 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "21e50800ec991574876040fff8ee46b136a53e985286fbe6a3bdfe6421b78860" 1236 | "checksum backtrace 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "99f2ce94e22b8e664d95c57fff45b98a966c2252b60691d0b7aeeccd88d70983" 1237 | "checksum backtrace-sys 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "c63ea141ef8fdb10409d0f5daf30ac51f84ef43bff66f16627773d2a292cd189" 1238 | "checksum base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96434f987501f0ed4eb336a411e0631ecd1afa11574fe148587adc4ff96143c9" 1239 | "checksum bitflags 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dead7461c1127cf637931a1e50934eb6eee8bff2f74433ac7909e9afcee04a3" 1240 | "checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d" 1241 | "checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" 1242 | "checksum byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff81738b726f5d099632ceaffe7fb65b90212e8dce59d518729e7e8634032d3d" 1243 | "checksum bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c129aff112dcc562970abb69e2508b40850dd24c274761bb50fb8a0067ba6c27" 1244 | "checksum bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d828f97b58cc5de3e40c421d0cf2132d6b2da4ee0e11b8632fa838f0f9333ad6" 1245 | "checksum cargo-watch 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3b7be1ae3ce3704768097aa9c49a5e510e7731b633bdc25ed7fe2e6e035017bf" 1246 | "checksum cc 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7db2f146208d7e0fbee761b09cd65a7f51ccc38705d4e7262dad4d73b12a76b1" 1247 | "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" 1248 | "checksum clap 2.26.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3451e409013178663435d6f15fdb212f14ee4424a3d74f979d081d0a66b6f1f2" 1249 | "checksum cmake 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)" = "357c07e7a1fc95732793c1edb5901e1a1f305cfcf63a90eb12dbd22bdb6b789d" 1250 | "checksum conv 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "78ff10625fd0ac447827aa30ea8b861fead473bb60aeb73af6c1c58caf0d1299" 1251 | "checksum core-foundation 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25bfd746d203017f7d5cbd31ee5d8e17f94b6521c7af77ece6c9e4b2d4b16c67" 1252 | "checksum core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "065a5d7ffdcbc8fa145d6f0746f3555025b9097a9e9cda59f7467abae670c78d" 1253 | "checksum crypt32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e34988f7e069e0b2f3bfc064295161e489b2d4e04a2e4248fb94360cdf00b4ec" 1254 | "checksum custom_derive 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "ef8ae57c4978a2acd8b869ce6b9ca1dfe817bff704c220209fdef2c0b75a01b9" 1255 | "checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850" 1256 | "checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab" 1257 | "checksum env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3ddf21e73e016298f5cb37d6ef8e8da8e39f91f9ec8b0df44b7deb16a9f8cd5b" 1258 | "checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3" 1259 | "checksum filetime 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "6ab199bf38537c6f38792669e081e0bb278b9b7405bba2642e4e5d15bf732c0e" 1260 | "checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344" 1261 | "checksum foreign-types 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e4056b9bd47f8ac5ba12be771f77a0dae796d1bbaaf5fd0b9c2d38b69b8a29d" 1262 | "checksum fsevent 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)" = "dfe593ebcfc76884138b25426999890b10da8e6a46d01b499d7c54c604672c38" 1263 | "checksum fsevent-sys 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1a772d36c338d07a032d5375a36f15f9a7043bf0cb8ce7cee658e037c6032874" 1264 | "checksum futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "05a23db7bd162d4e8265968602930c476f688f0c180b44bdaf55e0cb2c687558" 1265 | "checksum futures-cpupool 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "77d49e7de8b91b20d6fda43eea906637eff18b96702eb6b2872df8bfab1ad2b5" 1266 | "checksum gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5e33ec290da0d127825013597dbdfc28bee4964690c7ce1166cbc2a7bd08b1bb" 1267 | "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" 1268 | "checksum globset 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "feeb1b6840809ef5efcf7a4a990bc4e1b7ee3df8cf9e2379a75aeb2ba42ac9c3" 1269 | "checksum grpcio 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a49e76143184b5f2330a8a3997fbc8958b18d25c3707dc9a4f2cdd1d326fdfb8" 1270 | "checksum grpcio-compiler 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "64df412af141a98e7725f33871e467f3b5627d8dcd8bd49ee62696f968fad1ea" 1271 | "checksum grpcio-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "58c40e409903abc12399f6aa58007fb3a22324df8ed1fb17f2a41ef5cf09b0bf" 1272 | "checksum httparse 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "af2f2dd97457e8fb1ae7c5a420db346af389926e36f43768b96f101546b04a07" 1273 | "checksum hyper 0.11.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1b45eac8b696d59491b079bd04fcb0f3488c0f6ed62dcb36bcfea8a543e9cdc3" 1274 | "checksum hyper-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c81fa95203e2a6087242c38691a0210f23e9f3f8f944350bd676522132e2985" 1275 | "checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d" 1276 | "checksum inotify 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887fcc180136e77a85e6a6128579a719027b1bab9b1c38ea4444244fe262c20c" 1277 | "checksum iovec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b6e8b9c2247fcf6c6a1151f1156932be5606c9fd6f55a2d7f9fc1cb29386b2f7" 1278 | "checksum itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8324a32baf01e2ae060e9de58ed0bc2320c9a2833491ee36cd3b4c414de4db8c" 1279 | "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" 1280 | "checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" 1281 | "checksum lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c9e5e58fa1a4c3b915a561a78a22ee0cac6ab97dca2504428bc1cb074375f8d5" 1282 | "checksum lazycell 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3b585b7a6811fb03aa10e74b278a0f00f8dd9b45dc681f148bb29fa5cb61859b" 1283 | "checksum libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)" = "56cce3130fd040c28df6f495c8492e5ec5808fb4c9093c310df02b0c8f030148" 1284 | "checksum libflate 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "a2aa04ec0100812d31a5366130ff9e793291787bc31da845bede4a00ea329830" 1285 | "checksum log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "880f77541efa6e5cc74e76910c9884d9859683118839d6a1dc3b11e63512565b" 1286 | "checksum lru_time_cache 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "30f38a48ad40936ca7c69db730dad50cf003d9655b2b1419b238ea225c9ca1d6" 1287 | "checksum magenta 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4bf0336886480e671965f794bc9b6fce88503563013d1bfb7a502c81fe3ac527" 1288 | "checksum magenta-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "40d014c7011ac470ae28e2f76a02bfea4a8480f73e701353b49ad7a8d75f4699" 1289 | "checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376" 1290 | "checksum md5 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "11f2f3240857d306c26118e2e92a5eaf8990df379e3d96573ee6c92cdbf58a81" 1291 | "checksum memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1dbccc0e46f1ea47b9f17e6d67c5a96bd27030519c519c9c91327e31275a47b4" 1292 | "checksum mime 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e3d709ffbb330e1566dc2f2a3c9b58a5ad4a381f740b810cd305dc3f089bc160" 1293 | "checksum mime_guess 2.0.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)" = "27a5e6679a0614e25adc14c6434ba84e41632b765a6d9cb2031a0cca682699ae" 1294 | "checksum mio 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a637d1ca14eacae06296a008fa7ad955347e34efcb5891cfd8ba05491a37907e" 1295 | "checksum mio 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "dbd91d3bfbceb13897065e97b2ef177a09a438cb33612b2d371bf568819a9313" 1296 | "checksum miow 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3e690c5df6b2f60acd45d56378981e827ff8295562fc8d34f573deb267a59cd1" 1297 | "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" 1298 | "checksum native-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04b781c9134a954c84f0594b9ab3f5606abc516030388e8511887ef4c204a1e5" 1299 | "checksum net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)" = "3a80f842784ef6c9a958b68b7516bc7e35883c614004dd94959a4dca1b716c09" 1300 | "checksum nix 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bfb3ddedaa14746434a02041940495bf11325c22f6d36125d3bdd56090d50a79" 1301 | "checksum nix 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a2c5afeb0198ec7be8569d666644b574345aad2e95a53baf3a532da3e0f3fb32" 1302 | "checksum notify 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "298d4401ff2c6cebb7f8944c90288647c89ce59029d43b439444cf1067df55e1" 1303 | "checksum num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "99843c856d68d8b4313b03a17e33c4bb42ae8f6610ea81b28abe076ac721b9b0" 1304 | "checksum num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "514f0d73e64be53ff320680ca671b64fe3fb91da01e1ae2ddc99eb51d453b20d" 1305 | "checksum openssl 0.9.19 (registry+https://github.com/rust-lang/crates.io-index)" = "816914b22eb15671d62c73442a51978f311e911d6a6f6cbdafa6abce1b5038fc" 1306 | "checksum openssl-sys 0.9.19 (registry+https://github.com/rust-lang/crates.io-index)" = "1e4c63a7d559c1e5afa6d6a9e6fa34bbc5f800ffc9ae08b72c605420b0c4f5e8" 1307 | "checksum percent-encoding 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de154f638187706bde41d9b4738748933d64e6b37bdbffc0b47a97d16a6ae356" 1308 | "checksum phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "cb325642290f28ee14d8c6201159949a872f220c62af6e110a56ea914fbe42fc" 1309 | "checksum phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "d62594c0bb54c464f633175d502038177e90309daf2e0158be42ed5f023ce88f" 1310 | "checksum phf_generator 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "6b07ffcc532ccc85e3afc45865469bf5d9e4ef5bfcf9622e3cfe80c2d275ec03" 1311 | "checksum phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "07e24b0ca9643bdecd0632f2b3da6b1b89bbb0030e0b992afc1113b23a7bc2f2" 1312 | "checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903" 1313 | "checksum protobuf 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "568a15e4d572d9a5e63ae3a55f84328c984842887db179b40b4cc6a608bac6a4" 1314 | "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" 1315 | "checksum rand 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)" = "eb250fd207a4729c976794d03db689c9be1d634ab5a1c9da9492a13d8fecbcdf" 1316 | "checksum redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "8dde11f18c108289bef24469638a04dce49da56084f2d50618b226e47eb04509" 1317 | "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" 1318 | "checksum regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1731164734096285ec2a5ec7fea5248ae2f5485b3feeb0115af4fda2183b2d1b" 1319 | "checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db" 1320 | "checksum relay 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f301bafeb60867c85170031bdb2fcf24c8041f33aee09e7b116a58d4e9f781c5" 1321 | "checksum reqwest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "194fe0d39dea7f89738707bf70e9f3ed47e8aca47d4b2eeaad6ac7831d2d390b" 1322 | "checksum rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "aee45432acc62f7b9a108cc054142dac51f979e69e71ddce7d6fc7adf29e817e" 1323 | "checksum rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c5f5376ea5e30ce23c03eb77cbe4962b988deead10910c372b226388b594c084" 1324 | "checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" 1325 | "checksum schannel 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7554288337c1110e34d7a2433518d889374c1de1a45f856b7bcddb03702131fc" 1326 | "checksum scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f417c22df063e9450888a7561788e9bd46d3bb3c1466435b4eccb903807f147d" 1327 | "checksum secur32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3f412dfa83308d893101dd59c10d6fda8283465976c28c287c5c855bf8d216bc" 1328 | "checksum security-framework 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "dfa44ee9c54ce5eecc9de7d5acbad112ee58755239381f687e564004ba4a2332" 1329 | "checksum security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "5421621e836278a0b139268f36eee0dc7e389b784dc3f79d8f11aabadf41bead" 1330 | "checksum semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "d4f410fedcf71af0345d7607d246e7ad15faaadd49d240ee3b24e5dc21a820ac" 1331 | "checksum serde 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)" = "6a7046c9d4c6c522d10b2d098f9bebe2bef227e0e74044d8c1bfcf6b476af799" 1332 | "checksum serde_derive 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)" = "1afcaae083fd1c46952a315062326bc9957f182358eb7da03b57ef1c688f7aa9" 1333 | "checksum serde_derive_internals 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bd381f6d01a6616cdba8530492d453b7761b456ba974e98768a18cad2cd76f58" 1334 | "checksum serde_json 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d243424e06f9f9c39e3cd36147470fd340db785825e367625f79298a6ac6b7ac" 1335 | "checksum serde_urlencoded 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce0fd303af908732989354c6f02e05e2e6d597152870f2c6990efb0577137480" 1336 | "checksum siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537" 1337 | "checksum slab 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d807fd58c4181bbabed77cb3b891ba9748241a552bcc5be698faaebefc54f46e" 1338 | "checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23" 1339 | "checksum slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fdeff4cd9ecff59ec7e3744cbca73dfe5ac35c2aedb2cfba8a1c715a18912e9d" 1340 | "checksum smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4c8cbcd6df1e117c2210e13ab5109635ad68a929fcbb8964dc965b76cb5ee013" 1341 | "checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694" 1342 | "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" 1343 | "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" 1344 | "checksum take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b157868d8ac1f56b64604539990685fa7611d8fa9e5476cf0c02cf34d32917c5" 1345 | "checksum tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "87974a6f5c1dfb344d733055601650059a3363de2a6104819293baff662132d6" 1346 | "checksum term_size 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2b6b55df3198cc93372e85dd2ed817f0e38ce8cc0f22eb32391bfad9c4bf209" 1347 | "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" 1348 | "checksum textwrap 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df8e08afc40ae3459e4838f303e465aa50d823df8d7f83ca88108f6d3afe7edd" 1349 | "checksum thread_local 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1697c4b57aeeb7a536b647165a2825faddffb1d3bad386d507709bd51a90bb14" 1350 | "checksum time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)" = "d5d788d3aa77bc0ef3e9621256885555368b47bd495c13dd2e7413c89f845520" 1351 | "checksum tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "c843a027f7c1df5f81e7734a0df3f67bf329411781ebf36393ce67beef6071e3" 1352 | "checksum tokio-io 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b4ab83e7adb5677e42e405fa4ceff75659d93c4d7d7dd22f52fcec59ee9f02af" 1353 | "checksum tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8fbb47ae81353c63c487030659494b295f6cb6576242f907f203473b191b0389" 1354 | "checksum tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24da22d077e0f15f55162bdbdc661228c1581892f52074fb242678d015b45162" 1355 | "checksum tokio-tls 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d88e411cac1c87e405e4090be004493c5d8072a370661033b1a64ea205ec2e13" 1356 | "checksum toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a7540f4ffc193e0d3c94121edb19b055670d369f77d5804db11ae053a45b6e7e" 1357 | "checksum unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33" 1358 | "checksum unicase 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2e01da42520092d0cd2d6ac3ae69eb21a22ad43ff195676b86f8c37f487d6b80" 1359 | "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" 1360 | "checksum unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "51ccda9ef9efa3f7ef5d91e8f9b83bbe6955f9bf86aec89d5cce2c874625920f" 1361 | "checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f" 1362 | "checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" 1363 | "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" 1364 | "checksum url 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eeb819346883532a271eb626deb43c4a1bb4c4dd47c519bd78137c3e72a4fe27" 1365 | "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" 1366 | "checksum uuid 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcc7e3b898aa6f6c08e5295b6c89258d1331e9ac578cc992fb818759951bdc22" 1367 | "checksum vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9e0a7d8bed3178a8fb112199d466eeca9ed09a14ba8ad67718179b4fd5487d0b" 1368 | "checksum vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887b5b631c2ad01628bbbaa7dd4c869f80d3186688f8d0b6f58774fbe324988c" 1369 | "checksum version_check 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6b772017e347561807c1aa192438c5fd74242a670a6cffacc40f2defd1dc069d" 1370 | "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" 1371 | "checksum walkdir 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c66c0b9792f0a765345452775f3adbd28dde9d33f30d13e5dcc5ae17cf6f3780" 1372 | "checksum watchexec 1.8.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b9575caa023d80bdb6bb387371014b06f97b7952bcfa64045e755a5d7adf6a4d" 1373 | "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" 1374 | "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" 1375 | "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" 1376 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "diplomat" 3 | version = "0.1.0" 4 | authors = [ "Timothy Perrett" ] 5 | exclude = [ "etc/*" ] 6 | keywords = [ "envoy", "xds", "data-plane", "consul" ] 7 | readme = "README.markdown" 8 | description = "Envoy v2 gRPC provider, backed by Consul" 9 | license = "Apache 2.0" 10 | repository = "https://github.com/timperrett/diplomat" 11 | 12 | [dependencies] 13 | grpcio = "0.1" 14 | protobuf = "1.4" 15 | futures = "0.1" 16 | futures-cpupool = "0.1" 17 | clap = "2.24" 18 | toml = "0.4" 19 | serde = "1.0" 20 | serde_derive = "1.0" 21 | serde_json = "1.0" 22 | log = "0.3.8" 23 | env_logger = "0.4.3" 24 | error-chain = "0.11" 25 | reqwest = "0.8" 26 | url = "1.5" 27 | lru_time_cache = "0.7" 28 | md5 = "0.3" 29 | # prometheus = "0.2" 30 | 31 | [build-dependencies] 32 | protobuf = "1.4" 33 | grpcio-compiler = "0.1.0" 34 | cargo-watch = "6.0" 35 | 36 | # [profile.release] 37 | # lto = true 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | PROGRAM_NAME ?= diplomat 3 | 4 | all: setup compile 5 | 6 | compile: proto 7 | cargo build -v 8 | 9 | release: proto 10 | cargo build -v --release && \ 11 | mv target/release/diplomat diplomat && \ 12 | tar cvzf diplomat.tar.gz diplomat && \ 13 | rm diplomat 14 | 15 | run: compile 16 | ./target/debug/diplomat --help 17 | 18 | clean: 19 | rm -rf target 20 | 21 | clean-full: 22 | rm -rf vendor && \ 23 | rm -rf target 24 | 25 | setup: vendor 26 | cargo install protobuf || echo "[info] protobuf crate already installed, skipping..." && \ 27 | cargo install grpcio-compiler || echo "[info] grpcio-compiler crate already installed, skipping..." 28 | cargo install rustfmt || echo "[info] rustfmt crate already installed, skipping..." 29 | 30 | proto: setup 31 | mkdir -p `pwd`/src/api && \ 32 | cd `pwd`/vendor/envoy-api && \ 33 | protoc \ 34 | --rust_out=../../src/api \ 35 | --grpc_out=../../src/api \ 36 | --plugin=protoc-gen-grpc=`which grpc_rust_plugin` api/*.proto && \ 37 | cd ../../ && \ 38 | scripts/generate-api-mod 39 | 40 | vendor: 41 | mkdir -p vendor && \ 42 | git clone https://github.com/envoyproxy/data-plane-api.git vendor/envoy-api || echo "[warn] unable to clone data-plane-api" && \ 43 | git clone https://github.com/googleapis/googleapis.git vendor/googleapis || echo "[warn] unable to clone googleapis" && \ 44 | ln -s `pwd`/vendor/googleapis/google `pwd`/vendor/envoy-api || echo "[warn] unable to link to vendor/envoy-api" && \ 45 | echo "[info] successfully updated the vendor dependencies..." 46 | 47 | consul: 48 | consul agent -ui -server -advertise 127.0.0.1 -dev -data-dir target 49 | 50 | format: 51 | cargo fmt && \ 52 | find . -name *.bk | xargs -L1 rm 53 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | ============================================================== 2 | diplomat 3 | Copyright (C) 2017 Timothy Perrett. 4 | ============================================================== 5 | 6 | This product includes software developed by 7 | Timothy Perrett (timperrett.com; github.com/timperrett). 8 | 9 | diplomat includes derivative work consul-rust: 10 | https://crates.io/crates/consul 11 | https://github.com/stusmall/consul-rust 12 | Licensed under Apache 2.0 13 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | # Diplomat 2 | 3 | [![Build Status](https://travis-ci.org/timperrett/diplomat.svg?branch=master)](https://travis-ci.org/timperrett/diplomat) 4 | 5 | Highly experimental gRPC server providing the also experimental [v2 envoy-api](https://github.com/envoyproxy/data-plane-api), with information backed by [Consul](https://github.com/hashicorp/consul) 6 | 7 | This project is implemented wth [Rust](https://www.rust-lang.org/) 8 | 9 | ## Usage 10 | 11 | Diplomat is shipped as a standalone native binary and is configured via a TOML configuration file. Each xDS action can be invoked on the command line for debugging purposes, but to run the service in producution you should use sometihing like: 12 | 13 | ``` 14 | $ RUST_LOG=info diplomat --config /path/to/config.toml serve 15 | ``` 16 | 17 | Using the individual xDS APIs is just as simple, with the additional params passed directly on the command line as arguments: 18 | 19 | ``` 20 | $ diplomat --config /path/to/config.toml eds --service-name foo 21 | ``` 22 | 23 | ## Development 24 | 25 | As gRPC relies on [Protocol Buffers](https://developers.google.com/protocol-buffers/), you will need to ensure that you have the `protoc` tooling avaialble on your development machine. 26 | 27 | #### Install Rust 28 | 29 | Before you start with the rest of this guide, be sure to [Install Rust](https://www.rust-lang.org/en-US/install.html) for your appropriate platform. 30 | 31 | #### Installing Protobuf 32 | 33 | On OSX install protobuf with Homebrew: 34 | 35 | ``` 36 | $ brew install protobuf 37 | $ brew install cmake 38 | $ brew install go 39 | # for local dev testing only, can be skipped just to build 40 | $ brew install consul 41 | ``` 42 | 43 | On Linux, a few additional steps are needed. Sadly, using `apt-get install protobuf-compiler` does not provide a recent enough version of the `protoc` compiller. The Envoy `.proto` files require at **least version 3** of the compiller. 44 | 45 | ``` 46 | $ sudo apt-get install build-essential cmake git libssl-dev golang-go 47 | ``` 48 | 49 | Then the steps to insall `protoc`: 50 | 51 | ``` 52 | # download and unzip the needed tools 53 | $ curl -OL https://github.com/google/protobuf/releases/download/v3.4.0/protoc-3.4.0-linux-x86_64.zip 54 | $ unzip protoc-3.4.0-linux-x86_64.zip -d protoc3 55 | # move the binary onto your $PATH 56 | $ mv protoc3/bin/* /usr/local/bin && chmod 775 /usr/local/bin/protoc 57 | # move the common proto includes onto the include path 58 | $ mv protoc3/include/* /usr/local/include/ 59 | ``` 60 | 61 | #### Fetching dependencies 62 | 63 | Once you have the compiller installed, there is a one-time operation that is needed to fetch the various upstream dependencies for the version of protocol buffers. This has been encoded into the projects make file, so you simply need to run: 64 | 65 | ``` 66 | $ make proto 67 | ``` 68 | 69 | This will fetch to github.com and move all the gubbins which was downloaded into a local `vendor` folder. If for some reason you need to update these files over time, simply run: 70 | 71 | ``` 72 | $ make clean-full && make proto 73 | ``` 74 | 75 | #### Development Builds 76 | 77 | ``` 78 | # produce a development build (do not use in production) 79 | $ cargo build 80 | 81 | # run compilation whenever the source tree changes (useful for dev feedback) 82 | $ cargo watch 83 | ``` 84 | 85 | #### Release Builds 86 | 87 | Release builds are automatically built for this project and posted [on Github Releases](https://github.com/timperrett/diplomat/releases) for Linux amd64 machines. If you need to build your own release-class binaray for another platform, simply use: 88 | 89 | ``` 90 | $ make release 91 | ``` 92 | 93 | By default all builds are devel builds and contains symbols, so making a dedicated release is important. 94 | -------------------------------------------------------------------------------- /docs/diplomat-internals.graffle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timperrett/diplomat/c2b1821c30f008743f3be82ec7563f699356d887/docs/diplomat-internals.graffle -------------------------------------------------------------------------------- /etc/test.config.normal.toml: -------------------------------------------------------------------------------- 1 | [server] 2 | host = "127.0.0.1" 3 | port = 9000 4 | 5 | [consul] 6 | ssl = true 7 | address = "b" 8 | datacenter = "c" 9 | username = "d" 10 | password = "e" 11 | token = "f" 12 | 13 | [client] 14 | address = "127.0.0.1:9000" 15 | -------------------------------------------------------------------------------- /scripts/generate-api-mod: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | # generate the mod.rs definition 6 | ls `pwd`/src/api/*.rs | grep -v mod.rs | sed s/\.rs//g | sed s/src\\/api\\///g | xargs basename -a | awk '{print "pub mod " $1 ";"}' > `pwd`/src/api/mod.rs 7 | -------------------------------------------------------------------------------- /scripts/install-openssl-linux: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | cd /tmp 6 | wget https://www.openssl.org/source/openssl-1.1.0.tar.gz -O openssl.tar.gz 7 | tar xzvf openssl.tar.gz 8 | rm openssl.tar.gz 9 | mv openssl-* openssl 10 | cd openssl 11 | ./config --prefix=/opt/openssl --openssldir=/usr/local/ssl 12 | make 13 | sudo make install 14 | -------------------------------------------------------------------------------- /scripts/install-protobuf-linux: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | TARGET_DIR=/usr/local 6 | 7 | curl -OL https://github.com/google/protobuf/releases/download/v3.4.0/protoc-3.4.0-linux-x86_64.zip 8 | unzip protoc-3.4.0-linux-x86_64.zip -d protoc3 9 | sudo mv protoc3/bin/* ${TARGET_DIR}/bin && sudo chmod -R 775 ${TARGET_DIR}/bin 10 | sudo mv protoc3/include/* ${TARGET_DIR}/include && sudo chmod -R 755 ${TARGET_DIR}/include 11 | 12 | # remove the garbage 13 | rm protoc-3.4.0-linux-x86_64.zip && \ 14 | rm -rf protoc3 15 | -------------------------------------------------------------------------------- /src/config.rs: -------------------------------------------------------------------------------- 1 | 2 | #[derive(Deserialize, Clone)] 3 | pub struct Config { 4 | pub consul: Consul, 5 | pub client: ClientConfig, 6 | pub server: Server, 7 | } 8 | 9 | #[derive(Deserialize, Clone)] 10 | pub struct Server { 11 | pub host: String, 12 | pub port: u16, 13 | } 14 | 15 | #[derive(Deserialize, Clone)] 16 | pub struct Consul { 17 | pub ssl: bool, 18 | pub address: String, 19 | pub datacenter: String, 20 | pub username: String, 21 | pub password: String, 22 | pub token: String, 23 | } 24 | 25 | #[derive(Deserialize, Clone)] 26 | pub struct ClientConfig { 27 | pub address: String, 28 | } 29 | 30 | use toml; 31 | use std::fs::File; 32 | use std::io; 33 | use std::path::Path; 34 | 35 | #[derive(Debug)] 36 | pub enum ConfigError { 37 | IoError(io::Error), 38 | TomlError(toml::de::Error), 39 | } 40 | impl From for ConfigError { 41 | fn from(error: io::Error) -> Self { 42 | ConfigError::IoError(error) 43 | } 44 | } 45 | impl From for ConfigError { 46 | fn from(error: toml::de::Error) -> Self { 47 | ConfigError::TomlError(error) 48 | } 49 | } 50 | 51 | /// Given a string path, attempt to load the file. 52 | /// 53 | /// TODO: This function should do some sanitization on the input path, 54 | /// which will eventually be supplied by a user or defaulted. Eitherway, 55 | /// validation is needed here such that things dont get too crazy or unsafe. 56 | pub fn load(path: String) -> Result { 57 | if Path::new(&path).exists() { 58 | let a = read_file(path); 59 | let b: Result = 60 | a.and_then(|c| toml::from_str(&c).map_err(|e| ConfigError::from(e))); 61 | b 62 | } else { 63 | Err(ConfigError::from(io::Error::new( 64 | io::ErrorKind::NotFound, 65 | "specified configuraiton file does not exist.", 66 | ))) 67 | } 68 | } 69 | 70 | use std::io::prelude::*; 71 | 72 | fn read_file(path: String) -> Result { 73 | let mut file = File::open(path)?; 74 | let mut contents = String::new(); 75 | let res = file.read_to_string(&mut contents); 76 | 77 | match res { 78 | Ok(_) => Ok(contents), 79 | Err(e) => Err(ConfigError::from(e)), 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/config_test.rs: -------------------------------------------------------------------------------- 1 | 2 | use config; 3 | 4 | #[test] 5 | fn test_load() { 6 | let c: Result = 7 | config::load("etc/test.config.normal.toml".to_string()); 8 | assert_eq!(c.unwrap().consul.ssl, true); 9 | } 10 | -------------------------------------------------------------------------------- /src/consul/catalog.rs: -------------------------------------------------------------------------------- 1 | use std::collections::HashMap; 2 | use super::{Client, QueryMeta, QueryOptions}; 3 | use super::errors::Result; 4 | use super::request::{get, get_vec}; 5 | 6 | pub struct CatalogDeregistration { 7 | pub Node: String, 8 | pub Datacenter: String, 9 | pub CheckID: String, 10 | pub ServiceID: String, 11 | } 12 | 13 | #[derive(Deserialize, Debug, Clone)] 14 | pub struct CatalogNode { 15 | pub ID: String, 16 | pub Node: String, 17 | pub Address: String, 18 | pub Datacenter: String, 19 | pub ServiceID: String, 20 | pub ServiceName: String, 21 | pub ServiceAddress: String, 22 | pub ServicePort: i32, 23 | pub ServiceEnableTagOverride: bool, 24 | } 25 | 26 | pub trait Catalog { 27 | fn datacenters(&self) -> Result<(Vec, QueryMeta)>; 28 | fn list_nodes_for(&self, &str, Option<&QueryOptions>) -> Result<(Vec, QueryMeta)>; 29 | 30 | //fn deregister(&self, &CatalogDeregistration, &WriteOptions) -> Result<((), WriteMeta)>; 31 | } 32 | 33 | impl Catalog for Client { 34 | /// implements https://www.consul.io/api/catalog.html#list-datacenters 35 | fn datacenters(&self) -> Result<(Vec, QueryMeta)> { 36 | get( 37 | "/v1/catalog/datacenters", 38 | &self.config, 39 | HashMap::new(), 40 | None, 41 | ) 42 | } 43 | 44 | /// implements https://www.consul.io/api/catalog.html#list-nodes-for-service 45 | fn list_nodes_for( 46 | &self, 47 | service: &str, 48 | q: Option<&QueryOptions>, 49 | ) -> Result<(Vec, QueryMeta)> { 50 | get_vec( 51 | format!("/v1/catalog/service/{}", service).as_str(), 52 | &self.config, 53 | HashMap::new(), 54 | q, 55 | ) 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/consul/errors.rs: -------------------------------------------------------------------------------- 1 | error_chain!{ 2 | errors{ 3 | BadUrl{ 4 | description("") 5 | } 6 | ConsulError{ 7 | description("") 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/consul/kv.rs: -------------------------------------------------------------------------------- 1 | use std::collections::HashMap; 2 | 3 | use super::{Client, QueryOptions, QueryMeta, WriteOptions, WriteMeta}; 4 | use super::request::{delete, get, get_vec, put}; 5 | use super::errors::{Error, Result}; 6 | 7 | #[serde(default)] 8 | #[derive(Clone, Default, Eq, PartialEq, Serialize, Deserialize, Debug)] 9 | pub struct KVPair { 10 | pub Key: String, 11 | pub CreateIndex: Option, 12 | pub ModifyIndex: Option, 13 | pub LockIndex: Option, 14 | pub Flags: Option, 15 | pub Value: String, 16 | pub Session: Option, 17 | } 18 | 19 | pub trait KV { 20 | fn acquire(&self, &KVPair, Option<&WriteOptions>) -> Result<(bool, WriteMeta)>; 21 | fn delete(&self, key: &str, Option<&WriteOptions>) -> Result<(bool, WriteMeta)>; 22 | fn get(&self, &str, Option<&QueryOptions>) -> Result<(Option, QueryMeta)>; 23 | fn list(&self, &str, Option<&QueryOptions>) -> Result<(Vec, QueryMeta)>; 24 | fn put(&self, &KVPair, Option<&WriteOptions>) -> Result<(bool, WriteMeta)>; 25 | fn release(&self, &KVPair, Option<&WriteOptions>) -> Result<(bool, WriteMeta)>; 26 | } 27 | 28 | impl KV for Client { 29 | fn acquire(&self, pair: &KVPair, o: Option<&WriteOptions>) -> Result<(bool, WriteMeta)> { 30 | let mut params = HashMap::new(); 31 | if let Some(i) = pair.Flags { 32 | if i != 0 { 33 | params.insert(String::from("flags"), i.to_string()); 34 | } 35 | } 36 | if let Some(ref session) = pair.Session { 37 | params.insert(String::from("acquire"), session.to_owned()); 38 | let path = format!("/v1/kv/{}", pair.Key); 39 | put(&path, Some(&pair.Value), &self.config, params, o) 40 | } else { 41 | Err(Error::from("Session flag is required to acquire lock")) 42 | } 43 | } 44 | 45 | fn delete(&self, key: &str, options: Option<&WriteOptions>) -> Result<(bool, WriteMeta)> { 46 | let path = format!("/v1/kv/{}", key); 47 | delete(&path, &self.config, HashMap::new(), options) 48 | } 49 | fn get( 50 | &self, 51 | key: &str, 52 | options: Option<&QueryOptions>, 53 | ) -> Result<(Option, QueryMeta)> { 54 | let path = format!("/v1/kv/{}", key); 55 | let x: Result<(Vec, QueryMeta)> = get(&path, &self.config, HashMap::new(), options); 56 | x.map(|r| (r.0.first().cloned(), r.1)) 57 | } 58 | 59 | fn list(&self, prefix: &str, o: Option<&QueryOptions>) -> Result<(Vec, QueryMeta)> { 60 | let mut params = HashMap::new(); 61 | params.insert(String::from("recurse"), String::from("")); 62 | let path = format!("/v1/kv/{}", prefix); 63 | get_vec(&path, &self.config, params, o) 64 | } 65 | 66 | fn put(&self, pair: &KVPair, o: Option<&WriteOptions>) -> Result<(bool, WriteMeta)> { 67 | let mut params = HashMap::new(); 68 | if let Some(i) = pair.Flags { 69 | if i != 0 { 70 | params.insert(String::from("flags"), i.to_string()); 71 | } 72 | } 73 | let path = format!("/v1/kv/{}", pair.Key); 74 | put(&path, Some(&pair.Value), &self.config, params, o) 75 | } 76 | 77 | fn release(&self, pair: &KVPair, o: Option<&WriteOptions>) -> Result<(bool, WriteMeta)> { 78 | let mut params = HashMap::new(); 79 | if let Some(i) = pair.Flags { 80 | if i != 0 { 81 | params.insert(String::from("flags"), i.to_string()); 82 | } 83 | } 84 | if let Some(ref session) = pair.Session { 85 | params.insert(String::from("release"), session.to_owned()); 86 | let path = format!("/v1/kv/{}", pair.Key); 87 | put(&path, Some(&pair.Value), &self.config, params, o) 88 | } else { 89 | Err(Error::from("Session flag is required to release a lock")) 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/consul/mod.rs: -------------------------------------------------------------------------------- 1 | #![allow(non_snake_case)] 2 | 3 | pub mod catalog; 4 | pub mod errors; 5 | pub mod kv; 6 | 7 | mod request; 8 | 9 | use std::time::Duration; 10 | use reqwest::Client as HttpClient; 11 | use consul::errors::Result; 12 | use consul::errors::ResultExt; 13 | 14 | #[derive(Clone, Debug)] 15 | pub struct Client { 16 | config: Config, 17 | } 18 | 19 | impl Client { 20 | pub fn new(config: Config) -> Self { 21 | Client { config: config } 22 | } 23 | } 24 | 25 | #[derive(Clone, Debug)] 26 | pub struct Config { 27 | pub address: String, 28 | pub datacenter: Option, 29 | pub http_client: HttpClient, 30 | pub wait_time: Option, 31 | } 32 | 33 | impl Config { 34 | pub fn new() -> Result { 35 | HttpClient::builder() 36 | .build() 37 | .chain_err(|| "Failed to build reqwest client") 38 | .map(|client| { 39 | Config { 40 | address: String::from("http://localhost:8500"), 41 | datacenter: None, 42 | http_client: client, 43 | wait_time: None, 44 | } 45 | }) 46 | } 47 | } 48 | 49 | #[derive(Clone, Debug, Default)] 50 | pub struct QueryOptions { 51 | pub datacenter: Option, 52 | pub wait_index: Option, 53 | pub wait_time: Option, 54 | } 55 | 56 | #[derive(Clone, Debug)] 57 | pub struct QueryMeta { 58 | pub last_index: Option, 59 | pub request_time: Duration, 60 | } 61 | 62 | #[derive(Clone, Debug, Default)] 63 | pub struct WriteOptions { 64 | pub datacenter: Option, 65 | } 66 | 67 | #[derive(Clone, Debug)] 68 | pub struct WriteMeta { 69 | pub request_time: Duration, 70 | } 71 | -------------------------------------------------------------------------------- /src/consul/request.rs: -------------------------------------------------------------------------------- 1 | use url::Url; 2 | use std::collections::HashMap; 3 | use std::str; 4 | use std::str::FromStr; 5 | use std::time::Instant; 6 | use reqwest::Client as HttpClient; 7 | use reqwest::RequestBuilder; 8 | use reqwest::StatusCode; 9 | use serde::Serialize; 10 | use serde::de::DeserializeOwned; 11 | use super::{Config, QueryOptions, QueryMeta, WriteOptions, WriteMeta}; 12 | use super::errors::{Result, ResultExt}; 13 | 14 | pub fn get_vec( 15 | path: &str, 16 | config: &Config, 17 | mut params: HashMap, 18 | options: Option<&QueryOptions>, 19 | ) -> Result<(Vec, QueryMeta)> { 20 | let datacenter: Option<&String> = options.and_then(|o| o.datacenter.as_ref()).or_else(|| { 21 | config.datacenter.as_ref() 22 | }); 23 | 24 | if let Some(dc) = datacenter { 25 | params.insert(String::from("dc"), dc.to_owned()); 26 | } 27 | if let Some(options) = options { 28 | if let Some(index) = options.wait_index { 29 | params.insert(String::from("index"), index.to_string()); 30 | } 31 | if let Some(wait_time) = options.wait_time { 32 | params.insert(String::from("wait"), format!("{}s", wait_time.as_secs())); 33 | } 34 | } 35 | 36 | 37 | let url_str = format!("{}{}", config.address, path); 38 | let url = Url::parse_with_params(&url_str, params.iter()).chain_err( 39 | || "Failed to parse URL", 40 | )?; 41 | let start = Instant::now(); 42 | let response = config.http_client.get(url).send(); 43 | response 44 | .chain_err(|| "HTTP request to consul failed") 45 | .and_then(|mut r| { 46 | let j = if r.status() != StatusCode::NotFound { 47 | r.json().chain_err(|| "Failed to parse JSON response")? 48 | } else { 49 | Vec::new() 50 | }; 51 | let x: Option> = r.headers() 52 | .get_raw("X-Consul-Index") 53 | .and_then(|raw| raw.one()) 54 | .map(|bytes| { 55 | str::from_utf8(bytes) 56 | .chain_err(|| "Failed to parse valid UT8 for last index") 57 | .and_then(|s| { 58 | u64::from_str(s).chain_err( 59 | || "Failed to parse valid number for last index", 60 | ) 61 | }) 62 | }); 63 | 64 | match x { 65 | Some(r) => Ok((j, Some(r?))), 66 | None => Ok((j, None)), 67 | } 68 | }) 69 | .map(|x: (Vec, Option)| { 70 | ( 71 | x.0, 72 | QueryMeta { 73 | last_index: x.1, 74 | request_time: Instant::now() - start, 75 | }, 76 | ) 77 | }) 78 | } 79 | 80 | pub fn get( 81 | path: &str, 82 | config: &Config, 83 | mut params: HashMap, 84 | options: Option<&QueryOptions>, 85 | ) -> Result<(R, QueryMeta)> { 86 | let datacenter: Option<&String> = options.and_then(|o| o.datacenter.as_ref()).or_else(|| { 87 | config.datacenter.as_ref() 88 | }); 89 | 90 | if let Some(dc) = datacenter { 91 | params.insert(String::from("dc"), dc.to_owned()); 92 | } 93 | if let Some(options) = options { 94 | if let Some(index) = options.wait_index { 95 | params.insert(String::from("index"), index.to_string()); 96 | } 97 | if let Some(wait_time) = options.wait_time { 98 | params.insert(String::from("wait"), format!("{}s", wait_time.as_secs())); 99 | } 100 | } 101 | 102 | let url_str = format!("{}{}", config.address, path); 103 | let url = Url::parse_with_params(&url_str, params.iter()).chain_err( 104 | || "Failed to parse URL", 105 | )?; 106 | let start = Instant::now(); 107 | let response = config.http_client.get(url).send(); 108 | response 109 | .chain_err(|| "HTTP request to consul failed") 110 | .and_then(|mut r| { 111 | let j = r.json().chain_err(|| "Failed to parse JSON response")?; 112 | let x: Option> = r.headers() 113 | .get_raw("X-Consul-Index") 114 | .and_then(|raw| raw.one()) 115 | .map(|bytes| { 116 | str::from_utf8(bytes) 117 | .chain_err(|| "Failed to parse valid UT8 for last index") 118 | .and_then(|s| { 119 | u64::from_str(s).chain_err( 120 | || "Failed to parse valid number for last index", 121 | ) 122 | }) 123 | }); 124 | 125 | match x { 126 | Some(r) => Ok((j, Some(r?))), 127 | None => Ok((j, None)), 128 | } 129 | }) 130 | .map(|x: (R, Option)| { 131 | ( 132 | x.0, 133 | QueryMeta { 134 | last_index: x.1, 135 | request_time: Instant::now() - start, 136 | }, 137 | ) 138 | }) 139 | } 140 | 141 | pub fn delete( 142 | path: &str, 143 | config: &Config, 144 | params: HashMap, 145 | options: Option<&WriteOptions>, 146 | ) -> Result<(R, WriteMeta)> { 147 | let req = |http_client: &HttpClient, url: Url| -> RequestBuilder { http_client.delete(url) }; 148 | write_with_body(path, None as Option<&()>, config, params, options, req) 149 | } 150 | 151 | /* 152 | pub fn post(path: &str, 153 | body: Option<&T>, 154 | config: &Config, 155 | options: Option<&WriteOptions>) 156 | -> Result<(R, WriteMeta)> { 157 | let req = |http_client: &HttpClient, url: Url| -> RequestBuilder { http_client.post(url) }; 158 | write_with_body(path, body, config, options, req) 159 | } 160 | */ 161 | pub fn put( 162 | path: &str, 163 | body: Option<&T>, 164 | config: &Config, 165 | params: HashMap, 166 | options: Option<&WriteOptions>, 167 | ) -> Result<(R, WriteMeta)> { 168 | let req = |http_client: &HttpClient, url: Url| -> RequestBuilder { http_client.put(url) }; 169 | write_with_body(path, body, config, params, options, req) 170 | } 171 | 172 | 173 | fn write_with_body( 174 | path: &str, 175 | body: Option<&T>, 176 | config: &Config, 177 | mut params: HashMap, 178 | options: Option<&WriteOptions>, 179 | req: F, 180 | ) -> Result<(R, WriteMeta)> 181 | where 182 | F: Fn(&HttpClient, Url) -> RequestBuilder, 183 | { 184 | let start = Instant::now(); 185 | let datacenter: Option<&String> = options.and_then(|o| o.datacenter.as_ref()).or_else(|| { 186 | config.datacenter.as_ref() 187 | }); 188 | 189 | if let Some(dc) = datacenter { 190 | params.insert(String::from("dc"), dc.to_owned()); 191 | } 192 | 193 | 194 | let url_str = format!("{}{}", config.address, path); 195 | let url = Url::parse_with_params(&url_str, params.iter()).chain_err( 196 | || "Failed to parse URL", 197 | )?; 198 | let mut builder = req(&config.http_client, url); 199 | 200 | let builder = if let Some(b) = body { 201 | builder.json(b).build() 202 | } else { 203 | builder.build() 204 | }; 205 | 206 | builder.and_then(|b| config.http_client.execute(b)) 207 | .chain_err(|| "HTTP request to consul failed") 208 | .and_then(|mut x| x.json().chain_err(|| "Failed to parse JSON")) 209 | .map(|x| (x, WriteMeta { request_time: Instant::now() - start })) 210 | } 211 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_imports)] 2 | #![allow(dead_code)] 3 | #[allow(unused)] 4 | #[allow(unused_variables)] 5 | 6 | mod api; 7 | mod server; 8 | mod config; 9 | mod consul; 10 | 11 | #[cfg(test)] 12 | mod config_test; 13 | 14 | #[macro_use] 15 | extern crate log; 16 | extern crate env_logger; 17 | #[macro_use] 18 | extern crate clap; 19 | extern crate grpcio; 20 | extern crate futures; 21 | extern crate protobuf; 22 | #[macro_use] 23 | extern crate serde_derive; 24 | #[macro_use] 25 | extern crate serde_json; 26 | extern crate toml; 27 | #[macro_use] 28 | extern crate error_chain; 29 | #[macro_use] 30 | extern crate reqwest; 31 | extern crate serde; 32 | extern crate url; 33 | extern crate md5; 34 | 35 | use clap::{Arg, App, SubCommand}; 36 | use std::process::exit; 37 | use std::sync::Arc; 38 | use consul::Client as ConsulClient; 39 | use consul::catalog::Catalog; 40 | use std::borrow::Borrow; 41 | use grpcio::{Environment, ChannelBuilder, UnarySink}; 42 | use config::Config; 43 | use api::eds_grpc::EndpointDiscoveryServiceClient; 44 | use api::discovery::DiscoveryRequest; 45 | 46 | fn main() { 47 | let _ = env_logger::init(); 48 | 49 | let app = App::new("diplomat") 50 | .version(crate_version!()) 51 | .about( 52 | "Provides the Envoy v2 API as a gRPC service and CLI application.", 53 | ) 54 | .author("Timothy Perrett") 55 | .arg( 56 | Arg::with_name("config") 57 | .long("config") 58 | .value_name("config") 59 | .help("Path to the configuration for diplomat") 60 | .required(false) 61 | .takes_value(true), 62 | ) 63 | .subcommand( 64 | SubCommand::with_name("client") 65 | .about("Interact with diplomat using the cli") 66 | .subcommand( 67 | SubCommand::with_name("eds") 68 | .about( 69 | "given a service name, resolve the IPs providing that service", 70 | ) 71 | .arg( 72 | Arg::with_name("cluster") 73 | .long("cluster") 74 | .value_name("cluster") 75 | .required(true) 76 | .takes_value(true), 77 | ) 78 | .arg( 79 | Arg::with_name("node") 80 | .long("node") 81 | .value_name("node") 82 | .required(true) 83 | .takes_value(true), 84 | ), 85 | ) 86 | .subcommand( 87 | SubCommand::with_name("cds").about("cds").arg( 88 | Arg::with_name("cluster") 89 | .long("cluster") 90 | .value_name("cluster") 91 | .required(true) 92 | .takes_value(true), 93 | ), 94 | ), 95 | ) 96 | .subcommand(SubCommand::with_name("serve").about( 97 | "Starts the diplomat server", 98 | )); 99 | 100 | // TIM: Not sure if cloning here is going to cause problems, 101 | // but given this is once at the edge of the world it probally isn't 102 | // too much of a big deal. 103 | let matches = app.clone().get_matches(); 104 | 105 | let config_path: &str = matches.value_of("config").unwrap_or("diplomat.toml"); 106 | info!( 107 | "==>> attempting to load configuration from '{}'", 108 | config_path 109 | ); 110 | 111 | let configr = config::load(config_path.to_string()); 112 | if configr.is_err() { 113 | error!("==>> failed loading the specified configuration file... exiting."); 114 | exit(1); 115 | } 116 | let config = configr.unwrap(); 117 | let consul_config = consul::Config::new().unwrap(); 118 | let consu_client = ConsulClient::new(consul_config); 119 | 120 | match matches.subcommand() { 121 | ("client", Some(sub_m)) => { 122 | match sub_m.subcommand() { 123 | ("eds", Some(sub_client)) => { 124 | info!("==>> attempting to call {}", config.client.address); 125 | 126 | let env = Arc::new(Environment::new(1)); 127 | let channel = ChannelBuilder::new(env).connect(&config.client.address); 128 | let client = EndpointDiscoveryServiceClient::new(channel); 129 | 130 | let mut node = api::base::Node::new(); 131 | node.set_id(sub_client.value_of("node").unwrap().to_string()); 132 | node.set_cluster(sub_client.value_of("cluster").unwrap().to_string()); 133 | 134 | let mut dr = DiscoveryRequest::new(); 135 | dr.set_node(node); 136 | dr.set_type_url(server::MessageType::DiscoveryRequest.to_string()); 137 | 138 | let res = client.fetch_endpoints(dr); 139 | println!("eds {:?}", res); 140 | } 141 | ("cds", Some(_)) => println!("cds is currently not implemented"), 142 | _ => { 143 | let _ = app.clone().print_help(); 144 | println!(""); 145 | } 146 | } 147 | } 148 | ("serve", Some(_)) => { 149 | info!("==>> booting diplomat server on {}:{}...", config.server.host, config.server.port); 150 | ::server::start(config, consu_client); 151 | } 152 | _ => { 153 | let _ = app.clone().print_help(); 154 | println!(""); 155 | } 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /src/server/eds.rs: -------------------------------------------------------------------------------- 1 | 2 | use api::eds_grpc::EndpointDiscoveryService; 3 | use futures::Future; 4 | use config::Config; 5 | use std::sync::Arc; 6 | use consul::Client as ConsulClient; 7 | 8 | #[derive(Clone)] 9 | pub struct Service { 10 | pub config: Config, 11 | pub consul: ConsulClient, 12 | } 13 | 14 | use api::discovery::{DiscoveryRequest, DiscoveryResponse}; 15 | use grpcio::{RpcStatus, RpcStatusCode, UnarySinkResult}; 16 | 17 | impl EndpointDiscoveryService for Service { 18 | /// The resource_names field in DiscoveryRequest specifies a list of clusters 19 | /// to subscribe to updates for. 20 | fn stream_endpoints( 21 | &self, 22 | ctx: ::grpcio::RpcContext, 23 | stream: ::grpcio::RequestStream<::api::discovery::DiscoveryRequest>, 24 | sink: ::grpcio::DuplexSink<::api::discovery::DiscoveryResponse>, 25 | ) { 26 | 27 | } 28 | 29 | fn fetch_endpoints( 30 | &self, 31 | ctx: ::grpcio::RpcContext, 32 | req: DiscoveryRequest, 33 | sink: ::grpcio::UnarySink, 34 | ) { 35 | // req is: 36 | // pub version_info: ::std::string::String, 37 | // pub node: ::protobuf::SingularPtrField, 38 | // pub resource_names: ::protobuf::RepeatedField<::std::string::String>, 39 | // pub type_url: ::std::string::String, 40 | // pub response_nonce: ::std::string::String, 41 | 42 | // let y = match resp { 43 | // Ok(x) => sink.success(x), 44 | // Err(_) => sink.fail(RpcStatus::new(RpcStatusCode::Internal, None)), 45 | // }; 46 | 47 | // let f = y.map_err(move |e| error!("failed to reply {:?}: {:?}", req, e)); 48 | 49 | let resp = fetch_endpoints(); 50 | let f = sink.success(resp).map_err(move |e| { 51 | error!("failed to reply {:?}: {:?}", req, e) 52 | }); 53 | ctx.spawn(f) 54 | } 55 | 56 | /// Advanced API to allow for multi-dimensional load balancing by remote 57 | /// server. For receiving LB assignments, the steps are: 58 | /// 1, The management server is configured with per cluster/zone/load metric 59 | /// capacity configuration. The capacity configuration definition is 60 | /// outside of the scope of this document. 61 | /// 2. Envoy issues a standard {Stream,Fetch}Endpoints request for the clusters 62 | /// to balance. 63 | /// 64 | /// Independently, Envoy will initiate a StreamLoadStats bidi stream with a 65 | /// management server: 66 | /// 1. Once a connection establishes, the management server publishes a 67 | /// LoadStatsResponse for all clusters it is interested in learning load 68 | /// stats about. 69 | /// 2. For each cluster, Envoy load balances incoming traffic to upstream hosts 70 | /// based on per-zone weights and/or per-instance weights (if specified) 71 | /// based on intra-zone LbPolicy. This information comes from the above 72 | /// {Stream,Fetch}Endpoints. 73 | /// 3. When upstream hosts reply, they optionally add header with ASCII representation of EndpointLoadMetricStats. 75 | /// 4. Envoy aggregates load reports over the period of time given to it in 76 | /// LoadStatsResponse.load_reporting_interval. This includes aggregation 77 | /// stats Envoy maintains by itself (total_requests, rpc_errors etc.) as 78 | /// well as load metrics from upstream hosts. 79 | /// 5. When the timer of load_reporting_interval expires, Envoy sends new 80 | /// LoadStatsRequest filled with load reports for each cluster. 81 | /// 6. The management server uses the load reports from all reported Envoys 82 | /// from around the world, computes global assignment and prepares traffic 83 | /// assignment destined for each zone Envoys are located in. Goto 2. 84 | fn stream_load_stats( 85 | &self, 86 | ctx: ::grpcio::RpcContext, 87 | stream: ::grpcio::RequestStream<::api::eds::LoadStatsRequest>, 88 | sink: ::grpcio::DuplexSink<::api::eds::LoadStatsResponse>, 89 | ) { 90 | 91 | } 92 | } 93 | 94 | use consul::catalog::Catalog; 95 | use protobuf::{Message, RepeatedField}; 96 | use protobuf::error::ProtobufError; 97 | use protobuf::well_known_types::Any; 98 | 99 | use super::MessageType; 100 | use std::string::ToString; 101 | 102 | use api::base::Locality; 103 | use api::eds::{LocalityLbEndpoints, ClusterLoadAssignment}; 104 | 105 | // TODO: This is going to need to do something more useful that return 106 | // hardcoded values. This should really talk to consul or whatever 107 | // abstraction we figure out. 108 | fn fetch_endpoints() -> DiscoveryResponse { 109 | let mut loc = Locality::new(); 110 | loc.set_region("us-west-1".to_string()); 111 | loc.set_zone("a".to_string()); 112 | 113 | let mut az1 = LocalityLbEndpoints::new(); 114 | az1.set_locality(loc); 115 | 116 | let mut azs = Vec::new(); 117 | azs.push(az1); 118 | 119 | let mut cla = ClusterLoadAssignment::new(); 120 | cla.set_cluster_name("foo".to_string()); 121 | cla.set_endpoints(RepeatedField::from_vec(azs)); 122 | 123 | let mut items = Vec::new(); 124 | items.push(cla); 125 | 126 | create_discovery_response(items, MessageType::ClusterLoadAssignment) 127 | } 128 | 129 | /// here we're taking any `A` that has a `::protobuf::Message` implementation, such that 130 | /// we can encode the response (using protobuf); its turtles all the way down. 131 | /// TODO: currently this function assumes success, this should be refactored to properly 132 | /// handle bad results and take action accordingly. 133 | fn create_discovery_response( 134 | r: Vec, 135 | nested_type_url: MessageType, 136 | ) -> DiscoveryResponse { 137 | let serialized: Vec = r.iter() 138 | .map(|x| pack_to_any(x.write_to_bytes(), nested_type_url.clone())) 139 | .collect(); 140 | let repeated = RepeatedField::from_vec(serialized); 141 | let mut d = DiscoveryResponse::new(); 142 | d.set_canary(false); 143 | //TODO we'll need to set a version here that is the md5 of the payload to faithfully 144 | // represent the 'version' to Envoy, but for now we're just hardcoding it, because fuck it. 145 | d.set_version_info("1".to_string()); 146 | // This should really be an Enum 147 | d.set_type_url(MessageType::DiscoveryResponse.to_string()); 148 | d.set_resources(repeated); 149 | d 150 | } 151 | 152 | fn pack_to_any(r: Result, ProtobufError>, turl: MessageType) -> Any { 153 | match r { 154 | Ok(bytes) => any_from_bytes(bytes, turl), 155 | Err(_) => Any::new(), 156 | } 157 | } 158 | 159 | fn any_from_bytes(bytes: Vec, turl: MessageType) -> Any { 160 | let mut a = Any::new(); 161 | a.set_value(bytes); 162 | a.set_type_url(turl.to_string()); 163 | a 164 | } 165 | -------------------------------------------------------------------------------- /src/server/mod.rs: -------------------------------------------------------------------------------- 1 | mod eds; 2 | 3 | use std::io::Read; 4 | use std::sync::Arc; 5 | use std::{io, thread}; 6 | 7 | use futures::Future; 8 | use futures::sync::oneshot; 9 | 10 | use grpcio::{Environment, RpcContext, ServerBuilder, UnarySink}; 11 | use api::eds_grpc; 12 | use config::Config; 13 | use consul::Client; 14 | 15 | use std::string; 16 | 17 | #[derive(Copy, Clone)] 18 | pub enum MessageType { 19 | DiscoveryResponse, 20 | ClusterLoadAssignment, 21 | LocalityLbEndpoints, 22 | LbEndpoint, 23 | ClusterLoadAssignmentPolicy, 24 | Locality, 25 | Cluster, 26 | DiscoveryRequest 27 | } 28 | impl string::ToString for MessageType { 29 | fn to_string(&self) -> String { 30 | match *self { 31 | MessageType::DiscoveryRequest => 32 | "type.googleapis.com/envoy.api.v2.DiscoveryRequest".to_string(), 33 | MessageType::DiscoveryResponse => { 34 | "type.googleapis.com/envoy.api.v2.DiscoveryResponse".to_string() 35 | } 36 | MessageType::ClusterLoadAssignment => { 37 | "type.googleapis.com/envoy.api.v2.ClusterLoadAssignment".to_string() 38 | } 39 | MessageType::LocalityLbEndpoints => { 40 | "type.googleapis.com/envoy.api.v2.LocalityLbEndpoints".to_string() 41 | } 42 | MessageType::LbEndpoint => { 43 | "type.googleapis.com/envoy.api.v2.LocalityLbEndpoints".to_string() 44 | } 45 | MessageType::ClusterLoadAssignmentPolicy => { 46 | "type.googleapis.com/envoy.api.v2.ClusterLoadAssignment_Policy".to_string() 47 | } 48 | MessageType::Locality => "type.googleapis.com/envoy.api.v2.Locality".to_string(), 49 | MessageType::Cluster => "type.googleapis.com/envoy.api.v2.Cluster".to_string(), 50 | } 51 | } 52 | } 53 | 54 | 55 | pub fn start(cfg: Config, consul: Client) { 56 | let env = Arc::new(Environment::new(1)); 57 | 58 | // EDS 59 | let eds_instance = eds::Service { 60 | config: cfg.clone(), 61 | consul: consul, 62 | }; 63 | let eds_service = eds_grpc::create_endpoint_discovery_service(eds_instance); 64 | 65 | // CDS 66 | 67 | // LDS 68 | 69 | // RDS 70 | 71 | let mut server = ServerBuilder::new(env) 72 | .register_service(eds_service) 73 | .bind(cfg.server.host, cfg.server.port) 74 | .build() 75 | .unwrap(); 76 | server.start(); 77 | for &(ref host, port) in server.bind_addrs() { 78 | info!("listening on {}:{}", host, port); 79 | } 80 | let (tx, rx) = oneshot::channel(); 81 | thread::spawn(move || { 82 | info!("Press ENTER to exit..."); 83 | let _ = io::stdin().read(&mut [0]).unwrap(); 84 | tx.send(()) 85 | }); 86 | let _ = rx.wait(); 87 | let _ = server.shutdown().wait(); 88 | } 89 | --------------------------------------------------------------------------------