實作更新DDNS功能
This commit is contained in:
parent
935af29314
commit
cac3e9487b
@ -13,6 +13,12 @@ repositories {
|
|||||||
dependencies {
|
dependencies {
|
||||||
testImplementation(kotlin("test"))
|
testImplementation(kotlin("test"))
|
||||||
implementation("com.squareup.retrofit2:retrofit:2.9.0")
|
implementation("com.squareup.retrofit2:retrofit:2.9.0")
|
||||||
|
implementation("com.squareup.retrofit2:converter-gson:2.9.0")
|
||||||
|
|
||||||
|
implementation("com.google.code.gson:gson:2.10.1")
|
||||||
|
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")
|
||||||
|
|
||||||
|
implementation("org.jsoup:jsoup:1.14.3")
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.test {
|
tasks.test {
|
||||||
|
|||||||
4
config.json
Normal file
4
config.json
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"token": "n_9L9-W70oYWtMV16GgYTs0yWZ72Vjs17QD4dUZl",
|
||||||
|
"domain": "ray650128.com"
|
||||||
|
}
|
||||||
@ -1,7 +1,138 @@
|
|||||||
fun main(args: Array<String>) {
|
import api.CloudflareApiService
|
||||||
|
import com.google.gson.Gson
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import model.Configure
|
||||||
|
import model.zones.UpdateDnsBody
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
|
import okhttp3.Request
|
||||||
|
import okhttp3.Response
|
||||||
|
import retrofit2.Retrofit
|
||||||
|
import retrofit2.converter.gson.GsonConverterFactory
|
||||||
|
import java.io.File
|
||||||
|
import java.io.IOException
|
||||||
|
|
||||||
|
|
||||||
|
private lateinit var config: Configure
|
||||||
|
|
||||||
|
private lateinit var token: String
|
||||||
|
private lateinit var domain: String
|
||||||
|
|
||||||
|
fun main() {
|
||||||
println("Cloudflare DDNS 更新程式已啟動")
|
println("Cloudflare DDNS 更新程式已啟動")
|
||||||
|
|
||||||
// Try adding program arguments via Run/Debug configuration.
|
val confFile = File("config.json")
|
||||||
// Learn more about running applications: https://www.jetbrains.com/help/idea/running-applications.html.
|
if (!confFile.exists()) {
|
||||||
println("Program arguments: ${args.joinToString()}")
|
confFile.createNewFile()
|
||||||
|
|
||||||
|
println("請先設定 config.json 檔案")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val configRawText = confFile.readText(Charsets.UTF_8)
|
||||||
|
if (configRawText.isEmpty()) {
|
||||||
|
println("請先設定 config.json 檔案")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
config = loadConfigFile(configRawText)
|
||||||
|
|
||||||
|
val retrofit = Retrofit.Builder()
|
||||||
|
.baseUrl("https://api.cloudflare.com")
|
||||||
|
.addConverterFactory(GsonConverterFactory.create())
|
||||||
|
.build()
|
||||||
|
val apiService = retrofit.create(CloudflareApiService::class.java)
|
||||||
|
|
||||||
|
runBlocking {
|
||||||
|
println("-------- [ 開始更新 DNS ] --------")
|
||||||
|
val client = OkHttpClient()
|
||||||
|
val request: Request = Request.Builder()
|
||||||
|
.url("https://ifconfig.me")
|
||||||
|
.addHeader("User-Agent", "")
|
||||||
|
.method("GET", null)
|
||||||
|
.build()
|
||||||
|
val ipAddress = try {
|
||||||
|
val response = withContext(Dispatchers.IO) {
|
||||||
|
client.newCall(request).execute()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.isSuccessful) {
|
||||||
|
response.body()?.string() ?: run {
|
||||||
|
println("無法取得 WAN IP 位址")
|
||||||
|
return@runBlocking
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
} catch (e: IOException) {
|
||||||
|
null
|
||||||
|
} finally {
|
||||||
|
client.dispatcher().executorService().shutdown()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ipAddress != null) {
|
||||||
|
println("您目前的 WAN IP 位址為: $ipAddress")
|
||||||
|
try {
|
||||||
|
println("驗證 CF 權杖是否有效...")
|
||||||
|
val verifyTokenResult = apiService.getVerifyToken("Bearer $token")
|
||||||
|
if (verifyTokenResult.success) {
|
||||||
|
println("CF 權杖有效,載入 Zone 資料中...")
|
||||||
|
val zonesResult = apiService.getZones("Bearer $token")
|
||||||
|
if (zonesResult.success) {
|
||||||
|
println("Zone 資料載入成功,取得域名資料中...")
|
||||||
|
val zoneData = zonesResult.result.firstOrNull { it.name == domain } ?: run {
|
||||||
|
println("無法找到指定的域名 [ $domain ]...")
|
||||||
|
return@runBlocking
|
||||||
|
}
|
||||||
|
val zoneId = zoneData.id
|
||||||
|
val zoneDnsRecords = apiService.getZoneDnsRecords("Bearer $token", zoneId)
|
||||||
|
if (zoneDnsRecords.success) {
|
||||||
|
println("域名資料載入成功,處理中...")
|
||||||
|
val record = zoneDnsRecords.result.firstOrNull { it.name == domain } ?: run {
|
||||||
|
println("無法找到指定的域名 [ $domain ]...")
|
||||||
|
return@runBlocking
|
||||||
|
}
|
||||||
|
val recordId = record.id
|
||||||
|
val updateDnsBody = UpdateDnsBody(
|
||||||
|
type = "A",
|
||||||
|
name = record.name,
|
||||||
|
content = ipAddress,
|
||||||
|
ttl = 120,
|
||||||
|
proxied = false
|
||||||
|
)
|
||||||
|
val updateDnsResult = apiService.updateZoneDnsRecords("Bearer $token", zoneId, recordId, updateDnsBody)
|
||||||
|
if (updateDnsResult.success) {
|
||||||
|
println("更新 DDNS 成功")
|
||||||
|
} else {
|
||||||
|
println("更新 DDNS 失敗")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
println("無法取得域名資料資料")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
println("無法取得 Zone 資料")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
println("CF 權杖無效")
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
println("Error: ${e.message}")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
println("Error retrieving IP address")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun loadConfigFile(configRawText: String): Configure {
|
||||||
|
val config = Gson().fromJson(configRawText, Configure::class.java)
|
||||||
|
token = config.token
|
||||||
|
domain = config.domain
|
||||||
|
|
||||||
|
println("-------- [ 設定檔已載入 ] --------")
|
||||||
|
println("CF 權杖: $token")
|
||||||
|
println("欲更新的域名: $domain")
|
||||||
|
return config
|
||||||
}
|
}
|
||||||
@ -17,7 +17,7 @@ interface CloudflareApiService {
|
|||||||
@GET("/client/v4/zones")
|
@GET("/client/v4/zones")
|
||||||
suspend fun getZones(
|
suspend fun getZones(
|
||||||
@Header("Authorization") token: String
|
@Header("Authorization") token: String
|
||||||
): CloudflareResult<ZonesResult>
|
): CloudflareResult<List<ZonesResult>>
|
||||||
|
|
||||||
@GET("/client/v4/zones/{ZONE_ID}/dns_records")
|
@GET("/client/v4/zones/{ZONE_ID}/dns_records")
|
||||||
suspend fun getZoneDnsRecords(
|
suspend fun getZoneDnsRecords(
|
||||||
|
|||||||
9
src/main/kotlin/model/Configure.kt
Normal file
9
src/main/kotlin/model/Configure.kt
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName
|
||||||
|
|
||||||
|
data class Configure(
|
||||||
|
val token: String,
|
||||||
|
val domain: String
|
||||||
|
)
|
||||||
Loading…
Reference in New Issue
Block a user