mirror of
https://github.com/dalbodeule/sh0rt.kr-pdns.git
synced 2025-06-08 18:58:20 +00:00
fix pdns api clients (retry 5x)
This commit is contained in:
parent
4a72cd0453
commit
a41d8ae23c
@ -42,6 +42,9 @@ dependencies {
|
||||
implementation("com.google.code.gson:gson:2.11.0")
|
||||
implementation("io.github.cdimascio:dotenv-kotlin:6.4.1")
|
||||
|
||||
// https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp
|
||||
implementation("com.squareup.okhttp3:okhttp:4.12.0")
|
||||
|
||||
runtimeOnly("org.mariadb.jdbc:mariadb-java-client")
|
||||
|
||||
testImplementation("org.springframework.boot:spring-boot-starter-test")
|
||||
|
@ -1,14 +1,15 @@
|
||||
package space.mori.dnsapi
|
||||
|
||||
import com.google.gson.Gson
|
||||
import okhttp3.MediaType.Companion.toMediaType
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
import okhttp3.RequestBody.Companion.toRequestBody
|
||||
import org.springframework.beans.factory.annotation.Value
|
||||
import org.springframework.http.*
|
||||
import org.springframework.stereotype.Service
|
||||
import org.springframework.web.client.RestTemplate
|
||||
import space.mori.dnsapi.dto.RecordRequestDTO
|
||||
|
||||
@Service
|
||||
class PowerDNSApiClient {
|
||||
class PowerDNSAPIClient() {
|
||||
@Value("\${pdns.api.url}")
|
||||
private lateinit var apiUrl: String
|
||||
|
||||
@ -18,68 +19,73 @@ class PowerDNSApiClient {
|
||||
@Value("\${pdns.ns}")
|
||||
private lateinit var nameserver: String
|
||||
|
||||
private val restTemplate = RestTemplate()
|
||||
private val gson = Gson()
|
||||
private val client = OkHttpClient()
|
||||
|
||||
private fun createHeaders(): HttpHeaders {
|
||||
val headers = HttpHeaders()
|
||||
headers.set("X-API-Key", apiKey)
|
||||
headers.contentType = MediaType.APPLICATION_JSON
|
||||
return headers
|
||||
fun createZone(zoneName: String): Boolean {
|
||||
val body = gson.toJson(mapOf(
|
||||
"name" to zoneName,
|
||||
"nameservers" to nameserver.split(","))
|
||||
).toRequestBody("application/json; charset=utf-8".toMediaType())
|
||||
val request = Request.Builder()
|
||||
.url("$apiUrl/api/v1/servers/localhost/zones")
|
||||
.addHeader("Authorization", "Bearer $apiKey")
|
||||
.post(body)
|
||||
.build()
|
||||
|
||||
val response = client.newCall(request).execute()
|
||||
return response.isSuccessful
|
||||
}
|
||||
|
||||
fun createDomain(name: String): ResponseEntity<String> {
|
||||
val url = "$apiUrl/api/v1/servers/localhost/zones"
|
||||
val headers = createHeaders()
|
||||
val domainRequest = DomainRequest("$name.", "Native", arrayOf(), nameserver.split(",").toTypedArray())
|
||||
val body = gson.toJson(domainRequest)
|
||||
val entity = HttpEntity(body, headers)
|
||||
return restTemplate.exchange(url, HttpMethod.POST, entity, String::class.java)
|
||||
fun deleteZone(zoneName: String): Boolean {
|
||||
val request = Request.Builder()
|
||||
.url("$apiUrl/api/v1/servers/localhost/zones/$zoneName")
|
||||
.addHeader("Authorization", "Bearer $apiKey")
|
||||
.delete()
|
||||
.build()
|
||||
|
||||
val response = client.newCall(request).execute()
|
||||
return response.isSuccessful
|
||||
}
|
||||
|
||||
fun createRecord(domainName: String, recordRequest: RecordRequestDTO): ResponseEntity<String> {
|
||||
val url = "$apiUrl/api/v1/servers/localhost/zones/$domainName."
|
||||
val headers = createHeaders()
|
||||
val record = RecordRequest(
|
||||
name = "${recordRequest.name}.$domainName.",
|
||||
type = recordRequest.type,
|
||||
ttl = recordRequest.ttl,
|
||||
changetype = "REPLACE",
|
||||
records = arrayOf(RecordContent(recordRequest.content, false))
|
||||
)
|
||||
val body = gson.toJson(RecordRequestWrapper(arrayOf(record)))
|
||||
val entity = HttpEntity(body, headers)
|
||||
return restTemplate.exchange(url, HttpMethod.PATCH, entity, String::class.java)
|
||||
fun createRecord(zoneName: String, recordName: String, recordType: String, recordContent: String): Boolean {
|
||||
val body = gson.toJson(mapOf(
|
||||
"name" to recordName,
|
||||
"type" to recordType,
|
||||
"content" to recordContent
|
||||
)).toRequestBody("application/json; charset=utf-8".toMediaType())
|
||||
val request = Request.Builder()
|
||||
.url("$apiUrl/api/v1/servers/localhost/zones/$zoneName/records")
|
||||
.addHeader("Authorization", "Bearer $apiKey")
|
||||
.post(body)
|
||||
.build()
|
||||
|
||||
val response = client.newCall(request).execute()
|
||||
return response.isSuccessful
|
||||
}
|
||||
|
||||
fun deleteDomain(name: String): ResponseEntity<String> {
|
||||
val url = "$apiUrl/api/v1/servers/localhost/zones/$name."
|
||||
val headers = createHeaders()
|
||||
val entity = HttpEntity<String>(headers)
|
||||
return restTemplate.exchange(url, HttpMethod.DELETE, entity, String::class.java)
|
||||
fun updateRecord(zoneName: String, recordName: String, recordType: String, recordContent: String): Boolean {
|
||||
val body = gson.toJson(mapOf(
|
||||
"content" to recordContent
|
||||
)).toRequestBody("application/json; charset=utf-8".toMediaType())
|
||||
val request = Request.Builder()
|
||||
.url("$apiUrl/api/v1/servers/localhost/zones/$zoneName/records/$recordName/$recordType")
|
||||
.addHeader("Authorization", "Bearer $apiKey")
|
||||
.put(body)
|
||||
.build()
|
||||
|
||||
val response = client.newCall(request).execute()
|
||||
return response.isSuccessful
|
||||
}
|
||||
|
||||
private data class DomainRequest(
|
||||
val name: String,
|
||||
val kind: String,
|
||||
val masters: Array<String>,
|
||||
val nameservers: Array<String>
|
||||
)
|
||||
fun deleteRecord(zoneName: String, recordName: String, recordType: String): Boolean {
|
||||
val request = Request.Builder()
|
||||
.url("$apiUrl/api/v1/servers/localhost/zones/$zoneName/records/$recordName/$recordType")
|
||||
.addHeader("Authorization", "Bearer $apiKey")
|
||||
.delete()
|
||||
.build()
|
||||
|
||||
private data class RecordRequestWrapper(
|
||||
val rrsets: Array<RecordRequest>
|
||||
)
|
||||
|
||||
private data class RecordRequest(
|
||||
val name: String,
|
||||
val type: String,
|
||||
val ttl: Int,
|
||||
val changetype: String,
|
||||
val records: Array<RecordContent>
|
||||
)
|
||||
|
||||
private data class RecordContent(
|
||||
val content: String,
|
||||
val disabled: Boolean
|
||||
)
|
||||
val response = client.newCall(request).execute()
|
||||
return response.isSuccessful
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@ package space.mori.dnsapi.service
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.stereotype.Service
|
||||
import space.mori.dnsapi.PowerDNSApiClient
|
||||
import space.mori.dnsapi.PowerDNSAPIClient
|
||||
import space.mori.dnsapi.db.Domain
|
||||
import space.mori.dnsapi.db.DomainRepository
|
||||
import space.mori.dnsapi.dto.DomainRequestDTO
|
||||
@ -14,7 +14,7 @@ class DomainService(
|
||||
@Autowired
|
||||
private val domainRepository: DomainRepository,
|
||||
@Autowired
|
||||
private val powerDNSApiClient: PowerDNSApiClient
|
||||
private val powerDNSApiClient: PowerDNSAPIClient
|
||||
) {
|
||||
fun getAllDomains(): List<Domain> {
|
||||
val user = getCurrentUser()
|
||||
@ -38,7 +38,7 @@ class DomainService(
|
||||
fun createDomain(domain: DomainRequestDTO): Domain {
|
||||
val user = getCurrentUser()
|
||||
|
||||
powerDNSApiClient.createDomain(domain.name)
|
||||
powerDNSApiClient.createZone(domain.name)
|
||||
val saved_domain = domainRepository.save(Domain(name=domain.name, user=user))
|
||||
|
||||
return saved_domain
|
||||
@ -49,7 +49,7 @@ class DomainService(
|
||||
throw RuntimeException("Domain with CFID $domain_id not found")
|
||||
}
|
||||
|
||||
powerDNSApiClient.deleteDomain(domain.name)
|
||||
powerDNSApiClient.deleteZone(domain.name)
|
||||
val count = domainRepository.deleteByCfid(domain_id)
|
||||
|
||||
if(count > 0) throw RuntimeException("Domain with CFID $domain_id not found")
|
||||
|
@ -3,12 +3,10 @@ package space.mori.dnsapi.service
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.stereotype.Service
|
||||
import org.springframework.transaction.annotation.Transactional
|
||||
import space.mori.dnsapi.PowerDNSApiClient
|
||||
import space.mori.dnsapi.PowerDNSAPIClient
|
||||
import space.mori.dnsapi.db.DomainRepository
|
||||
import space.mori.dnsapi.db.Record as DomainRecord
|
||||
import space.mori.dnsapi.db.RecordRepository
|
||||
import space.mori.dnsapi.db.UserRepository
|
||||
import space.mori.dnsapi.dto.DomainRequestDTO
|
||||
import space.mori.dnsapi.dto.RecordRequestDTO
|
||||
import space.mori.dnsapi.dto.RecordResponseDTO
|
||||
import space.mori.dnsapi.filter.getCurrentUser
|
||||
@ -19,13 +17,11 @@ import java.util.*
|
||||
@Service
|
||||
class RecordService(
|
||||
@Autowired
|
||||
private val powerDNSApiClient: PowerDNSApiClient,
|
||||
private val powerDNSApiClient: PowerDNSAPIClient,
|
||||
@Autowired
|
||||
private val domainRepository: DomainRepository,
|
||||
@Autowired
|
||||
private val recordRepository: RecordRepository,
|
||||
@Autowired
|
||||
private val userRepository: UserRepository,
|
||||
) {
|
||||
fun createRecord(domain_id: String, recordRequest: RecordRequestDTO): RecordResponseDTO {
|
||||
val domain = domainRepository.findByCfid(domain_id).orElseThrow {
|
||||
@ -36,9 +32,9 @@ class RecordService(
|
||||
if(domain.user.id != user.id)
|
||||
throw RuntimeException("Unauthorized to create record in API: $domain_id")
|
||||
|
||||
val response = powerDNSApiClient.createRecord(domain.name, recordRequest)
|
||||
if (!response.statusCode.is2xxSuccessful) {
|
||||
throw RuntimeException("Failed to create record in PowerDNS: ${response.body}")
|
||||
val response = powerDNSApiClient.createRecord(domain.name, recordRequest.name, recordRequest.type, recordRequest.content)
|
||||
if (!response) {
|
||||
throw RuntimeException("Failed to create record in PowerDNS")
|
||||
}
|
||||
val record = DomainRecord(
|
||||
domain = domain,
|
||||
@ -146,9 +142,9 @@ class RecordService(
|
||||
record.comment = updatedRecord.comment
|
||||
record.modifiedOn = Date()
|
||||
|
||||
val response = powerDNSApiClient.createRecord(domain!!.name, updatedRecord)
|
||||
if (!response.statusCode.is2xxSuccessful) {
|
||||
throw RuntimeException("Failed to update record in PowerDNS: ${response.body}")
|
||||
val response = powerDNSApiClient.updateRecord(domain!!.name, updatedRecord.name, updatedRecord.type, updatedRecord.content)
|
||||
if (!response) {
|
||||
throw RuntimeException("Failed to update record in PowerDNS")
|
||||
}
|
||||
|
||||
// 저장
|
||||
@ -179,9 +175,13 @@ class RecordService(
|
||||
if(domain.user.id != user.id)
|
||||
throw RuntimeException("Unauthorized to create record in API: $domain_id")
|
||||
|
||||
val deletedCount = recordRepository.deleteByDomainIdAndCfid(domain.id!!, record_id)
|
||||
val record = recordRepository.findByDomainIdAndCfid(domain.id!!, record_id).orElseThrow {
|
||||
RuntimeException("Failed to find record in API: $record_id")
|
||||
}
|
||||
|
||||
if(deletedCount == 0) throw RuntimeException("Failed to find record in API: $record_id")
|
||||
else return record_id
|
||||
powerDNSApiClient.deleteRecord(domain.name, record.name, record.type)
|
||||
recordRepository.deleteByDomainIdAndCfid(domain.id!!, record_id)
|
||||
|
||||
return record_id
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user