Skip to content

Commit

Permalink
use http over stdio to update config (#8)
Browse files Browse the repository at this point in the history
  • Loading branch information
Hexilee authored May 8, 2021
1 parent 8d6f32f commit 4da2004
Show file tree
Hide file tree
Showing 16 changed files with 655 additions and 163 deletions.
56 changes: 48 additions & 8 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ clap = "2.33.3"
futures = "0.3.10"
http = "0.2.3"
humantime-serde = "1.0"
hyper = {version = "0.14.4", features = ["runtime", "client", "server", "http1", "http2"]}
hyper = {version = "0.14.4", features = ["runtime", "client", "server", "http1", "http2", "stream"]}
iptables = "0.4"
libc = {version = "0.2.81", features = ["std"]}
paw = "1.0"
Expand All @@ -24,9 +24,12 @@ serde_yaml = "0.8"
socket2 = "0.3"
structopt = {version = "0.3", features = ["paw"]}
tokio = {version = "1.4", features = ["full"]}
wildmatch = "2.1"
tracing = "0.1"
tracing-futures = "0.2"
tracing-subscriber = "0.2"
json-patch = "0.2.6"
async-trait = "0.1.50"

[dev-dependencies]
test-case = "1.1"
60 changes: 55 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,19 @@ Usage Example:

```
proxy 0.1.0
The option of tproxy.
The option of rs-proxy.
USAGE:
tproxy <input>
tproxy [FLAGS] [FILE]
FLAGS:
-h, --help Prints help information
-V, --version Prints version information
-h, --help Prints help information
-i, --interactive Allows to apply config by stdin/stdout
-V, --version Prints version information
-v, --verbose Verbose mode (-v, -vv, -vvv, etc.)
ARGS:
<input> path of config file
<FILE> path of config file, required if interactive mode is disabled
```
Support json and yaml config. Example of config could be found in `./example/config`

Expand All @@ -34,3 +36,51 @@ make build
```bash
make run config=<path>
```

### interactive mode

You can apply config by HTTP over stdio if interactive mode is enabled.

- apply

```bash
> sudo target/release/tproxy -i
PUT / HTTP/1.1
Content-Length: 129

{"proxy_ports": [30086], "rules": [{"target": "Request", "selector": {"path": "*", "method": "GET"},"actions": {"abort": true}}]}
```

- get the response:

```bash
HTTP/1.1 200 OK
content-length: 0
date: Mon, 03 May 2021 11:21:31 GMT
```

- recover

> Update config with empty proxy ports.
```
PUT / HTTP/1.1
Content-Length: 129
{"proxy_ports": [30086], "rules": [{"target": "Request", "selector": {"path": "*", "method": "GET"},"actions": {"abort": true}}]}
HTTP/1.1 200 OK
content-length: 0
date: Mon, 03 May 2021 11:21:31 GMT
PUT / HTTP/1.1
Content-Length: 124
{"proxy_ports": [], "rules": [{"target": "Request", "selector": {"path": "*", "method": "GET"},"actions": {"abort": true}}]}
HTTP/1.1 200 OK
content-length: 0
date: Mon, 03 May 2021 11:22:13 GMT
```

- exit

Ctrl-C
2 changes: 1 addition & 1 deletion config-examples/json_example.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
},
"actions": {
"delay": "10s",
"append": {
"patch": {
"queries": [
["foo", "bar"],
["foo", "other"]
Expand Down
2 changes: 1 addition & 1 deletion config-examples/yaml_example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ rules:
method: GET
actions:
delay: 10s
append:
patch:
queries:
- [foo, bar]
- [foo, other]
Expand Down
53 changes: 40 additions & 13 deletions src/cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,56 @@ use anyhow::{anyhow, Result};
use config::RawConfig;
use structopt::StructOpt;
use tokio::fs::read_to_string;
use tracing_subscriber::filter::LevelFilter;

use crate::tproxy::config::Config;

pub mod config;

#[derive(Debug, StructOpt)]
#[structopt(name = "proxy", about = "The option of rs-proxy.")]
struct Opt {
///path of config file
#[structopt(parse(from_os_str))]
input: Option<PathBuf>,
pub struct Opt {
/// Allows to apply config by stdin/stdout
#[structopt(short, long)]
pub interactive: bool,

// The number of occurrences of the `v/verbose` flag
/// Verbose mode (-v, -vv, -vvv, etc.)
#[structopt(short, long, parse(from_occurrences))]
pub verbose: u8,

/// path of config file, required if interactive mode is disabled
#[structopt(name = "FILE", parse(from_os_str))]
pub input: Option<PathBuf>,
}

pub async fn get_config() -> Result<Config> {
let opt: Opt = Opt::from_args();
get_config_from_opt(opt.input).await
impl Opt {
pub fn get_level_filter(&self) -> LevelFilter {
match self.verbose {
0 => LevelFilter::ERROR,
1 => LevelFilter::INFO,
2 => LevelFilter::DEBUG,
_ => LevelFilter::TRACE,
}
}

pub fn from_args_checked() -> Result<Self> {
Self::from_args_safe()?.checked()
}

fn checked(self) -> Result<Self> {
if !self.interactive && self.input.is_none() {
return Err(anyhow!("config file is required when interactive mode is disabled, use `-h | --help` for more details"));
}
Ok(self)
}
}

pub async fn get_config_from_opt(path: Option<PathBuf>) -> Result<Config> {
match path {
pub async fn get_config_from_opt(opt: &Opt) -> Result<Config> {
match opt.input {
None => RawConfig::default(),
Some(path_buf) => {
let buffer = read_to_string(&path_buf).await?;
Some(ref path_buf) => {
let buffer = read_to_string(path_buf).await?;
match path_buf.extension().and_then(|ext| ext.to_str()) {
Some("json") => serde_json::from_str(&buffer)?,
Some("yaml") => serde_yaml::from_str(&buffer)?,
Expand Down Expand Up @@ -72,8 +99,8 @@ mod test {
actions: RawActions {
abort: None,
delay: Some(Duration::from_secs(1)),
append: None,
replace: None,
patch: None,
},
},
RawRule {
Expand All @@ -99,8 +126,8 @@ mod test {
actions: RawActions {
abort: Some(true),
delay: Some(Duration::from_secs(1)),
append: None,
replace: None,
patch: None,
},
},
]),
Expand Down
Loading

0 comments on commit 4da2004

Please sign in to comment.