fixes related to acl, dao

This commit is contained in:
Manoj Kumar 2026-02-25 19:52:50 +05:30
parent add77636d9
commit 1fe79bdfb6
No known key found for this signature in database
GPG Key ID: E952B7234D2C6F88
15 changed files with 126 additions and 293 deletions

View File

@ -28,9 +28,13 @@ import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
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.lang3.BooleanUtils;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.utils.EnumUtils;
@APICommand(name = "addDnsServer",
description = "Adds a new external DNS server",
responseObject = DnsServerResponse.class,
@ -51,8 +55,8 @@ public class AddDnsServerCmd extends BaseCmd {
@Parameter(name = ApiConstants.URL, type = CommandType.STRING, required = true, description = "API URL of the provider")
private String url;
@Parameter(name = ApiConstants.PROVIDER, type = CommandType.STRING, required = true, description = "Provider type (e.g., PowerDNS)")
private String provider;
@Parameter(name = ApiConstants.PROVIDER_TYPE, type = CommandType.STRING, required = true, description = "Provider type (e.g., PowerDNS)")
private String providerType;
@Parameter(name = ApiConstants.DNS_USER_NAME, type = CommandType.STRING,
description = "Username or email associated with the external DNS provider account (used for authentication)")
@ -82,8 +86,9 @@ public class AddDnsServerCmd extends BaseCmd {
/////////////////////////////////////////////////////
public String getName() { return name; }
public String getUrl() { return url; }
public String getProvider() { return provider; }
public String getCredentials() {
return credentials;
}
@ -104,6 +109,15 @@ public class AddDnsServerCmd extends BaseCmd {
return nameServers;
}
public DnsProviderType getProviderType() {
DnsProviderType dnsProviderType = EnumUtils.getEnumIgnoreCase(DnsProviderType.class, providerType, DnsProviderType.PowerDNS);
if (dnsProviderType == null) {
throw new InvalidParameterValueException(String.format("Invalid value passed for provider type, valid values are: %s",
EnumUtils.listValues(DnsProviderType.values())));
}
return dnsProviderType;
}
@Override
public long getEntityOwnerId() {
return CallContext.current().getCallingAccount().getId();

View File

@ -18,6 +18,8 @@
package org.apache.cloudstack.api.command.user.dns;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.acl.SecurityChecker;
import org.apache.cloudstack.api.ACL;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
@ -27,12 +29,14 @@ import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.DnsZoneNetworkMapResponse;
import org.apache.cloudstack.api.response.DnsZoneResponse;
import org.apache.cloudstack.api.response.NetworkResponse;
import org.apache.cloudstack.dns.DnsZone;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.NetworkRuleConflictException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.user.Account;
@APICommand(name = "associateDnsZoneToNetwork",
description = "Associates a DNS Zone with a Network for VM auto-registration",
@ -47,6 +51,7 @@ public class AssociateDnsZoneToNetworkCmd extends BaseCmd {
required = true, description = "The ID of the DNS zone")
private Long dnsZoneId;
@ACL(accessType = SecurityChecker.AccessType.OperateEntry)
@Parameter(name = ApiConstants.NETWORK_ID, type = CommandType.UUID, entityType = NetworkResponse.class,
required = true, description = "The ID of the network")
private Long networkId;
@ -68,7 +73,11 @@ public class AssociateDnsZoneToNetworkCmd extends BaseCmd {
@Override
public long getEntityOwnerId() {
return dnsProviderManager.getDnsZone(dnsZoneId).getAccountId();
DnsZone zone = _entityMgr.findById(DnsZone.class, dnsZoneId);
if (zone != null) {
return zone.getAccountId();
}
return Account.ACCOUNT_ID_SYSTEM;
}
public Long getDnsZoneId() {

View File

@ -80,8 +80,7 @@ public class DeleteDnsZoneCmd extends BaseAsyncCmd {
@Override
public long getEntityOwnerId() {
// Look up the Zone to find the Account Owner
DnsZone zone = dnsProviderManager.getDnsZone(id);
DnsZone zone = _entityMgr.findById(DnsZone.class, id);
if (zone != null) {
return zone.getAccountId();
}

View File

@ -26,7 +26,8 @@ import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.DnsZoneNetworkMapResponse;
import org.apache.cloudstack.api.response.DnsZoneResponse;
import org.apache.cloudstack.api.response.NetworkResponse;
import org.apache.cloudstack.api.response.SuccessResponse;
import com.cloud.exception.ConcurrentOperationException;
@ -44,10 +45,14 @@ import com.cloud.user.Account;
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
public class DisassociateDnsZoneFromNetworkCmd extends BaseCmd {
@Parameter(name = ApiConstants.DNS_ZONE_ID, type = CommandType.UUID, entityType = DnsZoneResponse.class,
required = true, description = "The ID of the DNS zone")
private Long dnsZoneId;
@ACL(accessType = SecurityChecker.AccessType.OperateEntry)
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = DnsZoneNetworkMapResponse.class,
required = true, description = "The ID of the DNS zone to network mapping")
private Long id;
@Parameter(name = ApiConstants.NETWORK_ID, type = CommandType.UUID, entityType = NetworkResponse.class,
required = true, description = "The ID of the network")
private Long networkId;
@Override
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
@ -69,5 +74,11 @@ public class DisassociateDnsZoneFromNetworkCmd extends BaseCmd {
return Account.ACCOUNT_ID_SYSTEM;
}
public Long getId() { return id; }
public Long getDnsZoneId() {
return dnsZoneId;
}
public void setDnsZoneId(Long dnsZoneId) {
this.dnsZoneId = dnsZoneId;
}
}

View File

@ -24,8 +24,12 @@ import org.apache.cloudstack.api.BaseListAccountResourcesCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.response.DnsServerResponse;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.dns.DnsProviderType;
import org.apache.cloudstack.dns.DnsServer;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.utils.EnumUtils;
@APICommand(name = "listDnsServers",
description = "Lists DNS servers owned by the account.",
responseObject = DnsServerResponse.class,
@ -43,9 +47,9 @@ public class ListDnsServersCmd extends BaseListAccountResourcesCmd {
description = "the ID of the DNS server")
private Long id;
@Parameter(name = ApiConstants.PROVIDER, type = CommandType.STRING,
@Parameter(name = ApiConstants.PROVIDER_TYPE, type = CommandType.STRING,
description = "filter by provider type (e.g. PowerDNS, Cloudflare)")
private String provider;
private String providerType;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
@ -55,8 +59,13 @@ public class ListDnsServersCmd extends BaseListAccountResourcesCmd {
return id;
}
public String getProvider() {
return provider;
public DnsProviderType getProviderType() {
DnsProviderType dnsProviderType = EnumUtils.getEnumIgnoreCase(DnsProviderType.class, providerType, DnsProviderType.PowerDNS);
if (dnsProviderType == null) {
throw new InvalidParameterValueException(String.format("Invalid value passed for provider type, valid values are: %s",
EnumUtils.listValues(DnsProviderType.values())));
}
return dnsProviderType;
}
/////////////////////////////////////////////////////

View File

@ -20,7 +20,7 @@ package org.apache.cloudstack.api.command.user.dns;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseListAccountResourcesCmd;
import org.apache.cloudstack.api.BaseListCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.response.DnsServerResponse;
import org.apache.cloudstack.api.response.DnsZoneResponse;
@ -33,7 +33,7 @@ import org.apache.cloudstack.dns.DnsZone;
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
since = "4.23.0",
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
public class ListDnsZonesCmd extends BaseListAccountResourcesCmd {
public class ListDnsZonesCmd extends BaseListCmd {
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////

View File

@ -1,80 +0,0 @@
// 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.api.command.user.dns;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.ACL;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.NetworkResponse;
import org.apache.cloudstack.api.response.SuccessResponse;
import org.apache.cloudstack.api.response.UserVmResponse;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.dns.DnsRecord;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.NetworkRuleConflictException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
@APICommand(name = "registerDnsRecordForVm",
description = "Automatically registers a DNS record for a VM based on its associated Network and DNS Zone mapping",
responseObject = SuccessResponse.class,
entityType = {DnsRecord.class},
since = "4.23.0",
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
public class RegisterDnsRecordForVmCmd extends BaseCmd {
@ACL
@Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID, type = CommandType.UUID, entityType = UserVmResponse.class,
required = true, description = "The ID of the Virtual Machine")
private Long vmId;
@ACL
@Parameter(name = ApiConstants.NETWORK_ID, type = CommandType.UUID, entityType = NetworkResponse.class,
description = "The ID of the network. If not specified, the VM's default NIC network is used.")
private Long networkId;
public Long getVmId() { return vmId; }
public Long getNetworkId() { return networkId; }
@Override
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
try {
boolean result = dnsProviderManager.registerDnsRecordForVm(this);
if (result) {
SuccessResponse response = new SuccessResponse(getCommandName());
setResponseObject(response);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to register DNS record for VM");
}
} catch (Exception e) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
}
}
@Override
public long getEntityOwnerId() {
return CallContext.current().getCallingAccountId();
}
}

View File

@ -1,83 +0,0 @@
// 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.api.command.user.dns;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.ACL;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.NetworkResponse;
import org.apache.cloudstack.api.response.SuccessResponse;
import org.apache.cloudstack.api.response.UserVmResponse;
import org.apache.cloudstack.context.CallContext;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.NetworkRuleConflictException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
@APICommand(name = "removeDnsRecordForVm",
description = "Removes the auto-registered DNS record for a VM",
responseObject = SuccessResponse.class,
since = "4.23.0",
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
public class RemoveDnsRecordForVmCmd extends BaseCmd {
@ACL
@Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID, type = CommandType.UUID, entityType = UserVmResponse.class,
required = true, description = "The ID of the Virtual Machine")
private Long vmId;
@ACL
@Parameter(name = ApiConstants.NETWORK_ID, type = CommandType.UUID, entityType = NetworkResponse.class,
description = "The ID of the network. If not specified, the VM's default NIC network is used.")
private Long networkId;
public Long getVmId() {
return vmId;
}
public Long getNetworkId() {
return networkId;
}
@Override
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
try {
boolean result = dnsProviderManager.removeDnsRecordForVm(this);
if (result) {
SuccessResponse response = new SuccessResponse(getCommandName());
setResponseObject(response);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to remove DNS record for VM");
}
} catch (Exception e) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
}
}
@Override
public long getEntityOwnerId() {
return CallContext.current().getCallingAccountId();
}
}

View File

@ -24,6 +24,7 @@ import org.apache.cloudstack.dns.exception.DnsProviderException;
import com.cloud.utils.component.Adapter;
public interface DnsProvider extends Adapter {
DnsProviderType getProviderType();
// Validates connectivity to the server

View File

@ -29,8 +29,6 @@ import org.apache.cloudstack.api.command.user.dns.DisassociateDnsZoneFromNetwork
import org.apache.cloudstack.api.command.user.dns.ListDnsRecordsCmd;
import org.apache.cloudstack.api.command.user.dns.ListDnsServersCmd;
import org.apache.cloudstack.api.command.user.dns.ListDnsZonesCmd;
import org.apache.cloudstack.api.command.user.dns.RegisterDnsRecordForVmCmd;
import org.apache.cloudstack.api.command.user.dns.RemoveDnsRecordForVmCmd;
import org.apache.cloudstack.api.command.user.dns.UpdateDnsServerCmd;
import org.apache.cloudstack.api.command.user.dns.UpdateDnsZoneCmd;
import org.apache.cloudstack.api.response.DnsRecordResponse;
@ -56,7 +54,6 @@ public interface DnsProviderManager extends Manager, PluggableService {
// Calls the Plugin (State: Inactive -> Active)
DnsZone provisionDnsZone(long zoneId);
DnsZone getDnsZone(Long id);
DnsZone updateDnsZone(UpdateDnsZoneCmd cmd);
boolean deleteDnsZone(Long id);
ListResponse<DnsZoneResponse> listDnsZones(ListDnsZonesCmd cmd);
@ -75,9 +72,5 @@ public interface DnsProviderManager extends Manager, PluggableService {
boolean disassociateZoneFromNetwork(DisassociateDnsZoneFromNetworkCmd cmd);
boolean registerDnsRecordForVm(RegisterDnsRecordForVmCmd cmd);
boolean removeDnsRecordForVm(RemoveDnsRecordForVmCmd cmd);
void checkDnsServerPermissions(Account caller, DnsServer server);
void checkDnsZonePermission(Account caller, DnsZone zone);
}

View File

@ -20,15 +20,4 @@ package org.apache.cloudstack.dns;
public enum DnsProviderType {
PowerDNS;
// Cloudflare
// Helper to validate and return Enum from String safely
public static DnsProviderType fromString(String type) {
if (type == null) return null;
for (DnsProviderType t : DnsProviderType.values()) {
if (t.name().equalsIgnoreCase(type)) {
return t;
}
}
throw new IllegalArgumentException("Invalid DNS Provider type: " + type);
}
}

View File

@ -27,16 +27,15 @@ import org.apache.cloudstack.acl.ProjectRoleService;
import org.apache.cloudstack.acl.RolePermissionEntity;
import org.apache.cloudstack.acl.SecurityChecker;
import org.apache.cloudstack.affinity.AffinityGroup;
import org.apache.cloudstack.backup.BackupOffering;
import org.apache.cloudstack.backup.dao.BackupOfferingDetailsDao;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.dns.DnsProviderManager;
import org.apache.cloudstack.dns.DnsServer;
import org.apache.cloudstack.dns.DnsZone;
import org.apache.cloudstack.query.QueryService;
import org.apache.cloudstack.resourcedetail.dao.DiskOfferingDetailsDao;
import org.springframework.stereotype.Component;
import org.apache.cloudstack.backup.dao.BackupOfferingDetailsDao;
import org.apache.cloudstack.backup.BackupOffering;
import com.cloud.dc.DataCenter;
import com.cloud.dc.DedicatedResourceVO;
import com.cloud.dc.dao.DedicatedResourceDao;
@ -223,10 +222,7 @@ public class DomainChecker extends AdapterBase implements SecurityChecker {
return false;
} else if (entity instanceof DnsServer) {
dnsProviderManager.checkDnsServerPermissions(caller, (DnsServer) entity);
} else if (entity instanceof DnsZone) {
dnsProviderManager.checkDnsZonePermission(caller, (DnsZone) entity);
}
else {
} else {
validateCallerHasAccessToEntityOwner(caller, entity, accessType);
}
return true;

View File

@ -20,6 +20,7 @@ package org.apache.cloudstack.dns;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import javax.inject.Inject;
@ -37,8 +38,6 @@ import org.apache.cloudstack.api.command.user.dns.ListDnsProvidersCmd;
import org.apache.cloudstack.api.command.user.dns.ListDnsRecordsCmd;
import org.apache.cloudstack.api.command.user.dns.ListDnsServersCmd;
import org.apache.cloudstack.api.command.user.dns.ListDnsZonesCmd;
import org.apache.cloudstack.api.command.user.dns.RegisterDnsRecordForVmCmd;
import org.apache.cloudstack.api.command.user.dns.RemoveDnsRecordForVmCmd;
import org.apache.cloudstack.api.command.user.dns.UpdateDnsServerCmd;
import org.apache.cloudstack.api.command.user.dns.UpdateDnsZoneCmd;
import org.apache.cloudstack.api.response.DnsRecordResponse;
@ -55,7 +54,6 @@ import org.apache.cloudstack.dns.vo.DnsZoneNetworkMapVO;
import org.apache.cloudstack.dns.vo.DnsZoneVO;
import org.springframework.stereotype.Component;
import com.cloud.domain.DomainVO;
import com.cloud.domain.dao.DomainDao;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.PermissionDeniedException;
@ -98,7 +96,7 @@ public class DnsProviderManagerImpl extends ManagerBase implements DnsProviderMa
@Inject
DomainDao domainDao;
private DnsProvider getProvider(DnsProviderType type) {
private DnsProvider getProviderByType(DnsProviderType type) {
if (type == null) {
throw new CloudRuntimeException("Provider type cannot be null");
}
@ -131,13 +129,13 @@ public class DnsProviderManagerImpl extends ManagerBase implements DnsProviderMa
publicDomainSuffix = DnsProviderUtil.normalizeDomain(publicDomainSuffix);
}
DnsProviderType type = DnsProviderType.fromString(cmd.getProvider());
DnsProviderType type = cmd.getProviderType();
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 {
DnsProvider provider = getProvider(type);
String dnsServerId = provider.validateAndResolveServer(server); // localhost for PowerDNS
DnsProvider provider = getProviderByType(type);
String dnsServerId = provider.validateAndResolveServer(server); // returns localhost for PowerDNS
if (StringUtils.isNotBlank(dnsServerId)) {
server.setExternalServerId(dnsServerId);
}
@ -176,57 +174,51 @@ public class DnsProviderManagerImpl extends ManagerBase implements DnsProviderMa
domainId = domainIdRecursiveListProject.first();
isRecursive = domainIdRecursiveListProject.second();
Project.ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
Filter searchFilter = new Filter(DnsServerVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
Filter searchFilter = new Filter(DnsServerVO.class, ApiConstants.ID, true, cmd.getStartIndex(), cmd.getPageSizeVal());
// Step 2: Search for caller's own DNS servers using standard ACL pattern
SearchBuilder<DnsServerVO> sb = dnsServerDao.createSearchBuilder();
accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccountIds, listProjectResourcesCriteria);
sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ);
sb.and(ApiConstants.STATE, sb.entity().getState(), SearchCriteria.Op.EQ);
sb.and(ApiConstants.PROVIDER_TYPE, sb.entity().getProviderType(), SearchCriteria.Op.EQ);
sb.done();
SearchCriteria<DnsServerVO> sc = sb.create();
accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccountIds, listProjectResourcesCriteria);
sc.setParameters("state", DnsServer.State.Enabled);
sc.setParameters(ApiConstants.STATE, DnsServer.State.Enabled);
if (cmd.getProviderType() != null) {
sc.setParameters(ApiConstants.PROVIDER_TYPE, cmd.getProviderType());
}
Pair<List<DnsServerVO>, Integer> ownServersPair = dnsServerDao.searchAndCount(sc, searchFilter);
List<DnsServerVO> dnsServers = new ArrayList<>(ownServersPair.first());
int count = ownServersPair.second();
// Step 3: Search for public DNS servers from caller's domain and children
// domains
Long callerDomainId = caller.getDomainId();
DomainVO callerDomain = domainDao.findById(callerDomainId);
if (callerDomain != null) {
List<Long> domainIds = new ArrayList<>();
domainIds.add(callerDomainId);
List<DomainVO> childDomains = domainDao.findAllChildren(callerDomain.getPath(), callerDomainId);
for (DomainVO childDomain : childDomains) {
domainIds.add(childDomain.getId());
}
SearchBuilder<DnsServerVO> publicSb = dnsServerDao.createSearchBuilder();
publicSb.and("publicDns", publicSb.entity().isPublicServer(), SearchCriteria.Op.EQ);
publicSb.and("publicDomainId", publicSb.entity().getDomainId(), SearchCriteria.Op.IN);
publicSb.and("publicState", publicSb.entity().getState(), SearchCriteria.Op.EQ);
publicSb.done();
SearchCriteria<DnsServerVO> publicSc = publicSb.create();
publicSc.setParameters("publicDns", 1);
publicSc.setParameters("publicDomainId", domainIds.toArray());
publicSc.setParameters("publicState", DnsServer.State.Enabled);
List<DnsServerVO> publicServers = dnsServerDao.search(publicSc, null);
// Deduplicate: add only public servers not already in the own servers list
List<Long> ownServerIds = dnsServers.stream().map(DnsServerVO::getId).collect(Collectors.toList());
for (DnsServerVO publicServer : publicServers) {
if (!ownServerIds.contains(publicServer.getId())) {
dnsServers.add(publicServer);
count++;
if (cmd.getId() == null) {
Set<Long> parentDomainIds = domainDao.getDomainParentIds(caller.getDomainId());
if (!parentDomainIds.isEmpty()) {
SearchBuilder<DnsServerVO> publicSb = dnsServerDao.createSearchBuilder();
publicSb.and(ApiConstants.IS_PUBLIC, publicSb.entity().isPublicServer(), SearchCriteria.Op.EQ);
publicSb.and(ApiConstants.DOMAIN_IDS, publicSb.entity().getDomainId(), SearchCriteria.Op.IN);
publicSb.and(ApiConstants.STATE, publicSb.entity().getState(), SearchCriteria.Op.EQ);
publicSb.and(ApiConstants.PROVIDER_TYPE, publicSb.entity().getProviderType(), SearchCriteria.Op.EQ);
publicSb.done();
SearchCriteria<DnsServerVO> publicSc = publicSb.create();
publicSc.setParameters(ApiConstants.IS_PUBLIC, 1);
publicSc.setParameters(ApiConstants.DOMAIN_IDS, parentDomainIds.toArray());
publicSc.setParameters(ApiConstants.STATE, DnsServer.State.Enabled);
if (cmd.getProviderType() != null) {
publicSc.setParameters(ApiConstants.PROVIDER_TYPE, cmd.getProviderType());
}
List<DnsServerVO> publicServers = dnsServerDao.search(publicSc, null);
List<Long> ownServerIds = dnsServers.stream().map(DnsServerVO::getId).collect(Collectors.toList());
for (DnsServerVO publicServer : publicServers) {
if (!ownServerIds.contains(publicServer.getId())) {
dnsServers.add(publicServer);
count++;
}
}
}
}
return new Pair<>(dnsServers, count);
}
@ -284,7 +276,7 @@ public class DnsProviderManagerImpl extends ManagerBase implements DnsProviderMa
}
if (validationRequired) {
DnsProvider provider = getProvider(dnsServer.getProviderType());
DnsProvider provider = getProviderByType(dnsServer.getProviderType());
try {
provider.validate(dnsServer);
} catch (Exception ex) {
@ -340,7 +332,7 @@ public class DnsProviderManagerImpl extends ManagerBase implements DnsProviderMa
DnsServerVO server = dnsServerDao.findById(zone.getDnsServerId());
if (server != null && zone.getState() == DnsZone.State.Active) {
try {
DnsProvider provider = getProvider(server.getProviderType());
DnsProvider provider = getProviderByType(server.getProviderType());
provider.deleteZone(server, zone);
logger.debug("Deleted DNS zone: {}", zone.getName());
} catch (Exception ex) {
@ -351,11 +343,6 @@ public class DnsProviderManagerImpl extends ManagerBase implements DnsProviderMa
return dnsZoneDao.remove(zoneId);
}
@Override
public DnsZone getDnsZone(Long id) {
return dnsZoneDao.findById(id);
}
@Override
public DnsZone updateDnsZone(UpdateDnsZoneCmd cmd) {
DnsZoneVO dnsZone = dnsZoneDao.findById(cmd.getId());
@ -376,7 +363,7 @@ public class DnsProviderManagerImpl extends ManagerBase implements DnsProviderMa
throw new CloudRuntimeException("The underlying DNS server for this DNS zone is missing.");
}
try {
DnsProvider provider = getProvider(server.getProviderType());
DnsProvider provider = getProviderByType(server.getProviderType());
provider.updateZone(server, dnsZone);
} catch (Exception ex) {
logger.error("Failed to update DNS zone: {} on DNS server: {}", dnsZone.getName(), server.getName(), ex);
@ -438,7 +425,7 @@ public class DnsProviderManagerImpl extends ManagerBase implements DnsProviderMa
List<String> normalizedContents = cmd.getContents().stream()
.map(value -> DnsProviderUtil.normalizeDnsRecordValue(value, type)).collect(Collectors.toList());
DnsRecord record = new DnsRecord(recordName, type, normalizedContents, cmd.getTtl());
DnsProvider provider = getProvider(server.getProviderType());
DnsProvider provider = getProviderByType(server.getProviderType());
String normalizedRecordName = provider.addRecord(server, zone, record);
record.setName(normalizedRecordName);
return createDnsRecordResponse(record);
@ -465,7 +452,7 @@ public class DnsProviderManagerImpl extends ManagerBase implements DnsProviderMa
DnsRecord record = new DnsRecord();
record.setName(cmd.getName());
record.setType(cmd.getType());
DnsProvider provider = getProvider(server.getProviderType());
DnsProvider provider = getProviderByType(server.getProviderType());
provider.deleteRecord(server, zone, record);
return true;
} catch (Exception ex) {
@ -487,7 +474,7 @@ public class DnsProviderManagerImpl extends ManagerBase implements DnsProviderMa
throw new CloudRuntimeException("The underlying DNS server for this DNS zone is missing.");
}
try {
DnsProvider provider = getProvider(server.getProviderType());
DnsProvider provider = getProviderByType(server.getProviderType());
List<DnsRecord> records = provider.listRecords(server, zone);
List<DnsRecordResponse> responses = new ArrayList<>();
for (DnsRecord record : records) {
@ -550,7 +537,7 @@ public class DnsProviderManagerImpl extends ManagerBase implements DnsProviderMa
}
DnsServerVO server = dnsServerDao.findById(dnsZone.getDnsServerId());
try {
DnsProvider provider = getProvider(server.getProviderType());
DnsProvider provider = getProviderByType(server.getProviderType());
String externalReferenceId = provider.provisionZone(server, dnsZone);
dnsZone.setExternalReference(externalReferenceId);
dnsZone.setState(DnsZone.State.Active);
@ -619,7 +606,8 @@ public class DnsProviderManagerImpl extends ManagerBase implements DnsProviderMa
@Override
public boolean disassociateZoneFromNetwork(DisassociateDnsZoneFromNetworkCmd cmd) {
DnsZoneNetworkMapVO mapping = dnsZoneNetworkMapDao.findById(cmd.getId());
// fix this method
DnsZoneNetworkMapVO mapping = dnsZoneNetworkMapDao.findById(cmd.getDnsZoneId());
if (mapping == null) {
throw new InvalidParameterValueException("The specified DNS zone to network mapping does not exist.");
}
@ -634,15 +622,6 @@ public class DnsProviderManagerImpl extends ManagerBase implements DnsProviderMa
return dnsZoneNetworkMapDao.remove(mapping.getId());
}
@Override
public boolean registerDnsRecordForVm(RegisterDnsRecordForVmCmd cmd) {
return processDnsRecordForInstance(cmd.getVmId(), cmd.getNetworkId(), true);
}
@Override
public boolean removeDnsRecordForVm(RemoveDnsRecordForVmCmd cmd) {
return processDnsRecordForInstance(cmd.getVmId(), cmd.getNetworkId(), false);
}
@Override
public void checkDnsServerPermissions(Account caller, DnsServer server) {
@ -653,18 +632,11 @@ public class DnsProviderManagerImpl extends ManagerBase implements DnsProviderMa
throw new PermissionDeniedException(caller + "is not allowed to access the DNS server " + server.getName());
}
Account owner = accountMgr.getAccount(server.getAccountId());
if (!domainDao.isChildDomain(owner.getDomainId(), caller.getDomainId())) {
if (!domainDao.isChildDomain(caller.getDomainId(), owner.getDomainId())) {
throw new PermissionDeniedException(caller + "is not allowed to access the DNS server " + server.getName());
}
}
@Override
public void checkDnsZonePermission(Account caller, DnsZone zone) {
if (caller.getId() != zone.getAccountId()) {
throw new PermissionDeniedException(caller + "is not allowed to access the DNS Zone " + zone.getName());
}
}
/**
* Helper method to handle both Register and Remove logic for Instance
*/
@ -716,7 +688,7 @@ public class DnsProviderManagerImpl extends ManagerBase implements DnsProviderMa
}
try {
DnsProvider provider = getProvider(server.getProviderType());
DnsProvider provider = getProviderByType(server.getProviderType());
// Handle IPv4 (A Record)
if (nic.getIPv4Address() != null) {
DnsRecord recordA = new DnsRecord(recordName, DnsRecord.RecordType.A, Collections.singletonList(nic.getIPv4Address()), 3600);
@ -789,8 +761,6 @@ public class DnsProviderManagerImpl extends ManagerBase implements DnsProviderMa
cmdList.add(CreateDnsRecordCmd.class);
cmdList.add(ListDnsRecordsCmd.class);
cmdList.add(DeleteDnsRecordCmd.class);
cmdList.add(RegisterDnsRecordForVmCmd.class);
cmdList.add(RemoveDnsRecordForVmCmd.class);
return cmdList;
}

View File

@ -56,6 +56,7 @@ public class DnsServerDaoImpl extends GenericDaoBase<DnsServerVO, Long> implemen
DnsServerIdsByAccountSearch = createSearchBuilder(Long.class);
DnsServerIdsByAccountSearch.selectFields(DnsServerIdsByAccountSearch.entity().getId());
DnsServerIdsByAccountSearch.and(ApiConstants.ACCOUNT_ID, DnsServerIdsByAccountSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
DnsServerIdsByAccountSearch.and(ApiConstants.STATE, DnsServerIdsByAccountSearch.entity().getState(), SearchCriteria.Op.EQ);
DnsServerIdsByAccountSearch.done();
}
@ -74,6 +75,7 @@ public class DnsServerDaoImpl extends GenericDaoBase<DnsServerVO, Long> implemen
if (accountId != null) {
sc.setParameters(ApiConstants.ACCOUNT_ID, accountId);
}
sc.setParameters(ApiConstants.STATE, DnsServer.State.Enabled);
return customSearch(sc, null);
}

View File

@ -35,7 +35,6 @@ import com.cloud.utils.db.SearchCriteria;
public class DnsZoneDaoImpl extends GenericDaoBase<DnsZoneVO, Long> implements DnsZoneDao {
SearchBuilder<DnsZoneVO> AccountSearch;
SearchBuilder<DnsZoneVO> NameServerTypeSearch;
SearchBuilder<DnsZoneVO> AllFieldsSearch;
public DnsZoneDaoImpl() {
super();
@ -51,16 +50,6 @@ public class DnsZoneDaoImpl extends GenericDaoBase<DnsZoneVO, Long> implements D
NameServerTypeSearch.and(ApiConstants.TYPE, NameServerTypeSearch.entity().getType(), SearchCriteria.Op.EQ);
NameServerTypeSearch.and(ApiConstants.STATE, NameServerTypeSearch.entity().getState(), SearchCriteria.Op.EQ);
NameServerTypeSearch.done();
AllFieldsSearch = createSearchBuilder();
AllFieldsSearch.and().op(ApiConstants.DNS_SERVER_ID, AllFieldsSearch.entity().getDnsServerId(), SearchCriteria.Op.IN);
AllFieldsSearch.or(ApiConstants.ACCOUNT_ID, AllFieldsSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
AllFieldsSearch.cp();
AllFieldsSearch.and(ApiConstants.STATE, AllFieldsSearch.entity().getState(), SearchCriteria.Op.EQ);
AllFieldsSearch.and(ApiConstants.ID, AllFieldsSearch.entity().getId(), SearchCriteria.Op.EQ);
AllFieldsSearch.and(ApiConstants.NAME, AllFieldsSearch.entity().getName(), SearchCriteria.Op.LIKE);
AllFieldsSearch.and(ApiConstants.TARGET_ID, AllFieldsSearch.entity().getDnsServerId(), SearchCriteria.Op.EQ);
AllFieldsSearch.done();
}
@Override
@ -85,7 +74,21 @@ public class DnsZoneDaoImpl extends GenericDaoBase<DnsZoneVO, Long> implements D
public Pair<List<DnsZoneVO>, Integer> searchZones(Long id, Long accountId, List<Long> ownDnsServerIds, Long targetDnsServerId,
String keyword, Filter filter) {
SearchCriteria<DnsZoneVO> sc = AllFieldsSearch.create();
SearchBuilder<DnsZoneVO> sb = createSearchBuilder();
sb.and(ApiConstants.STATE, sb.entity().getState(), SearchCriteria.Op.EQ);
sb.and(ApiConstants.ID, sb.entity().getId(), SearchCriteria.Op.EQ);
sb.and(ApiConstants.NAME, sb.entity().getName(), SearchCriteria.Op.LIKE);
sb.and(ApiConstants.TARGET_ID, sb.entity().getDnsServerId(), SearchCriteria.Op.EQ);
if (!CollectionUtils.isEmpty(ownDnsServerIds)) {
sb.and().op(ApiConstants.DNS_SERVER_ID, sb.entity().getDnsServerId(), SearchCriteria.Op.IN);
sb.or(ApiConstants.ACCOUNT_ID, sb.entity().getAccountId(), SearchCriteria.Op.EQ);
sb.cp();
} else {
sb.and(ApiConstants.ACCOUNT_ID, sb.entity().getAccountId(), SearchCriteria.Op.EQ);
}
sb.done();
SearchCriteria<DnsZoneVO> sc = sb.create();
if (id != null) {
sc.setParameters(ApiConstants.ID, id);
}