server: update network offering for specified domain(s) & zone(s)

Added checkAccess while creating network from offering.
Response fixes for networkoffering APIs.

Signed-off-by: Abhishek Kumar <abhishek.kumar@shapeblue.com>
This commit is contained in:
Abhishek Kumar 2019-04-11 17:56:34 +05:30 committed by Abhishek Kumar
parent eaa759209a
commit c671e07c18
11 changed files with 218 additions and 77 deletions

View File

@ -29,6 +29,7 @@ import com.cloud.dc.DataCenter;
import com.cloud.domain.Domain; import com.cloud.domain.Domain;
import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.PermissionDeniedException;
import com.cloud.offering.DiskOffering; import com.cloud.offering.DiskOffering;
import com.cloud.offering.NetworkOffering;
import com.cloud.offering.ServiceOffering; import com.cloud.offering.ServiceOffering;
public interface AccountService { public interface AccountService {
@ -101,6 +102,8 @@ public interface AccountService {
void checkAccess(Account account, DiskOffering dof, DataCenter zone) throws PermissionDeniedException; void checkAccess(Account account, DiskOffering dof, DataCenter zone) throws PermissionDeniedException;
void checkAccess(Account account, NetworkOffering nof, DataCenter zone) throws PermissionDeniedException;
void checkAccess(User user, ControlledEntity entity); void checkAccess(User user, ControlledEntity entity);
void checkAccess(Account account, AccessType accessType, boolean sameOwner, String apiName, ControlledEntity... entities) throws PermissionDeniedException; void checkAccess(Account account, AccessType accessType, boolean sameOwner, String apiName, ControlledEntity... entities) throws PermissionDeniedException;

View File

@ -20,6 +20,7 @@ import com.cloud.dc.DataCenter;
import com.cloud.domain.Domain; import com.cloud.domain.Domain;
import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.PermissionDeniedException;
import com.cloud.offering.DiskOffering; import com.cloud.offering.DiskOffering;
import com.cloud.offering.NetworkOffering;
import com.cloud.offering.ServiceOffering; import com.cloud.offering.ServiceOffering;
import com.cloud.user.Account; import com.cloud.user.Account;
import com.cloud.user.User; import com.cloud.user.User;
@ -139,4 +140,6 @@ public interface SecurityChecker extends Adapter {
boolean checkAccess(Account account, ServiceOffering so, DataCenter zone) throws PermissionDeniedException; boolean checkAccess(Account account, ServiceOffering so, DataCenter zone) throws PermissionDeniedException;
boolean checkAccess(Account account, DiskOffering dof, DataCenter zone) throws PermissionDeniedException; boolean checkAccess(Account account, DiskOffering dof, DataCenter zone) throws PermissionDeniedException;
boolean checkAccess(Account account, NetworkOffering nof, DataCenter zone) throws PermissionDeniedException;
} }

View File

@ -171,6 +171,7 @@ import com.cloud.offerings.dao.NetworkOfferingDao;
import com.cloud.offerings.dao.NetworkOfferingDetailsDao; import com.cloud.offerings.dao.NetworkOfferingDetailsDao;
import com.cloud.offerings.dao.NetworkOfferingServiceMapDao; import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
import com.cloud.user.Account; import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.ResourceLimitService; import com.cloud.user.ResourceLimitService;
import com.cloud.user.User; import com.cloud.user.User;
import com.cloud.user.dao.AccountDao; import com.cloud.user.dao.AccountDao;
@ -286,6 +287,8 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
RemoteAccessVpnDao _remoteAccessVpnDao; RemoteAccessVpnDao _remoteAccessVpnDao;
@Inject @Inject
VpcVirtualNetworkApplianceService _routerService; VpcVirtualNetworkApplianceService _routerService;
@Inject
AccountManager accountManager;
List<NetworkGuru> networkGurus; List<NetworkGuru> networkGurus;
@ -2162,6 +2165,8 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
final Boolean isDisplayNetworkEnabled, final String isolatedPvlan, String externalId) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException { final Boolean isDisplayNetworkEnabled, final String isolatedPvlan, String externalId) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException {
final NetworkOfferingVO ntwkOff = _networkOfferingDao.findById(networkOfferingId); final NetworkOfferingVO ntwkOff = _networkOfferingDao.findById(networkOfferingId);
final DataCenterVO zone = _dcDao.findById(zoneId);
accountManager.checkAccess(owner, ntwkOff, zone);
// this method supports only guest network creation // this method supports only guest network creation
if (ntwkOff.getTrafficType() != TrafficType.Guest) { if (ntwkOff.getTrafficType() != TrafficType.Guest) {
s_logger.warn("Only guest networks can be created using this method"); s_logger.warn("Only guest networks can be created using this method");
@ -2196,7 +2201,6 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
ipv6 = true; ipv6 = true;
} }
// Validate zone // Validate zone
final DataCenterVO zone = _dcDao.findById(zoneId);
if (zone.getNetworkType() == NetworkType.Basic) { if (zone.getNetworkType() == NetworkType.Basic) {
// In Basic zone the network should have aclType=Domain, domainId=1, subdomainAccess=true // In Basic zone the network should have aclType=Domain, domainId=1, subdomainAccess=true
if (aclType == null || aclType != ACLType.Domain) { if (aclType == null || aclType != ACLType.Domain) {

View File

@ -54,11 +54,11 @@ public class NetworkOfferingDetailsVO implements ResourceDetail {
public NetworkOfferingDetailsVO() { public NetworkOfferingDetailsVO() {
} }
public NetworkOfferingDetailsVO(long resourceId, Detail detailName, String value) { public NetworkOfferingDetailsVO(long resourceId, Detail detailName, String value, boolean display) {
this.resourceId = resourceId; this.resourceId = resourceId;
this.name = detailName; this.name = detailName;
this.value = value; this.value = value;
this.display = false; this.display = display;
} }
@Override @Override

View File

@ -23,7 +23,6 @@ import java.util.Map;
import javax.inject.Inject; import javax.inject.Inject;
import javax.persistence.EntityExistsException; import javax.persistence.EntityExistsException;
import com.cloud.offerings.NetworkOfferingServiceMapVO;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -33,6 +32,7 @@ import com.cloud.offering.NetworkOffering;
import com.cloud.offering.NetworkOffering.Availability; import com.cloud.offering.NetworkOffering.Availability;
import com.cloud.offering.NetworkOffering.Detail; import com.cloud.offering.NetworkOffering.Detail;
import com.cloud.offerings.NetworkOfferingDetailsVO; import com.cloud.offerings.NetworkOfferingDetailsVO;
import com.cloud.offerings.NetworkOfferingServiceMapVO;
import com.cloud.offerings.NetworkOfferingVO; import com.cloud.offerings.NetworkOfferingVO;
import com.cloud.utils.db.DB; import com.cloud.utils.db.DB;
import com.cloud.utils.db.Filter; import com.cloud.utils.db.Filter;
@ -187,7 +187,7 @@ public class NetworkOfferingDaoImpl extends GenericDaoBase<NetworkOfferingVO, Lo
//2) persist the details //2) persist the details
if (details != null && !details.isEmpty()) { if (details != null && !details.isEmpty()) {
for (NetworkOffering.Detail detail : details.keySet()) { for (NetworkOffering.Detail detail : details.keySet()) {
_detailsDao.persist(new NetworkOfferingDetailsVO(off.getId(), detail, details.get(detail))); _detailsDao.persist(new NetworkOfferingDetailsVO(off.getId(), detail, details.get(detail), true));
} }
} }

View File

@ -43,12 +43,14 @@ public class NetworkOfferingDetailsDaoImpl extends ResourceDetailsDaoBase<Networ
DetailSearch.and("resourceId", DetailSearch.entity().getResourceId(), SearchCriteria.Op.EQ); DetailSearch.and("resourceId", DetailSearch.entity().getResourceId(), SearchCriteria.Op.EQ);
DetailSearch.and("name", DetailSearch.entity().getName(), SearchCriteria.Op.EQ); DetailSearch.and("name", DetailSearch.entity().getName(), SearchCriteria.Op.EQ);
DetailSearch.and("value", DetailSearch.entity().getValue(), SearchCriteria.Op.EQ); DetailSearch.and("value", DetailSearch.entity().getValue(), SearchCriteria.Op.EQ);
DetailSearch.and("display", DetailSearch.entity().isDisplay(), SearchCriteria.Op.EQ);
DetailSearch.done(); DetailSearch.done();
ValueSearch = createSearchBuilder(String.class); ValueSearch = createSearchBuilder(String.class);
ValueSearch.select(null, Func.DISTINCT, ValueSearch.entity().getValue()); ValueSearch.select(null, Func.DISTINCT, ValueSearch.entity().getValue());
ValueSearch.and("resourceId", ValueSearch.entity().getResourceId(), SearchCriteria.Op.EQ); ValueSearch.and("resourceId", ValueSearch.entity().getResourceId(), SearchCriteria.Op.EQ);
ValueSearch.and("name", ValueSearch.entity().getName(), Op.EQ); ValueSearch.and("name", ValueSearch.entity().getName(), Op.EQ);
ValueSearch.and("display", ValueSearch.entity().isDisplay(), SearchCriteria.Op.EQ);
ValueSearch.done(); ValueSearch.done();
} }
@ -56,6 +58,7 @@ public class NetworkOfferingDetailsDaoImpl extends ResourceDetailsDaoBase<Networ
public Map<NetworkOffering.Detail, String> getNtwkOffDetails(long offeringId) { public Map<NetworkOffering.Detail, String> getNtwkOffDetails(long offeringId) {
SearchCriteria<NetworkOfferingDetailsVO> sc = DetailSearch.create(); SearchCriteria<NetworkOfferingDetailsVO> sc = DetailSearch.create();
sc.setParameters("resourceId", offeringId); sc.setParameters("resourceId", offeringId);
sc.setParameters("display", true);
List<NetworkOfferingDetailsVO> results = search(sc, null); List<NetworkOfferingDetailsVO> results = search(sc, null);
Map<NetworkOffering.Detail, String> details = new HashMap<NetworkOffering.Detail, String>(results.size()); Map<NetworkOffering.Detail, String> details = new HashMap<NetworkOffering.Detail, String>(results.size());
@ -81,7 +84,7 @@ public class NetworkOfferingDetailsDaoImpl extends ResourceDetailsDaoBase<Networ
@Override @Override
public void addDetail(long resourceId, String key, String value, boolean display) { public void addDetail(long resourceId, String key, String value, boolean display) {
persist(new NetworkOfferingDetailsVO(resourceId, Detail.valueOf(key), value)); persist(new NetworkOfferingDetailsVO(resourceId, Detail.valueOf(key), value, display));
} }
@Override @Override

View File

@ -35,7 +35,9 @@ import com.cloud.exception.PermissionDeniedException;
import com.cloud.network.Network; import com.cloud.network.Network;
import com.cloud.network.NetworkModel; import com.cloud.network.NetworkModel;
import com.cloud.offering.DiskOffering; import com.cloud.offering.DiskOffering;
import com.cloud.offering.NetworkOffering;
import com.cloud.offering.ServiceOffering; import com.cloud.offering.ServiceOffering;
import com.cloud.offerings.dao.NetworkOfferingDetailsDao;
import com.cloud.projects.ProjectManager; import com.cloud.projects.ProjectManager;
import com.cloud.projects.dao.ProjectAccountDao; import com.cloud.projects.dao.ProjectAccountDao;
import com.cloud.service.dao.ServiceOfferingDetailsDao; import com.cloud.service.dao.ServiceOfferingDetailsDao;
@ -71,6 +73,8 @@ public class DomainChecker extends AdapterBase implements SecurityChecker {
DiskOfferingDetailsDao diskOfferingDetailsDao; DiskOfferingDetailsDao diskOfferingDetailsDao;
@Inject @Inject
ServiceOfferingDetailsDao serviceOfferingDetailsDao; ServiceOfferingDetailsDao serviceOfferingDetailsDao;
@Inject
NetworkOfferingDetailsDao networkserviceOfferingDetailsDao;
protected DomainChecker() { protected DomainChecker() {
super(); super();
@ -249,6 +253,44 @@ public class DomainChecker extends AdapterBase implements SecurityChecker {
return isAccess; return isAccess;
} }
@Override
public boolean checkAccess(Account account, NetworkOffering nof, DataCenter zone) throws PermissionDeniedException {
boolean isAccess = false;
// Check fo domains
if (account == null || nof == null) {
isAccess = true;
} else {
//admin has all permissions
if (_accountService.isRootAdmin(account.getId())) {
isAccess = true;
}
//if account is normal user or domain admin
//check if account's domain is a child of offering's domain (Note: This is made consistent with the list command for disk offering)
else if (_accountService.isNormalUser(account.getId())
|| account.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN
|| _accountService.isDomainAdmin(account.getId())
|| account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
final List<Long> doDomainIds = networkserviceOfferingDetailsDao.findDomainIds(nof.getId());
if (doDomainIds.isEmpty()) {
isAccess = true;
} else {
for (Long domainId : doDomainIds) {
if (_domainDao.isChildDomain(domainId, account.getDomainId())) {
isAccess = true;
break;
}
}
}
}
}
// Check for zones
if (isAccess && nof != null && zone != null) {
final List<Long> doZoneIds = networkserviceOfferingDetailsDao.findZoneIds(nof.getId());
isAccess = doZoneIds.isEmpty() || doZoneIds.contains(zone.getId());
}
return isAccess;
}
@Override @Override
public boolean checkAccess(Account account, DataCenter zone) throws PermissionDeniedException { public boolean checkAccess(Account account, DataCenter zone) throws PermissionDeniedException {
if (account == null || zone.getDomainId() == null) {//public zone if (account == null || zone.getDomainId() == null) {//public zone

View File

@ -175,6 +175,7 @@ import com.cloud.api.query.vo.EventJoinVO;
import com.cloud.api.query.vo.HostJoinVO; import com.cloud.api.query.vo.HostJoinVO;
import com.cloud.api.query.vo.ImageStoreJoinVO; import com.cloud.api.query.vo.ImageStoreJoinVO;
import com.cloud.api.query.vo.InstanceGroupJoinVO; import com.cloud.api.query.vo.InstanceGroupJoinVO;
import com.cloud.api.query.vo.NetworkOfferingJoinVO;
import com.cloud.api.query.vo.ProjectAccountJoinVO; import com.cloud.api.query.vo.ProjectAccountJoinVO;
import com.cloud.api.query.vo.ProjectInvitationJoinVO; import com.cloud.api.query.vo.ProjectInvitationJoinVO;
import com.cloud.api.query.vo.ProjectJoinVO; import com.cloud.api.query.vo.ProjectJoinVO;
@ -1913,6 +1914,9 @@ public class ApiResponseHelper implements ResponseGenerator {
@Override @Override
public NetworkOfferingResponse createNetworkOfferingResponse(NetworkOffering offering) { public NetworkOfferingResponse createNetworkOfferingResponse(NetworkOffering offering) {
if (!(offering instanceof NetworkOfferingJoinVO)) {
offering = ApiDBUtils.newNetworkOfferingView(offering);
}
NetworkOfferingResponse response = ApiDBUtils.newNetworkOfferingResponse(offering); NetworkOfferingResponse response = ApiDBUtils.newNetworkOfferingResponse(offering);
response.setNetworkRate(ApiDBUtils.getNetworkRate(offering.getId())); response.setNetworkRate(ApiDBUtils.getNetworkRate(offering.getId()));
Long so = null; Long so = null;

View File

@ -541,7 +541,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
} }
if(name.equals(CapacityManager.StorageOverprovisioningFactor.key())) { if(name.equals(CapacityManager.StorageOverprovisioningFactor.key())) {
if(!pool.getPoolType().supportsOverProvisioning() ) { if(!pool.getPoolType().supportsOverProvisioning() ) {
throw new InvalidParameterValueException("Unable to update storage pool with id " + resourceId + ". Overprovision not supported for " + pool.getPoolType()); throw new InvalidParameterValueException("Unable to update storage pool with id " + resourceId + ". Overprovision not supported for " + pool.getPoolType());
} }
} }
@ -2631,12 +2631,12 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
} }
for (Long domainId : existingDomainIds) { for (Long domainId : existingDomainIds) {
if (!_domainDao.isChildDomain(account.getDomainId(), domainId)) { if (!_domainDao.isChildDomain(account.getDomainId(), domainId)) {
throw new InvalidParameterValueException("Unable to update disk service by another domain admin with id " + userId); throw new InvalidParameterValueException("Unable to update service by another domain admin with id " + userId);
} }
} }
for (Long domainId : filteredDomainIds) { for (Long domainId : filteredDomainIds) {
if (!_domainDao.isChildDomain(account.getDomainId(), domainId)) { if (!_domainDao.isChildDomain(account.getDomainId(), domainId)) {
throw new InvalidParameterValueException("Unable to update disk service by another domain admin with id " + userId); throw new InvalidParameterValueException("Unable to update service by another domain admin with id " + userId);
} }
} }
} else if (account.getType() != Account.ACCOUNT_TYPE_ADMIN) { } else if (account.getType() != Account.ACCOUNT_TYPE_ADMIN) {
@ -5135,11 +5135,11 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
List<Long> filteredDomainIds = filterChildSubDomains(domainIds); List<Long> filteredDomainIds = filterChildSubDomains(domainIds);
List<NetworkOfferingDetailsVO> detailsVO = new ArrayList<>(); List<NetworkOfferingDetailsVO> detailsVO = new ArrayList<>();
for (Long domainId : filteredDomainIds) { for (Long domainId : filteredDomainIds) {
detailsVO.add(new NetworkOfferingDetailsVO(offering.getId(), Detail.domainid, String.valueOf(domainId))); detailsVO.add(new NetworkOfferingDetailsVO(offering.getId(), Detail.domainid, String.valueOf(domainId), false));
} }
if (CollectionUtils.isNotEmpty(zoneIds)) { if (CollectionUtils.isNotEmpty(zoneIds)) {
for (Long zoneId : zoneIds) { for (Long zoneId : zoneIds) {
detailsVO.add(new NetworkOfferingDetailsVO(offering.getId(), Detail.zoneid, String.valueOf(zoneId))); detailsVO.add(new NetworkOfferingDetailsVO(offering.getId(), Detail.zoneid, String.valueOf(zoneId), false));
} }
} }
if (!detailsVO.isEmpty()) { if (!detailsVO.isEmpty()) {
@ -5507,10 +5507,13 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
Availability availability = null; Availability availability = null;
final String state = cmd.getState(); final String state = cmd.getState();
final String tags = cmd.getTags(); final String tags = cmd.getTags();
final List<Long> domainIds = cmd.getDomainIds();
final List<Long> zoneIds = cmd.getZoneIds();
CallContext.current().setEventDetails(" Id: " + id); CallContext.current().setEventDetails(" Id: " + id);
// Verify input parameters // Verify input parameters
final NetworkOfferingVO offeringToUpdate = _networkOfferingDao.findById(id); final NetworkOfferingVO offeringToUpdate = _networkOfferingDao.findById(id);
List<Long> existingDomainIds = networkOfferingDetailsDao.findDomainIds(id);
if (offeringToUpdate == null) { if (offeringToUpdate == null) {
throw new InvalidParameterValueException("unable to find network offering " + id); throw new InvalidParameterValueException("unable to find network offering " + id);
} }
@ -5520,91 +5523,148 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
throw new InvalidParameterValueException("Can't update system network offerings"); throw new InvalidParameterValueException("Can't update system network offerings");
} }
// check if valid domain
if (CollectionUtils.isNotEmpty(domainIds)) {
for (final Long domainId: domainIds) {
if (_domainDao.findById(domainId) == null) {
throw new InvalidParameterValueException("Please specify a valid domain id");
}
}
}
// check if valid zone
if (CollectionUtils.isNotEmpty(zoneIds)) {
for (Long zoneId : zoneIds) {
if (_zoneDao.findById(zoneId) == null)
throw new InvalidParameterValueException("Please specify a valid zone id");
}
}
// Filter child domains when both parent and child domains are present
List<Long> filteredDomainIds = filterChildSubDomains(domainIds);
if (CollectionUtils.isNotEmpty(existingDomainIds) && CollectionUtils.isNotEmpty(filteredDomainIds)) {
filteredDomainIds.removeIf(existingDomainIds::contains);
for (Long domainId : filteredDomainIds) {
for (Long existingDomainId : existingDomainIds) {
if (_domainDao.isChildDomain(existingDomainId, domainId)) {
throw new InvalidParameterValueException("Unable to update network offering for domain " + _domainDao.findById(domainId).getUuid() + " as offering is already available for parent domain");
}
}
}
}
List<Long> filteredZoneIds = new ArrayList<>();
if (CollectionUtils.isNotEmpty(zoneIds)) {
filteredZoneIds.addAll(zoneIds);
List<Long> existingZoneIds = networkOfferingDetailsDao.findZoneIds(id);
if (CollectionUtils.isNotEmpty(existingZoneIds)) {
filteredZoneIds.removeIf(existingZoneIds::contains);
}
}
final NetworkOfferingVO offering = _networkOfferingDao.createForUpdate(id); final NetworkOfferingVO offering = _networkOfferingDao.createForUpdate(id);
if (name != null) { boolean updateNeeded = name != null || displayText != null || sortKey != null ||
offering.setName(name); state != null || tags != null || availabilityStr != null || maxconn != null;
}
if (displayText != null) { if(updateNeeded) {
offering.setDisplayText(displayText); if (name != null) {
} offering.setName(name);
if (sortKey != null) {
offering.setSortKey(sortKey);
}
if (state != null) {
boolean validState = false;
for (final NetworkOffering.State st : NetworkOffering.State.values()) {
if (st.name().equalsIgnoreCase(state)) {
validState = true;
offering.setState(st);
}
} }
if (!validState) {
throw new InvalidParameterValueException("Incorrect state value: " + state); if (displayText != null) {
offering.setDisplayText(displayText);
} }
}
if (tags != null) { if (sortKey != null) {
List<DataCenterVO> dataCenters = _zoneDao.listAll(); offering.setSortKey(sortKey);
TrafficType trafficType = offeringToUpdate.getTrafficType(); }
String oldTags = offeringToUpdate.getTags();
for (DataCenterVO dataCenter : dataCenters) { if (state != null) {
long zoneId = dataCenter.getId(); boolean validState = false;
long newPhysicalNetworkId = _networkModel.findPhysicalNetworkId(zoneId, tags, trafficType); for (final NetworkOffering.State st : NetworkOffering.State.values()) {
if (oldTags != null) { if (st.name().equalsIgnoreCase(state)) {
long oldPhysicalNetworkId = _networkModel.findPhysicalNetworkId(zoneId, oldTags, trafficType); validState = true;
if (newPhysicalNetworkId != oldPhysicalNetworkId) { offering.setState(st);
throw new InvalidParameterValueException("New tags: selects different physical network for zone " + zoneId);
} }
} }
} if (!validState) {
throw new InvalidParameterValueException("Incorrect state value: " + state);
offering.setTags(tags);
}
// Verify availability
if (availabilityStr != null) {
for (final Availability avlb : Availability.values()) {
if (avlb.name().equalsIgnoreCase(availabilityStr)) {
availability = avlb;
} }
} }
if (availability == null) {
throw new InvalidParameterValueException("Invalid value for Availability. Supported types: " + Availability.Required + ", " + Availability.Optional);
} else {
if (availability == NetworkOffering.Availability.Required) {
final boolean canOffBeRequired = offeringToUpdate.getGuestType() == GuestType.Isolated && _networkModel.areServicesSupportedByNetworkOffering(
offeringToUpdate.getId(), Service.SourceNat);
if (!canOffBeRequired) {
throw new InvalidParameterValueException("Availability can be " + NetworkOffering.Availability.Required + " only for networkOfferings of type "
+ GuestType.Isolated + " and with " + Service.SourceNat.getName() + " enabled");
}
// only one network offering in the system can be Required if (tags != null) {
final List<NetworkOfferingVO> offerings = _networkOfferingDao.listByAvailability(Availability.Required, false); List<DataCenterVO> dataCenters = _zoneDao.listAll();
if (!offerings.isEmpty() && offerings.get(0).getId() != offeringToUpdate.getId()) { TrafficType trafficType = offeringToUpdate.getTrafficType();
throw new InvalidParameterValueException("System already has network offering id=" + offerings.get(0).getId() + " with availability " String oldTags = offeringToUpdate.getTags();
+ Availability.Required);
for (DataCenterVO dataCenter : dataCenters) {
long zoneId = dataCenter.getId();
long newPhysicalNetworkId = _networkModel.findPhysicalNetworkId(zoneId, tags, trafficType);
if (oldTags != null) {
long oldPhysicalNetworkId = _networkModel.findPhysicalNetworkId(zoneId, oldTags, trafficType);
if (newPhysicalNetworkId != oldPhysicalNetworkId) {
throw new InvalidParameterValueException("New tags: selects different physical network for zone " + zoneId);
}
} }
} }
offering.setAvailability(availability);
offering.setTags(tags);
} }
}
if (_ntwkOffServiceMapDao.areServicesSupportedByNetworkOffering(offering.getId(), Service.Lb)) { // Verify availability
if (maxconn != null) { if (availabilityStr != null) {
offering.setConcurrentConnections(maxconn); for (final Availability avlb : Availability.values()) {
if (avlb.name().equalsIgnoreCase(availabilityStr)) {
availability = avlb;
}
}
if (availability == null) {
throw new InvalidParameterValueException("Invalid value for Availability. Supported types: " + Availability.Required + ", " + Availability.Optional);
} else {
if (availability == NetworkOffering.Availability.Required) {
final boolean canOffBeRequired = offeringToUpdate.getGuestType() == GuestType.Isolated && _networkModel.areServicesSupportedByNetworkOffering(
offeringToUpdate.getId(), Service.SourceNat);
if (!canOffBeRequired) {
throw new InvalidParameterValueException("Availability can be " + NetworkOffering.Availability.Required + " only for networkOfferings of type "
+ GuestType.Isolated + " and with " + Service.SourceNat.getName() + " enabled");
}
// only one network offering in the system can be Required
final List<NetworkOfferingVO> offerings = _networkOfferingDao.listByAvailability(Availability.Required, false);
if (!offerings.isEmpty() && offerings.get(0).getId() != offeringToUpdate.getId()) {
throw new InvalidParameterValueException("System already has network offering id=" + offerings.get(0).getId() + " with availability "
+ Availability.Required);
}
}
offering.setAvailability(availability);
}
}
if (_ntwkOffServiceMapDao.areServicesSupportedByNetworkOffering(offering.getId(), Service.Lb)) {
if (maxconn != null) {
offering.setConcurrentConnections(maxconn);
}
}
if (!_networkOfferingDao.update(id, offering)) {
return null;
} }
} }
if (_networkOfferingDao.update(id, offering)) { List<NetworkOfferingDetailsVO> detailsVO = new ArrayList<>();
return _networkOfferingDao.findById(id); for (Long domainId : filteredDomainIds) {
} else { detailsVO.add(new NetworkOfferingDetailsVO(id, Detail.domainid, String.valueOf(domainId), false));
return null;
} }
for (Long zoneId : filteredZoneIds) {
detailsVO.add(new NetworkOfferingDetailsVO(id, Detail.zoneid, String.valueOf(zoneId), false));
}
if (!detailsVO.isEmpty()) {
for (NetworkOfferingDetailsVO detailVO : detailsVO) {
networkOfferingDetailsDao.persist(detailVO);
}
}
return _networkOfferingDao.findById(id);
} }
@Override @Override

View File

@ -118,6 +118,7 @@ import com.cloud.network.vpc.VpcManager;
import com.cloud.network.vpn.RemoteAccessVpnService; import com.cloud.network.vpn.RemoteAccessVpnService;
import com.cloud.network.vpn.Site2SiteVpnManager; import com.cloud.network.vpn.Site2SiteVpnManager;
import com.cloud.offering.DiskOffering; import com.cloud.offering.DiskOffering;
import com.cloud.offering.NetworkOffering;
import com.cloud.offering.ServiceOffering; import com.cloud.offering.ServiceOffering;
import com.cloud.projects.Project; import com.cloud.projects.Project;
import com.cloud.projects.Project.ListProjectResourcesCriteria; import com.cloud.projects.Project.ListProjectResourcesCriteria;
@ -2859,6 +2860,21 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
throw new PermissionDeniedException("There's no way to confirm " + account + " has access to " + dof); throw new PermissionDeniedException("There's no way to confirm " + account + " has access to " + dof);
} }
@Override
public void checkAccess(Account account, NetworkOffering nof, DataCenter zone) throws PermissionDeniedException {
for (SecurityChecker checker : _securityCheckers) {
if (checker.checkAccess(account, nof, zone)) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Access granted to " + account + " to " + nof + " by " + checker.getName());
}
return;
}
}
assert false : "How can all of the security checkers pass on checking this caller?";
throw new PermissionDeniedException("There's no way to confirm " + account + " has access to " + nof);
}
@Override @Override
public void checkAccess(User user, ControlledEntity entity) throws PermissionDeniedException { public void checkAccess(User user, ControlledEntity entity) throws PermissionDeniedException {
for (SecurityChecker checker : _securityCheckers) { for (SecurityChecker checker : _securityCheckers) {

View File

@ -42,6 +42,7 @@ import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.PermissionDeniedException;
import com.cloud.exception.ResourceUnavailableException; import com.cloud.exception.ResourceUnavailableException;
import com.cloud.offering.DiskOffering; import com.cloud.offering.DiskOffering;
import com.cloud.offering.NetworkOffering;
import com.cloud.offering.ServiceOffering; import com.cloud.offering.ServiceOffering;
import com.cloud.projects.Project.ListProjectResourcesCriteria; import com.cloud.projects.Project.ListProjectResourcesCriteria;
import com.cloud.utils.Pair; import com.cloud.utils.Pair;
@ -222,6 +223,11 @@ public class MockAccountManagerImpl extends ManagerBase implements Manager, Acco
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
@Override
public void checkAccess(Account account, NetworkOffering nof, DataCenter zone) throws PermissionDeniedException {
// TODO Auto-generated method stub
}
@Override @Override
public Long checkAccessAndSpecifyAuthority(Account caller, Long zoneId) { public Long checkAccessAndSpecifyAuthority(Account caller, Long zoneId) {
// TODO Auto-generated method stub // TODO Auto-generated method stub