add cache to reduce load on cloudflare
Some checks failed
Docker Image CI / build (push) Failing after 12s
Some checks failed
Docker Image CI / build (push) Failing after 12s
This commit is contained in:
45
.vscode/launch.json
vendored
Normal file
45
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"type": "lldb",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Debug executable 'cloudflare-dynamic-dns'",
|
||||||
|
"cargo": {
|
||||||
|
"args": [
|
||||||
|
"build",
|
||||||
|
"--bin=cloudflare-dynamic-dns",
|
||||||
|
"--package=cloudflare-dynamic-dns"
|
||||||
|
],
|
||||||
|
"filter": {
|
||||||
|
"name": "cloudflare-dynamic-dns",
|
||||||
|
"kind": "bin"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"args": [],
|
||||||
|
"cwd": "${workspaceFolder}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "lldb",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Debug unit tests in executable 'cloudflare-dynamic-dns'",
|
||||||
|
"cargo": {
|
||||||
|
"args": [
|
||||||
|
"test",
|
||||||
|
"--no-run",
|
||||||
|
"--bin=cloudflare-dynamic-dns",
|
||||||
|
"--package=cloudflare-dynamic-dns"
|
||||||
|
],
|
||||||
|
"filter": {
|
||||||
|
"name": "cloudflare-dynamic-dns",
|
||||||
|
"kind": "bin"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"args": [],
|
||||||
|
"cwd": "${workspaceFolder}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
55
src/main.rs
55
src/main.rs
@@ -11,6 +11,11 @@ use serde_json::Value;
|
|||||||
|
|
||||||
use crate::errors::Error;
|
use crate::errors::Error;
|
||||||
|
|
||||||
|
struct CloudflareDnsEntry {
|
||||||
|
id: String,
|
||||||
|
ip_address: String,
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
env_logger::Builder::from_default_env()
|
env_logger::Builder::from_default_env()
|
||||||
.target(env_logger::Target::Stdout)
|
.target(env_logger::Target::Stdout)
|
||||||
@@ -20,35 +25,49 @@ fn main() {
|
|||||||
dotenv().ok();
|
dotenv().ok();
|
||||||
let (token, zone_id, domain) = get_and_ensure_env_vars();
|
let (token, zone_id, domain) = get_and_ensure_env_vars();
|
||||||
|
|
||||||
|
let mut cache = None;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let result = update(&token, &zone_id, &domain);
|
let result = update_and_get_cache(cache, &token, &zone_id, &domain);
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
Ok(_) => (),
|
Ok(entry) => cache = Some(entry),
|
||||||
Err(err) => error!("{}", err.message),
|
Err(err) => {
|
||||||
|
error!("{}", err.message);
|
||||||
|
cache = None;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
sleep(Duration::from_secs(5 * 60));
|
sleep(Duration::from_secs(5 * 60));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(token: &str, zone_id: &str, domain: &str) -> Result<(), Error> {
|
fn update_and_get_cache(
|
||||||
let (id, content) = get_id_and_content_of_dns(token, zone_id, domain)?;
|
cache: Option<CloudflareDnsEntry>,
|
||||||
|
token: &str,
|
||||||
|
zone_id: &str,
|
||||||
|
domain: &str,
|
||||||
|
) -> Result<CloudflareDnsEntry, Error> {
|
||||||
|
let result = match cache {
|
||||||
|
Some(entry) => entry,
|
||||||
|
None => get_id_and_content_of_dns(token, zone_id, domain)?,
|
||||||
|
};
|
||||||
|
|
||||||
let current_ip_address = get_public_ip_address()?;
|
let current_ip_address = get_public_ip_address()?;
|
||||||
|
|
||||||
if content == current_ip_address {
|
if result.ip_address == current_ip_address {
|
||||||
info!("Not updating IP Address");
|
info!("Not updating IP Address");
|
||||||
} else {
|
} else {
|
||||||
update_ip_address(token, zone_id, ¤t_ip_address, domain, &id)?;
|
update_ip_address(token, zone_id, ¤t_ip_address, domain, &result.id)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_id_and_content_of_dns(
|
fn get_id_and_content_of_dns(
|
||||||
token: &str,
|
token: &str,
|
||||||
zone_id: &str,
|
zone_id: &str,
|
||||||
domain: &str,
|
domain: &str,
|
||||||
) -> Result<(String, String), Error> {
|
) -> Result<CloudflareDnsEntry, Error> {
|
||||||
let client = reqwest::blocking::Client::new();
|
let client = reqwest::blocking::Client::new();
|
||||||
|
|
||||||
let resp = client
|
let resp = client
|
||||||
@@ -59,6 +78,8 @@ fn get_id_and_content_of_dns(
|
|||||||
.send()
|
.send()
|
||||||
.map_err(|err| Error::new(err.to_string().as_str()))?;
|
.map_err(|err| Error::new(err.to_string().as_str()))?;
|
||||||
|
|
||||||
|
info!("Fetched current DNS record from Cloudflare");
|
||||||
|
|
||||||
let content = resp
|
let content = resp
|
||||||
.text()
|
.text()
|
||||||
.map_err(|err| Error::new(err.to_string().as_str()))?;
|
.map_err(|err| Error::new(err.to_string().as_str()))?;
|
||||||
@@ -73,22 +94,22 @@ fn get_id_and_content_of_dns(
|
|||||||
|
|
||||||
for value in array {
|
for value in array {
|
||||||
if value["name"] == domain {
|
if value["name"] == domain {
|
||||||
return Ok((
|
return Ok(CloudflareDnsEntry {
|
||||||
String::from(
|
id: String::from(
|
||||||
value["id"]
|
value["id"]
|
||||||
.as_str()
|
.as_str()
|
||||||
.ok_or(Error::new("Could not parse id"))?,
|
.ok_or(Error::new("Could not parse id"))?,
|
||||||
),
|
),
|
||||||
String::from(
|
ip_address: String::from(
|
||||||
value["content"]
|
value["content"]
|
||||||
.as_str()
|
.as_str()
|
||||||
.ok_or(Error::new("Could not parse content"))?,
|
.ok_or(Error::new("Could not parse content"))?,
|
||||||
),
|
),
|
||||||
));
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
panic!();
|
Err(Error::new("No Element in Array"))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_ip_address(
|
fn update_ip_address(
|
||||||
@@ -126,9 +147,9 @@ fn get_and_ensure_env_vars() -> (String, String, String) {
|
|||||||
let mut domain: Option<String> = Option::None;
|
let mut domain: Option<String> = Option::None;
|
||||||
|
|
||||||
env::vars().for_each(|(key, value)| match key.as_str() {
|
env::vars().for_each(|(key, value)| match key.as_str() {
|
||||||
"AUTH_BEARER" => token = Some(String::from(value)),
|
"AUTH_BEARER" => token = Some(value),
|
||||||
"ZONE_ID" => zone_id = Some(String::from(value)),
|
"ZONE_ID" => zone_id = Some(value),
|
||||||
"DOMAIN" => domain = Some(String::from(value)),
|
"DOMAIN" => domain = Some(value),
|
||||||
_ => {}
|
_ => {}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user