feat: получение записей домена
This commit is contained in:
@@ -24,9 +24,13 @@ ext {
|
||||
junitVersion = "5.9.2"
|
||||
jacksonVersion = "2.15.3"
|
||||
slf4jVersion = "2.0.16"
|
||||
lombokVersion = "1.18.34"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
annotationProcessor("org.projectlombok:lombok:$lombokVersion")
|
||||
compileOnly("org.projectlombok:lombok:$lombokVersion")
|
||||
|
||||
implementation("org.apache.httpcomponents.client5:httpclient5:5.5")
|
||||
implementation("org.apache.commons:commons-lang3:3.18.0")
|
||||
implementation("com.fasterxml.jackson.core:jackson-databind:$jacksonVersion")
|
||||
|
||||
49
src/main/java/ru/di9/ihc/DomainRecord.java
Normal file
49
src/main/java/ru/di9/ihc/DomainRecord.java
Normal file
@@ -0,0 +1,49 @@
|
||||
package ru.di9.ihc;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
public class DomainRecord {
|
||||
private final int id;
|
||||
private final boolean readOnly;
|
||||
private final RecordType type;
|
||||
|
||||
private String name;
|
||||
private String content;
|
||||
private Integer priority;
|
||||
|
||||
public DomainRecord(int id, boolean readOnly, String name, RecordType type, String content, Integer priority) {
|
||||
this.id = id;
|
||||
this.readOnly = readOnly;
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.content = content;
|
||||
this.priority = priority;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
if (readOnly) {
|
||||
throw new RuntimeException("READ ONLY RECORD");
|
||||
}
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setContent(String content) {
|
||||
if (readOnly) {
|
||||
throw new RuntimeException("READ ONLY RECORD");
|
||||
}
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public void setPriority(Integer priority) {
|
||||
if (readOnly) {
|
||||
throw new RuntimeException("READ ONLY RECORD");
|
||||
}
|
||||
if (!RecordType.MX.equals(type) && !RecordType.SRV.equals(type)) {
|
||||
throw new RuntimeException("NOT SUPPORT SET PRIORITY FOR " + type.name() + " RECORD");
|
||||
}
|
||||
this.priority = priority;
|
||||
}
|
||||
}
|
||||
22
src/main/java/ru/di9/ihc/DomainRecordsResponse.java
Normal file
22
src/main/java/ru/di9/ihc/DomainRecordsResponse.java
Normal file
@@ -0,0 +1,22 @@
|
||||
package ru.di9.ihc;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public record DomainRecordsResponse(Data data) {
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public record Data(List<Record> records) {
|
||||
}
|
||||
|
||||
public record Record(
|
||||
int id,
|
||||
boolean readOnly,
|
||||
String name,
|
||||
String type,
|
||||
String content,
|
||||
Integer prio
|
||||
) {
|
||||
}
|
||||
}
|
||||
@@ -16,9 +16,7 @@ import org.jsoup.select.Elements;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
public class IhcClient {
|
||||
private final String baseUrl;
|
||||
@@ -90,4 +88,45 @@ public class IhcClient {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public List<DomainRecord> getDomainRecords(int domainId) {
|
||||
if (!isAuth) {
|
||||
throw new RuntimeException("IS NOT AUTH");
|
||||
}
|
||||
|
||||
HttpPost httpPost = new HttpPost(URI.create("%s/dnsZone/records".formatted(baseUrl)));
|
||||
httpPost.setHeader("Accept", "application/json");
|
||||
httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
|
||||
httpPost.setHeader("Referer", "%s/dnsZone/index/%d".formatted(baseUrl, domainId));
|
||||
httpPost.setEntity(new UrlEncodedFormEntity(List.of(
|
||||
new BasicNameValuePair("id", String.valueOf(domainId))
|
||||
)));
|
||||
|
||||
try {
|
||||
return httpClient.execute(httpPost, resp -> {
|
||||
if (resp.getCode() != 200) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
DomainRecordsResponse response = mapper.readValue(resp.getEntity().getContent(), DomainRecordsResponse.class);
|
||||
List<DomainRecord> list = new ArrayList<>();
|
||||
|
||||
for (DomainRecordsResponse.Record rec : response.data().records()) {
|
||||
list.add(new DomainRecord(
|
||||
rec.id(),
|
||||
rec.readOnly(),
|
||||
rec.name(),
|
||||
RecordType.valueOf(rec.type()),
|
||||
rec.content(),
|
||||
rec.prio()
|
||||
));
|
||||
}
|
||||
|
||||
list.sort(Comparator.comparingInt(DomainRecord::getId));
|
||||
return list;
|
||||
});
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
13
src/main/java/ru/di9/ihc/RecordType.java
Normal file
13
src/main/java/ru/di9/ihc/RecordType.java
Normal file
@@ -0,0 +1,13 @@
|
||||
package ru.di9.ihc;
|
||||
|
||||
public enum RecordType {
|
||||
SOA,
|
||||
A,
|
||||
AAAA,
|
||||
CNAME,
|
||||
MX,
|
||||
TXT,
|
||||
SRV,
|
||||
NS,
|
||||
CAA
|
||||
}
|
||||
79
src/test/java/ru/di9/ihc/GetDomainRecordsTest.java
Normal file
79
src/test/java/ru/di9/ihc/GetDomainRecordsTest.java
Normal file
@@ -0,0 +1,79 @@
|
||||
package ru.di9.ihc;
|
||||
|
||||
import com.github.tomakehurst.wiremock.WireMockServer;
|
||||
import com.github.tomakehurst.wiremock.client.WireMock;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.RandomUtils;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
|
||||
import static com.github.tomakehurst.wiremock.client.WireMock.get;
|
||||
import static com.github.tomakehurst.wiremock.client.WireMock.post;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class GetDomainRecordsTest {
|
||||
static int port;
|
||||
static WireMockServer wireMockServer;
|
||||
|
||||
@BeforeAll
|
||||
static void beforeAll() {
|
||||
port = RandomUtils.nextInt(9000, 9999);
|
||||
wireMockServer = new WireMockServer(port);
|
||||
wireMockServer.start();
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
static void afterAll() {
|
||||
wireMockServer.stop();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void after() {
|
||||
wireMockServer.resetAll();
|
||||
}
|
||||
|
||||
@Test
|
||||
void test() throws IOException {
|
||||
wireMockServer.stubFor(post("/j_spring_security_check?ajax=true")
|
||||
.willReturn(WireMock.okJson("""
|
||||
{"redirect":{"url":"/"},"alert":{"type":"none","message":""}}""")));
|
||||
wireMockServer.stubFor(get("/dnsZone/list")
|
||||
.willReturn(WireMock.ok(IOUtils.resourceToString("/ihc-dns.html", StandardCharsets.UTF_8))
|
||||
.withHeader("Content-Type", "text/html")));
|
||||
wireMockServer.stubFor(post("/dnsZone/records")
|
||||
.willReturn(WireMock.okJson(IOUtils.resourceToString("/ihc-domain.json", StandardCharsets.UTF_8))));
|
||||
|
||||
var ihc = new IhcClient("http://localhost:%d".formatted(port));
|
||||
ihc.auth("user1", "passwd1");
|
||||
Integer domainId = ihc.getDomains().getFirst().getValue();
|
||||
List<DomainRecord> domainRecords = ihc.getDomainRecords(domainId);
|
||||
|
||||
assertEquals(7, domainRecords.size());
|
||||
|
||||
DomainRecord record1 = domainRecords.getFirst();
|
||||
assertEquals(7000001, record1.getId());
|
||||
assertTrue(record1.isReadOnly());
|
||||
assertEquals(RecordType.SOA, record1.getType());
|
||||
assertEquals("", record1.getName());
|
||||
assertEquals("ns1.ihc.ru. info.ihc.ru. 2014120801 10800 3600 604800 3600", record1.getContent());
|
||||
assertNull(record1.getPriority());
|
||||
|
||||
assertThrows(RuntimeException.class, () -> record1.setName("xx"));
|
||||
|
||||
DomainRecord record2 = domainRecords.get(4);
|
||||
assertEquals(7000005, record2.getId());
|
||||
assertFalse(record2.isReadOnly());
|
||||
assertEquals(RecordType.MX, record2.getType());
|
||||
assertEquals("", record2.getName());
|
||||
assertEquals("mx.yandex.ru", record2.getContent());
|
||||
assertEquals(10, record2.getPriority());
|
||||
|
||||
assertDoesNotThrow(() -> record2.setName("xx"));
|
||||
}
|
||||
}
|
||||
72
src/test/resources/ihc-domain.json
Normal file
72
src/test/resources/ihc-domain.json
Normal file
@@ -0,0 +1,72 @@
|
||||
{
|
||||
"alert": {
|
||||
"type": "none",
|
||||
"message": ""
|
||||
},
|
||||
"data": {
|
||||
"errors": [],
|
||||
"messages": [],
|
||||
"domain": {
|
||||
"name": "example-1.ru",
|
||||
"id": 111111
|
||||
},
|
||||
"records": [
|
||||
{
|
||||
"readOnly": true,
|
||||
"id": 7000001,
|
||||
"name": "",
|
||||
"type": "SOA",
|
||||
"content": "ns1.ihc.ru. info.ihc.ru. 2014120801 10800 3600 604800 3600",
|
||||
"prio": null
|
||||
},
|
||||
{
|
||||
"readOnly": true,
|
||||
"id": 7000002,
|
||||
"name": "",
|
||||
"type": "NS",
|
||||
"content": "ns1.ihc.ru",
|
||||
"prio": null
|
||||
},
|
||||
{
|
||||
"readOnly": true,
|
||||
"id": 7000003,
|
||||
"name": "",
|
||||
"type": "NS",
|
||||
"content": "ns2.ihc.ru",
|
||||
"prio": null
|
||||
},
|
||||
{
|
||||
"readOnly": false,
|
||||
"id": 7000004,
|
||||
"name": "yamail-XXXXXXXXXXXX",
|
||||
"type": "CNAME",
|
||||
"content": "mail.yandex.ru",
|
||||
"prio": null
|
||||
},
|
||||
{
|
||||
"readOnly": false,
|
||||
"id": 7000005,
|
||||
"name": "",
|
||||
"type": "MX",
|
||||
"content": "mx.yandex.ru",
|
||||
"prio": 10
|
||||
},
|
||||
{
|
||||
"readOnly": false,
|
||||
"id": 7000006,
|
||||
"name": "",
|
||||
"type": "A",
|
||||
"content": "127.0.0.1",
|
||||
"prio": null
|
||||
},
|
||||
{
|
||||
"readOnly": false,
|
||||
"id": 7000007,
|
||||
"name": "_acme-challenge",
|
||||
"type": "TXT",
|
||||
"content": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
|
||||
"prio": null
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user