Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,5 @@ Cargo.lock
*.json
!*.example.json
*.env

.DS_Store
16 changes: 8 additions & 8 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
[package]
name = "update_dns_records"
version = "0.1.0"
version = "0.2.0"
edition = "2021"

[dependencies]
serde_json = "1"
bytes = "1"
serde_json = "1.0"
bytes = "1.11"
serde = { version = "1.0", features = ["derive"] }
tokio = { version = "1", features = ["full"] }
tokio-native-tls = { version = "0.3.1" }
tokio = { version = "1.51", features = ["full"] }
tokio-native-tls = { version = "0.3" }
hyper-util = { version = "0.1", features = ["full"] }
native-tls = "0.2"
hyper = { version = "1", features = ["full"] }
hyper = { version = "1.9", features = ["full"] }
http-body-util = "0.1"
rand = "0.8.5"
base64 = { version = "0.21" }
rand = "0.8"
base64 = { version = "0.22" }

[features]
default = ["cloudflare", "dyndns2"]
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
BSD 3-Clause License

Copyright (c) 2024, W-lfpup
Copyright (c) 2024, Taylor Vann

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
Expand Down
4 changes: 2 additions & 2 deletions src/toolkit/config.rs → src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use serde_json;
use std::path;
use tokio::fs;

use crate::toolkit::domain_services::DomainServices;
use crate::toolkit::ip_services::IpServices;
use crate::domain_services::DomainServices;
use crate::ip_services::IpServices;

#[derive(Clone, Serialize, Deserialize, Debug)]
pub struct Config {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,23 @@ use hyper::Request;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;

use crate::toolkit::config::Config;
use crate::toolkit::domain_services::cloudflare::Cloudflare;
use crate::toolkit::requests::{request_http1_tls_response, ResponseJson};
use crate::toolkit::results::{DomainResult, UpdateIpResults};
use crate::domain_services::DomainServices;
use crate::requests::{request_http1_tls_response, ResponseDetails};
use crate::results::{DomainResult, UpdateIpResults};

#[derive(Clone, Serialize, Deserialize, Debug)]
pub struct Cloudflare {
pub api_token: String,
pub dns_record_id: String,
pub email: String,
pub name: String,
pub r#type: String,
pub zone_id: String,
pub comment: Option<String>,
pub proxied: Option<bool>,
pub tags: Option<Vec<String>>,
pub ttl: Option<usize>,
}

#[derive(Clone, Serialize, Debug)]
pub struct CloudflareRequestBody {
Expand All @@ -37,12 +50,12 @@ pub struct CloudflareMinimalResponseBody {
}

pub async fn update_domains(
config: &Config,
domain_services: &DomainServices,
prev_results: &Result<UpdateIpResults, String>,
domain_results: &mut HashMap<String, DomainResult>,
ip_address: &str,
) {
let domains = match &config.domain_services.cloudflare {
let domains = match &domain_services.cloudflare {
Some(domains) => domains,
_ => return,
};
Expand All @@ -65,9 +78,7 @@ pub async fn update_domains(
}
}

// build domain result
domain_result = build_domain_result(&domain, ip_address).await;
// write over previous entry
domain_results.insert(hostname, domain_result);
}
}
Expand Down Expand Up @@ -99,7 +110,7 @@ async fn build_domain_result(domain: &Cloudflare, ip_address: &str) -> DomainRes
domain_result
}

fn verify_resposne(res: &ResponseJson) -> bool {
fn verify_resposne(res: &ResponseDetails) -> bool {
if res.status_code != 200 {
return false;
}
Expand Down
13 changes: 0 additions & 13 deletions src/domain_services/cloudflare/README.md

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,30 @@ use base64::{engine::general_purpose, Engine as _};
use bytes::Bytes;
use http_body_util::Full;
use hyper::Request;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;

use crate::toolkit::config::Config;
use crate::toolkit::domain_services::dyndns2::Dyndns2;
use crate::toolkit::requests::{request_http1_tls_response, ResponseJson};
use crate::toolkit::results::{DomainResult, UpdateIpResults};
use crate::domain_services::DomainServices;
use crate::requests::{request_http1_tls_response, ResponseDetails};
use crate::results::{DomainResult, UpdateIpResults};

#[derive(Clone, Serialize, Deserialize, Debug)]
pub struct Dyndns2 {
pub hostname: String,
pub password: String,
pub service_uri: String,
pub username: String,
}

const CLIENT_HEADER_VALUE: &str = "hyper/1.0 rust-client";

// must return results
pub async fn update_domains(
config: &Config,
domain_services: &DomainServices,
prev_results: &Result<UpdateIpResults, String>,
domain_results: &mut HashMap<String, DomainResult>,
ip_address: &str,
) {
let domains = match &config.domain_services.dyndns2 {
let domains = match &domain_services.dyndns2 {
Some(domains) => domains,
_ => return,
};
Expand Down Expand Up @@ -82,7 +89,7 @@ async fn build_domain_result(domain: &Dyndns2, ip_address: &str) -> DomainResult
domain_result
}

fn verify_resposne(res: &ResponseJson) -> bool {
fn verify_resposne(res: &ResponseDetails) -> bool {
if res.status_code < 200 || res.status_code >= 300 {
return false;
}
Expand Down
30 changes: 25 additions & 5 deletions src/domain_services/mod.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
use serde::{Deserialize, Serialize};
use std::collections::HashMap;

use crate::toolkit::config::Config;
use crate::toolkit::results::{DomainResult, IpServiceResult, UpdateIpResults};
use crate::results::{DomainResult, IpServiceResult, UpdateIpResults};

#[cfg(feature = "cloudflare")]
mod cloudflare;
#[cfg(feature = "dyndns2")]
mod dyndns2;

#[derive(Clone, Serialize, Deserialize, Debug)]
pub struct DomainServices {
#[cfg(feature = "cloudflare")]
pub cloudflare: Option<Vec<cloudflare::Cloudflare>>,
#[cfg(feature = "dyndns2")]
pub dyndns2: Option<Vec<dyndns2::Dyndns2>>,
}

pub async fn update_domains(
config: &Config,
domain_services: &DomainServices,
prev_results: &Result<UpdateIpResults, String>,
ip_service_result: &IpServiceResult,
) -> Result<HashMap<String, DomainResult>, String> {
Expand All @@ -21,10 +29,22 @@ pub async fn update_domains(
let mut domain_results = HashMap::<String, DomainResult>::new();

#[cfg(feature = "dyndns2")]
dyndns2::update_domains(config, prev_results, &mut domain_results, &ip_address).await;
dyndns2::update_domains(
domain_services,
prev_results,
&mut domain_results,
&ip_address,
)
.await;

#[cfg(feature = "cloudflare")]
cloudflare::update_domains(config, prev_results, &mut domain_results, &ip_address).await;
cloudflare::update_domains(
domain_services,
prev_results,
&mut domain_results,
&ip_address,
)
.await;

Ok(domain_results)
}
Expand Down
34 changes: 5 additions & 29 deletions src/ip_services/address_as_body.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
use bytes::Bytes;
use http_body_util::Full;
use hyper::Request;
use std::net;

use crate::toolkit::requests::{get_host_and_authority, request_http1_tls_response, ResponseJson};
use crate::requests::{
create_request_with_empty_body, request_http1_tls_response, ResponseDetails,
};

pub async fn request_address_as_body(service: &str) -> Result<ResponseJson, String> {
pub async fn request_address_as_body(service: &str) -> Result<ResponseDetails, String> {
let request = match create_request_with_empty_body(service) {
Ok(req) => req,
Err(e) => return Err(e),
Expand All @@ -17,7 +16,7 @@ pub async fn request_address_as_body(service: &str) -> Result<ResponseJson, Stri
}
}

pub async fn get_ip_address_from_body(response_json: &ResponseJson) -> Result<String, String> {
pub async fn get_ip_address_from_body(response_json: &ResponseDetails) -> Result<String, String> {
if response_json.status_code != 200 {
return Err("response_json was not okay".to_string());
}
Expand All @@ -30,26 +29,3 @@ pub async fn get_ip_address_from_body(response_json: &ResponseJson) -> Result<St

Ok(ip_address)
}

fn create_request_with_empty_body(url_string: &str) -> Result<Request<Full<Bytes>>, String> {
let uri = match hyper::Uri::try_from(url_string) {
Ok(u) => u,
Err(e) => return Err(e.to_string()),
};

let (_, authority) = match get_host_and_authority(&uri) {
Some(u) => u.clone(),
_ => return Err("authority not found in url".to_string()),
};

let req = match Request::builder()
.uri(uri)
.header(hyper::header::HOST, authority.as_str())
.body(Full::new(bytes::Bytes::new()))
{
Ok(r) => r,
Err(e) => return Err(e.to_string()),
};

Ok(req)
}
10 changes: 5 additions & 5 deletions src/ip_services/mod.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
use rand::{thread_rng, Rng};

use crate::toolkit::config::Config;
use crate::toolkit::ip_services::IpServices;
use crate::toolkit::results::{IpServiceResult, UpdateIpResults};
use crate::results::{IpServiceResult, UpdateIpResults};

mod address_as_body;

pub type IpServices = Vec<(String, String)>;

pub async fn fetch_service_results(
config: &Config,
ip_services: &IpServices,
prev_results: &Result<UpdateIpResults, String>,
) -> Result<IpServiceResult, String> {
let service = match prev_results {
Ok(results) => &results.ip_service_result.service,
_ => "previous-results-do-not-exist",
};

let (ip_service, response_type) = match get_random_ip_service(&config.ip_services, service) {
let (ip_service, response_type) = match get_random_ip_service(ip_services, service) {
Some(r) => r,
_ => return Err("failed to find ip service".to_string()),
};
Expand Down
29 changes: 18 additions & 11 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use std::{env, path};

mod config;
mod domain_services;
mod ip_services;
mod toolkit;

use crate::toolkit::{config, results};
mod requests;
mod results;

#[tokio::main]
async fn main() -> Result<(), String> {
Expand All @@ -20,15 +20,22 @@ async fn main() -> Result<(), String> {
Err(e) => return Err(e),
};

let prev_results = results::read_results_from_disk(&config).await;
let prev_results = results::read_results_from_disk(&config.results_filepath).await;

let ip_service_result = match ip_services::fetch_service_results(&config, &prev_results).await {
Ok(ip_result) => ip_result,
Err(e) => return Err(e),
};
let ip_service_result =
match ip_services::fetch_service_results(&config.ip_services, &prev_results).await {
Ok(ip_result) => ip_result,
Err(e) => return Err(e),
};

let domain_service_results =
domain_services::update_domains(&config, &prev_results, &ip_service_result).await;

results::write_results_to_disk(&config, ip_service_result, domain_service_results).await
domain_services::update_domains(&config.domain_services, &prev_results, &ip_service_result)
.await;

results::write_results_to_disk(
&config.results_filepath,
ip_service_result,
domain_service_results,
)
.await
}
Loading
Loading