refactor
This commit is contained in:
@@ -1,13 +1,11 @@
|
|||||||
package com.infendro.ddns
|
package com.infendro.ddns
|
||||||
|
|
||||||
import io.ktor.client.HttpClient
|
import io.ktor.client.*
|
||||||
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
|
import io.ktor.client.plugins.contentnegotiation.*
|
||||||
import io.ktor.serialization.kotlinx.json.json
|
import io.ktor.serialization.kotlinx.json.*
|
||||||
|
|
||||||
object Http {
|
val http = HttpClient {
|
||||||
val client = HttpClient {
|
|
||||||
install(ContentNegotiation) {
|
install(ContentNegotiation) {
|
||||||
json()
|
json()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import com.infendro.ddns.Argument.SUBDOMAIN
|
|||||||
import com.infendro.ddns.argument.ipService
|
import com.infendro.ddns.argument.ipService
|
||||||
import com.infendro.ddns.config.Config
|
import com.infendro.ddns.config.Config
|
||||||
import com.infendro.ddns.dns.DnsService
|
import com.infendro.ddns.dns.DnsService
|
||||||
import com.infendro.ddns.dns.DnsServices.PORKBUN
|
import com.infendro.ddns.dns.DnsService.Companion.PORKBUN
|
||||||
import com.infendro.ddns.dns.model.DnsRecord
|
import com.infendro.ddns.dns.model.DnsRecord
|
||||||
import com.infendro.ddns.dns.porkbun.Porkbun
|
import com.infendro.ddns.dns.porkbun.Porkbun
|
||||||
import com.infendro.ddns.ip.IpService
|
import com.infendro.ddns.ip.IpService
|
||||||
|
|||||||
@@ -3,13 +3,16 @@ package com.infendro.ddns.argument
|
|||||||
import com.infendro.cli.argument.Argument
|
import com.infendro.cli.argument.Argument
|
||||||
import com.infendro.cli.command.Command
|
import com.infendro.cli.command.Command
|
||||||
import com.infendro.ddns.ip.IpService
|
import com.infendro.ddns.ip.IpService
|
||||||
import com.infendro.ddns.ip.IpServices
|
import com.infendro.ddns.ip.ipify.Ipify
|
||||||
|
|
||||||
object IpServiceParser : Argument.Parser<IpService> {
|
object IpServiceParser : Argument.Parser<IpService> {
|
||||||
override fun parse(
|
override fun parse(
|
||||||
text: String?,
|
text: String?,
|
||||||
): IpService {
|
): IpService {
|
||||||
return IpServices.get(text!!)
|
return when (text) {
|
||||||
|
IpService.IPIFY -> Ipify
|
||||||
|
else -> throw Exception()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -17,7 +20,7 @@ class IpServiceOrDefaultArgument(
|
|||||||
override val name: String,
|
override val name: String,
|
||||||
) : Argument.SingleOrElse<IpService>() {
|
) : Argument.SingleOrElse<IpService>() {
|
||||||
override val other: IpService
|
override val other: IpService
|
||||||
get() = IpServices.DEFAULT
|
get() = IpService.DEFAULT
|
||||||
|
|
||||||
override val parser: Parser<IpService>
|
override val parser: Parser<IpService>
|
||||||
get() = IpServiceParser
|
get() = IpServiceParser
|
||||||
|
|||||||
@@ -2,13 +2,13 @@ package com.infendro.ddns.dns
|
|||||||
|
|
||||||
import com.infendro.ddns.dns.model.DnsRecord
|
import com.infendro.ddns.dns.model.DnsRecord
|
||||||
|
|
||||||
abstract class DnsService {
|
interface DnsService {
|
||||||
abstract fun getRecords(
|
fun getRecords(
|
||||||
domain: String,
|
domain: String,
|
||||||
subdomains: List<String>,
|
subdomains: List<String>,
|
||||||
): List<DnsRecord>
|
): List<DnsRecord>
|
||||||
|
|
||||||
abstract fun updateRecord(
|
fun updateRecord(
|
||||||
record: DnsRecord,
|
record: DnsRecord,
|
||||||
value: String,
|
value: String,
|
||||||
)
|
)
|
||||||
@@ -22,4 +22,8 @@ abstract class DnsService {
|
|||||||
updateRecord(record, value)
|
updateRecord(record, value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val PORKBUN = "porkbun"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
package com.infendro.ddns.dns
|
|
||||||
|
|
||||||
object DnsServices {
|
|
||||||
const val PORKBUN = "porkbun"
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
package com.infendro.ddns.dns
|
|
||||||
|
|
||||||
object Regex {
|
|
||||||
val DOMAIN = Regex("""(?:(?<subdomain>(?:\w+\.)*\w+)\.)?(?<domain>\w+\.\w+)""")
|
|
||||||
}
|
|
||||||
@@ -1,36 +1,52 @@
|
|||||||
package com.infendro.ddns.dns.porkbun
|
package com.infendro.ddns.dns.porkbun
|
||||||
|
|
||||||
import com.infendro.ddns.Http.client
|
|
||||||
import com.infendro.ddns.dns.Regex.DOMAIN
|
|
||||||
import com.infendro.ddns.dns.DnsService
|
import com.infendro.ddns.dns.DnsService
|
||||||
import com.infendro.ddns.dns.model.DnsRecord
|
import com.infendro.ddns.dns.model.DnsRecord
|
||||||
import com.infendro.ddns.dns.porkbun.dto.request.GetRecordsRequest
|
import com.infendro.ddns.dns.porkbun.dto.request.GetRecordsRequest
|
||||||
import com.infendro.ddns.dns.porkbun.dto.request.UpdateRecordRequest
|
import com.infendro.ddns.dns.porkbun.dto.request.UpdateRecordRequest
|
||||||
import com.infendro.ddns.dns.porkbun.dto.response.GetRecordsResponse
|
import com.infendro.ddns.dns.porkbun.dto.response.GetRecordsResponse
|
||||||
import io.ktor.client.call.body
|
import com.infendro.ddns.http
|
||||||
import io.ktor.client.request.post
|
import io.ktor.client.call.*
|
||||||
import io.ktor.client.request.setBody
|
import io.ktor.client.request.*
|
||||||
import io.ktor.http.ContentType
|
import io.ktor.http.*
|
||||||
import io.ktor.http.contentType
|
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
|
|
||||||
class Porkbun(
|
class Porkbun(
|
||||||
val key: String,
|
val key: String,
|
||||||
val secretkey: String,
|
val secretkey: String,
|
||||||
) : DnsService() {
|
) : DnsService {
|
||||||
override fun getRecords(
|
override fun getRecords(
|
||||||
domain: String,
|
domain: String,
|
||||||
subdomains: List<String>,
|
subdomains: List<String>,
|
||||||
): List<DnsRecord> = runBlocking {
|
): List<DnsRecord> = runBlocking {
|
||||||
val response = client.post("https://api.porkbun.com/api/json/v3/dns/retrieve/$domain") {
|
val response = http.post("https://api.porkbun.com/api/json/v3/dns/retrieve/$domain") {
|
||||||
val request = getRecordsRequest()
|
val request = GetRecordsRequest(
|
||||||
|
apikey = key,
|
||||||
|
secretapikey = secretkey,
|
||||||
|
)
|
||||||
contentType(ContentType.Application.Json)
|
contentType(ContentType.Application.Json)
|
||||||
setBody(request)
|
setBody(request)
|
||||||
}
|
}
|
||||||
val body = response.body<GetRecordsResponse>()
|
val body = response.body<GetRecordsResponse>()
|
||||||
|
|
||||||
body.records
|
body.records
|
||||||
.map { model(it) }
|
.map {
|
||||||
|
val labels = it.name.split('.')
|
||||||
|
val subdomain = labels.dropLast(2).joinToString(".")
|
||||||
|
val domain = labels.takeLast(2).joinToString(".")
|
||||||
|
|
||||||
|
DnsRecord(
|
||||||
|
id = it.id,
|
||||||
|
type = DnsRecord.Type.valueOf(it.type),
|
||||||
|
domain = DnsRecord.Domain(
|
||||||
|
subdomain = subdomain,
|
||||||
|
domain = domain,
|
||||||
|
),
|
||||||
|
value = it.content,
|
||||||
|
ttl = it.ttl.toInt(),
|
||||||
|
priority = it.prio?.toInt(),
|
||||||
|
)
|
||||||
|
}
|
||||||
.filter { it.type in DnsRecord.Type.address && (it.domain.subdomain ?: "") in subdomains }
|
.filter { it.type in DnsRecord.Type.address && (it.domain.subdomain ?: "") in subdomains }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,51 +54,17 @@ class Porkbun(
|
|||||||
record: DnsRecord,
|
record: DnsRecord,
|
||||||
value: String,
|
value: String,
|
||||||
): Unit = runBlocking {
|
): Unit = runBlocking {
|
||||||
client.post("https://api.porkbun.com/api/json/v3/dns/edit/${record.domain.domain}/${record.id}") {
|
http.post("https://api.porkbun.com/api/json/v3/dns/edit/${record.domain.domain}/${record.id}") {
|
||||||
val request = updateRecordRequest(record, value)
|
val request = UpdateRecordRequest(
|
||||||
contentType(ContentType.Application.Json)
|
|
||||||
setBody(request)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun model(
|
|
||||||
record: GetRecordsResponse.Record,
|
|
||||||
): DnsRecord {
|
|
||||||
val match = DOMAIN.matchEntire(record.name)!!
|
|
||||||
val domain = match.groups["domain"]!!.value
|
|
||||||
val subdomain = match.groups["subdomain"]?.value
|
|
||||||
|
|
||||||
return DnsRecord(
|
|
||||||
id = record.id,
|
|
||||||
type = DnsRecord.Type.valueOf(record.type),
|
|
||||||
domain = DnsRecord.Domain(
|
|
||||||
subdomain = subdomain,
|
|
||||||
domain = domain,
|
|
||||||
),
|
|
||||||
value = record.content,
|
|
||||||
ttl = record.ttl.toInt(),
|
|
||||||
priority = record.prio?.toInt(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getRecordsRequest(): GetRecordsRequest {
|
|
||||||
return GetRecordsRequest(
|
|
||||||
apikey = key,
|
|
||||||
secretapikey = secretkey,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun updateRecordRequest(
|
|
||||||
record: DnsRecord,
|
|
||||||
ip: String,
|
|
||||||
): UpdateRecordRequest {
|
|
||||||
return UpdateRecordRequest(
|
|
||||||
apikey = key,
|
apikey = key,
|
||||||
secretapikey = secretkey,
|
secretapikey = secretkey,
|
||||||
type = record.type.toString(),
|
type = record.type.toString(),
|
||||||
name = record.domain.subdomain ?: "",
|
name = record.domain.subdomain ?: "",
|
||||||
content = ip,
|
content = value,
|
||||||
ttl = record.ttl.toString(),
|
ttl = record.ttl.toString(),
|
||||||
)
|
)
|
||||||
|
contentType(ContentType.Application.Json)
|
||||||
|
setBody(request)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,16 @@
|
|||||||
package com.infendro.ddns.ip
|
package com.infendro.ddns.ip
|
||||||
|
|
||||||
abstract class IpService {
|
import com.infendro.ddns.ip.ipify.Ipify
|
||||||
abstract val ipv4: String
|
|
||||||
abstract val ipv6: String
|
|
||||||
|
|
||||||
val ip: List<String>
|
interface IpService {
|
||||||
get() = listOf(ipv4, ipv6)
|
val ipv4: String
|
||||||
|
val ipv6: String
|
||||||
|
|
||||||
|
val ip: Pair<String, String>
|
||||||
|
get() = Pair(ipv4, ipv6)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val IPIFY = "ipify"
|
||||||
|
val DEFAULT = Ipify
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
package com.infendro.ddns.ip
|
|
||||||
|
|
||||||
import com.infendro.ddns.ip.ipify.Ipify
|
|
||||||
|
|
||||||
object IpServices {
|
|
||||||
const val IPIFY = "ipify"
|
|
||||||
val DEFAULT = Ipify
|
|
||||||
|
|
||||||
fun get(
|
|
||||||
name: String,
|
|
||||||
): IpService {
|
|
||||||
return when (name) {
|
|
||||||
IPIFY -> Ipify
|
|
||||||
else -> throw Exception()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,23 +1,23 @@
|
|||||||
package com.infendro.ddns.ip.ipify
|
package com.infendro.ddns.ip.ipify
|
||||||
|
|
||||||
import com.infendro.ddns.Http
|
import com.infendro.ddns.http
|
||||||
import com.infendro.ddns.ip.IpService
|
import com.infendro.ddns.ip.IpService
|
||||||
import com.infendro.ddns.ip.ipify.dto.response.GetIpResponse
|
import com.infendro.ddns.ip.ipify.dto.response.GetIpResponse
|
||||||
import io.ktor.client.call.body
|
import io.ktor.client.call.*
|
||||||
import io.ktor.client.request.get
|
import io.ktor.client.request.*
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
|
|
||||||
object Ipify : IpService() {
|
object Ipify : IpService {
|
||||||
override val ipv4: String
|
override val ipv4: String
|
||||||
get() = runBlocking {
|
get() = runBlocking {
|
||||||
val response = Http.client.get("https://api.ipify.org?format=json")
|
val response = http.get("https://api.ipify.org?format=json")
|
||||||
val body = response.body<GetIpResponse>()
|
val body = response.body<GetIpResponse>()
|
||||||
body.ip
|
body.ip
|
||||||
}
|
}
|
||||||
|
|
||||||
override val ipv6: String
|
override val ipv6: String
|
||||||
get() = runBlocking {
|
get() = runBlocking {
|
||||||
val response = Http.client.get("https://api64.ipify.org?format=json")
|
val response = http.get("https://api6.ipify.org?format=json")
|
||||||
val body = response.body<GetIpResponse>()
|
val body = response.body<GetIpResponse>()
|
||||||
body.ip
|
body.ip
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user