add dns_server_details table, change param externalserverid to details for AddDnsServerCmd

This commit is contained in:
Manoj Kumar 2026-04-29 19:58:15 +05:30
parent 80f7983910
commit 1da794f4d9
No known key found for this signature in database
GPG Key ID: E952B7234D2C6F88
19 changed files with 336 additions and 63 deletions

View File

@ -17,7 +17,10 @@
package org.apache.cloudstack.api.command.user.dns;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.APICommand;
@ -30,6 +33,7 @@ import org.apache.cloudstack.api.response.DnsServerResponse;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.dns.DnsProviderType;
import org.apache.cloudstack.dns.DnsServer;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.BooleanUtils;
import com.cloud.exception.InvalidParameterValueException;
@ -82,9 +86,9 @@ public class AddDnsServerCmd extends BaseCmd {
description = "Comma separated list of name servers; used to create NS records for the DNS Zone (for example, ns1.example.com, ns2.example.com)")
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;
@Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, description = "Details in key/value pairs using " +
"format details[i].keyname=keyvalue. Example: details[0].pdnsServerId=localhost")
protected Map details;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
@ -145,11 +149,21 @@ public class AddDnsServerCmd extends BaseCmd {
}
}
public String getExternalServerId() {
return externalServerId;
}
public String getDnsUserName() {
return dnsUserName;
}
public Map<String, String> getDetails() {
Map<String, String> detailsMap = new HashMap<>();
if (MapUtils.isNotEmpty(details)) {
Collection<?> props = details.values();
for (Object prop : props) {
HashMap<String, String> detail = (HashMap<String, String>) prop;
for (Map.Entry<String, String> entry: detail.entrySet()) {
detailsMap.put(entry.getKey(),entry.getValue());
}
}
}
return detailsMap;
}
}

View File

@ -19,6 +19,7 @@ package org.apache.cloudstack.dns;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.apache.cloudstack.acl.ControlledEntity;
import org.apache.cloudstack.api.Identity;
@ -49,7 +50,13 @@ public interface DnsServer extends InternalIdentity, Identity, ControlledEntity
String getPublicDomainSuffix();
String getExternalServerId();
Integer getPort();
Map<String, String> getDetails();
String getDetail(String name);
void setDetails(Map<String, String> details);
void appendDetails(String name, String value);
}

View File

@ -45,7 +45,6 @@ public class AddDnsServerCmdTest extends BaseDnsCmdTest {
setField(cmd, "isPublic", true);
setField(cmd, "publicDomainSuffix", "public.example.com");
setField(cmd, "nameServers", Arrays.asList("ns1.example.com", "ns2.example.com"));
setField(cmd, "externalServerId", "localhost");
setField(cmd, "dnsUserName", "admin@example.com");
return cmd;
}
@ -62,7 +61,6 @@ public class AddDnsServerCmdTest extends BaseDnsCmdTest {
assertEquals("public.example.com", cmd.getPublicDomainSuffix());
assertEquals(Arrays.asList("ns1.example.com", "ns2.example.com"), cmd.getNameServers());
assertEquals(DnsProviderType.PowerDNS, cmd.getProvider());
assertEquals("localhost", cmd.getExternalServerId());
assertEquals("admin@example.com", cmd.getDnsUserName());
}

View File

@ -318,5 +318,6 @@
<bean id="dnsServerJoinDao" class="org.apache.cloudstack.dns.dao.DnsServerJoinDaoImpl" />
<bean id="dnsZoneJoinDao" class="org.apache.cloudstack.dns.dao.DnsZoneJoinDaoImpl" />
<bean id="dnsNicJoinDao" class="org.apache.cloudstack.dns.dao.NicDnsJoinDaoImpl" />
<bean id="dnsServerDetailsDao" class="org.apache.cloudstack.dns.dao.DnsServerDetailsDaoImpl" />
</beans>

View File

@ -132,7 +132,6 @@ CREATE TABLE IF NOT EXISTS `cloud`.`dns_server` (
`url` varchar(1024) NOT NULL COMMENT 'dns server url',
`dns_username` varchar(255) COMMENT 'username or email for dns server credentials',
`dns_api_key` varchar(255) NOT NULL COMMENT 'api key or token for the dns server ',
`external_server_id` varchar(255) COMMENT 'dns server id 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',
@ -147,6 +146,17 @@ CREATE TABLE IF NOT EXISTS `cloud`.`dns_server` (
CONSTRAINT `fk_dns_server__account_id` FOREIGN KEY (`account_id`) REFERENCES `account` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- DNS Server Details Table
CREATE TABLE IF NOT EXISTS `cloud`.`dns_server_details` (
`id` bigint unsigned UNIQUE NOT NULL AUTO_INCREMENT COMMENT 'id',
`dns_server_id` bigint unsigned NOT NULL COMMENT 'dns_server the detail is related to',
`name` varchar(255) NOT NULL COMMENT 'name of the detail',
`value` varchar(255) NOT NULL COMMENT 'value of the detail',
`display` tinyint(1) NOT NULL DEFAULT 1 COMMENT 'Should detail be displayed to the end user',
PRIMARY KEY (`id`),
CONSTRAINT `fk_dns_server_details__dns_server_id` FOREIGN KEY (`dns_server_id`) REFERENCES `dns_server`(`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- DNS Zone Table (Stores DNS Zone Metadata)
CREATE TABLE IF NOT EXISTS `cloud`.`dns_zone` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id of the dns zone',

View File

@ -28,14 +28,15 @@ import org.apache.cloudstack.dns.DnsRecord;
import org.apache.cloudstack.dns.DnsServer;
import org.apache.cloudstack.dns.DnsZone;
import org.apache.cloudstack.dns.exception.DnsProviderException;
import org.apache.logging.log4j.util.Strings;
import com.cloud.utils.StringUtils;
import com.cloud.utils.component.AdapterBase;
import com.fasterxml.jackson.databind.JsonNode;
public class PowerDnsProvider extends AdapterBase implements DnsProvider {
private PowerDnsClient client;
static String PDNS_SERVER_ID = "pdnsServerId";
@Override
public DnsProviderType getProviderType() {
@ -44,13 +45,17 @@ public class PowerDnsProvider extends AdapterBase implements DnsProvider {
public void validate(DnsServer server) throws DnsProviderException {
validateRequiredServerFields(server);
client.validateServerId(server.getUrl(), server.getPort(), server.getDnsApiKey(), server.getExternalServerId());
client.validateServerId(server.getUrl(), server.getPort(), server.getDnsApiKey(), server.getDetail(PDNS_SERVER_ID));
}
@Override
public String validateAndResolveServer(DnsServer server) throws Exception {
validateRequiredServerFields(server);
return client.resolveServerId(server.getUrl(), server.getPort(), server.getDnsApiKey(), server.getExternalServerId());
String resolvedDnsServerId = client.resolveServerId(server.getUrl(), server.getPort(), server.getDnsApiKey(), server.getDetail(PDNS_SERVER_ID));
if (Strings.isNotBlank(resolvedDnsServerId)) {
server.appendDetails(PDNS_SERVER_ID, resolvedDnsServerId);
}
return resolvedDnsServerId;
}
@Override
@ -60,7 +65,7 @@ public class PowerDnsProvider extends AdapterBase implements DnsProvider {
server.getUrl(),
server.getPort(),
server.getDnsApiKey(),
server.getExternalServerId(),
server.getDetail(PDNS_SERVER_ID),
zone.getName(),
ApiConstants.NATIVE_ZONE, false, server.getNameServers()
);
@ -69,7 +74,7 @@ public class PowerDnsProvider extends AdapterBase implements DnsProvider {
@Override
public void deleteZone(DnsServer server, DnsZone zone) throws DnsProviderException {
validateRequiredServerAndZoneFields(server, zone);
client.deleteZone(server.getUrl(), server.getPort(), server.getDnsApiKey(), server.getExternalServerId(), zone.getName());
client.deleteZone(server.getUrl(), server.getPort(), server.getDnsApiKey(), server.getDetail(PDNS_SERVER_ID), zone.getName());
}
@Override
@ -79,7 +84,7 @@ public class PowerDnsProvider extends AdapterBase implements DnsProvider {
server.getUrl(),
server.getPort(),
server.getDnsApiKey(),
server.getExternalServerId(),
server.getDetail(PDNS_SERVER_ID),
zone.getName(), ApiConstants.NATIVE_ZONE, false, server.getNameServers());
}
@ -94,7 +99,7 @@ public class PowerDnsProvider extends AdapterBase implements DnsProvider {
server.getUrl(),
server.getPort(),
server.getDnsApiKey(),
server.getExternalServerId(),
server.getDetail(PDNS_SERVER_ID),
zone.getName(), record, ChangeType.REPLACE);
}
@ -110,7 +115,7 @@ public class PowerDnsProvider extends AdapterBase implements DnsProvider {
return applyRecord(server.getUrl(),
server.getPort(),
server.getDnsApiKey(),
server.getExternalServerId(),
server.getDetail(PDNS_SERVER_ID),
zone.getName(), record, ChangeType.DELETE);
}
@ -126,7 +131,7 @@ public class PowerDnsProvider extends AdapterBase implements DnsProvider {
validateRequiredServerAndZoneFields(server, zone);
List<DnsRecord> records = new ArrayList<>();
Iterable<JsonNode> rrsetNodes = client.listRecords(server.getUrl(), server.getPort(), server.getDnsApiKey(),
server.getExternalServerId(), zone.getName());
server.getDetail(PDNS_SERVER_ID), zone.getName());
for (JsonNode rrset : rrsetNodes) {
String name = rrset.path(ApiConstants.NAME).asText();
@ -155,7 +160,7 @@ public class PowerDnsProvider extends AdapterBase implements DnsProvider {
public boolean dnsRecordExists(DnsServer server, DnsZone zone, String recordName, String recordType) throws DnsProviderException {
return client.dnsRecordExists(server.getUrl(), server.getPort(), server.getDnsApiKey(),
server.getExternalServerId(), zone.getName(), recordName, recordType);
server.getDetail(PDNS_SERVER_ID), zone.getName(), recordName, recordType);
}
void validateRequiredServerAndZoneFields(DnsServer server, DnsZone zone) {

View File

@ -75,7 +75,7 @@ public class PowerDnsProviderTest {
when(serverMock.getUrl()).thenReturn("http://pdns:8081");
when(serverMock.getDnsApiKey()).thenReturn("secret");
when(serverMock.getPort()).thenReturn(8081);
when(serverMock.getExternalServerId()).thenReturn("localhost");
when(serverMock.getDetail(PowerDnsProvider.PDNS_SERVER_ID)).thenReturn("localhost");
when(serverMock.getNameServers()).thenReturn(Arrays.asList("ns1.example.com"));
when(zoneMock.getName()).thenReturn("example.com");

View File

@ -57,25 +57,27 @@ import org.apache.cloudstack.api.response.DnsZoneNetworkMapResponse;
import org.apache.cloudstack.api.response.DnsZoneResponse;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.dns.dao.NicDnsJoinDao;
import org.apache.cloudstack.dns.dao.DnsServerDao;
import org.apache.cloudstack.dns.dao.DnsServerDetailsDao;
import org.apache.cloudstack.dns.dao.DnsServerJoinDao;
import org.apache.cloudstack.dns.dao.DnsZoneDao;
import org.apache.cloudstack.dns.dao.DnsZoneJoinDao;
import org.apache.cloudstack.dns.dao.DnsZoneNetworkMapDao;
import org.apache.cloudstack.dns.dao.NicDnsJoinDao;
import org.apache.cloudstack.dns.exception.DnsConflictException;
import org.apache.cloudstack.dns.exception.DnsNotFoundException;
import org.apache.cloudstack.dns.exception.DnsProviderException;
import org.apache.cloudstack.dns.exception.DnsTransportException;
import org.apache.cloudstack.dns.vo.NicDnsJoinVO;
import org.apache.cloudstack.dns.vo.DnsServerJoinVO;
import org.apache.cloudstack.dns.vo.DnsServerVO;
import org.apache.cloudstack.dns.vo.DnsZoneJoinVO;
import org.apache.cloudstack.dns.vo.DnsZoneNetworkMapVO;
import org.apache.cloudstack.dns.vo.DnsZoneVO;
import org.apache.cloudstack.dns.vo.NicDnsJoinVO;
import org.apache.cloudstack.framework.messagebus.MessageBus;
import org.apache.cloudstack.framework.messagebus.MessageSubscriber;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.springframework.stereotype.Component;
import com.cloud.domain.Domain;
@ -142,6 +144,8 @@ public class DnsProviderManagerImpl extends ManagerBase implements DnsProviderMa
VMInstanceDao vmInstanceDao;
@Inject
NicDnsJoinDao nicDnsJoinDao;
@Inject
DnsServerDetailsDao dnsServerDetailsDao;
private static final Set<VirtualMachine.State> VM_ALLOWED_STATES = EnumSet.of(VirtualMachine.State.Running, VirtualMachine.State.Stopped);
@ -180,15 +184,17 @@ public class DnsProviderManagerImpl extends ManagerBase implements DnsProviderMa
}
DnsProviderType type = cmd.getProvider();
DnsServerVO server = new DnsServerVO(cmd.getName(), cmd.getUrl(), cmd.getPort(), cmd.getExternalServerId(), type,
DnsServerVO server = new DnsServerVO(cmd.getName(), cmd.getUrl(), cmd.getPort(), type,
cmd.getDnsUserName(), cmd.getDnsApiKey(), isDnsPublic, publicDomainSuffix, cmd.getNameServers(),
caller.getAccountId(), caller.getDomainId());
if (MapUtils.isNotEmpty(cmd.getDetails())) {
server.setDetails(cmd.getDetails());
}
try {
DnsProvider provider = getProviderByType(type);
String dnsServerId = provider.validateAndResolveServer(server); // returns localhost for PowerDNS
if (StringUtils.isNotBlank(dnsServerId)) {
server.setExternalServerId(dnsServerId);
}
provider.validateAndResolveServer(server);
return dnsServerDao.persist(server);
} catch (Exception ex) {
logger.error("Failed to validate DNS server", ex);

View File

@ -34,4 +34,8 @@ public interface DnsServerDao extends GenericDao<DnsServerVO, Long> {
List<Long> listDnsServerIdsByAccountId(Long accountId);
Pair<List<DnsServerVO>, Integer> searchDnsServer(Long dnsServerId, Long accountId, Set<Long> domainIds, DnsProviderType providerType, String keyword, Filter filter);
void loadDetails(DnsServer dnsServer);
void saveDetails(DnsServer dnsServer);
}

View File

@ -17,12 +17,17 @@
package org.apache.cloudstack.dns.dao;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.inject.Inject;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.dns.DnsProviderType;
import org.apache.cloudstack.dns.DnsServer;
import org.apache.cloudstack.dns.vo.DnsServerDetailVO;
import org.apache.cloudstack.dns.vo.DnsServerVO;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Component;
@ -33,9 +38,14 @@ import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.GenericSearchBuilder;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.db.TransactionCallback;
@Component
public class DnsServerDaoImpl extends GenericDaoBase<DnsServerVO, Long> implements DnsServerDao {
@Inject
DnsServerDetailsDao dnsServerDetailsDao;
SearchBuilder<DnsServerVO> AllFieldsSearch;
SearchBuilder<DnsServerVO> AccountUrlSearch;
GenericSearchBuilder<DnsServerVO, Long> DnsServerIdsByAccountSearch;
@ -121,4 +131,56 @@ public class DnsServerDaoImpl extends GenericDaoBase<DnsServerVO, Long> implemen
sc.setParameters(ApiConstants.STATE, DnsServer.State.Enabled);
return searchAndCount(sc, filter);
}
@Override
public DnsServerVO persist(DnsServerVO dnsServer) {
return Transaction.execute((TransactionCallback<DnsServerVO>) status -> {
DnsServerVO dnsServerDb = super.persist(dnsServer);
saveDetails(dnsServer);
loadDetails(dnsServerDb);
return dnsServerDb;
});
}
@Override
public boolean update(Long id, DnsServerVO dnsServer) {
return Transaction.execute((TransactionCallback<Boolean>) status -> {
boolean result = super.update(id, dnsServer);
if (result) {
saveDetails(dnsServer);
}
return result;
});
}
@Override
public boolean remove(Long dnsServerId) {
return Transaction.execute((TransactionCallback<Boolean>) status -> {
boolean result = super.remove(dnsServerId);
if (result) {
dnsServerDetailsDao.removeDetails(dnsServerId);
}
return result;
});
}
@Override
public void loadDetails(DnsServer dnsServer) {
Map<String, String> details = dnsServerDetailsDao.listDetailsKeyPairs(dnsServer.getId());
dnsServer.setDetails(details);
}
@Override
public void saveDetails(DnsServer dnsServer) {
Map<String, String> detailsStr = dnsServer.getDetails();
if (detailsStr == null) {
return;
}
List<DnsServerDetailVO> details = new ArrayList<>();
for (String key : detailsStr.keySet()) {
DnsServerDetailVO detail = new DnsServerDetailVO(dnsServer.getId(), key, detailsStr.get(key), true);
details.add(detail);
}
dnsServerDetailsDao.saveDetails(details);
}
}

View File

@ -0,0 +1,26 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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 org.apache.cloudstack.dns.dao;
import org.apache.cloudstack.dns.vo.DnsServerDetailVO;
import org.apache.cloudstack.resourcedetail.ResourceDetailsDao;
import com.cloud.utils.db.GenericDao;
public interface DnsServerDetailsDao extends GenericDao<DnsServerDetailVO, Long>, ResourceDetailsDao<DnsServerDetailVO> {
}

View File

@ -0,0 +1,29 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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 org.apache.cloudstack.dns.dao;
import org.apache.cloudstack.dns.vo.DnsServerDetailVO;
import org.apache.cloudstack.resourcedetail.ResourceDetailsDaoBase;
public class DnsServerDetailsDaoImpl extends ResourceDetailsDaoBase<DnsServerDetailVO> implements DnsServerDetailsDao {
@Override
public void addDetail(long resourceId, String key, String value, boolean display) {
super.addDetail(new DnsServerDetailVO(resourceId, key, value, display));
}
}

View File

@ -0,0 +1,99 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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 org.apache.cloudstack.dns.vo;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import org.apache.cloudstack.api.ResourceDetail;
@Entity
@Table(name = "dns_server_details")
public class DnsServerDetailVO implements ResourceDetail {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private long id;
@Column(name = "dns_server_id")
private long resourceId;
@Column(name = "name")
private String name;
@Column(name = "value")
private String value;
@Column(name = "display")
private boolean display = true;
protected DnsServerDetailVO() {
}
public DnsServerDetailVO(long dnsServerId, String name, String value, boolean display) {
this.resourceId = dnsServerId;
this.name = name;
this.value = value;
this.display = display;
}
@Override
public long getId() {
return id;
}
@Override
public long getResourceId() {
return resourceId;
}
@Override
public String getName() {
return name;
}
@Override
public String getValue() {
return value;
}
@Override
public boolean isDisplay() {
return display;
}
public void setId(long id) {
this.id = id;
}
public void setResourceId(long resourceId) {
this.resourceId = resourceId;
}
public void setName(String name) {
this.name = name;
}
public void setValue(String value) {
this.value = value;
}
}

View File

@ -20,7 +20,9 @@ package org.apache.cloudstack.dns.vo;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import javax.persistence.Column;
@ -33,6 +35,7 @@ import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
import org.apache.cloudstack.dns.DnsProviderType;
import org.apache.cloudstack.dns.DnsServer;
@ -72,9 +75,6 @@ public class DnsServerVO implements DnsServer {
@Column(name = "dns_api_key")
private String dnsApiKey;
@Column(name = "external_server_id")
private String externalServerId;
@Column(name = "is_public")
private boolean publicServer;
@ -102,18 +102,20 @@ public class DnsServerVO implements DnsServer {
@Temporal(value = TemporalType.TIMESTAMP)
private Date removed = null;
@Transient
Map<String, String> details;
DnsServerVO() {
this.uuid = UUID.randomUUID().toString();
this.created = new Date();
}
public DnsServerVO(String name, String url, Integer port, String externalServerId, DnsProviderType providerType, String dnsUserName, String dnsApiKey,
public DnsServerVO(String name, String url, Integer port, DnsProviderType providerType, String dnsUserName, String dnsApiKey,
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.dnsApiKey = dnsApiKey;
@ -241,15 +243,29 @@ public class DnsServerVO implements DnsServer {
return publicDomainSuffix;
}
public String getExternalServerId() {
return externalServerId;
}
public void setExternalServerId(String externalServerId) {
this.externalServerId = externalServerId;
}
public Integer getPort() {
return this.port;
}
@Override
public Map<String, String> getDetails() {
return details;
}
@Override
public String getDetail(String name) {
return details != null ? details.get(name) : null;
}
public void setDetails(Map<String, String> details) {
this.details = details;
}
@Override
public void appendDetails(String name, String value) {
if (details == null) {
details = new HashMap<>();
}
details.put(name, value);
}
}

View File

@ -156,7 +156,7 @@ public class DnsProviderManagerImplTest {
when(callerMock.getDomainId()).thenReturn(DOMAIN_ID);
serverVO = Mockito.spy(
new DnsServerVO("test-server", "http://pdns:8081", 8081, "localhost", DnsProviderType.PowerDNS, null,
new DnsServerVO("test-server", "http://pdns:8081", 8081, DnsProviderType.PowerDNS, null,
"apikey", false, null, Collections.singletonList("ns1.example.com"), ACCOUNT_ID, DOMAIN_ID));
Mockito.lenient().doReturn(SERVER_ID).when(serverVO).getId();

View File

@ -50,7 +50,7 @@ public class DnsServerDaoImplTest {
@Before
public void setUp() {
dao = spy(new DnsServerDaoImpl());
mockServer = new DnsServerVO("test-server", "http://pdns:8081", 8081, "localhost", DnsProviderType.PowerDNS, null, "apikey", false, null, Collections.singletonList("ns1.example.com"), 1L, 10L);
mockServer = new DnsServerVO("test-server", "http://pdns:8081", 8081, DnsProviderType.PowerDNS, null, "apikey", false, null, Collections.singletonList("ns1.example.com"), 1L, 10L);
}
@Test

View File

@ -42,14 +42,13 @@ public class DnsServerVOTest {
@Test
public void testParameterizedConstructor() {
List<String> nameServers = Arrays.asList("ns1.example.com", "ns2.example.com");
DnsServerVO vo = new DnsServerVO("test-server", "http://pdns:8081", 8081,
"localhost", DnsProviderType.PowerDNS, "admin", "api-key-123",
DnsServerVO vo = new DnsServerVO("test-server", "http://pdns:8081", 8081, DnsProviderType.PowerDNS, "admin", "api-key-123",
true, "public.example.com", nameServers, 10L, 20L);
assertEquals("test-server", vo.getName());
assertEquals("http://pdns:8081", vo.getUrl());
assertEquals(Integer.valueOf(8081), vo.getPort());
assertEquals("localhost", vo.getExternalServerId());
// assertEquals("localhost", vo.getDetail());
assertEquals(DnsProviderType.PowerDNS, vo.getProviderType());
assertEquals("api-key-123", vo.getDnsApiKey());
assertTrue(vo.getPublicServer());
@ -91,9 +90,6 @@ public class DnsServerVOTest {
vo.setPublicDomainSuffix("new.suffix.com");
assertEquals("new.suffix.com", vo.getPublicDomainSuffix());
vo.setExternalServerId("remote-host");
assertEquals("remote-host", vo.getExternalServerId());
vo.setState(DnsServer.State.Disabled);
assertEquals(DnsServer.State.Disabled, vo.getState());
@ -124,8 +120,7 @@ public class DnsServerVOTest {
@Test
public void testToString() {
List<String> nameServers = Collections.singletonList("ns1.example.com");
DnsServerVO vo = new DnsServerVO("test-server", "http://pdns:8081", 8081,
"localhost", DnsProviderType.PowerDNS, null, "secret-key",
DnsServerVO vo = new DnsServerVO("test-server", "http://pdns:8081", 8081, DnsProviderType.PowerDNS, null, "secret-key",
false, null, nameServers, 1L, 10L);
String result = vo.toString();
@ -139,7 +134,7 @@ public class DnsServerVOTest {
@Test
public void testConstructorNotPublicServer() {
List<String> nameServers = Collections.singletonList("ns1.example.com");
DnsServerVO vo = new DnsServerVO("srv", "http://url", null, null,
DnsServerVO vo = new DnsServerVO("srv", "http://url", null,
DnsProviderType.PowerDNS, null, "key",
false, null, nameServers, 1L, 1L);

View File

@ -958,7 +958,7 @@
"label.dns.delete.server": "Delete DNS Server",
"label.dns.delete.zone": "Delete DNS Zone",
"label.dns.dnsapikey": "DNS API key",
"label.dns.externalserverid": "DNS server ID",
"label.dns.pdnsserverid": "PowerDNS server ID",
"label.dns.name": "DNS Name",
"label.dns.publicdomainsuffix": "Public domain suffix",
"label.dns.records": "DNS Records",

View File

@ -91,15 +91,15 @@
:placeholder="apiParams.dnsapikey?.description || 'Enter API Key'" />
</a-form-item>
<a-form-item name="externalserverid" ref="externalserverid">
<a-form-item v-if="form.provider === 'PowerDNS'" name="pdnsserverid" ref="pdnsserverid">
<template #label>
<tooltip-label
:title="$t('label.dns.externalserverid')"
:tooltip="apiParams.externalserverid?.description" />
:title="$t('label.dns.pdnsserverid')"
:tooltip="'PowerDNS Server ID'" />
</template>
<a-input
v-model:value="form.externalserverid"
:placeholder="apiParams.externalserverid?.description || 'Enter Server ID of PowerDNS e.g. localhost'" />
v-model:value="form.pdnsserverid"
:placeholder="'Enter PowerDNS Server ID (optional if localhost)'" />
</a-form-item>
<a-form-item v-if="isAdminOrDomainAdmin()" name="publicdomainsuffix" ref="publicdomainsuffix">
@ -175,7 +175,7 @@ export default {
nameservers: [],
ispublic: false,
publicdomainsuffix: '',
externalserverid: 'localhost'
pdnsserverid: ''
},
rules: {},
fetchingProviders: false,
@ -196,7 +196,6 @@ export default {
],
provider: [{ required: true, message: this.$t('message.error.required.input') }],
dnsapikey: [{ required: true, message: this.$t('message.error.required.input') }],
externalserverid: [{ required: true, message: this.$t('message.error.required.input') }],
nameservers: [
{ required: true, type: 'array', min: 1, message: this.$t('message.error.required.input') },
{ validator: this.validateNameservers }
@ -226,13 +225,15 @@ export default {
port: this.form.port,
provider: this.form.provider,
dnsapikey: this.form.dnsapikey?.trim(),
externalserverid: this.form.externalserverid?.trim(),
nameservers: this.form.nameservers || [],
ispublic: this.form.ispublic
}
if (this.form.publicdomainsuffix) {
params.publicdomainsuffix = this.form.publicdomainsuffix?.toLowerCase().trim()
}
if (this.form.pdnsserverid) {
params['details[0].pdnsServerId'] = this.form.pdnsserverid?.trim()
}
await postAPI('addDnsServer', params)
this.$notification.success({
message: this.$t('label.dns.add.server'),