diff --git a/LICENSE b/LICENSE
index fdc70aa..9cbcb68 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,7 +1,7 @@
- KloudflareAPI -
[The Apache Software License, Version 2.0]
https://git.dorkbox.com/dorkbox/KloudflareAPI
- Copyright 2020
+ Copyright 2021
Dorkbox LLC
Cloudflare API v4 for Kotlin
@@ -13,3 +13,30 @@
JetBrains s.r.o. and Kotlin Programming Language contributors
Kotlin Compiler, Test Data+Libraries, and Tools repository contain third-party code, to which different licenses may apply
See: https://github.com/JetBrains/kotlin/blob/master/license/README.md
+
+ - OkHttp - Square’s meticulous HTTP client for the JVM, Android, and GraalVM
+ [The Apache Software License, Version 2.0]
+ https://github.com/square/okhttp
+ Copyright 2021
+ Square, Inc
+
+ - Conscrypt - An open platform for building modern web apps for Java back ends
+ [The Apache Software License, Version 2.0]
+ https://github.com/google/conscrypt
+ Copyright 2021
+ Google Inc
+ The Android Open Source Project
+ The Netty Project
+ Apache Harmony
+
+ - Retrofit - A type-safe HTTP client for Android and the JVM
+ [The Apache Software License, Version 2.0]
+ https://github.com/square/retrofit
+ Copyright 2021
+ Square, Inc
+
+ - Moshi - A modern JSON library for Kotlin and Java
+ [The Apache Software License, Version 2.0]
+ https://github.com/square/moshi
+ Copyright 2021
+ Square, Inc
diff --git a/README.md b/README.md
index db05992..5a65dfc 100644
--- a/README.md
+++ b/README.md
@@ -60,7 +60,7 @@ Maven Info
com.dorkbox
KloudflareAPI
- 1.3
+ 1.4
```
diff --git a/build.gradle.kts b/build.gradle.kts
index 4e581a4..7afeb88 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -1,30 +1,45 @@
+/*
+ * Copyright 2021 dorkbox, llc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
import java.time.Instant
-
///////////////////////////////
////// PUBLISH TO SONATYPE / MAVEN CENTRAL
////// TESTING : (to local maven repo) <'publish and release' - 'publishToMavenLocal'>
////// RELEASE : (to sonatype/maven central), <'publish and release' - 'publishToSonatypeAndRelease'>
///////////////////////////////
+gradle.startParameter.showStacktrace = ShowStacktrace.ALWAYS // always show the stacktrace!
+gradle.startParameter.warningMode = WarningMode.All
+
plugins {
- java
+ id("com.dorkbox.GradleUtils") version "2.9"
+ id("com.dorkbox.Licensing") version "2.9.2"
+ id("com.dorkbox.VersionUpdate") version "2.4"
+ id("com.dorkbox.GradlePublish") version "1.11"
- id("com.dorkbox.GradleUtils") version "1.12"
- id("com.dorkbox.Licensing") version "2.5.2"
- id("com.dorkbox.VersionUpdate") version "2.0.5"
- id("com.dorkbox.GradlePublish") version "1.8"
-
- kotlin("jvm") version "1.4.21"
- kotlin("kapt") version "1.4.21"
+ kotlin("jvm") version "1.5.21"
+ kotlin("kapt") version "1.5.21"
}
object Extras {
// set for the project
const val description = "Cloudflare API v4 for Kotlin"
const val group = "com.dorkbox"
- const val version = "1.3"
+ const val version = "1.4"
// set as project.ext
const val name = "KloudflareAPI"
@@ -32,6 +47,7 @@ object Extras {
const val vendor = "Dorkbox LLC"
const val vendorUrl = "https://dorkbox.com"
const val url = "https://git.dorkbox.com/dorkbox/KloudflareAPI"
+
val buildDate = Instant.now().toString()
}
@@ -39,8 +55,7 @@ object Extras {
///// assign 'Extras'
///////////////////////////////
GradleUtils.load("$projectDir/../../gradle.properties", Extras)
-GradleUtils.fixIntellijPaths()
-GradleUtils.defaultResolutionStrategy()
+GradleUtils.defaults()
GradleUtils.compileConfiguration(JavaVersion.VERSION_11)
licensing {
@@ -71,12 +86,6 @@ sourceSets {
}
}
-repositories {
-// mavenLocal() // this must be first!
- jcenter()
-}
-
-
tasks.jar.get().apply {
manifest {
// https://docs.oracle.com/javase/tutorial/deployment/jar/packageman.html
@@ -98,16 +107,17 @@ dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
implementation("org.jetbrains.kotlin:kotlin-stdlib")
implementation("org.jetbrains.kotlin:kotlin-stdlib-common")
+ implementation("org.jetbrains.kotlin:kotlin-reflect")
- val moshiVer = "1.11.0"
- val okHttpVer = "4.9.0"
+ val moshiVer = "1.12.0"
+ val okHttpVer = "4.9.1"
val retroVer = "2.9.0"
implementation("com.squareup.okhttp3:okhttp:$okHttpVer")
implementation("com.squareup.okhttp3:logging-interceptor:$okHttpVer") // Log Network Calls
// better SSL library
- implementation("org.conscrypt:conscrypt-openjdk-uber:2.5.1")
+ implementation("org.conscrypt:conscrypt-openjdk-uber:2.5.2")
// For serialization. THESE ARE NOT TRANSITIVE because it screws up the kotlin version
implementation("com.squareup.retrofit2:retrofit:$retroVer")
@@ -116,6 +126,8 @@ dependencies {
implementation ("com.squareup.moshi:moshi:$moshiVer")
implementation ("com.squareup.moshi:moshi-kotlin:$moshiVer")
+ implementation("com.dorkbox:Updates:1.1")
+
// for AUTOMATIC kotlin reflective serialization of json classes
kapt ("com.squareup.moshi:moshi-kotlin-codegen:$moshiVer")
kaptTest ("com.squareup.moshi:moshi-kotlin-codegen:$moshiVer")
diff --git a/src/dorkbox/kloudflareApi/Kloudflare.kt b/src/dorkbox/kloudflareApi/Kloudflare.kt
index efd8947..f6258a4 100644
--- a/src/dorkbox/kloudflareApi/Kloudflare.kt
+++ b/src/dorkbox/kloudflareApi/Kloudflare.kt
@@ -35,31 +35,33 @@ import okhttp3.ResponseBody
import org.conscrypt.Conscrypt
import retrofit2.Call
import retrofit2.Converter
+import retrofit2.Response
import retrofit2.Retrofit
import retrofit2.converter.moshi.MoshiConverterFactory
import java.io.IOException
import java.security.Security
-import java.util.Collections.emptyMap
class Kloudflare(private val xAuthEmail: String, private val xAuthKey: String) {
companion object {
private const val API_BASE_URL = "https://api.cloudflare.com/client/v4/"
-
- init {
- try {
- Security.insertProviderAt(Conscrypt.newProvider(), 1);
- }
- catch (e: Throwable) {
- e.printStackTrace();
- }
- }
-
/**
* Gets the version number.
*/
- const val version = "1.3"
+ const val version = "1.4"
+
+ init {
+ // Add this project to the updates system, which verifies this class + UUID + version information
+ dorkbox.updates.Updates.add(Kloudflare::class.java, "16bcc9060ac6483782aafc2a5502e7b3", version)
+
+ try {
+ Security.insertProviderAt(Conscrypt.newProvider(), 1)
+ }
+ catch (e: Throwable) {
+ e.printStackTrace()
+ }
+ }
}
private val errorConverter: Converter
@@ -69,11 +71,11 @@ class Kloudflare(private val xAuthEmail: String, private val xAuthKey: String) {
init {
// JSON mapping to java classes
- // val interceptor = HttpLoggingInterceptor()
- // interceptor.level = HttpLoggingInterceptor.Level.BODY
+// val interceptor = HttpLoggingInterceptor()
+// interceptor.level = HttpLoggingInterceptor.Level.BODY
client = OkHttpClient.Builder()
- // .addInterceptor(interceptor) // this is the raw HTTP interceptor
+// .addInterceptor(interceptor) // this is the raw HTTP interceptor
.build()
val moshi = Moshi.Builder()
@@ -103,11 +105,10 @@ class Kloudflare(private val xAuthEmail: String, private val xAuthKey: String) {
return response.body?.string()!!
}
- @Throws(IOException::class)
private fun wrap(call: Call>): T {
- val response = call.execute()
+ val response: Response> = call.execute()
- val body = response.body()
+ val body: CfResponse? = response.body()
if (response.isSuccessful && body != null && body.success) {
return body.result!!
}
@@ -116,6 +117,18 @@ class Kloudflare(private val xAuthEmail: String, private val xAuthKey: String) {
throw IOException("Call failed: " + errorResponse?.errors?.joinToString { error: Error -> "[${error.code} : ${error.message}]" })
}
+ private fun wrapOptions(call: Call>): Pair {
+ val response: Response> = call.execute()
+
+ val body: CfResponse? = response.body()
+ if (response.isSuccessful && body != null && body.success) {
+ return Pair(body.resultInfo!!, body.result!!)
+ }
+
+ val errorResponse = errorConverter.convert(response.errorBody()!!)
+ throw IOException("Call failed: " + errorResponse?.errors?.joinToString { error: Error -> "[${error.code} : ${error.message}]" })
+ }
+
/**
* Gets the User details
*
@@ -149,14 +162,25 @@ class Kloudflare(private val xAuthEmail: String, private val xAuthKey: String) {
* https://api.cloudflare.com/#zone-properties
*/
fun listZones(options: Map = emptyMap()): List {
- val zones = wrap(cloudflare.listZones(xAuthEmail, xAuthKey, options))
- zones.forEach { zone ->
- // have to assign
- zone.kloudflare = this;
+ val actualOptions = mutableMapOf()
+ actualOptions.putAll(options)
+ actualOptions.putIfAbsent("per_page", "20") // not too many at once!
+ val (info, data) = wrapOptions(cloudflare.listZones(xAuthEmail, xAuthKey, actualOptions))
+ data.forEach { zone ->
+ // have to assign
+ zone.kloudflare = this
}
- return zones
+ val zones = mutableListOf()
+ zones.addAll(data)
+
+ if (info.totalPages - info.page > 0) {
+ actualOptions["page"] = "${info.page + 1}"
+ zones.addAll(listZones(actualOptions))
+ }
+
+ return data
}
/**
@@ -182,13 +206,25 @@ class Kloudflare(private val xAuthEmail: String, private val xAuthKey: String) {
*
* https://api.cloudflare.com/#dns-records-for-a-zone-properties
*/
- fun listDnsRecords(zone: Zone): List {
- val wrap =
- wrap(cloudflare.listDnsRecords(xAuthEmail, xAuthKey, zone.id))
- wrap.forEach {
+ fun listDnsRecords(zone: Zone, options: Map = emptyMap()): List {
+ val actualOptions = mutableMapOf()
+ actualOptions.putAll(options)
+ actualOptions.putIfAbsent("per_page", "20") // not too many at once!
+
+ val (info, data) = wrapOptions(cloudflare.listDnsRecords(xAuthEmail, xAuthKey, zone.id, actualOptions))
+ data.forEach {
it.zone = zone
}
- return wrap
+
+ val records = mutableListOf()
+ records.addAll(data)
+
+ if (info.totalPages - info.page > 0) {
+ actualOptions["page"] = "${info.page + 1}"
+ records.addAll(listDnsRecords(zone, actualOptions))
+ }
+
+ return records
}
/**
@@ -197,10 +233,9 @@ class Kloudflare(private val xAuthEmail: String, private val xAuthKey: String) {
* https://api.cloudflare.com/#dns-records-for-a-zone-create-dns-record
*/
fun createDnsRecord(dnsRecord: CreateDnsRecord): DnsRecord {
- val wrap =
- wrap(cloudflare.createDnsRecord(xAuthEmail, xAuthKey, dnsRecord.zone.id, dnsRecord))
- wrap.zone = dnsRecord.zone
- return wrap
+ return wrap(cloudflare.createDnsRecord(xAuthEmail, xAuthKey, dnsRecord.zone.id, dnsRecord)).apply {
+ zone = dnsRecord.zone
+ }
}
/**
@@ -208,7 +243,7 @@ class Kloudflare(private val xAuthEmail: String, private val xAuthKey: String) {
*
* https://api.cloudflare.com/#dns-records-for-a-zone-update-dns-record
*/
- fun updateDnsRecord(updatedDnsRecord: UpdateDnsRecord): Any {
+ fun updateDnsRecord(updatedDnsRecord: UpdateDnsRecord): DnsRecord {
return wrap(cloudflare.updateDnsRecord(xAuthEmail,
xAuthKey,
updatedDnsRecord.zone.id,
diff --git a/src/dorkbox/kloudflareApi/api/CloudflareActions.kt b/src/dorkbox/kloudflareApi/api/CloudflareActions.kt
index d06471e..ddb162d 100644
--- a/src/dorkbox/kloudflareApi/api/CloudflareActions.kt
+++ b/src/dorkbox/kloudflareApi/api/CloudflareActions.kt
@@ -28,15 +28,7 @@ import dorkbox.kloudflareApi.api.zone.RatePlan
import dorkbox.kloudflareApi.api.zone.Zone
import dorkbox.kloudflareApi.api.zone.settings.ZoneSetting
import retrofit2.Call
-import retrofit2.http.Body
-import retrofit2.http.DELETE
-import retrofit2.http.GET
-import retrofit2.http.Header
-import retrofit2.http.Headers
-import retrofit2.http.POST
-import retrofit2.http.PUT
-import retrofit2.http.Path
-import retrofit2.http.QueryMap
+import retrofit2.http.*
interface CloudflareActions {
/**
@@ -124,7 +116,8 @@ interface CloudflareActions {
fun listDnsRecords(
@Header("X-Auth-Email") email: String,
@Header("X-Auth-Key") key: String,
- @Path("zone_identifier") zoneIdentifier: String
+ @Path("zone_identifier") zoneIdentifier: String,
+ @QueryMap options: Map = emptyMap()
): Call>>
diff --git a/src/dorkbox/kloudflareApi/api/core/ResultInfo.kt b/src/dorkbox/kloudflareApi/api/core/ResultInfo.kt
index 0c46d4b..6b55705 100644
--- a/src/dorkbox/kloudflareApi/api/core/ResultInfo.kt
+++ b/src/dorkbox/kloudflareApi/api/core/ResultInfo.kt
@@ -26,6 +26,9 @@ class ResultInfo {
@field:[Json(name = "per_page")]
var perPage = 20
+ @field:[Json(name = "total_pages")]
+ var totalPages = 1
+
@field:[Json(name = "count")]
var count = 1
diff --git a/src/dorkbox/kloudflareApi/api/dns/CreateDnsRecord.kt b/src/dorkbox/kloudflareApi/api/dns/CreateDnsRecord.kt
index cef6fe0..12793af 100644
--- a/src/dorkbox/kloudflareApi/api/dns/CreateDnsRecord.kt
+++ b/src/dorkbox/kloudflareApi/api/dns/CreateDnsRecord.kt
@@ -67,4 +67,10 @@ open class CreateDnsRecord(@Transient val zone: Zone = Zone()) {
*/
@field:[Json(name = "proxied")]
var proxied = false
+
+ /**
+ * Whether the record is receiving the performance and security benefits of Cloudflare
+ */
+ @field:[Json(name = "data")]
+ var data = mutableMapOf()
}
diff --git a/src/dorkbox/kloudflareApi/api/dns/Data.kt b/src/dorkbox/kloudflareApi/api/dns/Data.kt
deleted file mode 100644
index 6110a8a..0000000
--- a/src/dorkbox/kloudflareApi/api/dns/Data.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright 2019 dorkbox, llc
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package dorkbox.kloudflareApi.api.dns
-
-import com.squareup.moshi.JsonClass
-
-/**
- * https://api.cloudflare.com/#dns-records-for-a-zone-properties
- */
-@JsonClass(generateAdapter = true)
-class Data {
-
-}
diff --git a/src/dorkbox/kloudflareApi/api/dns/DnsRecord.kt b/src/dorkbox/kloudflareApi/api/dns/DnsRecord.kt
index 0add1ac..68c94e4 100644
--- a/src/dorkbox/kloudflareApi/api/dns/DnsRecord.kt
+++ b/src/dorkbox/kloudflareApi/api/dns/DnsRecord.kt
@@ -43,7 +43,9 @@ open class DnsRecord {
}
}
-
+ override fun toString(): String {
+ return "DnsRecord(type=$type, name='${name}, content='${content}', ttl='${ttl}')"
+ }
/**
* DNS record identifier tag
@@ -53,7 +55,7 @@ open class DnsRecord {
/**
* Record type
- * A, AAAA, CNAME, TXT, SRV, LOC, MX, NS, SPF, CERT, DNSKEY, DS, NAPTR, SMIMEA, SSHFP, TLSA, URI
+ * A, AAAA, CNAME, TXT, SRV, LOC, MX, NS, SPF, CERT, DNSKEY, DS, NAPTR, SMIMEA, SSHFP, TLSA, URI, CCA
*/
@field:[Json(name = "type")]
var type = RecordType.A
@@ -125,5 +127,5 @@ open class DnsRecord {
* Metadata about the record
*/
@field:[Json(name = "data")]
- var data: Data = Data()
+ var data = mutableMapOf()
}
diff --git a/src/dorkbox/kloudflareApi/api/dns/RecordType.kt b/src/dorkbox/kloudflareApi/api/dns/RecordType.kt
index 4d26d46..b1b0326 100644
--- a/src/dorkbox/kloudflareApi/api/dns/RecordType.kt
+++ b/src/dorkbox/kloudflareApi/api/dns/RecordType.kt
@@ -16,5 +16,5 @@
package dorkbox.kloudflareApi.api.dns
enum class RecordType {
- A, AAAA, CNAME, TXT, SRV, LOC, MX, NS, SPF, CERT, DNSKEY, DS, NAPTR, SMIMEA, SSHFP, TLSA, URI
+ A, AAAA, CNAME, TXT, SRV, LOC, MX, NS, SPF, CERT, DNSKEY, DS, NAPTR, SMIMEA, SSHFP, TLSA, URI, CAA
}
diff --git a/test/dorkbox/kloudflareApi/KloudflareTest.kt b/test/dorkbox/kloudflareApi/KloudflareTest.kt
index fe8f237..c08fc7e 100644
--- a/test/dorkbox/kloudflareApi/KloudflareTest.kt
+++ b/test/dorkbox/kloudflareApi/KloudflareTest.kt
@@ -53,18 +53,32 @@ object KloudflareTest {
// println(kloudflare.getUserBillingHistory())
- val zones = kloudflare.listZones()
- zones.forEach {
- println(it)
- }
+// val zones = kloudflare.listZones().filter { it.name == "example.com" }
+// zones.forEach {
+// println(it)
+// }
// println(kloudflare.getZoneRatePlans("123"))
// println(kloudflare.getZoneRatePlans("123"))
// println(kloudflare.getZoneSettings("123"))
- // println(kloudflare.listDnsRecords("123"))
- println(kloudflare.listAccessRules())
+// println(kloudflare.listDnsRecords("123"))
+// println(kloudflare.listAccessRules())
+ val zone = kloudflare.listZones().first { it.name == "example.com" }
+ zone.dnsRecords.forEach {
+ println(it)
+ }
+
+// val newDnsRecord = CreateDnsRecord(zone)
+// newDnsRecord.type = RecordType.CAA
+// newDnsRecord.name = "example.com"
+// newDnsRecord.data["flags"] = 0
+// newDnsRecord.data["tag"] = "issue"
+// newDnsRecord.data["value"] = "letsencrypt.org"
+//
+// val newRecord = kloudflare.createDnsRecord(newDnsRecord)
+// println("Created: ${newRecord.name} -> ${newRecord.content}")
}
finally {