fix issue #8: Refactor sldInfo to support filtering by multiple record types. Adjust related methods, tests, and documentation accordingly.

This commit is contained in:
2025-12-31 13:19:56 +01:00
parent 6027e66afe
commit 77a584afb6
5 changed files with 65 additions and 34 deletions
+29 -5
View File
@@ -127,18 +127,42 @@ records.forEach(record ->
### `sldInfo`
Retrieve DNS record details for a specific SLD, zone, and record type.
Retrieve DNS record details for a specific SLD and zone, optionally filtered by record types.
- **Parameters**:
- `ZoneEntity zone` - The zone object.
- `String sld` - The second-level domain.
- `RecordType type` - Record type (e.g., A, CNAME).
- `RecordType... types` - Optional record types to filter by (e.g., A, CNAME). If not specified, returns all record
types.
- **Returns**: A list of `RecordEntity` objects matching the criteria.
```java
RecordEntity record = cfDnsClient.sldInfo(zone, "www", RecordType.A);
System.out.println("Record IP: " + record.getContent());
```
// Get all records for a specific SLD
List<RecordEntity> allRecords = cfDnsClient.sldInfo(zone, "www");
allRecords.
forEach(record ->
System.out.
println("Type: "+record.getType() +", Content: "+record.
getContent())
);
// Get only A records
List<RecordEntity> aRecords = cfDnsClient.sldInfo(zone, "www", RecordType.A);
System.out.
println("Found "+aRecords.size() +" A records");
// Get A and AAAA records
List<RecordEntity> ipRecords = cfDnsClient.sldInfo(zone, "www", RecordType.A, RecordType.AAAA);
ipRecords.
forEach(record ->System.out.
println("IP Record: "+record.getContent()));
```
---
### `recordCreate`
@@ -188,21 +188,35 @@ public class CfDnsClient extends CfBasicHttpClient {
* Retrieves detailed information about a specific second-level domain (SLD) record for a given
* zone and record type from the Cloudflare API.
*
* @param zone the zone entity that contains information about the DNS zone
* @param sld the second-level domain (SLD) for which the record information is requested
* @param type the type of DNS record (e.g., A, AAAA, CNAME) being queried
* @return the {@link RecordEntity} of the requested SLD and record type
* @param zone the zone entity that contains information about the DNS zone
* @param sld the second-level domain (SLD) for which the record information is requested
* @param types the type of DNS record (e.g., A, AAAA, CNAME) being queried, nullable
* @return a list of {@code RecordEntity} objects representing the requested record(s)
* @throws CloudflareApiException if an error occurs during interaction with the Cloudflare API
*/
public List<RecordEntity> sldInfo(ZoneEntity zone, String sld, RecordType type)
public List<RecordEntity> sldInfo(ZoneEntity zone, String sld, @Nullable RecordType... types)
throws CloudflareApiException {
String fqdn = buildFqdn(zone, sld);
String endpoint = CfRequest.RECORD_INFO_NAME_TYPE.buildPath(zone.getId(), fqdn, type);
String endpoint = buildEndpointWithTypeFilters(zone.getId(), fqdn, types);
RecordMultipleResponse resp = getRequest(endpoint, RecordMultipleResponse.class);
checkResponse(resp, false);
return resp.getResult();
}
private String buildEndpointWithTypeFilters(String zoneId, String fqdn, @Nullable RecordType... types) {
String baseEndpoint = CfRequest.RECORD_INFO_NAME.buildPath(zoneId, fqdn);
if (types == null || types.length == 0) {
return baseEndpoint;
}
StringBuilder queryParams = new StringBuilder();
for (RecordType type : types) {
queryParams.append("&");
queryParams.append("type=").append(type);
}
return baseEndpoint + queryParams;
}
/**
* Creates a new DNS record for a given second-level domain (SLD) within the specified zone.
*
@@ -327,19 +341,19 @@ public class CfDnsClient extends CfBasicHttpClient {
public void recordDeleteTypeIfExists(ZoneEntity zone, String sld, RecordType... recordTypes)
throws CloudflareApiException {
String fqdn = buildFqdn(zone, sld);
for (RecordType recordType : recordTypes) {
List<RecordEntity> recs;
try {
recs = sldInfo(zone, sld, recordTypes);
} catch (CloudflareNotFoundException e) {
log.trace("No record of type {} found for domain {}.", recordTypes, fqdn);
return;
}
for (RecordEntity rec : recs) {
try {
List<RecordEntity> recs = sldInfo(zone, sld, recordType);
recs.forEach(rec -> {
try {
recordDelete(zone, rec);
log.info("Record {} of type [{}] successful deleted.", fqdn, recordType);
} catch (CloudflareApiException e) {
log.error("Failed to delete record {} of type {} for zone {}: {}", fqdn, recordType, zone.getName(), e.getMessage());
}
});
} catch (CloudflareNotFoundException e) {
log.debug("Record {} of type {} does not exist.", fqdn, recordType);
recordDelete(zone, rec);
log.info("Record {} of type {} successful deleted.", fqdn, recordTypes);
} catch (CloudflareApiException e) {
log.error("Failed to delete record {} of type {} for zone {}: {}", fqdn, recordTypes, zone.getName(), e.getMessage());
}
}
}
@@ -32,13 +32,6 @@ public enum CfRequest {
* and the record name, which need to be provided to construct the complete path.
*/
RECORD_INFO_NAME("/zones/%s/dns_records?name=%s"),
/**
* Represents the API endpoint path for retrieving information about a DNS record within a
* specific DNS zone by its name and type. The endpoint path includes placeholders for the zone
* identifier, record name, and record type, which need to be provided to construct the complete
* path.
*/
RECORD_INFO_NAME_TYPE("/zones/%s/dns_records?name=%s&type=%s"),
/**
* Represents the API endpoint path for updating an existing DNS record within a specific DNS
* zone. The endpoint path includes placeholders for the zone identifier and the record
@@ -38,6 +38,7 @@ public class CfClientTest {
@Test
void testAddHost() throws Exception {
ZoneEntity zone = client.zoneInfo(ZONE_STR);
client.recordDeleteTypeIfExists(zone, SLD_STR, RecordType.A, RecordType.AAAA);
RecordEntity record = RecordEntity.build(SLD_STR, RecordType.A, TTL, "127.0.0.1");
RecordEntity createdRecord = client.recordCreate(zone, record);
assertNotNull(createdRecord.getId());
@@ -3,7 +3,6 @@ package codes.thischwa.cf;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import codes.thischwa.cf.model.RecordType;
import org.junit.jupiter.api.Test;
public class CfRequestTest {
@@ -46,14 +45,14 @@ public class CfRequestTest {
@Test
public void testBuildRecordInfo() {
String result = CfRequest.RECORD_INFO_NAME_TYPE.buildPath("zone123", "sld.domain.com", RecordType.A);
assertEquals("/zones/zone123/dns_records?name=sld.domain.com&type=A", result);
String result = CfRequest.RECORD_INFO_NAME.buildPath("zone123", "sld.domain.com");
assertEquals("/zones/zone123/dns_records?name=sld.domain.com", result);
}
@Test
public void testBuildPathInvalidArguments() {
assertThrows(
IllegalArgumentException.class,
() -> CfRequest.RECORD_INFO_NAME_TYPE.buildPath("zone123", "sld.domain.com"));
() -> CfRequest.RECORD_UPDATE.buildPath("zone123"));
}
}