Make it work in nomad

This commit is contained in:
Fabian Stamm 2023-04-14 04:13:41 +02:00
parent 747c4ddf6f
commit ef1a922933
6 changed files with 309 additions and 62 deletions

260
Cargo.lock generated
View File

@ -159,10 +159,31 @@ dependencies = [
] ]
[[package]] [[package]]
name = "fastrand" name = "errno"
version = "1.8.0" version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a"
dependencies = [
"errno-dragonfly",
"libc",
"windows-sys 0.48.0",
]
[[package]]
name = "errno-dragonfly"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
dependencies = [
"cc",
"libc",
]
[[package]]
name = "fastrand"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be"
dependencies = [ dependencies = [
"instant", "instant",
] ]
@ -290,6 +311,12 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "hermit-abi"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
[[package]] [[package]]
name = "http" name = "http"
version = "0.2.8" version = "0.2.8"
@ -414,6 +441,17 @@ dependencies = [
"cfg-if", "cfg-if",
] ]
[[package]]
name = "io-lifetimes"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220"
dependencies = [
"hermit-abi 0.3.1",
"libc",
"windows-sys 0.48.0",
]
[[package]] [[package]]
name = "ipnet" name = "ipnet"
version = "2.7.1" version = "2.7.1"
@ -456,6 +494,12 @@ dependencies = [
"cc", "cc",
] ]
[[package]]
name = "linux-raw-sys"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d59d8c75012853d2e872fb56bc8a2e53718e2cafe1a4c823143141c6d90c322f"
[[package]] [[package]]
name = "lock_api" name = "lock_api"
version = "0.4.9" version = "0.4.9"
@ -542,7 +586,7 @@ version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
dependencies = [ dependencies = [
"hermit-abi", "hermit-abi 0.2.6",
"libc", "libc",
] ]
@ -554,9 +598,9 @@ checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66"
[[package]] [[package]]
name = "openssl" name = "openssl"
version = "0.10.45" version = "0.10.50"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b102428fd03bc5edf97f62620f7298614c45cedf287c271e7ed450bbaf83f2e1" checksum = "7e30d8bc91859781f0a943411186324d580f2bbeb71b452fe91ae344806af3f1"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"cfg-if", "cfg-if",
@ -586,11 +630,10 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
[[package]] [[package]]
name = "openssl-sys" name = "openssl-sys"
version = "0.9.80" version = "0.9.85"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23bbbf7854cd45b83958ebe919f0e8e516793727652e27fda10a8384cfc790b7" checksum = "0d3d193fb1488ad46ffe3aaabc912cc931d02ee8518fe2959aea8ef52718b0c0"
dependencies = [ dependencies = [
"autocfg",
"cc", "cc",
"libc", "libc",
"pkg-config", "pkg-config",
@ -615,7 +658,7 @@ checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"libc", "libc",
"redox_syscall", "redox_syscall 0.2.16",
"smallvec", "smallvec",
"windows-sys 0.45.0", "windows-sys 0.45.0",
] ]
@ -708,12 +751,12 @@ dependencies = [
] ]
[[package]] [[package]]
name = "remove_dir_all" name = "redox_syscall"
version = "0.5.3" version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
dependencies = [ dependencies = [
"winapi", "bitflags",
] ]
[[package]] [[package]]
@ -736,15 +779,14 @@ dependencies = [
"js-sys", "js-sys",
"log", "log",
"mime", "mime",
"native-tls",
"once_cell", "once_cell",
"percent-encoding", "percent-encoding",
"pin-project-lite", "pin-project-lite",
"rustls",
"serde", "serde",
"serde_json", "serde_json",
"serde_urlencoded", "serde_urlencoded",
"tokio", "tokio",
"tokio-native-tls",
"tower-service", "tower-service",
"url", "url",
"wasm-bindgen", "wasm-bindgen",
@ -753,9 +795,50 @@ dependencies = [
"winreg", "winreg",
] ]
[[package]]
name = "ring"
version = "0.16.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
dependencies = [
"cc",
"libc",
"once_cell",
"spin",
"untrusted",
"web-sys",
"winapi",
]
[[package]]
name = "rustix"
version = "0.37.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62b24138615de35e32031d041a09032ef3487a616d901ca4db224e7d557efae2"
dependencies = [
"bitflags",
"errno",
"io-lifetimes",
"libc",
"linux-raw-sys",
"windows-sys 0.45.0",
]
[[package]]
name = "rustls"
version = "0.20.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f"
dependencies = [
"log",
"ring",
"sct",
"webpki",
]
[[package]] [[package]]
name = "rustocat" name = "rustocat"
version = "0.1.2" version = "0.1.9"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"chrono", "chrono",
@ -796,6 +879,16 @@ version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddccb15bcce173023b3fedd9436f882a0739b8dfb45e4f6b6002bee5929f61b2" checksum = "ddccb15bcce173023b3fedd9436f882a0739b8dfb45e4f6b6002bee5929f61b2"
[[package]]
name = "sct"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4"
dependencies = [
"ring",
"untrusted",
]
[[package]] [[package]]
name = "security-framework" name = "security-framework"
version = "2.8.2" version = "2.8.2"
@ -909,6 +1002,12 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "spin"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
[[package]] [[package]]
name = "syn" name = "syn"
version = "1.0.107" version = "1.0.107"
@ -922,16 +1021,15 @@ dependencies = [
[[package]] [[package]]
name = "tempfile" name = "tempfile"
version = "3.3.0" version = "3.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"fastrand", "fastrand",
"libc", "redox_syscall 0.3.5",
"redox_syscall", "rustix",
"remove_dir_all", "windows-sys 0.45.0",
"winapi",
] ]
[[package]] [[package]]
@ -1002,9 +1100,9 @@ dependencies = [
[[package]] [[package]]
name = "tokio-native-tls" name = "tokio-native-tls"
version = "0.3.0" version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b" checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
dependencies = [ dependencies = [
"native-tls", "native-tls",
"tokio", "tokio",
@ -1089,6 +1187,12 @@ version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc7ed8ba44ca06be78ea1ad2c3682a43349126c8818054231ee6f4748012aed2" checksum = "bc7ed8ba44ca06be78ea1ad2c3682a43349126c8818054231ee6f4748012aed2"
[[package]]
name = "untrusted"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
[[package]] [[package]]
name = "url" name = "url"
version = "2.3.1" version = "2.3.1"
@ -1204,6 +1308,16 @@ dependencies = [
"wasm-bindgen", "wasm-bindgen",
] ]
[[package]]
name = "webpki"
version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd"
dependencies = [
"ring",
"untrusted",
]
[[package]] [[package]]
name = "winapi" name = "winapi"
version = "0.3.9" version = "0.3.9"
@ -1241,13 +1355,13 @@ version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
dependencies = [ dependencies = [
"windows_aarch64_gnullvm", "windows_aarch64_gnullvm 0.42.1",
"windows_aarch64_msvc", "windows_aarch64_msvc 0.42.1",
"windows_i686_gnu", "windows_i686_gnu 0.42.1",
"windows_i686_msvc", "windows_i686_msvc 0.42.1",
"windows_x86_64_gnu", "windows_x86_64_gnu 0.42.1",
"windows_x86_64_gnullvm", "windows_x86_64_gnullvm 0.42.1",
"windows_x86_64_msvc", "windows_x86_64_msvc 0.42.1",
] ]
[[package]] [[package]]
@ -1256,7 +1370,16 @@ version = "0.45.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
dependencies = [ dependencies = [
"windows-targets", "windows-targets 0.42.1",
]
[[package]]
name = "windows-sys"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
dependencies = [
"windows-targets 0.48.0",
] ]
[[package]] [[package]]
@ -1265,13 +1388,28 @@ version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7" checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7"
dependencies = [ dependencies = [
"windows_aarch64_gnullvm", "windows_aarch64_gnullvm 0.42.1",
"windows_aarch64_msvc", "windows_aarch64_msvc 0.42.1",
"windows_i686_gnu", "windows_i686_gnu 0.42.1",
"windows_i686_msvc", "windows_i686_msvc 0.42.1",
"windows_x86_64_gnu", "windows_x86_64_gnu 0.42.1",
"windows_x86_64_gnullvm", "windows_x86_64_gnullvm 0.42.1",
"windows_x86_64_msvc", "windows_x86_64_msvc 0.42.1",
]
[[package]]
name = "windows-targets"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5"
dependencies = [
"windows_aarch64_gnullvm 0.48.0",
"windows_aarch64_msvc 0.48.0",
"windows_i686_gnu 0.48.0",
"windows_i686_msvc 0.48.0",
"windows_x86_64_gnu 0.48.0",
"windows_x86_64_gnullvm 0.48.0",
"windows_x86_64_msvc 0.48.0",
] ]
[[package]] [[package]]
@ -1280,42 +1418,84 @@ version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
[[package]] [[package]]
name = "windows_aarch64_msvc" name = "windows_aarch64_msvc"
version = "0.42.1" version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7" checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
[[package]] [[package]]
name = "windows_i686_gnu" name = "windows_i686_gnu"
version = "0.42.1" version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640" checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640"
[[package]]
name = "windows_i686_gnu"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
[[package]] [[package]]
name = "windows_i686_msvc" name = "windows_i686_msvc"
version = "0.42.1" version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605" checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605"
[[package]]
name = "windows_i686_msvc"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
[[package]] [[package]]
name = "windows_x86_64_gnu" name = "windows_x86_64_gnu"
version = "0.42.1" version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45" checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
[[package]] [[package]]
name = "windows_x86_64_gnullvm" name = "windows_x86_64_gnullvm"
version = "0.42.1" version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
[[package]] [[package]]
name = "windows_x86_64_msvc" name = "windows_x86_64_msvc"
version = "0.42.1" version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd"
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
[[package]] [[package]]
name = "winreg" name = "winreg"
version = "0.10.1" version = "0.10.1"

View File

@ -1,6 +1,6 @@
[package] [package]
name = "rustocat" name = "rustocat"
version = "0.1.2" version = "0.1.9"
edition = "2021" edition = "2021"
description = "Socat in rust with many less features and a configuration file" description = "Socat in rust with many less features and a configuration file"
license = "ISC" license = "ISC"
@ -20,7 +20,7 @@ log = "0.4"
fern = "0.6" fern = "0.6"
chrono = "0.4" chrono = "0.4"
async-trait = "0.1" async-trait = "0.1"
reqwest = { version = "0.11", features = ["json"] } reqwest = { version = "0.11", features = ["json", "rustls", "hyper-tls"], default-features = false }
[profile.release] [profile.release]
opt-level = 3 # Optimize for size. opt-level = 3 # Optimize for size.

View File

@ -2,9 +2,9 @@ FROM rust:alpine as builder
WORKDIR /app WORKDIR /app
RUN apk add --no-cache musl-dev RUN apk add --no-cache musl-dev libssl3 openssl-dev
# This should fetch the index and cache it. This should reduce subsequent builds # This should fetch the index and cache it. This should reduce the time required of subsequent builds
RUN cargo search test RUN cargo search test
COPY Cargo.toml Cargo.lock /app/ COPY Cargo.toml Cargo.lock /app/
@ -12,11 +12,15 @@ COPY Cargo.toml Cargo.lock /app/
COPY src /app/src COPY src /app/src
RUN cargo build --release RUN cargo build --release
FROM alpine FROM alpine
RUN apk add --no-cache libssl3
COPY --from=builder /app/target/release/rustocat /usr/bin/rustocat COPY --from=builder /app/target/release/rustocat /usr/bin/rustocat
ENTRYPOINT ["rustocat"] ENTRYPOINT ["/bin/sh"]
CMD [ "-c", "/usr/bin/rustocat" ]

View File

@ -1,5 +1,6 @@
use std::{fs::File, path::Path}; use std::{fs::File, path::Path};
use log::info;
use serde::Deserialize; use serde::Deserialize;
use tokio::signal::unix::Signal; use tokio::signal::unix::Signal;
@ -15,6 +16,8 @@ pub struct Target {
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
pub struct Config { pub struct Config {
pub consul: Option<bool>, pub consul: Option<bool>,
pub consul_http_addr: Option<String>,
pub consul_http_token: Option<String>,
mappings: Vec<Target>, mappings: Vec<Target>,
} }
@ -76,11 +79,13 @@ impl FileConfigProvider {
#[async_trait::async_trait] #[async_trait::async_trait]
impl ConfigProvider for FileConfigProvider { impl ConfigProvider for FileConfigProvider {
async fn get_targets(&self) -> Result<Vec<Target>> { async fn get_targets(&self) -> Result<Vec<Target>> {
info!("Getting targets from file");
let config = self.load_config()?; let config = self.load_config()?;
return Ok(config.mappings); return Ok(config.mappings);
} }
async fn wait_for_change(&mut self) -> Result<()> { async fn wait_for_change(&mut self) -> Result<()> {
info!("Waiting for file config change (SIGHUP)");
self.sighup_stream.recv().await; self.sighup_stream.recv().await;
return Ok(()); return Ok(());

View File

@ -2,10 +2,14 @@
use std::collections::HashMap; use std::collections::HashMap;
use log::debug;
use log::info;
use log::trace;
use log::warn; use log::warn;
use reqwest::header::HeaderMap; use reqwest::header::HeaderMap;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::config::Config;
use crate::config::ConfigProvider; use crate::config::ConfigProvider;
use crate::config::Target; use crate::config::Target;
@ -17,9 +21,13 @@ pub struct ConsulConfigProvider {
} }
impl ConsulConfigProvider { impl ConsulConfigProvider {
pub fn new() -> Self { pub fn new(config: Option<&Config>) -> Self {
Self { Self {
consul_config: ConsulConfig::from_env(), consul_config: if let Some(config) = config {
ConsulConfig::from_config_or_env(config)
} else {
ConsulConfig::from_env()
},
interval: tokio::time::interval(tokio::time::Duration::from_secs(10)), interval: tokio::time::interval(tokio::time::Duration::from_secs(10)),
} }
} }
@ -28,16 +36,21 @@ impl ConsulConfigProvider {
#[async_trait::async_trait] #[async_trait::async_trait]
impl ConfigProvider for ConsulConfigProvider { impl ConfigProvider for ConsulConfigProvider {
async fn get_targets(&self) -> Result<Vec<Target>> { async fn get_targets(&self) -> Result<Vec<Target>> {
info!("Getting targets from consul");
let mut targets: Vec<Target> = Vec::new(); let mut targets: Vec<Target> = Vec::new();
debug!("Calling consul_get_services");
let services = consul_get_services(&self.consul_config).await?; let services = consul_get_services(&self.consul_config).await?;
// Find consul services and tags // Find consul services and tags
// Format of tags: rustocat:udp:port // Format of tags: rustocat:udp:port
// rustocat:tcp:port // rustocat:tcp:port
debug!("Iterating over services: {:?}", services);
for (name, tags) in services { for (name, tags) in services {
for tag in tags { for tag in tags {
if tag.starts_with("rustocat") { if tag.starts_with("rustocat") {
trace!("Found rustocat tag: {}", tag);
let parts = tag.split(":").collect::<Vec<&str>>(); let parts = tag.split(":").collect::<Vec<&str>>();
if parts.len() != 3 { if parts.len() != 3 {
warn!("Invalid tag: {} on service {}", tag, name); warn!("Invalid tag: {} on service {}", tag, name);
@ -45,17 +58,19 @@ impl ConfigProvider for ConsulConfigProvider {
} }
let port = parts[2]; let port = parts[2];
trace!("Getting nodes for service: {}", name);
let nodes = consul_get_service_nodes(&self.consul_config, &name).await?; let nodes = consul_get_service_nodes(&self.consul_config, &name).await?;
let mut t = vec![]; let mut t = vec![];
for node in nodes { for node in nodes {
t.push(format!("{}:{}", node.Service.Address, node.Service.Port)); t.push(format!("{}:{}", node.ServiceAddress, node.ServicePort));
} }
let target = Target { let target = Target {
udp: Some(parts[1] == "udp"), udp: Some(parts[1] == "udp"),
source: format!("0.0.0.0:{}", port), source: format!("0.0.0.0:{}", port),
targets: t, targets: t,
}; };
trace!("Adding target: {:?}", target);
targets.push(target); targets.push(target);
} }
} }
@ -65,6 +80,7 @@ impl ConfigProvider for ConsulConfigProvider {
} }
async fn wait_for_change(&mut self) -> Result<()> { async fn wait_for_change(&mut self) -> Result<()> {
info!("Waiting for consul config change");
self.interval.tick().await; self.interval.tick().await;
Ok(()) Ok(())
@ -74,7 +90,7 @@ impl ConfigProvider for ConsulConfigProvider {
async fn consul_get_services(config: &ConsulConfig) -> Result<HashMap<String, Vec<String>>> { async fn consul_get_services(config: &ConsulConfig) -> Result<HashMap<String, Vec<String>>> {
let mut headers = HeaderMap::new(); let mut headers = HeaderMap::new();
if let Some(token) = config.token.clone() { if let Some(token) = config.token.clone() {
headers.insert("X-Consul-Token", token.parse().unwrap()); headers.insert("X-Consul-Token", token.parse()?);
} }
return Ok(reqwest::Client::new() return Ok(reqwest::Client::new()
@ -86,21 +102,23 @@ async fn consul_get_services(config: &ConsulConfig) -> Result<HashMap<String, Ve
.await?); .await?);
} }
async fn consul_get_service_nodes( async fn consul_get_service_nodes(config: &ConsulConfig, service: &str) -> Result<Vec<Node>> {
config: &ConsulConfig,
service: &str,
) -> Result<Vec<ServiceEntry>> {
let mut headers = HeaderMap::new(); let mut headers = HeaderMap::new();
if let Some(token) = config.token.clone() { if let Some(token) = config.token.clone() {
headers.insert("X-Consul-Token", token.parse().unwrap()); headers.insert("X-Consul-Token", token.parse()?);
} }
trace!(
"Calling consul_get_service_nodes: {}/v1/catalog/service/{service}",
config.baseurl
);
return Ok(reqwest::Client::new() return Ok(reqwest::Client::new()
.get(format!("{}/v1/catalog/services/{service}", config.baseurl)) .get(format!("{}/v1/catalog/service/{service}", config.baseurl))
.headers(headers) .headers(headers)
.send() .send()
.await? .await?
.json::<Vec<ServiceEntry>>() .json::<Vec<Node>>()
.await?); .await?);
} }
@ -136,7 +154,8 @@ struct HealthCheck {
struct Node { struct Node {
ID: String, ID: String,
Node: String, Node: String,
Address: String, ServiceAddress: String,
ServicePort: u16,
Datacenter: Option<String>, Datacenter: Option<String>,
TaggedAddresses: Option<HashMap<String, String>>, TaggedAddresses: Option<HashMap<String, String>>,
Meta: Option<HashMap<String, String>>, Meta: Option<HashMap<String, String>>,
@ -166,4 +185,20 @@ impl ConsulConfig {
token: option_env!("CONSUL_HTTP_TOKEN").map(|s| s.to_string()), token: option_env!("CONSUL_HTTP_TOKEN").map(|s| s.to_string()),
} }
} }
fn from_config_or_env(config: &Config) -> Self {
let baseurl = match config.consul_http_addr {
Some(ref s) => s.clone(),
None => option_env!("CONSUL_HTTP_ADDR")
.expect("CONSUL_HTTP_ADDR not set")
.to_string(),
};
let token = match config.consul_http_token {
Some(ref s) => Some(s.clone()),
None => option_env!("CONSUL_HTTP_TOKEN").map(|s| s.to_string()),
};
Self { baseurl, token }
}
} }

View File

@ -7,6 +7,7 @@ mod udp;
#[cfg(feature = "consul")] #[cfg(feature = "consul")]
mod consul; mod consul;
use config::ConfigProvider;
use log::{debug, error, info, warn}; use log::{debug, error, info, warn};
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::error::Error; use std::error::Error;
@ -39,15 +40,18 @@ async fn main() -> Result<()> {
.chain(std::io::stdout()) .chain(std::io::stdout())
.apply()?; .apply()?;
let mut listeners: HashMap<String, ActiveListener> = HashMap::new(); let listeners: HashMap<String, ActiveListener> = HashMap::new();
let text_config_provider = config::FileConfigProvider::new(); let text_config_provider = config::FileConfigProvider::new();
let mut target_provider: Box<dyn config::ConfigProvider> = { let target_provider: Box<dyn config::ConfigProvider> = {
#[cfg(feature = "consul")] #[cfg(feature = "consul")]
{ {
let cfg = text_config_provider.load_config()?; let cfg = text_config_provider.load_config()?;
info!("Loaded yaml config");
if cfg.consul.is_some() && cfg.consul.unwrap() { if cfg.consul.is_some() && cfg.consul.unwrap() {
let consul_config_provider = consul::ConsulConfigProvider::new(); info!("Using consul config provider");
let consul_config_provider = consul::ConsulConfigProvider::new(Some(&cfg));
info!("Loaded consul config provider");
Box::new(consul_config_provider) Box::new(consul_config_provider)
} else { } else {
Box::new(text_config_provider) Box::new(text_config_provider)
@ -55,9 +59,28 @@ async fn main() -> Result<()> {
} }
#[cfg(not(feature = "consul"))] #[cfg(not(feature = "consul"))]
Box::new(text_config_provider) {
let cfg = Box::new(text_config_provider);
info!("Loaded yaml config");
cfg
}
}; };
match run_loop(target_provider, listeners).await {
Ok(_) => {}
Err(e) => {
error!("Error in run loop: {}", e);
info!("Exiting");
}
}
Ok(())
}
async fn run_loop(
mut target_provider: Box<dyn ConfigProvider>,
mut listeners: HashMap<String, ActiveListener>,
) -> Result<()> {
loop { loop {
let mappings = target_provider.get_targets().await?; let mappings = target_provider.get_targets().await?;
let mut required_listeners: HashSet<String> = HashSet::new(); let mut required_listeners: HashSet<String> = HashSet::new();
@ -151,6 +174,6 @@ async fn main() -> Result<()> {
} }
target_provider.wait_for_change().await?; target_provider.wait_for_change().await?;
info!("Recevied SIGHUP, reloading config!"); info!("Reloading config!");
} }
} }