Add new IP source "seeip" (#90)

This commit is contained in:
Kaan Barmore-Genç 2023-02-01 23:19:57 -05:00 committed by GitHub
parent 327b14a00a
commit 27a60d3ac2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 61 additions and 3 deletions

View File

@ -19,8 +19,9 @@ ttl = 300
# Ipify is used by default. If you want to change it, uncomment the one you want
# to use.
#
# ip_source = "Ipify"
# ip_source = "Icanhazip"
#ip_source = "Ipify" # An open source and public service. https://github.com/rdegges/ipify-api
#ip_source = "Icanhazip" # A free service, currently run by Cloudflare. https://major.io/2021/06/06/a-new-future-for-icanhazip/
#ip_source = "SeeIP" # A free service, run by UNVIO, LLC. https://seeip.org/
# For every domain or subdomain you want to update, create an entry below.

View File

@ -25,6 +25,7 @@ fn default_ttl() -> u32 {
pub enum IPSourceName {
Ipify,
Icanhazip,
SeeIP,
}
impl Default for IPSourceName {

View File

@ -2,5 +2,5 @@ The IP sources. These are APIs that we can query to get the IP address of the
current service.
The tests under this directory are all marked to be skipped, the tests hit the
actual APIs and can be flakey in CI. Make sure to run the tests manually if you
actual APIs and can be flaky in CI. Make sure to run the tests manually if you
have to modify the code.

View File

@ -1,3 +1,4 @@
pub(crate) mod icanhazip;
pub(crate) mod ip_source;
pub(crate) mod ipify;
pub(crate) mod seeip;

53
src/ip_source/seeip.rs Normal file
View File

@ -0,0 +1,53 @@
use async_trait::async_trait;
use super::ip_source::IPSource;
pub(crate) struct IPSourceSeeIP;
async fn get_ip(api_url: &str) -> anyhow::Result<String> {
let response = reqwest::get(api_url).await?;
let text = response.text().await?;
Ok(text)
}
#[async_trait]
impl IPSource for IPSourceSeeIP {
async fn get_ipv4(&self) -> anyhow::Result<String> {
get_ip("https://ip4.seeip.org").await
}
async fn get_ipv6(&self) -> anyhow::Result<String> {
get_ip("https://ip6.seeip.org").await
}
}
#[cfg(test)]
mod tests {
use regex::Regex;
use super::IPSource;
use super::IPSourceSeeIP;
#[tokio::test]
#[ignore]
async fn ipv4_test() {
let ipv4 = IPSourceSeeIP
.get_ipv4()
.await
.expect("Failed to get the IP address");
assert!(Regex::new(r"^\d+[.]\d+[.]\d+[.]\d+$")
.unwrap()
.is_match(ipv4.as_str()))
}
#[tokio::test]
#[ignore]
async fn ipv6_test() {
let ipv6 = IPSourceSeeIP
.get_ipv6()
.await
.expect("Failed to get the IP address");
assert!(Regex::new(r"^([0-9a-fA-F]*:){7}[0-9a-fA-F]*$")
.unwrap()
.is_match(ipv6.as_str()))
}
}

View File

@ -4,6 +4,7 @@ use crate::ip_source::{ip_source::IPSource, ipify::IPSourceIpify};
use clap::Parser;
use config::IPSourceName;
use ip_source::icanhazip::IPSourceIcanhazip;
use ip_source::seeip::IPSourceSeeIP;
use opts::Opts;
use reqwest::{header, Client, ClientBuilder, StatusCode};
use serde::Serialize;
@ -158,6 +159,7 @@ async fn main() -> anyhow::Result<()> {
let ip_source: Box<dyn IPSource> = match conf.ip_source {
IPSourceName::Ipify => Box::new(IPSourceIpify),
IPSourceName::Icanhazip => Box::new(IPSourceIcanhazip),
IPSourceName::SeeIP => Box::new(IPSourceSeeIP),
};
config::validate_config(&conf).die_with(|error| format!("Invalid config: {}", error));
run("https://api.gandi.net", &ip_source, &conf, &opts).await?;