Skip to content

Commit 2dd2955

Browse files
authored
server: fix listnetworkofferings with domain, refactor listvpofferings (apache#6748)
1 parent d74f64a commit 2dd2955

File tree

5 files changed

+71
-36
lines changed

5 files changed

+71
-36
lines changed

api/src/main/java/org/apache/cloudstack/api/command/user/vpc/ListVPCOfferingsCmd.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.apache.cloudstack.api.ApiConstants;
2424
import org.apache.cloudstack.api.BaseListCmd;
2525
import org.apache.cloudstack.api.Parameter;
26+
import org.apache.cloudstack.api.response.DomainResponse;
2627
import org.apache.cloudstack.api.response.ListResponse;
2728
import org.apache.cloudstack.api.response.VpcOfferingResponse;
2829
import org.apache.cloudstack.api.response.ZoneResponse;
@@ -60,10 +61,17 @@ public class ListVPCOfferingsCmd extends BaseListCmd {
6061
@Parameter(name = ApiConstants.STATE, type = CommandType.STRING, description = "list VPC offerings by state")
6162
private String state;
6263

64+
@Parameter(name = ApiConstants.DOMAIN_ID,
65+
type = CommandType.UUID,
66+
entityType = DomainResponse.class,
67+
description = "list VPC offerings available for VPC creation in specific domain",
68+
since = "4.18")
69+
private Long domainId;
70+
6371
@Parameter(name = ApiConstants.ZONE_ID,
6472
type = CommandType.UUID,
6573
entityType = ZoneResponse.class,
66-
description = "id of zone disk offering is associated with",
74+
description = "id of zone VPC offering is associated with",
6775
since = "4.13")
6876
private Long zoneId;
6977

@@ -94,6 +102,10 @@ public String getState() {
94102
return state;
95103
}
96104

105+
public Long getDomainId() {
106+
return domainId;
107+
}
108+
97109
public Long getZoneId() {
98110
return zoneId;
99111
}

engine/schema/src/main/java/com/cloud/domain/dao/DomainDao.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.util.Set;
2121

2222
import com.cloud.domain.DomainVO;
23+
import com.cloud.user.Account;
2324
import com.cloud.utils.db.GenericDao;
2425

2526
public interface DomainDao extends GenericDao<DomainVO, Long> {
@@ -40,4 +41,6 @@ public interface DomainDao extends GenericDao<DomainVO, Long> {
4041
Set<Long> getDomainParentIds(long domainId);
4142

4243
List<Long> getDomainChildrenIds(String path);
44+
45+
boolean domainIdListContainsAccessibleDomain(String domainIdList, Account caller, Long domainId);
4346
}

engine/schema/src/main/java/com/cloud/domain/dao/DomainDaoImpl.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,13 @@
2424
import java.util.Set;
2525

2626

27+
import org.apache.commons.lang3.StringUtils;
2728
import org.apache.log4j.Logger;
2829
import org.springframework.stereotype.Component;
2930

3031
import com.cloud.domain.Domain;
3132
import com.cloud.domain.DomainVO;
33+
import com.cloud.user.Account;
3234
import com.cloud.utils.db.DB;
3335
import com.cloud.utils.db.GenericDaoBase;
3436
import com.cloud.utils.db.GenericSearchBuilder;
@@ -290,4 +292,27 @@ public Set<Long> getDomainParentIds(long domainId) {
290292

291293
return parentDomains;
292294
}
295+
296+
@Override
297+
public boolean domainIdListContainsAccessibleDomain(String domainIdList, Account caller, Long domainId) {
298+
if (StringUtils.isEmpty(domainIdList)) {
299+
return false;
300+
}
301+
String[] domainIdsArray = domainIdList.split(",");
302+
for (String domainIdString : domainIdsArray) {
303+
try {
304+
Long dId = Long.valueOf(domainIdString.trim());
305+
if (!Account.Type.ADMIN.equals(caller.getType()) &&
306+
isChildDomain(dId, caller.getDomainId())) {
307+
return true;
308+
}
309+
if (domainId != null && isChildDomain(dId, domainId)) {
310+
return true;
311+
}
312+
} catch (NumberFormatException nfe) {
313+
s_logger.debug(String.format("Unable to parse %s as domain ID from the list of domain IDs: %s", domainIdList.trim(), domainIdList), nfe);
314+
}
315+
}
316+
return false;
317+
}
293318
}

server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6705,28 +6705,15 @@ public Pair<List<? extends NetworkOffering>, Integer> searchForNetworkOfferings(
67056705

67066706
final List<NetworkOfferingJoinVO> offerings = networkOfferingJoinDao.search(sc, searchFilter);
67076707
// Remove offerings that are not associated with caller's domain or domainId passed
6708-
if ((caller.getType() != Account.Type.ADMIN || domainId != null) && CollectionUtils.isNotEmpty(offerings)) {
6708+
if ((!Account.Type.ADMIN.equals(caller.getType()) || domainId != null) && CollectionUtils.isNotEmpty(offerings)) {
67096709
ListIterator<NetworkOfferingJoinVO> it = offerings.listIterator();
67106710
while (it.hasNext()) {
67116711
NetworkOfferingJoinVO offering = it.next();
6712-
if (StringUtils.isNotEmpty(offering.getDomainId())) {
6713-
boolean toRemove = false;
6714-
String[] domainIdsArray = offering.getDomainId().split(",");
6715-
for (String domainIdString : domainIdsArray) {
6716-
Long dId = Long.valueOf(domainIdString.trim());
6717-
if (caller.getType() != Account.Type.ADMIN &&
6718-
!_domainDao.isChildDomain(dId, caller.getDomainId())) {
6719-
toRemove = true;
6720-
break;
6721-
}
6722-
if (domainId != null && !_domainDao.isChildDomain(dId, domainId)) {
6723-
toRemove = true;
6724-
break;
6725-
}
6726-
}
6727-
if (toRemove) {
6728-
it.remove();
6729-
}
6712+
if (StringUtils.isEmpty(offering.getDomainId())) {
6713+
continue;
6714+
}
6715+
if (!_domainDao.domainIdListContainsAccessibleDomain(offering.getDomainId(), caller, domainId)) {
6716+
it.remove();
67306717
}
67316718
}
67326719
}

server/src/main/java/com/cloud/network/vpc/VpcManagerImpl.java

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@
8181
import com.cloud.dc.dao.DataCenterDao;
8282
import com.cloud.dc.dao.VlanDao;
8383
import com.cloud.deploy.DeployDestination;
84+
import com.cloud.domain.Domain;
8485
import com.cloud.domain.dao.DomainDao;
8586
import com.cloud.event.ActionEvent;
8687
import com.cloud.event.EventTypes;
@@ -703,6 +704,19 @@ public Map<Service, Set<Provider>> getVpcOffSvcProvidersMap(final long vpcOffId)
703704
return serviceProviderMap;
704705
}
705706

707+
private void verifyDomainId(Long domainId, Account caller) {
708+
if (domainId == null) {
709+
return;
710+
}
711+
Domain domain = _entityMgr.findById(Domain.class, domainId);
712+
if (domain == null) {
713+
throw new InvalidParameterValueException("Unable to find the domain by id=" + domainId);
714+
}
715+
if (!domainDao.isChildDomain(caller.getDomainId(), domainId)) {
716+
throw new InvalidParameterValueException(String.format("Unable to list VPC offerings for domain: %s as caller does not have access for it", domain.getUuid()));
717+
}
718+
}
719+
706720
@Override
707721
public Pair<List<? extends VpcOffering>, Integer> listVpcOfferings(ListVPCOfferingsCmd cmd) {
708722
Account caller = CallContext.current().getCallingAccount();
@@ -715,11 +729,14 @@ public Pair<List<? extends VpcOffering>, Integer> listVpcOfferings(ListVPCOfferi
715729
final String state = cmd.getState();
716730
final Long startIndex = cmd.getStartIndex();
717731
final Long pageSizeVal = cmd.getPageSizeVal();
732+
final Long domainId = cmd.getDomainId();
718733
final Long zoneId = cmd.getZoneId();
719734
final Filter searchFilter = new Filter(VpcOfferingJoinVO.class, "sortKey", QueryService.SortKeyAscending.value(), null, null);
720735
searchFilter.addOrderBy(VpcOfferingJoinVO.class, "id", true);
721736
final SearchCriteria<VpcOfferingJoinVO> sc = vpcOfferingJoinDao.createSearchCriteria();
722737

738+
verifyDomainId(domainId, caller);
739+
723740
if (keyword != null) {
724741
final SearchCriteria<VpcOfferingJoinVO> ssc = vpcOfferingJoinDao.createSearchCriteria();
725742
ssc.addOr("displayText", SearchCriteria.Op.LIKE, "%" + keyword + "%");
@@ -760,25 +777,16 @@ public Pair<List<? extends VpcOffering>, Integer> listVpcOfferings(ListVPCOfferi
760777

761778
final List<VpcOfferingJoinVO> offerings = vpcOfferingJoinDao.search(sc, searchFilter);
762779

763-
// Remove offerings that are not associated with caller's domain
764-
// TODO: Better approach
765-
if (caller.getType() != Account.Type.ADMIN && CollectionUtils.isNotEmpty(offerings)) {
780+
// Remove offerings that are not associated with caller's domain or domainId passed
781+
if ((!Account.Type.ADMIN.equals(caller.getType()) || domainId != null) && CollectionUtils.isNotEmpty(offerings)) {
766782
ListIterator<VpcOfferingJoinVO> it = offerings.listIterator();
767783
while (it.hasNext()) {
768784
VpcOfferingJoinVO offering = it.next();
769-
if(org.apache.commons.lang3.StringUtils.isNotEmpty(offering.getDomainId())) {
770-
boolean toRemove = true;
771-
String[] domainIdsArray = offering.getDomainId().split(",");
772-
for (String domainIdString : domainIdsArray) {
773-
Long dId = Long.valueOf(domainIdString.trim());
774-
if (domainDao.isChildDomain(dId, caller.getDomainId())) {
775-
toRemove = false;
776-
break;
777-
}
778-
}
779-
if (toRemove) {
780-
it.remove();
781-
}
785+
if (org.apache.commons.lang3.StringUtils.isEmpty(offering.getDomainId())) {
786+
continue;
787+
}
788+
if (!domainDao.domainIdListContainsAccessibleDomain(offering.getDomainId(), caller, domainId)) {
789+
it.remove();
782790
}
783791
}
784792
}

0 commit comments

Comments
 (0)