Skip to content

Commit

Permalink
Cloudflare updated response fields
Browse files Browse the repository at this point in the history
Notify telegram in case of sync errors
Run tests weekly
  • Loading branch information
IRus committed Nov 10, 2024
1 parent c6485f3 commit 64c37b5
Show file tree
Hide file tree
Showing 21 changed files with 220 additions and 157 deletions.
6 changes: 4 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
name: "Build"
on:
- push
push:
schedule:
- cron: "0 8 * * 6"
jobs:
build:
name: "Build on JDK ${{ matrix.jdk }}"
Expand Down Expand Up @@ -50,7 +52,7 @@ jobs:
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: "Build and push"
uses: docker/build-push-action@v5
uses: docker/build-push-action@v6
with:
context: .
push: true
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
.gradle
build
out
.env
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Container with application
FROM bellsoft/liberica-openjre-alpine:21.0.3
FROM bellsoft/liberica-openjre-alpine:21.0.5
RUN apk --no-cache add curl
COPY /build/install/ddns /ddns
ENTRYPOINT /ddns/bin/ddns
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ Simple client-server DDNS setup for personal use.
| Parameter | Default | Required | Description |
|-------------------------|---------|----------|--------------------------------------------------------------------------------------------|
| MODE | client | false | Describes mode in which application running, omit or set to `client` to run as DNS updater |
| RECORD_TYPE | A | false | Record type to update |
| SERVER_URL | none | true | URL to endpoint that returns IP |
| CHECK_PERIOD | 5m | false | Period of time between checks for IP change |
| REQUEST_TIMEOUT | 30s | false | Timeout for request to server |
Expand Down
26 changes: 16 additions & 10 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,31 +1,37 @@
plugins {
application
kotlin("jvm").version("2.0.0-RC3")
kotlin("plugin.serialization").version("2.0.0-RC3")
kotlin("jvm").version("2.0.21")
kotlin("plugin.serialization").version("2.0.21")
}

application {
mainClass.set("io.heapy.ddns.Application")
applicationName = "ddns"
}

kotlin {
jvmToolchain(21)
}

repositories {
mavenCentral()
}

dependencies {
implementation("io.ktor:ktor-serialization-kotlinx-json:2.3.11")
implementation("io.ktor:ktor-serialization-kotlinx-json:3.0.1")

implementation("io.ktor:ktor-client-cio:3.0.1")
implementation("io.ktor:ktor-client-content-negotiation:3.0.1")

implementation("io.ktor:ktor-client-cio:2.3.11")
implementation("io.ktor:ktor-client-content-negotiation:2.3.11")
implementation("io.ktor:ktor-server-cio:3.0.1")
implementation("io.ktor:ktor-server-content-negotiation:3.0.1")
implementation("io.ktor:ktor-server-call-logging:3.0.1")

implementation("io.ktor:ktor-server-cio:2.3.11")
implementation("io.ktor:ktor-server-content-negotiation:2.3.11")
implementation("io.ktor:ktor-server-call-logging:2.3.11")
implementation("ch.qos.logback:logback-classic:1.5.12")

implementation("ch.qos.logback:logback-classic:1.5.6")
implementation("io.heapy.komok:komok-tech-dotenv:1.0.7")

testImplementation("io.ktor:ktor-server-tests:2.3.11")
testImplementation("io.ktor:ktor-server-test-host:3.0.1")

testImplementation(kotlin("test-junit"))
}
Binary file modified gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
4 changes: 2 additions & 2 deletions gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionSha256Sum=544c35d6bd849ae8a5ed0bcea39ba677dc40f49df7d1835561582da2009b961d
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
distributionSha256Sum=31c55713e40233a8303827ceb42ca48a47267a0ad4bab9177123121e71524c26
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
7 changes: 5 additions & 2 deletions gradlew
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#

##############################################################################
#
Expand Down Expand Up @@ -55,7 +57,7 @@
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
Expand Down Expand Up @@ -84,7 +86,8 @@ done
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
' "$PWD" ) || exit

# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
Expand Down
2 changes: 2 additions & 0 deletions gradlew.bat
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@rem SPDX-License-Identifier: Apache-2.0
@rem

@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
Expand Down
5 changes: 4 additions & 1 deletion src/main/kotlin/io/heapy/ddns/Application.kt
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
@file:JvmName("Application")
package io.heapy.ddns

import io.heapy.ddns.server.ServerFactory
import io.heapy.komok.tech.dotenv.dotenv

suspend fun main() {
val config = System.getenv()
val config = dotenv()

if (config["MODE"] == "server") {
ServerFactory(config).start()
Expand Down
66 changes: 6 additions & 60 deletions src/main/kotlin/io/heapy/ddns/Client.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,15 @@ import io.heapy.ddns.dns_clients.DigitalOceanDnsClient
import io.heapy.ddns.dns_clients.DnsClient
import io.heapy.ddns.ip_provider.IpProvider
import io.heapy.ddns.ip_provider.ServerIpProvider
import io.heapy.ddns.updater.SimpleUpdater
import io.heapy.ddns.updater.Updater
import io.heapy.ddns.notifiers.Notifier
import io.heapy.ddns.notifiers.TelegramNotifier
import io.ktor.client.HttpClient
import io.ktor.client.engine.cio.CIO
import io.ktor.serialization.kotlinx.json.json
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
import kotlinx.coroutines.delay
import org.slf4j.LoggerFactory
import java.time.ZonedDateTime
import kotlin.concurrent.thread
import kotlinx.serialization.json.Json
import kotlin.time.Duration
import kotlin.time.Duration.Companion.minutes
import kotlin.time.Duration.Companion.seconds
Expand All @@ -39,7 +38,9 @@ open class ClientFactory(
open val httpClient by lazy {
HttpClient(CIO) {
install(ContentNegotiation) {
json()
json(Json {
ignoreUnknownKeys = true
})
}
}
}
Expand Down Expand Up @@ -152,58 +153,3 @@ open class ClientFactory(
updater.start()
}
}

interface Updater {
suspend fun start()
}

class SimpleUpdater(
private val checkPeriod: Duration,
private val ipProvider: IpProvider,
private val notifier: Notifier?,
private val dnsClients: List<DnsClient>,
) : Updater {
override suspend fun start() {
var nextUpdate = ZonedDateTime.now()
var running = true

Runtime.getRuntime().addShutdownHook(thread(start = false) {
log.info("Shutting down updater")
running = false
})

while (running) {
delay(100)
if (ZonedDateTime.now().isAfter(nextUpdate)) {
log.info("Updating IP")
sync()
nextUpdate = ZonedDateTime.now()
.plusSeconds(checkPeriod.inWholeSeconds)
log.info("Next sync at $nextUpdate")
}
}

log.info("Updater stopped")
}

private var IP = ""

private suspend fun sync() {
val newIP = ipProvider.getIp()

if (newIP != IP) {
IP = newIP
log.info("IP changed to $IP")
dnsClients.forEach {
val oldIp = it.createOrUpdateRecord(IP)
if (oldIp != IP) {
notifier?.notify(IP)
}
}
}
}

companion object {
private val log = LoggerFactory.getLogger(SimpleUpdater::class.java)
}
}
71 changes: 0 additions & 71 deletions src/main/kotlin/io/heapy/ddns/Server.kt

This file was deleted.

10 changes: 8 additions & 2 deletions src/main/kotlin/io/heapy/ddns/dns_clients/CloudflareDnsClient.kt
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ class CloudflareDnsClient(
}
.bodyAsText()

log.info("Creare record response: $response")
log.info("Create record response: $response")
}

private suspend fun updateRecord(
Expand Down Expand Up @@ -178,15 +178,21 @@ class CloudflareDnsClient(
val proxied: Boolean,
val ttl: Long,
val priority: Long? = null,
val locked: Boolean,
val locked: Boolean? = null,
val meta: Meta,
val comment: String?,
@SerialName("comment_modified_on")
val commentModifiedOn: String,
val tags: List<String>,
@SerialName("created_on")
val createdOn: String,
@SerialName("modified_on")
val modifiedOn: String,
val settings: Settings,
) {
@Serializable
class Settings

@Serializable
data class Meta(
@SerialName("auto_added")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,4 @@ class CloudflareVerifyToken(
val type: String? = null,
)
}

}
7 changes: 7 additions & 0 deletions src/main/kotlin/io/heapy/ddns/server/ServerConfiguration.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package io.heapy.ddns.server

data class ServerConfiguration(
val port: Int,
val host: String,
val header: String?,
)
41 changes: 41 additions & 0 deletions src/main/kotlin/io/heapy/ddns/server/ServerFactory.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package io.heapy.ddns.server

import io.ktor.server.cio.CIO
import io.ktor.server.engine.embeddedServer

/**
* DDNS Server: Returning request source ip in response
*/
open class ServerFactory(
open val config: Map<String, String>,
) {
open val server by lazy {
embeddedServer(
factory = CIO,
port = serverConfiguration.port,
host = serverConfiguration.host,
) {
with(serverModule) {
install()
}
}
}

open val serverModule by lazy {
ServerModule(
serverConfiguration = serverConfiguration,
)
}

open val serverConfiguration by lazy {
ServerConfiguration(
port = config["PORT"]?.toInt() ?: 8080,
host = config["HOST"] ?: "0.0.0.0",
header = config["HEADER"],
)
}

open fun start() {
server.start(wait = true)
}
}
Loading

0 comments on commit 64c37b5

Please sign in to comment.