Compare commits
No commits in common. "d8f547d1e78af2ba09b32813d569fb5470758388" and "552454cf6e1eca9f5bed43a3ad6a7ddf337d6678" have entirely different histories.
d8f547d1e7
...
552454cf6e
11 changed files with 40 additions and 276 deletions
|
@ -1,9 +1,7 @@
|
||||||
# ddnsclient
|
# ddnsclient
|
||||||
|
|
||||||
This application can be use to update dynamic hostnames. Currently it implements the following DynDNS providers:
|
This application can be use to update dynamic hostnames. Currently it implements only the ddnss.de provider, but it
|
||||||
|
is extensible and more providers can be added easily.
|
||||||
- ddnss.de
|
|
||||||
- duckdns.org
|
|
||||||
|
|
||||||
This project uses Quarkus.
|
This project uses Quarkus.
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ public class Updater {
|
||||||
}
|
}
|
||||||
|
|
||||||
void run() {
|
void run() {
|
||||||
log.info("Updater running.");
|
log.trace("Updater running.");
|
||||||
|
|
||||||
if (config.isEmpty()) {
|
if (config.isEmpty()) {
|
||||||
throw new IllegalStateException("Missing configuration");
|
throw new IllegalStateException("Missing configuration");
|
||||||
|
@ -58,7 +58,7 @@ public class Updater {
|
||||||
|
|
||||||
if (updateMap.containsKey(cfg.hostname())
|
if (updateMap.containsKey(cfg.hostname())
|
||||||
&& Duration.between(updateMap.get(cfg.hostname()), LocalDateTime.now()).toSeconds() < backoff.toSeconds()) {
|
&& Duration.between(updateMap.get(cfg.hostname()), LocalDateTime.now()).toSeconds() < backoff.toSeconds()) {
|
||||||
log.info("Back-off period, skipping update.");
|
log.debug("Back-off period, skipping update.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ public class Updater {
|
||||||
dynDns.update(cfg.hostname(), publicIps, new DyndnsAuth(null, null, cfg.token()));
|
dynDns.update(cfg.hostname(), publicIps, new DyndnsAuth(null, null, cfg.token()));
|
||||||
updateMap.put(cfg.hostname(), LocalDateTime.now());
|
updateMap.put(cfg.hostname(), LocalDateTime.now());
|
||||||
} else {
|
} else {
|
||||||
log.infof("Hostname %s is up-to-date.", cfg.hostname());
|
log.debugf("Hostname is up-to-date.", cfg.hostname());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,9 @@ import jakarta.enterprise.context.ApplicationScoped;
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.URI;
|
||||||
import java.net.http.HttpClient;
|
import java.net.http.HttpClient;
|
||||||
|
import java.net.http.HttpRequest;
|
||||||
import java.net.http.HttpResponse;
|
import java.net.http.HttpResponse;
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
|
|
||||||
|
@ -27,29 +29,26 @@ public class Ddnss implements DynDns {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update(String hostname, IPs currentIps, DyndnsAuth auth) {
|
public void update(String hostname, IPs currentIps, DyndnsAuth auth) {
|
||||||
log.tracef("Updating ddnss hostname %s", hostname);
|
|
||||||
|
String updateUrl = MessageFormat.format("https://ddnss.de/upd.php?key={0}&host={1}&ip={2}&ip6={3}",
|
||||||
|
auth.token(), hostname, currentIps.v4(), currentIps.v6());
|
||||||
|
|
||||||
try (HttpClient http = httpClientFactory.create()) {
|
try (HttpClient http = httpClientFactory.create()) {
|
||||||
String updateUrl = getUpdateUrl(hostname, currentIps, auth.token());
|
|
||||||
HttpResponse<String> response = http.send(getRequest(updateUrl), HttpResponse.BodyHandlers.ofString());
|
HttpRequest request = HttpRequest.newBuilder()
|
||||||
|
.header("User-Agent", "ddns-client")
|
||||||
|
.GET()
|
||||||
|
.uri(URI.create(updateUrl))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
HttpResponse<String> response = http.send(request, HttpResponse.BodyHandlers.ofString());
|
||||||
if (response.statusCode() != 200) {
|
if (response.statusCode() != 200) {
|
||||||
log.errorf("Couldn't update hostname %s." + hostname);
|
log.errorf("Couldn't update hostname %s." + hostname);
|
||||||
}
|
}
|
||||||
log.infof("Hostname %s updated.", hostname);
|
log.info("Hostname updated.");
|
||||||
} catch (IOException | InterruptedException e) {
|
} catch (IOException | InterruptedException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getUpdateUrl(String hostname, IPs currentIps, String token) {
|
|
||||||
if (currentIps.v4().isPresent() && currentIps.v6().isPresent()) {
|
|
||||||
return MessageFormat.format("https://ddnss.de/upd.php?key={0}&host={1}&ip={2}&ip6={3}", token, hostname, currentIps.v4().get(), currentIps.v6().get());
|
|
||||||
} else if (currentIps.v4().isPresent()) {
|
|
||||||
return MessageFormat.format("https://ddnss.de/upd.php?key={0}&host={1}&ip={2}", token, hostname, currentIps.v4().get());
|
|
||||||
} else if (currentIps.v6().isPresent()) {
|
|
||||||
return MessageFormat.format("https://ddnss.de/upd.php?key={0}&host={1}&ip6={2}", token, hostname, currentIps.v6().get());
|
|
||||||
}
|
|
||||||
throw new RuntimeException("No ips to update!");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,58 +0,0 @@
|
||||||
package de.rpr.ddnsclient.dyndns;
|
|
||||||
|
|
||||||
import de.rpr.ddnsclient.model.DyndnsAuth;
|
|
||||||
import de.rpr.ddnsclient.model.IPs;
|
|
||||||
import jakarta.enterprise.context.ApplicationScoped;
|
|
||||||
import org.jboss.logging.Logger;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.http.HttpClient;
|
|
||||||
import java.net.http.HttpResponse;
|
|
||||||
import java.text.MessageFormat;
|
|
||||||
|
|
||||||
@ApplicationScoped
|
|
||||||
public class DuckDNS implements DynDns {
|
|
||||||
|
|
||||||
private static final Logger log = Logger.getLogger(DuckDNS.class);
|
|
||||||
|
|
||||||
private final HttpClientFactory httpClientFactory;
|
|
||||||
|
|
||||||
public DuckDNS(HttpClientFactory httpClientFactory) {
|
|
||||||
this.httpClientFactory = httpClientFactory;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String name() {
|
|
||||||
return "duckdns";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void update(String hostname, IPs currentIps, DyndnsAuth auth) {
|
|
||||||
log.tracef("Updating duckdns hostname %s", hostname);
|
|
||||||
|
|
||||||
try (HttpClient http = httpClientFactory.create()) {
|
|
||||||
String updateUrl = getUpdateUrl(hostname, currentIps, auth.token());
|
|
||||||
HttpResponse<String> response = http.send(getRequest(updateUrl), HttpResponse.BodyHandlers.ofString());
|
|
||||||
if (response.statusCode() != 200) {
|
|
||||||
log.errorf("Couldn't update hostname %s." + hostname);
|
|
||||||
} else if (!response.body().equals("OK")) {
|
|
||||||
throw new RuntimeException("Couldn't update hostname!");
|
|
||||||
}
|
|
||||||
log.infof("Hostname %s updated.", hostname);
|
|
||||||
} catch (IOException | InterruptedException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getUpdateUrl(String hostname, IPs currentIps, String token) {
|
|
||||||
if (currentIps.v4().isPresent() && currentIps.v6().isPresent()) {
|
|
||||||
return MessageFormat.format("https://www.duckdns.org/update?domains={0}&token={1}&ip={2}&ipv6={3}", hostname, token, currentIps.v4().get(), currentIps.v6().get());
|
|
||||||
} else if (currentIps.v4().isPresent()) {
|
|
||||||
return MessageFormat.format("https://www.duckdns.org/update?domains={0}&token={1}&ip={2}", hostname, token, currentIps.v4().get());
|
|
||||||
} else if (currentIps.v6().isPresent()) {
|
|
||||||
return MessageFormat.format("https://www.duckdns.org/update?domains={0}&token={1}&ipv6={2}", hostname, token, currentIps.v6().get());
|
|
||||||
}
|
|
||||||
throw new RuntimeException("No ips to update!");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -3,20 +3,9 @@ package de.rpr.ddnsclient.dyndns;
|
||||||
import de.rpr.ddnsclient.model.DyndnsAuth;
|
import de.rpr.ddnsclient.model.DyndnsAuth;
|
||||||
import de.rpr.ddnsclient.model.IPs;
|
import de.rpr.ddnsclient.model.IPs;
|
||||||
|
|
||||||
import java.net.URI;
|
|
||||||
import java.net.http.HttpRequest;
|
|
||||||
|
|
||||||
public interface DynDns {
|
public interface DynDns {
|
||||||
|
|
||||||
String name();
|
String name();
|
||||||
|
|
||||||
void update(String hostname, IPs currentIps, DyndnsAuth auth);
|
void update(String hostname, IPs currentIps, DyndnsAuth auth);
|
||||||
|
|
||||||
default HttpRequest getRequest(String updateUrl) {
|
|
||||||
return HttpRequest.newBuilder()
|
|
||||||
.header("User-Agent", "ddns-client")
|
|
||||||
.GET()
|
|
||||||
.uri(URI.create(updateUrl))
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@ package de.rpr.ddnsclient.lookup;
|
||||||
import de.rpr.ddnsclient.model.IPs;
|
import de.rpr.ddnsclient.model.IPs;
|
||||||
import jakarta.enterprise.context.ApplicationScoped;
|
import jakarta.enterprise.context.ApplicationScoped;
|
||||||
import org.eclipse.microprofile.config.inject.ConfigProperty;
|
import org.eclipse.microprofile.config.inject.ConfigProperty;
|
||||||
import org.jboss.logging.Logger;
|
|
||||||
import org.xbill.DNS.Record;
|
import org.xbill.DNS.Record;
|
||||||
import org.xbill.DNS.*;
|
import org.xbill.DNS.*;
|
||||||
|
|
||||||
|
@ -12,8 +11,6 @@ import java.util.Optional;
|
||||||
@ApplicationScoped
|
@ApplicationScoped
|
||||||
public class DnsJava implements DnsResolver {
|
public class DnsJava implements DnsResolver {
|
||||||
|
|
||||||
private static final Logger log = Logger.getLogger(DnsJava.class);
|
|
||||||
|
|
||||||
private final String resolverAddress;
|
private final String resolverAddress;
|
||||||
|
|
||||||
public DnsJava(@ConfigProperty(name = "ddnsclient.dns.resolver", defaultValue = "9.9.9.9") String resolverAddress) {
|
public DnsJava(@ConfigProperty(name = "ddnsclient.dns.resolver", defaultValue = "9.9.9.9") String resolverAddress) {
|
||||||
|
@ -22,24 +19,19 @@ public class DnsJava implements DnsResolver {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IPs resolve(String hostname) {
|
public IPs resolve(String hostname) {
|
||||||
Optional<String> v4 = getIp(hostname, RecordType.A);
|
String v4 = getIp(hostname, Type.A).orElseThrow(() -> new RuntimeException("Missing A Record"));
|
||||||
Optional<String> v6 = getIp(hostname, RecordType.AAAA);
|
String v6 = getIp(hostname, Type.AAAA).orElseThrow(() -> new RuntimeException("Missing AAAA Record"));
|
||||||
return new IPs(v4, v6);
|
return new IPs(v4, v6);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Optional<String> getIp(String hostname, RecordType type) {
|
private Optional<String> getIp(String hostname, int type) {
|
||||||
try {
|
try {
|
||||||
SimpleResolver resolver = new SimpleResolver(resolverAddress);
|
SimpleResolver resolver = new SimpleResolver(resolverAddress);
|
||||||
|
|
||||||
Lookup lookup = new Lookup(hostname, type.value);
|
Lookup lookup = new Lookup(hostname, type);
|
||||||
lookup.setResolver(resolver);
|
lookup.setResolver(resolver);
|
||||||
|
|
||||||
Record[] records = lookup.run();
|
Record[] records = lookup.run();
|
||||||
if (records == null || records.length == 0) {
|
|
||||||
log.infof("Hostname %s has no record for type %s found", hostname, type.name());
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Record record : records) {
|
for (Record record : records) {
|
||||||
if (record instanceof ARecord) {
|
if (record instanceof ARecord) {
|
||||||
return Optional.of(((ARecord) record).getAddress().getHostAddress());
|
return Optional.of(((ARecord) record).getAddress().getHostAddress());
|
||||||
|
@ -53,15 +45,4 @@ public class DnsJava implements DnsResolver {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private enum RecordType {
|
|
||||||
A(1),
|
|
||||||
AAAA(28);
|
|
||||||
|
|
||||||
private final int value; // org.bill.DNS.Type.AAAA
|
|
||||||
|
|
||||||
RecordType(int value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,10 @@ public class PublicIpLookup {
|
||||||
private final CurlProcessFactory curlProcessFactory;
|
private final CurlProcessFactory curlProcessFactory;
|
||||||
private final Optional<String> configuredProvider;
|
private final Optional<String> configuredProvider;
|
||||||
|
|
||||||
PublicIpLookup(CurlProcessFactory curlProcessFactory, @ConfigProperty(name = "ddnsclient.ip-provider") Optional<String> configuredProvider) {
|
PublicIpLookup(
|
||||||
|
CurlProcessFactory curlProcessFactory,
|
||||||
|
@ConfigProperty(name = "ddnsclient.ip-provider") Optional<String> configuredProvider
|
||||||
|
) {
|
||||||
this.curlProcessFactory = curlProcessFactory;
|
this.curlProcessFactory = curlProcessFactory;
|
||||||
this.configuredProvider = configuredProvider;
|
this.configuredProvider = configuredProvider;
|
||||||
}
|
}
|
||||||
|
@ -32,7 +35,8 @@ public class PublicIpLookup {
|
||||||
configuredProvider.ifPresent(it -> {
|
configuredProvider.ifPresent(it -> {
|
||||||
log.tracef("Setting ip lookup provider %s", it);
|
log.tracef("Setting ip lookup provider %s", it);
|
||||||
provider = Optional.of(IpLookupProviders.get(it));
|
provider = Optional.of(IpLookupProviders.get(it));
|
||||||
});
|
}
|
||||||
|
);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new IllegalStateException("Unknow provider configured!", e);
|
throw new IllegalStateException("Unknow provider configured!", e);
|
||||||
}
|
}
|
||||||
|
@ -44,8 +48,8 @@ public class PublicIpLookup {
|
||||||
try {
|
try {
|
||||||
String provider = this.provider.map(it -> it.url).orElseGet(() -> IpLookupProviders.random().url);
|
String provider = this.provider.map(it -> it.url).orElseGet(() -> IpLookupProviders.random().url);
|
||||||
|
|
||||||
Optional<String> v4 = getIp(provider, CurlProcessFactory.IpClass.V4);
|
String v4 = getIp(provider, CurlProcessFactory.IpClass.V4);
|
||||||
Optional<String> v6 = getIp(provider, CurlProcessFactory.IpClass.V6);
|
String v6 = getIp(provider, CurlProcessFactory.IpClass.V6);
|
||||||
|
|
||||||
return new IPs(v4, v6);
|
return new IPs(v4, v6);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -53,7 +57,7 @@ public class PublicIpLookup {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Optional<String> getIp(String provider, CurlProcessFactory.IpClass ipClass) {
|
private String getIp(String provider, CurlProcessFactory.IpClass ipClass) {
|
||||||
try {
|
try {
|
||||||
Process curlProcess = curlProcessFactory.create(provider, ipClass).start();
|
Process curlProcess = curlProcessFactory.create(provider, ipClass).start();
|
||||||
curlProcess.waitFor();
|
curlProcess.waitFor();
|
||||||
|
@ -61,10 +65,9 @@ public class PublicIpLookup {
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
|
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
|
||||||
String ip = reader.readLine();
|
String ip = reader.readLine();
|
||||||
log.tracef("Retrieved ip: %s", ip);
|
log.tracef("Retrieved ip: %s", ip);
|
||||||
return Optional.of(ip);
|
return ip;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.errorf("Couldn't lookup ip. Provider: %s, ipClass: %s", provider, ipClass.name());
|
throw new RuntimeException(e);
|
||||||
return Optional.empty();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,6 @@
|
||||||
package de.rpr.ddnsclient.model;
|
package de.rpr.ddnsclient.model;
|
||||||
|
|
||||||
import java.util.Optional;
|
public record IPs(String v4, String v6) {
|
||||||
|
|
||||||
public record IPs(Optional<String> v4, Optional<String> v6) {
|
|
||||||
|
|
||||||
public IPs(String v4, String v6) {
|
|
||||||
this(Optional.ofNullable(v4), Optional.ofNullable(v6));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ class DdnssTest {
|
||||||
);
|
);
|
||||||
|
|
||||||
ArgumentCaptor<HttpRequest> requestCaptor = ArgumentCaptor.forClass(HttpRequest.class);
|
ArgumentCaptor<HttpRequest> requestCaptor = ArgumentCaptor.forClass(HttpRequest.class);
|
||||||
verify(httpClient).send(requestCaptor.capture(), any());
|
verify(httpClient).send(requestCaptor.capture(),any());
|
||||||
|
|
||||||
HttpRequest capturedRequest = requestCaptor.getValue();
|
HttpRequest capturedRequest = requestCaptor.getValue();
|
||||||
|
|
||||||
|
@ -58,45 +58,4 @@ class DdnssTest {
|
||||||
.allValues("User-Agent")).containsExactly("ddns-client");
|
.allValues("User-Agent")).containsExactly("ddns-client");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
void should_send_correct_request_if_only_ipv4_is_present() throws IOException, InterruptedException {
|
|
||||||
when(httpClientFactory.create()).thenReturn(httpClient);
|
|
||||||
when(httpClient.send(any(), ArgumentMatchers.<HttpResponse.BodyHandler<String>>any())).thenReturn(httpResponse);
|
|
||||||
Ddnss dynDns = new Ddnss(httpClientFactory);
|
|
||||||
|
|
||||||
dynDns.update(
|
|
||||||
"example.com",
|
|
||||||
new IPs("ipv4", null),
|
|
||||||
new DyndnsAuth(null, null, "token")
|
|
||||||
);
|
|
||||||
|
|
||||||
ArgumentCaptor<HttpRequest> requestCaptor = ArgumentCaptor.forClass(HttpRequest.class);
|
|
||||||
verify(httpClient).send(requestCaptor.capture(), any());
|
|
||||||
|
|
||||||
HttpRequest capturedRequest = requestCaptor.getValue();
|
|
||||||
|
|
||||||
assertThat(capturedRequest.uri().toString())
|
|
||||||
.isEqualTo("https://ddnss.de/upd.php?key=token&host=example.com&ip=ipv4");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void should_send_correct_request_if_only_ipv6_is_present() throws IOException, InterruptedException {
|
|
||||||
when(httpClientFactory.create()).thenReturn(httpClient);
|
|
||||||
when(httpClient.send(any(), ArgumentMatchers.<HttpResponse.BodyHandler<String>>any())).thenReturn(httpResponse);
|
|
||||||
Ddnss dynDns = new Ddnss(httpClientFactory);
|
|
||||||
|
|
||||||
dynDns.update(
|
|
||||||
"example.com",
|
|
||||||
new IPs(null, "ipv6"),
|
|
||||||
new DyndnsAuth(null, null, "token")
|
|
||||||
);
|
|
||||||
|
|
||||||
ArgumentCaptor<HttpRequest> requestCaptor = ArgumentCaptor.forClass(HttpRequest.class);
|
|
||||||
verify(httpClient).send(requestCaptor.capture(), any());
|
|
||||||
|
|
||||||
HttpRequest capturedRequest = requestCaptor.getValue();
|
|
||||||
|
|
||||||
assertThat(capturedRequest.uri().toString())
|
|
||||||
.isEqualTo("https://ddnss.de/upd.php?key=token&host=example.com&ip6=ipv6");
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -1,102 +0,0 @@
|
||||||
package de.rpr.ddnsclient.dyndns;
|
|
||||||
|
|
||||||
import de.rpr.ddnsclient.model.DyndnsAuth;
|
|
||||||
import de.rpr.ddnsclient.model.IPs;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
|
||||||
import org.mockito.ArgumentCaptor;
|
|
||||||
import org.mockito.ArgumentMatchers;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.http.HttpClient;
|
|
||||||
import java.net.http.HttpRequest;
|
|
||||||
import java.net.http.HttpResponse;
|
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
|
||||||
import static org.mockito.Mockito.verify;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
|
||||||
class DuckDNSTest {
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
HttpClientFactory httpClientFactory;
|
|
||||||
@Mock
|
|
||||||
HttpClient httpClient;
|
|
||||||
@Mock
|
|
||||||
HttpResponse<String> httpResponse;
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void should_have_correct_name() {
|
|
||||||
assertThat(new DuckDNS(httpClientFactory).name()).isEqualTo("duckdns");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void should_send_correct_request_if_ipv4_and_ipv6_are_present() throws IOException, InterruptedException {
|
|
||||||
when(httpClientFactory.create()).thenReturn(httpClient);
|
|
||||||
when(httpClient.send(any(), ArgumentMatchers.<HttpResponse.BodyHandler<String>>any())).thenReturn(httpResponse);
|
|
||||||
DuckDNS dynDns = new DuckDNS(httpClientFactory);
|
|
||||||
|
|
||||||
dynDns.update(
|
|
||||||
"example.com",
|
|
||||||
new IPs("ipv4", "ipv6"),
|
|
||||||
new DyndnsAuth(null, null, "token")
|
|
||||||
);
|
|
||||||
|
|
||||||
ArgumentCaptor<HttpRequest> requestCaptor = ArgumentCaptor.forClass(HttpRequest.class);
|
|
||||||
verify(httpClient).send(requestCaptor.capture(), any());
|
|
||||||
|
|
||||||
HttpRequest capturedRequest = requestCaptor.getValue();
|
|
||||||
|
|
||||||
assertThat(capturedRequest.uri().toString())
|
|
||||||
.isEqualTo("https://www.duckdns.org/update?domains=example.com&token=token&ip=ipv4&ipv6=ipv6");
|
|
||||||
|
|
||||||
assertThat(capturedRequest.headers()
|
|
||||||
.allValues("User-Agent")).containsExactly("ddns-client");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void should_send_correct_request_if_only_ipv4_is_present() throws IOException, InterruptedException {
|
|
||||||
when(httpClientFactory.create()).thenReturn(httpClient);
|
|
||||||
when(httpClient.send(any(), ArgumentMatchers.<HttpResponse.BodyHandler<String>>any())).thenReturn(httpResponse);
|
|
||||||
DuckDNS dynDns = new DuckDNS(httpClientFactory);
|
|
||||||
|
|
||||||
dynDns.update(
|
|
||||||
"example.com",
|
|
||||||
new IPs("ipv4", null),
|
|
||||||
new DyndnsAuth(null, null, "token")
|
|
||||||
);
|
|
||||||
|
|
||||||
ArgumentCaptor<HttpRequest> requestCaptor = ArgumentCaptor.forClass(HttpRequest.class);
|
|
||||||
verify(httpClient).send(requestCaptor.capture(), any());
|
|
||||||
|
|
||||||
HttpRequest capturedRequest = requestCaptor.getValue();
|
|
||||||
|
|
||||||
assertThat(capturedRequest.uri().toString())
|
|
||||||
.isEqualTo("https://www.duckdns.org/update?domains=example.com&token=token&ip=ipv4");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void should_send_correct_request_if_only_ipv6_is_present() throws IOException, InterruptedException {
|
|
||||||
when(httpClientFactory.create()).thenReturn(httpClient);
|
|
||||||
when(httpClient.send(any(), ArgumentMatchers.<HttpResponse.BodyHandler<String>>any())).thenReturn(httpResponse);
|
|
||||||
DuckDNS dynDns = new DuckDNS(httpClientFactory);
|
|
||||||
|
|
||||||
dynDns.update(
|
|
||||||
"example.com",
|
|
||||||
new IPs(null, "ipv6"),
|
|
||||||
new DyndnsAuth(null, null, "token")
|
|
||||||
);
|
|
||||||
|
|
||||||
ArgumentCaptor<HttpRequest> requestCaptor = ArgumentCaptor.forClass(HttpRequest.class);
|
|
||||||
verify(httpClient).send(requestCaptor.capture(), any());
|
|
||||||
|
|
||||||
HttpRequest capturedRequest = requestCaptor.getValue();
|
|
||||||
|
|
||||||
assertThat(capturedRequest.uri().toString())
|
|
||||||
.isEqualTo("https://www.duckdns.org/update?domains=example.com&token=token&ipv6=ipv6");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -10,7 +10,7 @@ class DnsJavaTest {
|
||||||
@Test
|
@Test
|
||||||
void test() {
|
void test() {
|
||||||
IPs result = new DnsJava("9.9.9.9").resolve("example.com");
|
IPs result = new DnsJava("9.9.9.9").resolve("example.com");
|
||||||
assertThat(result.v4()).isPresent();
|
assertThat(result.v4()).isNotBlank();
|
||||||
assertThat(result.v6()).isPresent();
|
assertThat(result.v6()).isNotBlank();
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue