Skip to content
This repository has been archived by the owner on Jun 13, 2022. It is now read-only.

Commit

Permalink
cargo fmt
Browse files Browse the repository at this point in the history
  • Loading branch information
ciphax committed Apr 13, 2019
1 parent 8e59cbb commit 6f7b0ae
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 108 deletions.
54 changes: 37 additions & 17 deletions src/cli.rs
Original file line number Diff line number Diff line change
@@ -1,44 +1,52 @@
use crate::config::Config;
use crate::dns::{check_txt_record, lookup_real_domain};
use crate::inwx::{Inwx, InwxError};
use clap::{App, Arg, SubCommand};
use std::fs::File;
use std::io::BufReader;
use std::thread::sleep;
use std::time::{Duration, Instant};
use clap::{Arg, App, SubCommand};
use crate::config::Config;
use crate::inwx::{Inwx, InwxError};
use crate::dns::{check_txt_record, lookup_real_domain};

fn execute_api_commands<F>(config: &Config, domain: &str, op: F) -> Result<bool, ()> where F: Fn(&mut Inwx) -> Result<(), InwxError> {
fn execute_api_commands<F>(config: &Config, domain: &str, op: F) -> Result<bool, ()>
where
F: Fn(&mut Inwx) -> Result<(), InwxError>,
{
if config.accounts.len() == 0 {
error!("No accounts configured");
return Err(());
}

let mut filtered_accounts = Vec::new();

match config.accounts.iter().find(|account|
account.domains.iter().any(|d| domain == d || domain.ends_with(&format!(".{}", d)))
) {
match config.accounts.iter().find(|account| {
account
.domains
.iter()
.any(|d| domain == d || domain.ends_with(&format!(".{}", d)))
}) {
Some(account) => {
info!("Using account {}", account.username);
filtered_accounts.push(account);
},
}
None => {
warn!("Domain not configured: Trying {} configured domains", config.accounts.len());
warn!(
"Domain not configured: Trying {} configured domains",
config.accounts.len()
);
filtered_accounts.extend(config.accounts.iter());
}
};


for account in filtered_accounts {
let mut success = false;
let mut api = Inwx::new(&account).map_err(|e| error!("{}", e))?;

match op(&mut api) {
Err(InwxError::DomainNotFound) => {},
Err(InwxError::DomainNotFound) => {}
Err(e) => {
error!("{}", e);
return Err(());
},
}
_ => {
success = true;
}
Expand All @@ -60,7 +68,10 @@ fn execute_api_commands<F>(config: &Config, domain: &str, op: F) -> Result<bool,
fn read_config(path: &str) -> Result<Config, ()> {
let file = File::open(path).map_err(|e| error!("Failed to open config file: {}", e))?;
let reader = BufReader::new(file);
Ok(serde_json::from_reader(reader).map_err(|e| error!("Failed to parse config file: {}", e))?)
Ok(
serde_json::from_reader(reader)
.map_err(|e| error!("Failed to parse config file: {}", e))?,
)
}

fn create(config: &Config, domain: &str, value: &str) -> Result<(), ()> {
Expand Down Expand Up @@ -99,7 +110,10 @@ fn create(config: &Config, domain: &str, value: &str) -> Result<(), ()> {
}

if config.options.wait_interval > 0 {
info!("Waiting {} additional seconds...", &config.options.wait_interval);
info!(
"Waiting {} additional seconds...",
&config.options.wait_interval
);

sleep(Duration::from_secs(config.options.wait_interval));

Expand Down Expand Up @@ -172,13 +186,19 @@ pub fn run() -> Result<(), ()> {

if let Some(matches) = matches.subcommand_matches("create") {
let config = read_config(matches.value_of("configfile").unwrap())?;
let domain = lookup_real_domain(&config.options.dns_server, matches.value_of("domain").unwrap());
let domain = lookup_real_domain(
&config.options.dns_server,
matches.value_of("domain").unwrap(),
);
let value = matches.value_of("value").unwrap();

create(&config, &domain, &value)?;
} else if let Some(matches) = matches.subcommand_matches("delete") {
let config = read_config(matches.value_of("configfile").unwrap())?;
let domain = lookup_real_domain(&config.options.dns_server, matches.value_of("domain").unwrap());
let domain = lookup_real_domain(
&config.options.dns_server,
matches.value_of("domain").unwrap(),
);

delete(&config, &domain)?;
} else {
Expand Down
12 changes: 6 additions & 6 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ use serde::Deserialize;
#[serde(default)]
pub struct Config {
pub accounts: Vec<Account>,
pub options: Options
pub options: Options,
}

impl Default for Config {
fn default() -> Config {
Config {
accounts: vec!(),
options: Options::default()
accounts: vec![],
options: Options::default(),
}
}
}
Expand All @@ -23,23 +23,23 @@ pub struct Account {
#[serde(default)]
pub domains: Vec<String>,
#[serde(default)]
pub ote: bool
pub ote: bool,
}

#[derive(Deserialize, Debug, Clone)]
#[serde(default)]
pub struct Options {
pub no_dns_check: bool,
pub wait_interval: u64,
pub dns_server: String
pub dns_server: String,
}

impl Default for Options {
fn default() -> Options {
Options {
no_dns_check: false,
wait_interval: 5,
dns_server: "8.8.8.8".to_owned()
dns_server: "8.8.8.8".to_owned(),
}
}
}
4 changes: 2 additions & 2 deletions src/dns.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use std::str::FromStr;
use trust_dns::client::{Client, SyncClient};
use trust_dns::udp::UdpClientConnection;
use trust_dns::op::DnsResponse;
use trust_dns::rr::{DNSClass, Name, RData, Record, RecordType};
use trust_dns::udp::UdpClientConnection;

fn dns_client(dns_server: &str) -> SyncClient<UdpClientConnection> {
let address = format!("{}:53", dns_server).parse().unwrap();
Expand Down Expand Up @@ -67,7 +67,7 @@ pub fn check_txt_record(dns_server: &str, domain: &str, value: &str) -> bool {
let client = dns_client(dns_server);
let name = match Name::from_str(&add_trailing_dot(domain)) {
Ok(name) => name,
Err(_) => return false
Err(_) => return false,
};

if let Ok(response) = client.query(&name, DNSClass::IN, RecordType::TXT) {
Expand Down
149 changes: 83 additions & 66 deletions src/inwx.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use std::fmt;
use super::config::Account;
use super::rpc::{
RpcError, RpcRequest, RpcRequestParameter, RpcRequestParameterValue, RpcResponse,
};
use cookie::CookieJar;
use std::fmt;
use sxd_xpath::{evaluate_xpath, Value};
use super::rpc::{RpcRequest, RpcResponse, RpcRequestParameter, RpcRequestParameterValue, RpcError};
use super::config::Account;

const API_URL: &str = "https://api.domrobot.com/xmlrpc/";
const OTE_API_URL: &str = "https://api.ote.domrobot.com/xmlrpc/";
Expand All @@ -11,15 +13,17 @@ const OTE_API_URL: &str = "https://api.ote.domrobot.com/xmlrpc/";
pub enum InwxError {
RpcError(RpcError),
DomainNotFound,
RecordNotFound
RecordNotFound,
}

impl fmt::Display for InwxError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
&InwxError::RpcError(ref e) => write!(f, "An inwx api call failed: {}", e),
&InwxError::DomainNotFound => write!(f, "There is no nameserver for the specified domain"),
&InwxError::RecordNotFound => write!(f, "The specified record does not exist")
&InwxError::DomainNotFound => {
write!(f, "There is no nameserver for the specified domain")
}
&InwxError::RecordNotFound => write!(f, "The specified record does not exist"),
}
}
}
Expand All @@ -32,31 +36,34 @@ impl From<RpcError> for InwxError {

pub struct Inwx<'a> {
cookies: CookieJar,
account: &'a Account
account: &'a Account,
}

impl<'a> Inwx<'a> {
fn send_request(&mut self, request: RpcRequest) -> Result<RpcResponse, InwxError> {
let url = match self.account.ote {
true => OTE_API_URL,
false => API_URL
false => API_URL,
};
let response = request.send(url, &mut self.cookies)?;

Ok(response)
}

fn login(&mut self) -> Result<(), InwxError> {
let request = RpcRequest::new("account.login", &[
RpcRequestParameter {
name: "user",
value: RpcRequestParameterValue::String(self.account.username.to_owned())
},
RpcRequestParameter {
name: "pass",
value: RpcRequestParameterValue::String(self.account.password.to_owned())
}
]);
let request = RpcRequest::new(
"account.login",
&[
RpcRequestParameter {
name: "user",
value: RpcRequestParameterValue::String(self.account.username.to_owned()),
},
RpcRequestParameter {
name: "pass",
value: RpcRequestParameterValue::String(self.account.password.to_owned()),
},
],
);

debug!("Logging into account {}", self.account.username);

Expand All @@ -68,7 +75,7 @@ impl<'a> Inwx<'a> {
pub fn new(account: &'a Account) -> Result<Inwx<'a>, InwxError> {
let mut api = Inwx {
cookies: CookieJar::new(),
account
account,
};

api.login()?;
Expand All @@ -83,16 +90,19 @@ impl<'a> Inwx<'a> {

loop {
debug!("Requesting page {} of nameserver.list", page);
let request = RpcRequest::new("nameserver.list", &[
RpcRequestParameter {
name: "pagelimit",
value: RpcRequestParameterValue::Int(page_size)
},
RpcRequestParameter {
name: "page",
value: RpcRequestParameterValue::Int(page)
}
]);
let request = RpcRequest::new(
"nameserver.list",
&[
RpcRequestParameter {
name: "pagelimit",
value: RpcRequestParameterValue::Int(page_size),
},
RpcRequestParameter {
name: "page",
value: RpcRequestParameterValue::Int(page),
},
],
);

let response = self.send_request(request)?;

Expand Down Expand Up @@ -137,24 +147,27 @@ impl<'a> Inwx<'a> {
pub fn create_txt_record(&mut self, domain: &str, content: &str) -> Result<(), InwxError> {
let (domain, name) = self.split_domain(domain)?;

let request = RpcRequest::new("nameserver.createRecord", &[
RpcRequestParameter {
name: "type",
value: RpcRequestParameterValue::String("TXT".to_owned())
},
RpcRequestParameter {
name: "name",
value: RpcRequestParameterValue::String(name)
},
RpcRequestParameter {
name: "content",
value: RpcRequestParameterValue::String(content.to_owned())
},
RpcRequestParameter {
name: "domain",
value: RpcRequestParameterValue::String(domain)
}
]);
let request = RpcRequest::new(
"nameserver.createRecord",
&[
RpcRequestParameter {
name: "type",
value: RpcRequestParameterValue::String("TXT".to_owned()),
},
RpcRequestParameter {
name: "name",
value: RpcRequestParameterValue::String(name),
},
RpcRequestParameter {
name: "content",
value: RpcRequestParameterValue::String(content.to_owned()),
},
RpcRequestParameter {
name: "domain",
value: RpcRequestParameterValue::String(domain),
},
],
);

self.send_request(request)?;

Expand All @@ -164,20 +177,23 @@ impl<'a> Inwx<'a> {
pub fn get_record_id(&mut self, domain: &str) -> Result<i32, InwxError> {
let (domain, name) = self.split_domain(domain)?;

let request = RpcRequest::new("nameserver.info", &[
RpcRequestParameter {
name: "type",
value: RpcRequestParameterValue::String("TXT".to_owned())
},
RpcRequestParameter {
name: "name",
value: RpcRequestParameterValue::String(name.to_owned())
},
RpcRequestParameter {
name: "domain",
value: RpcRequestParameterValue::String(domain.to_owned())
}
]);
let request = RpcRequest::new(
"nameserver.info",
&[
RpcRequestParameter {
name: "type",
value: RpcRequestParameterValue::String("TXT".to_owned()),
},
RpcRequestParameter {
name: "name",
value: RpcRequestParameterValue::String(name.to_owned()),
},
RpcRequestParameter {
name: "domain",
value: RpcRequestParameterValue::String(domain.to_owned()),
},
],
);

let response = self.send_request(request)?;

Expand All @@ -192,12 +208,13 @@ impl<'a> Inwx<'a> {
pub fn delete_txt_record(&mut self, domain: &str) -> Result<(), InwxError> {
let id = self.get_record_id(domain)?;

let request = RpcRequest::new("nameserver.deleteRecord", &[
RpcRequestParameter {
let request = RpcRequest::new(
"nameserver.deleteRecord",
&[RpcRequestParameter {
name: "id",
value: RpcRequestParameterValue::Int(id)
}
]);
value: RpcRequestParameterValue::Int(id),
}],
);

self.send_request(request)?;

Expand Down
Loading

0 comments on commit 6f7b0ae

Please sign in to comment.