mirror of https://github.com/apache/cloudstack.git
include:
1. port for dns_server 2. remove hard coded localhost for server_id 3. resolve and store server id if not passed in the api request 4. restrict public dns_server for domain admins and admins
This commit is contained in:
parent
4a9f66d532
commit
c64cf81db3
|
|
@ -1335,6 +1335,7 @@ public class ApiConstants {
|
|||
|
||||
// DNS provider related
|
||||
public static final String NAME_SERVERS = "nameservers";
|
||||
public static final String DNS_USER_NAME = "dnsusername";
|
||||
public static final String CREDENTIALS = "credentials";
|
||||
public static final String DNS_ZONE_ID = "dnszoneid";
|
||||
public static final String DNS_SERVER_ID = "dnsserverid";
|
||||
|
|
@ -1351,6 +1352,7 @@ public class ApiConstants {
|
|||
public static final String X_API_KEY = "X-API-Key";
|
||||
public static final String DISABLED = "disabled";
|
||||
public static final String CONTENT_TYPE = "Content-Type";
|
||||
public static final String NATIVE_ZONE = "Native";
|
||||
|
||||
|
||||
public static final String PARAMETER_DESCRIPTION_ACTIVATION_RULE = "Quota tariff's activation rule. It can receive a JS script that results in either " +
|
||||
|
|
|
|||
|
|
@ -53,7 +53,11 @@ public class AddDnsServerCmd extends BaseCmd {
|
|||
@Parameter(name = ApiConstants.PROVIDER, type = CommandType.STRING, required = true, description = "Provider type (e.g., PowerDNS)")
|
||||
private String provider;
|
||||
|
||||
@Parameter(name = ApiConstants.CREDENTIALS, type = CommandType.STRING, description = "API Key or Credentials for the external provider")
|
||||
@Parameter(name = ApiConstants.DNS_USER_NAME, type = CommandType.STRING,
|
||||
description = "Username or email associated with the external DNS provider account (used for authentication)")
|
||||
private String dnsUserName;
|
||||
|
||||
@Parameter(name = ApiConstants.CREDENTIALS, required = true, type = CommandType.STRING, description = "API key or credentials for the external provider")
|
||||
private String credentials;
|
||||
|
||||
@Parameter(name = ApiConstants.PORT, type = CommandType.INTEGER, description = "Port number of the external DNS server")
|
||||
|
|
@ -69,6 +73,9 @@ public class AddDnsServerCmd extends BaseCmd {
|
|||
required = true, description = "Comma separated list of name servers")
|
||||
private List<String> nameServers;
|
||||
|
||||
@Parameter(name = "externalserverid", type = CommandType.STRING, description = "External server id or hostname for the DNS server, e.g., 'localhost' for PowerDNS")
|
||||
private String externalServerId;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -117,4 +124,12 @@ public class AddDnsServerCmd extends BaseCmd {
|
|||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public String getExternalServerId() {
|
||||
return externalServerId;
|
||||
}
|
||||
|
||||
public String getDnsUserName() {
|
||||
return dnsUserName;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,10 +55,12 @@ public class DnsServerResponse extends BaseResponse {
|
|||
@Param(description = "Is the DNS server publicly available")
|
||||
private Boolean isPublic;
|
||||
|
||||
@SerializedName(ApiConstants.PUBLIC_DOMAIN_SUFFIX) @Param(description = "The public domain suffix for the DNS server")
|
||||
@SerializedName(ApiConstants.PUBLIC_DOMAIN_SUFFIX)
|
||||
@Param(description = "The public domain suffix for the DNS server")
|
||||
private String publicDomainSuffix;
|
||||
|
||||
@SerializedName(ApiConstants.NAME_SERVERS) @Param(description = "Name servers entries associated to DNS server")
|
||||
@SerializedName(ApiConstants.NAME_SERVERS)
|
||||
@Param(description = "Name servers entries associated to DNS server")
|
||||
private List<String> nameServers;
|
||||
|
||||
public DnsServerResponse() {
|
||||
|
|
|
|||
|
|
@ -39,10 +39,6 @@ public class DnsZoneResponse extends BaseResponse {
|
|||
@Param(description = "ID of the DNS server this zone belongs to")
|
||||
private Long dnsServerId;
|
||||
|
||||
@SerializedName("dnsservername")
|
||||
@Param(description = "Name of the DNS server this zone belongs to")
|
||||
private String dnsServerName;
|
||||
|
||||
@SerializedName(ApiConstants.NETWORK_ID)
|
||||
@Param(description = "ID of the network this zone is associated with")
|
||||
private String networkId;
|
||||
|
|
@ -76,10 +72,6 @@ public class DnsZoneResponse extends BaseResponse {
|
|||
this.dnsServerId = dnsServerId;
|
||||
}
|
||||
|
||||
public void setDnsServerName(String dnsServerName) {
|
||||
this.dnsServerName = dnsServerName;
|
||||
}
|
||||
|
||||
public void setNetworkId(String networkId) {
|
||||
this.networkId = networkId;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@ public interface DnsProvider extends Adapter {
|
|||
// Validates connectivity to the server
|
||||
void validate(DnsServer server) throws Exception;
|
||||
|
||||
String validateAndResolveServer(DnsServer server) throws Exception;
|
||||
|
||||
// Zone Operations
|
||||
String provisionZone(DnsServer server, DnsZone zone) throws DnsProviderException;
|
||||
void deleteZone(DnsServer server, DnsZone zone) throws DnsProviderException;
|
||||
|
|
|
|||
|
|
@ -46,4 +46,10 @@ public interface DnsServer extends InternalIdentity, Identity, ControlledEntity
|
|||
Date getCreated();
|
||||
|
||||
Date getRemoved();
|
||||
|
||||
String getPublicDomainSuffix();
|
||||
|
||||
String getExternalServerId();
|
||||
|
||||
Integer getPort();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,7 +62,9 @@ CREATE TABLE `cloud`.`dns_server` (
|
|||
`name` varchar(255) NOT NULL COMMENT 'display name of the dns server',
|
||||
`provider_type` varchar(255) NOT NULL COMMENT 'Provider type such as PowerDns',
|
||||
`url` varchar(1024) NOT NULL COMMENT 'dns server url',
|
||||
`dns_username` varchar(255) NOT NULL COMMENT 'username or email for dns server credentials',
|
||||
`api_key` varchar(255) NOT NULL COMMENT 'dns server api_key',
|
||||
`dns_server_name` varchar(255) COMMENT 'dns server name e.g. localhost for powerdns',
|
||||
`port` int(11) DEFAULT NULL COMMENT 'optional dns server port',
|
||||
`name_servers` varchar(1024) DEFAULT NULL COMMENT 'Comma separated list of name servers',
|
||||
`is_public` tinyint(1) NOT NULL DEFAULT '0',
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@
|
|||
package org.apache.cloudstack.dns.powerdns;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Collections;
|
||||
|
|
@ -62,7 +64,7 @@ public class PowerDnsClient implements AutoCloseable {
|
|||
private static final int MAX_CONNECTIONS_TOTAL = 50;
|
||||
private static final int MAX_CONNECTIONS_PER_ROUTE = 10;
|
||||
private static final String API_PREFIX = "/api/v1";
|
||||
private static final String DEFAULT_SERVER = "localhost";
|
||||
public static final String DEFAULT_SERVER_NAME = "localhost";
|
||||
|
||||
private final CloseableHttpClient httpClient;
|
||||
|
||||
|
|
@ -85,30 +87,59 @@ public class PowerDnsClient implements AutoCloseable {
|
|||
.build();
|
||||
}
|
||||
|
||||
public void validate(String baseUrl, String apiKey) throws DnsProviderException {
|
||||
String url = buildUrl(baseUrl, "/servers");
|
||||
public String resolveServerId(String baseUrl, Integer port, String apiKey, String externalServerId) throws DnsProviderException {
|
||||
if (StringUtils.isNotBlank(externalServerId)) {
|
||||
return validateServerId(baseUrl, port, apiKey, externalServerId);
|
||||
}
|
||||
return discoverAuthoritativeServerId(baseUrl, port, apiKey);
|
||||
}
|
||||
|
||||
public String validateServerId(String baseUrl, Integer port, String apiKey, String externalServerId) throws DnsProviderException {
|
||||
String encodedServer = URLEncoder.encode(externalServerId, StandardCharsets.UTF_8);
|
||||
HttpGet request = new HttpGet(buildUrl(baseUrl, port, "/servers/" + encodedServer));
|
||||
JsonNode server = execute(request, apiKey, 200);
|
||||
if (!ApiConstants.AUTHORITATIVE.equalsIgnoreCase(server.path("daemon_type").asText(null))) {
|
||||
throw new DnsOperationException(String.format("Server %s is not authoritative type=%s", externalServerId,
|
||||
server.path("daemon_type").asText(null)));
|
||||
}
|
||||
return externalServerId;
|
||||
}
|
||||
|
||||
public String discoverAuthoritativeServerId(String baseUrl, Integer port, String apiKey) throws DnsProviderException {
|
||||
String url = buildUrl(baseUrl, port , "/servers");
|
||||
HttpGet request = new HttpGet(url);
|
||||
JsonNode servers = execute(request, apiKey, 200);
|
||||
if (servers == null || !servers.isArray() || servers.isEmpty()) {
|
||||
throw new DnsOperationException("No servers returned by PowerDNS API");
|
||||
}
|
||||
boolean authoritativeFound = false;
|
||||
String fallbackId = null;
|
||||
for (JsonNode server : servers) {
|
||||
if (ApiConstants.AUTHORITATIVE.equalsIgnoreCase(server.path("daemon_type").asText(null))) {
|
||||
authoritativeFound = true;
|
||||
break;
|
||||
String daemonType = server.path("daemon_type").asText(null);
|
||||
if (!ApiConstants.AUTHORITATIVE.equalsIgnoreCase(daemonType)) {
|
||||
continue;
|
||||
}
|
||||
String serverId = server.path(ApiConstants.ID).asText(null);
|
||||
if (StringUtils.isBlank(serverId)) {
|
||||
continue;
|
||||
}
|
||||
// Prefer localhost if present
|
||||
if (DEFAULT_SERVER_NAME.equals(serverId)) {
|
||||
return serverId;
|
||||
}
|
||||
if (fallbackId == null) {
|
||||
fallbackId = serverId;
|
||||
}
|
||||
}
|
||||
if (!authoritativeFound) {
|
||||
throw new DnsOperationException("No authoritative PowerDNS server found");
|
||||
if (fallbackId != null) {
|
||||
return fallbackId;
|
||||
}
|
||||
throw new DnsOperationException("No authoritative PowerDNS server found");
|
||||
}
|
||||
|
||||
public String createZone(String baseUrl, String apiKey, String zoneName, String zoneKind, boolean dnsSecFlag,
|
||||
List<String> nameServers) throws DnsProviderException {
|
||||
|
||||
validate(baseUrl, apiKey);
|
||||
public String createZone(String baseUrl, Integer port, String apiKey, String externalServerId, String zoneName,
|
||||
String zoneKind, boolean dnsSecFlag, List<String> nameServers) throws DnsProviderException {
|
||||
|
||||
validateServerId(baseUrl, port, externalServerId, apiKey);
|
||||
String normalizedZone = normalizeZone(zoneName);
|
||||
ObjectNode json = MAPPER.createObjectNode();
|
||||
json.put(ApiConstants.NAME, normalizedZone);
|
||||
|
|
@ -120,7 +151,7 @@ public class PowerDnsClient implements AutoCloseable {
|
|||
nsArray.add(ns.endsWith(".") ? ns : ns + ".");
|
||||
}
|
||||
}
|
||||
HttpPost request = new HttpPost(buildUrl(baseUrl, "/servers/" + DEFAULT_SERVER + "/zones"));
|
||||
HttpPost request = new HttpPost(buildUrl(baseUrl, port, "/servers/" + externalServerId + "/zones"));
|
||||
request.setEntity(new StringEntity(json.toString(), StandardCharsets.UTF_8));
|
||||
JsonNode response = execute(request, apiKey, 201);
|
||||
if (response == null) {
|
||||
|
|
@ -133,15 +164,15 @@ public class PowerDnsClient implements AutoCloseable {
|
|||
return zoneId;
|
||||
}
|
||||
|
||||
public void updateZone(String baseUrl, String apiKey, String zoneName, String zoneKind, Boolean dnsSecFlag,
|
||||
List<String> nameServers) throws DnsProviderException {
|
||||
public void updateZone(String baseUrl, Integer port, String apiKey, String externalServerId, String zoneName,
|
||||
String zoneKind, Boolean dnsSecFlag, List<String> nameServers) throws DnsProviderException {
|
||||
|
||||
validateServerId(baseUrl, port, externalServerId, apiKey);
|
||||
String normalizedZone = normalizeZone(zoneName);
|
||||
String encodedZone = URLEncoder.encode(normalizedZone, StandardCharsets.UTF_8);
|
||||
String url = buildUrl(baseUrl, "/servers/" + DEFAULT_SERVER + "/zones/" + encodedZone);
|
||||
String url = buildUrl(baseUrl, port,"/servers/" + externalServerId + "/zones/" + encodedZone);
|
||||
|
||||
ObjectNode json = MAPPER.createObjectNode();
|
||||
|
||||
if (dnsSecFlag != null) {
|
||||
json.put(ApiConstants.DNS_SEC, dnsSecFlag);
|
||||
}
|
||||
|
|
@ -159,18 +190,18 @@ public class PowerDnsClient implements AutoCloseable {
|
|||
execute(request, apiKey, 204);
|
||||
}
|
||||
|
||||
public void deleteZone(String baseUrl, String apiKey, String zoneName) throws DnsProviderException {
|
||||
validate(baseUrl, apiKey);
|
||||
public void deleteZone(String baseUrl, Integer port, String apiKey, String externalServerId, String zoneName) throws DnsProviderException {
|
||||
validateServerId(baseUrl, port, apiKey, externalServerId);
|
||||
String normalizedZone = normalizeZone(zoneName);
|
||||
String encodedZone = URLEncoder.encode(normalizedZone, StandardCharsets.UTF_8);
|
||||
HttpDelete request = new HttpDelete(buildUrl(baseUrl, "/servers/" + DEFAULT_SERVER + "/zones/" + encodedZone));
|
||||
HttpDelete request = new HttpDelete(buildUrl(baseUrl, port, "/servers/" + externalServerId + "/zones/" + encodedZone));
|
||||
execute(request, apiKey, 204, 404);
|
||||
}
|
||||
|
||||
public String modifyRecord(String baseUrl, String apiKey, String zoneName, String recordName, String type, long ttl,
|
||||
List<String> contents, String changeType) throws DnsProviderException {
|
||||
public String modifyRecord(String baseUrl, Integer port, String apiKey, String externalServerId, String zoneName,
|
||||
String recordName, String type, long ttl, List<String> contents, String changeType) throws DnsProviderException {
|
||||
|
||||
validate(baseUrl, apiKey);
|
||||
validateServerId(baseUrl, port, apiKey, externalServerId);
|
||||
String normalizedZone = normalizeZone(zoneName);
|
||||
String normalizedRecord = normalizeRecordName(recordName, normalizedZone);
|
||||
ObjectNode root = MAPPER.createObjectNode();
|
||||
|
|
@ -189,17 +220,17 @@ public class PowerDnsClient implements AutoCloseable {
|
|||
}
|
||||
}
|
||||
String encodedZone = URLEncoder.encode(normalizedZone, StandardCharsets.UTF_8);
|
||||
HttpPatch request = new HttpPatch(buildUrl(baseUrl, "/servers/" + DEFAULT_SERVER + "/zones/" + encodedZone));
|
||||
HttpPatch request = new HttpPatch(buildUrl(baseUrl, port, "/servers/" + externalServerId + "/zones/" + encodedZone));
|
||||
request.setEntity(new org.apache.http.entity.StringEntity(root.toString(), StandardCharsets.UTF_8));
|
||||
execute(request, apiKey, 204);
|
||||
return normalizedRecord;
|
||||
}
|
||||
|
||||
public Iterable<JsonNode> listRecords(String baseUrl, String apiKey, String zoneName) throws DnsProviderException {
|
||||
validate(baseUrl, apiKey);
|
||||
public Iterable<JsonNode> listRecords(String baseUrl, Integer port, String apiKey, String externalServerId, String zoneName) throws DnsProviderException {
|
||||
validateServerId(baseUrl, port, apiKey, externalServerId);
|
||||
String normalizedZone = normalizeZone(zoneName);
|
||||
String encodedZone = URLEncoder.encode(normalizedZone, StandardCharsets.UTF_8);
|
||||
HttpGet request = new HttpGet(buildUrl(baseUrl, "/servers/" + DEFAULT_SERVER + "/zones/" + encodedZone));
|
||||
HttpGet request = new HttpGet(buildUrl(baseUrl, port, "/servers/" + externalServerId + "/zones/" + encodedZone));
|
||||
JsonNode zoneNode = execute(request, apiKey, 200);
|
||||
if (zoneNode == null || !zoneNode.has(ApiConstants.RR_SETS)) {
|
||||
return Collections.emptyList();
|
||||
|
|
@ -239,8 +270,22 @@ public class PowerDnsClient implements AutoCloseable {
|
|||
}
|
||||
}
|
||||
|
||||
private String buildUrl(String baseUrl, String path) {
|
||||
return normalizeBaseUrl(baseUrl) + API_PREFIX + path;
|
||||
private String buildUrl(String baseUrl, Integer port, String path) {
|
||||
String fullUrl = normalizeBaseUrl(baseUrl);
|
||||
if (port != null && port > 0) {
|
||||
try {
|
||||
URI uri = new URI(fullUrl);
|
||||
if (uri.getPort() == -1) {
|
||||
fullUrl = fullUrl + ":" + port;
|
||||
}
|
||||
} catch (URISyntaxException e) {
|
||||
fullUrl = fullUrl + ":" + port;
|
||||
}
|
||||
}
|
||||
if (!path.startsWith("/")) {
|
||||
path = "/" + path;
|
||||
}
|
||||
return fullUrl + API_PREFIX + path;
|
||||
}
|
||||
|
||||
private String normalizeBaseUrl(String baseUrl) {
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.dns.DnsProvider;
|
||||
import org.apache.cloudstack.dns.DnsProviderType;
|
||||
import org.apache.cloudstack.dns.DnsRecord;
|
||||
|
|
@ -42,32 +43,44 @@ public class PowerDnsProvider extends AdapterBase implements DnsProvider {
|
|||
}
|
||||
|
||||
public void validate(DnsServer server) throws DnsProviderException {
|
||||
validateServerParams(server);
|
||||
client.validate(server.getUrl(), server.getApiKey());
|
||||
validateRequiredServerFields(server);
|
||||
client.validateServerId(server.getUrl(), server.getPort(), server.getApiKey(), server.getExternalServerId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String validateAndResolveServer(DnsServer server) throws Exception {
|
||||
validateRequiredServerFields(server);
|
||||
return client.resolveServerId(server.getUrl(), server.getPort(), server.getApiKey(), server.getExternalServerId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String provisionZone(DnsServer server, DnsZone zone) throws DnsProviderException {
|
||||
validateServerZoneParams(server, zone);
|
||||
return client.createZone(server.getUrl(),
|
||||
validateRequiredServerAndZoneFields(server, zone);
|
||||
return client.createZone(
|
||||
server.getUrl(),
|
||||
server.getPort(),
|
||||
server.getApiKey(),
|
||||
server.getExternalServerId(),
|
||||
zone.getName(),
|
||||
"Native",
|
||||
false,
|
||||
server.getNameServers()
|
||||
ApiConstants.NATIVE_ZONE, false, server.getNameServers()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteZone(DnsServer server, DnsZone zone) throws DnsProviderException {
|
||||
validateServerZoneParams(server, zone);
|
||||
client.deleteZone(server.getUrl(), server.getApiKey(), zone.getName());
|
||||
validateRequiredServerAndZoneFields(server, zone);
|
||||
client.deleteZone(server.getUrl(), server.getPort(), server.getApiKey(), server.getExternalServerId(), zone.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateZone(DnsServer server, DnsZone zone) throws DnsProviderException {
|
||||
validateServerZoneParams(server, zone);
|
||||
client.updateZone(server.getUrl(), server.getApiKey(), zone.getName(), "Native", false, server.getNameServers());
|
||||
validateRequiredServerAndZoneFields(server, zone);
|
||||
client.updateZone(
|
||||
server.getUrl(),
|
||||
server.getPort(),
|
||||
server.getApiKey(),
|
||||
server.getExternalServerId(),
|
||||
zone.getName(), ApiConstants.NATIVE_ZONE, false, server.getNameServers());
|
||||
}
|
||||
|
||||
public enum ChangeType {
|
||||
|
|
@ -76,42 +89,56 @@ public class PowerDnsProvider extends AdapterBase implements DnsProvider {
|
|||
|
||||
@Override
|
||||
public String addRecord(DnsServer server, DnsZone zone, DnsRecord record) throws DnsProviderException {
|
||||
validateServerZoneParams(server, zone);
|
||||
return applyRecord(server.getUrl(), server.getApiKey(), zone.getName(), record, ChangeType.REPLACE);
|
||||
validateRequiredServerAndZoneFields(server, zone);
|
||||
return applyRecord(
|
||||
server.getUrl(),
|
||||
server.getPort(),
|
||||
server.getApiKey(),
|
||||
server.getExternalServerId(),
|
||||
zone.getName(), record, ChangeType.REPLACE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String updateRecord(DnsServer server, DnsZone zone, DnsRecord record) throws DnsProviderException {
|
||||
validateServerZoneParams(server, zone);
|
||||
validateRequiredServerAndZoneFields(server, zone);
|
||||
return addRecord(server, zone, record);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteRecord(DnsServer server, DnsZone zone, DnsRecord record) throws DnsProviderException {
|
||||
validateServerZoneParams(server, zone);
|
||||
applyRecord(server.getUrl(), server.getApiKey(), zone.getName(), record, ChangeType.DELETE);
|
||||
validateRequiredServerAndZoneFields(server, zone);
|
||||
applyRecord(server.getUrl(),
|
||||
server.getPort(),
|
||||
server.getApiKey(),
|
||||
server.getExternalServerId(),
|
||||
zone.getName(), record, ChangeType.DELETE);
|
||||
}
|
||||
|
||||
public String applyRecord(String serverUrl, String apiKey, String zoneName, DnsRecord record, ChangeType changeType) throws DnsProviderException {
|
||||
return client.modifyRecord(serverUrl, apiKey, zoneName, record.getName(), record.getType().name(),
|
||||
record.getTtl(), record.getContents(), changeType.name());
|
||||
public String applyRecord(String serverUrl, Integer port, String apiKey, String externalServerId, String zoneName,
|
||||
DnsRecord record, ChangeType changeType) throws DnsProviderException {
|
||||
|
||||
return client.modifyRecord(serverUrl, port, apiKey, externalServerId, zoneName, record.getName(),
|
||||
record.getType().name(), record.getTtl(), record.getContents(), changeType.name());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DnsRecord> listRecords(DnsServer server, DnsZone zone) throws DnsProviderException {
|
||||
validateServerZoneParams(server, zone);
|
||||
validateRequiredServerAndZoneFields(server, zone);
|
||||
List<DnsRecord> records = new ArrayList<>();
|
||||
for (JsonNode rrset: client.listRecords(server.getUrl(), server.getApiKey(), zone.getName())) {
|
||||
String name = rrset.path("name").asText();
|
||||
String typeStr = rrset.path("type").asText();
|
||||
int ttl = rrset.path("ttl").asInt(0);
|
||||
Iterable<JsonNode> rrsetNodes = client.listRecords(server.getUrl(), server.getPort(), server.getApiKey(),
|
||||
server.getExternalServerId(), zone.getName());
|
||||
|
||||
for (JsonNode rrset : rrsetNodes) {
|
||||
String name = rrset.path(ApiConstants.NAME).asText();
|
||||
String typeStr = rrset.path(ApiConstants.TYPE).asText();
|
||||
int ttl = rrset.path(ApiConstants.TTL).asInt(0);
|
||||
if (!"SOA".equalsIgnoreCase(typeStr)) {
|
||||
try {
|
||||
List<String> contents = new ArrayList<>();
|
||||
JsonNode recordsNode = rrset.path("records");
|
||||
JsonNode recordsNode = rrset.path(ApiConstants.RECORDS);
|
||||
if (recordsNode.isArray()) {
|
||||
for (JsonNode rec : recordsNode) {
|
||||
String content = rec.path("content").asText();
|
||||
String content = rec.path(ApiConstants.CONTENT).asText();
|
||||
if (!content.isEmpty()) {
|
||||
contents.add(content);
|
||||
}
|
||||
|
|
@ -126,14 +153,14 @@ public class PowerDnsProvider extends AdapterBase implements DnsProvider {
|
|||
return records;
|
||||
}
|
||||
|
||||
void validateServerZoneParams(DnsServer server, DnsZone zone) throws DnsProviderException {
|
||||
validateServerParams(server);
|
||||
void validateRequiredServerAndZoneFields(DnsServer server, DnsZone zone) {
|
||||
validateRequiredServerFields(server);
|
||||
if (StringUtils.isBlank(zone.getName())) {
|
||||
throw new IllegalArgumentException("Zone name cannot be empty");
|
||||
}
|
||||
}
|
||||
|
||||
void validateServerParams(DnsServer server) {
|
||||
void validateRequiredServerFields(DnsServer server) {
|
||||
if (StringUtils.isBlank(server.getUrl())) {
|
||||
throw new IllegalArgumentException("PowerDNS API URL cannot be empty");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -109,17 +109,29 @@ public class DnsProviderManagerImpl extends ManagerBase implements DnsProviderMa
|
|||
throw new InvalidParameterValueException(
|
||||
"This Account already has a DNS server integration for URL: " + cmd.getUrl());
|
||||
}
|
||||
|
||||
boolean isDnsPublic = cmd.isPublic();
|
||||
String publicDomainSuffix = cmd.getPublicDomainSuffix();
|
||||
if (caller.getType().equals(Account.Type.NORMAL)) {
|
||||
logger.info("Only admin and domain admin users are allowed to configure a public DNS server");
|
||||
isDnsPublic = false;
|
||||
publicDomainSuffix = null;
|
||||
}
|
||||
DnsProviderType type = DnsProviderType.fromString(cmd.getProvider());
|
||||
DnsProvider provider = getProvider(type);
|
||||
DnsServerVO server = new DnsServerVO(cmd.getName(), cmd.getUrl(), type, cmd.getCredentials(), cmd.getPort(),
|
||||
cmd.isPublic(), cmd.getPublicDomainSuffix(), cmd.getNameServers(), caller.getId());
|
||||
DnsServerVO server = new DnsServerVO(cmd.getName(), cmd.getUrl(), cmd.getPort(), cmd.getExternalServerId(), type,
|
||||
cmd.getDnsUserName(), cmd.getCredentials(), isDnsPublic, publicDomainSuffix, cmd.getNameServers(),
|
||||
caller.getAccountId(), caller.getDomainId());
|
||||
try {
|
||||
provider.validate(server);
|
||||
DnsProvider provider = getProvider(type);
|
||||
String dnsServerId = provider.validateAndResolveServer(server); // localhost for PowerDNS
|
||||
if (StringUtils.isNotBlank(dnsServerId)) {
|
||||
server.setExternalServerId(dnsServerId);
|
||||
}
|
||||
return dnsServerDao.persist(server);
|
||||
} catch (Exception ex) {
|
||||
logger.error("Failed to validate DNS server", ex);
|
||||
throw new CloudRuntimeException("Failed to validate DNS server");
|
||||
}
|
||||
return dnsServerDao.persist(server);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -246,6 +258,7 @@ public class DnsProviderManagerImpl extends ManagerBase implements DnsProviderMa
|
|||
response.setProvider(server.getProviderType());
|
||||
response.setPublic(server.isPublic());
|
||||
response.setNameServers(server.getNameServers());
|
||||
response.setPublicDomainSuffix(server.getPublicDomainSuffix());
|
||||
response.setObjectName("dnsserver");
|
||||
return response;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ import com.cloud.utils.db.GenericDao;
|
|||
|
||||
@Entity
|
||||
@Table(name = "dns_server")
|
||||
public class DnsServerVO implements DnsServer {
|
||||
public class DnsServerVO implements DnsServer {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "id")
|
||||
|
|
@ -66,10 +66,16 @@ public class DnsServerVO implements DnsServer {
|
|||
@Enumerated(EnumType.STRING)
|
||||
private DnsProviderType providerType;
|
||||
|
||||
@Column(name = "dns_user_name")
|
||||
private String dnsUserName;
|
||||
|
||||
@Encrypt
|
||||
@Column(name = "api_key")
|
||||
private String apiKey;
|
||||
|
||||
@Column(name = "external_server_id")
|
||||
private String externalServerId;
|
||||
|
||||
@Column(name = "is_public")
|
||||
private boolean isPublic;
|
||||
|
||||
|
|
@ -91,7 +97,7 @@ public class DnsServerVO implements DnsServer {
|
|||
|
||||
@Column(name = GenericDao.CREATED_COLUMN)
|
||||
@Temporal(value = TemporalType.TIMESTAMP)
|
||||
private Date created = null;
|
||||
private Date created;
|
||||
|
||||
@Column(name = GenericDao.REMOVED_COLUMN)
|
||||
@Temporal(value = TemporalType.TIMESTAMP)
|
||||
|
|
@ -102,16 +108,18 @@ public class DnsServerVO implements DnsServer {
|
|||
this.created = new Date();
|
||||
}
|
||||
|
||||
public DnsServerVO(String name, String url, DnsProviderType providerType, String apiKey,
|
||||
Integer port, boolean isPublic, String publicDomainSuffix, List<String> nameServers,
|
||||
long accountId) {
|
||||
public DnsServerVO(String name, String url, Integer port, String externalServerId, DnsProviderType providerType, String dnsUserName, String apiKey,
|
||||
boolean isPublic, String publicDomainSuffix, List<String> nameServers, Long accountId, Long domainId) {
|
||||
this();
|
||||
this.name = name;
|
||||
this.url = url;
|
||||
this.port = port;
|
||||
this.externalServerId = externalServerId;
|
||||
this.providerType = providerType;
|
||||
this.dnsUserName = dnsUserName;
|
||||
this.apiKey = apiKey;
|
||||
this.accountId = accountId;
|
||||
this.domainId = domainId;
|
||||
this.publicDomainSuffix = publicDomainSuffix;
|
||||
this.isPublic = isPublic;
|
||||
this.state = State.Enabled;
|
||||
|
|
@ -229,4 +237,20 @@ public class DnsServerVO implements DnsServer {
|
|||
public long getDomainId() {
|
||||
return domainId;
|
||||
}
|
||||
|
||||
public String getPublicDomainSuffix() {
|
||||
return publicDomainSuffix;
|
||||
}
|
||||
|
||||
public String getExternalServerId() {
|
||||
return externalServerId;
|
||||
}
|
||||
|
||||
public void setExternalServerId(String externalServerId) {
|
||||
this.externalServerId = externalServerId;
|
||||
}
|
||||
|
||||
public Integer getPort() {
|
||||
return this.port;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue