Skip to content

Commit

Permalink
Fix schema change
Browse files Browse the repository at this point in the history
  • Loading branch information
IRus committed May 16, 2024
1 parent bffe60c commit 6371a3b
Show file tree
Hide file tree
Showing 10 changed files with 153 additions and 41 deletions.
21 changes: 11 additions & 10 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,51 +1,52 @@
name: "Build"
on:
- "push"
- push
jobs:
build:
name: "Build on JDK ${{ matrix.jdk }}"
runs-on: ubuntu-latest
strategy:
matrix:
jdk:
- 17
- 21
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: "Set up JDK ${{ matrix.jdk }}"
uses: actions/setup-java@v3
uses: actions/setup-java@v4
with:
java-version: "${{ matrix.jdk }}"
distribution: "zulu"
- name: "Build with Gradle"
run: ./gradlew check distTar
- name: "Upload Artifact"
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: "Kotlin Application"
path: "build/distributions/ddns.tar"
retention-days: 1
build-and-push-image:
if: ${{ github.ref == 'refs/heads/main' }}
runs-on: ubuntu-latest
needs: build
steps:
- name: "Checkout"
uses: actions/checkout@v3
- uses: actions/download-artifact@v3
uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
name: "Kotlin Application"
path: "build/distributions/"
- name: "Untar files"
run: mkdir -p build/install && tar -xvf build/distributions/ddns.tar -C $_
- name: "Set up Docker Buildx"
uses: docker/setup-buildx-action@v2
uses: docker/setup-buildx-action@v3
- name: "Login to GHCR"
uses: docker/login-action@v2
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: "Build and push"
uses: docker/build-push-action@v3
uses: docker/build-push-action@v5
with:
context: .
push: true
Expand Down
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:17.0.5
FROM bellsoft/liberica-openjre-alpine:21.0.3
RUN apk --no-cache add curl
COPY /build/install/ddns /ddns
ENTRYPOINT /ddns/bin/ddns
20 changes: 10 additions & 10 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
plugins {
application
kotlin("jvm").version("1.9.22")
kotlin("plugin.serialization").version("1.9.22")
kotlin("jvm").version("2.0.0-RC3")
kotlin("plugin.serialization").version("2.0.0-RC3")
}

application {
Expand All @@ -14,18 +14,18 @@ repositories {
}

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

implementation("io.ktor:ktor-client-cio:2.3.7")
implementation("io.ktor:ktor-client-content-negotiation:2.3.7")
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:2.3.7")
implementation("io.ktor:ktor-server-content-negotiation:2.3.7")
implementation("io.ktor:ktor-server-call-logging:2.3.7")
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.4.14")
implementation("ch.qos.logback:logback-classic:1.5.6")

testImplementation("io.ktor:ktor-server-tests:2.3.7")
testImplementation("io.ktor:ktor-server-tests:2.3.11")

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=9d926787066a081739e8200858338b4a69e837c3a821a33aca9db09dd4a41026
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
distributionSha256Sum=544c35d6bd849ae8a5ed0bcea39ba677dc40f49df7d1835561582da2009b961d
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
20 changes: 10 additions & 10 deletions gradlew.bat
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute

echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2

goto fail

Expand All @@ -57,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe

if exist "%JAVA_EXE%" goto execute

echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2

goto fail

Expand Down
28 changes: 22 additions & 6 deletions src/main/kotlin/io/heapy/ddns/Client.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.heapy.ddns

import io.heapy.ddns.dns_clients.CloudflareDnsClient
import io.heapy.ddns.dns_clients.CloudflareVerifyToken
import io.heapy.ddns.dns_clients.DigitalOceanDnsClient
import io.heapy.ddns.dns_clients.DnsClient
import io.heapy.ddns.ip_provider.IpProvider
Expand Down Expand Up @@ -78,22 +79,33 @@ open class ClientFactory(
)
}

open val cloudflareDnsClient: DnsClient by lazy {
open val cloudflareDnsClient: CloudflareDnsClient by lazy {
CloudflareDnsClient(
httpClient = httpClient,
configuration = cloudflareConfiguration,
verifyToken = cloudflareVerifyToken,
)
}

open val cloudflareVerifyToken: CloudflareVerifyToken by lazy {
CloudflareVerifyToken(
httpClient = httpClient,
)
}

open val cloudflareToken by lazy {
config["CLOUDFLARE_TOKEN"]
?: error("CLOUDFLARE_TOKEN is not set")
}

open val cloudflareConfiguration: CloudflareDnsClient.Configuration by lazy {
CloudflareDnsClient.Configuration(
zoneId = config["CLOUDFLARE_ZONE_ID"]
?: error("CLOUDFLARE_ZONE_ID is not set"),
token = config["CLOUDFLARE_TOKEN"]
?: error("CLOUDFLARE_TOKEN is not set"),
domainName = config["CLOUDFLARE_DOMAIN_NAME"]
?: error("CLOUDFLARE_DOMAIN_NAME is not set"),
ttl = configuration.checkPeriod.inWholeSeconds,
token = cloudflareToken,
ttl = checkPeriod.inWholeSeconds,
)
}

Expand All @@ -113,12 +125,16 @@ open class ClientFactory(
)
}

open val checkPeriod by lazy {
config["CHECK_PERIOD"]?.let(Duration::parse)
?: 5.minutes
}

open val configuration by lazy {
Configuration(
serverUrl = config["SERVER_URL"]
?: error("SERVER_URL is not set"),
checkPeriod = config["CHECK_PERIOD"]?.let(Duration::parse)
?: 5.minutes,
checkPeriod = checkPeriod,
requestTimeout = config["REQUEST_TIMEOUT"]?.let(Duration::parse)
?: 30.seconds,
attemptsBeforeWarning = config["ATTEMPTS_BEFORE_WARNING"]?.toInt() ?: 5,
Expand Down
12 changes: 10 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 @@ -12,10 +12,18 @@ import java.time.OffsetDateTime
class CloudflareDnsClient(
private val httpClient: HttpClient,
private val configuration: Configuration,
private val verifyToken: CloudflareVerifyToken,
) : DnsClient {
override suspend fun createOrUpdateRecord(
ip: String,
): String? {
val verifyTokenResponse = verifyToken(configuration.token)

if (!verifyTokenResponse.success) {
log.error("Token verification failed: ${verifyTokenResponse.errors}")
return null
}

val record = getRecord(
name = configuration.domainName,
zoneId = configuration.zoneId,
Expand Down Expand Up @@ -112,7 +120,7 @@ class CloudflareDnsClient(
return "$type by io.heapy.ddns-fullstack on ${OffsetDateTime.now()}"
}

private suspend fun getRecord(
internal suspend fun getRecord(
name: String,
zoneId: String,
token: String,
Expand Down Expand Up @@ -187,7 +195,7 @@ class CloudflareDnsClient(
val managedByApps: Boolean,
@SerialName("managed_by_argo_tunnel")
val managedByArgoTunnel: Boolean,
val source: String,
val source: String? = null,
)
}

Expand Down
49 changes: 49 additions & 0 deletions src/main/kotlin/io/heapy/ddns/dns_clients/CloudflareVerifyToken.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package io.heapy.ddns.dns_clients

import io.ktor.client.*
import io.ktor.client.call.*
import io.ktor.client.request.*
import kotlinx.serialization.Serializable

class CloudflareVerifyToken(
private val httpClient: HttpClient,
) {
suspend operator fun invoke(
token: String,
): VerifyTokenResponse {
return httpClient
.get("https://api.cloudflare.com/client/v4/user/tokens/verify") {
header("Content-Type", "application/json")
bearerAuth(token)
}
.body<VerifyTokenResponse>()
}

@Serializable
data class VerifyTokenResponse(
val result: Result? = null,
val success: Boolean,
val errors: List<Error>,
val messages: List<Message>,
) {
@Serializable
data class Result(
val id: String,
val status: String,
)

@Serializable
data class Error(
val code: Int,
val message: String,
)

@Serializable
data class Message(
val code: Int,
val message: String,
val type: String? = null,
)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package io.heapy.ddns.dns_clients

import io.heapy.ddns.ClientFactory
import kotlinx.coroutines.runBlocking
import org.junit.Test
import kotlin.test.assertEquals

class CloudflareClientFactoryTest {
@Test
fun `verify test token`() = runBlocking {
val factory = ClientFactory(System.getenv())
val token = factory.cloudflareToken

val response = factory.cloudflareVerifyToken(token)

assertEquals(
response.success,
true,
)
}

@Test
fun `get dns record`() = runBlocking {
val factory = ClientFactory(System.getenv())
val config = factory.cloudflareConfiguration

val record = factory.cloudflareDnsClient.getRecord(
name = config.domainName,
zoneId = config.zoneId,
token = config.token,
)

assertEquals(
record?.name,
config.domainName,
)
}
}

0 comments on commit 6371a3b

Please sign in to comment.