mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
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:
parent
eaa759209a
commit
c671e07c18
@ -29,6 +29,7 @@ import com.cloud.dc.DataCenter;
|
||||
import com.cloud.domain.Domain;
|
||||
import com.cloud.exception.PermissionDeniedException;
|
||||
import com.cloud.offering.DiskOffering;
|
||||
import com.cloud.offering.NetworkOffering;
|
||||
import com.cloud.offering.ServiceOffering;
|
||||
|
||||
public interface AccountService {
|
||||
@ -101,6 +102,8 @@ public interface AccountService {
|
||||
|
||||
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(Account account, AccessType accessType, boolean sameOwner, String apiName, ControlledEntity... entities) throws PermissionDeniedException;
|
||||
|
||||
@ -20,6 +20,7 @@ import com.cloud.dc.DataCenter;
|
||||
import com.cloud.domain.Domain;
|
||||
import com.cloud.exception.PermissionDeniedException;
|
||||
import com.cloud.offering.DiskOffering;
|
||||
import com.cloud.offering.NetworkOffering;
|
||||
import com.cloud.offering.ServiceOffering;
|
||||
import com.cloud.user.Account;
|
||||
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, DiskOffering dof, DataCenter zone) throws PermissionDeniedException;
|
||||
|
||||
boolean checkAccess(Account account, NetworkOffering nof, DataCenter zone) throws PermissionDeniedException;
|
||||
}
|
||||
|
||||
@ -171,6 +171,7 @@ import com.cloud.offerings.dao.NetworkOfferingDao;
|
||||
import com.cloud.offerings.dao.NetworkOfferingDetailsDao;
|
||||
import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountManager;
|
||||
import com.cloud.user.ResourceLimitService;
|
||||
import com.cloud.user.User;
|
||||
import com.cloud.user.dao.AccountDao;
|
||||
@ -286,6 +287,8 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
||||
RemoteAccessVpnDao _remoteAccessVpnDao;
|
||||
@Inject
|
||||
VpcVirtualNetworkApplianceService _routerService;
|
||||
@Inject
|
||||
AccountManager accountManager;
|
||||
|
||||
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 NetworkOfferingVO ntwkOff = _networkOfferingDao.findById(networkOfferingId);
|
||||
final DataCenterVO zone = _dcDao.findById(zoneId);
|
||||
accountManager.checkAccess(owner, ntwkOff, zone);
|
||||
// this method supports only guest network creation
|
||||
if (ntwkOff.getTrafficType() != TrafficType.Guest) {
|
||||
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;
|
||||
}
|
||||
// Validate zone
|
||||
final DataCenterVO zone = _dcDao.findById(zoneId);
|
||||
if (zone.getNetworkType() == NetworkType.Basic) {
|
||||
// In Basic zone the network should have aclType=Domain, domainId=1, subdomainAccess=true
|
||||
if (aclType == null || aclType != ACLType.Domain) {
|
||||
|
||||
@ -54,11 +54,11 @@ public class NetworkOfferingDetailsVO implements ResourceDetail {
|
||||
public NetworkOfferingDetailsVO() {
|
||||
}
|
||||
|
||||
public NetworkOfferingDetailsVO(long resourceId, Detail detailName, String value) {
|
||||
public NetworkOfferingDetailsVO(long resourceId, Detail detailName, String value, boolean display) {
|
||||
this.resourceId = resourceId;
|
||||
this.name = detailName;
|
||||
this.value = value;
|
||||
this.display = false;
|
||||
this.display = display;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -23,7 +23,6 @@ import java.util.Map;
|
||||
import javax.inject.Inject;
|
||||
import javax.persistence.EntityExistsException;
|
||||
|
||||
import com.cloud.offerings.NetworkOfferingServiceMapVO;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
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.Detail;
|
||||
import com.cloud.offerings.NetworkOfferingDetailsVO;
|
||||
import com.cloud.offerings.NetworkOfferingServiceMapVO;
|
||||
import com.cloud.offerings.NetworkOfferingVO;
|
||||
import com.cloud.utils.db.DB;
|
||||
import com.cloud.utils.db.Filter;
|
||||
@ -187,7 +187,7 @@ public class NetworkOfferingDaoImpl extends GenericDaoBase<NetworkOfferingVO, Lo
|
||||
//2) persist the details
|
||||
if (details != null && !details.isEmpty()) {
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -43,12 +43,14 @@ public class NetworkOfferingDetailsDaoImpl extends ResourceDetailsDaoBase<Networ
|
||||
DetailSearch.and("resourceId", DetailSearch.entity().getResourceId(), SearchCriteria.Op.EQ);
|
||||
DetailSearch.and("name", DetailSearch.entity().getName(), SearchCriteria.Op.EQ);
|
||||
DetailSearch.and("value", DetailSearch.entity().getValue(), SearchCriteria.Op.EQ);
|
||||
DetailSearch.and("display", DetailSearch.entity().isDisplay(), SearchCriteria.Op.EQ);
|
||||
DetailSearch.done();
|
||||
|
||||
ValueSearch = createSearchBuilder(String.class);
|
||||
ValueSearch.select(null, Func.DISTINCT, ValueSearch.entity().getValue());
|
||||
ValueSearch.and("resourceId", ValueSearch.entity().getResourceId(), SearchCriteria.Op.EQ);
|
||||
ValueSearch.and("name", ValueSearch.entity().getName(), Op.EQ);
|
||||
ValueSearch.and("display", ValueSearch.entity().isDisplay(), SearchCriteria.Op.EQ);
|
||||
ValueSearch.done();
|
||||
}
|
||||
|
||||
@ -56,6 +58,7 @@ public class NetworkOfferingDetailsDaoImpl extends ResourceDetailsDaoBase<Networ
|
||||
public Map<NetworkOffering.Detail, String> getNtwkOffDetails(long offeringId) {
|
||||
SearchCriteria<NetworkOfferingDetailsVO> sc = DetailSearch.create();
|
||||
sc.setParameters("resourceId", offeringId);
|
||||
sc.setParameters("display", true);
|
||||
|
||||
List<NetworkOfferingDetailsVO> results = search(sc, null);
|
||||
Map<NetworkOffering.Detail, String> details = new HashMap<NetworkOffering.Detail, String>(results.size());
|
||||
@ -81,7 +84,7 @@ public class NetworkOfferingDetailsDaoImpl extends ResourceDetailsDaoBase<Networ
|
||||
|
||||
@Override
|
||||
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
|
||||
|
||||
@ -35,7 +35,9 @@ import com.cloud.exception.PermissionDeniedException;
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.network.NetworkModel;
|
||||
import com.cloud.offering.DiskOffering;
|
||||
import com.cloud.offering.NetworkOffering;
|
||||
import com.cloud.offering.ServiceOffering;
|
||||
import com.cloud.offerings.dao.NetworkOfferingDetailsDao;
|
||||
import com.cloud.projects.ProjectManager;
|
||||
import com.cloud.projects.dao.ProjectAccountDao;
|
||||
import com.cloud.service.dao.ServiceOfferingDetailsDao;
|
||||
@ -71,6 +73,8 @@ public class DomainChecker extends AdapterBase implements SecurityChecker {
|
||||
DiskOfferingDetailsDao diskOfferingDetailsDao;
|
||||
@Inject
|
||||
ServiceOfferingDetailsDao serviceOfferingDetailsDao;
|
||||
@Inject
|
||||
NetworkOfferingDetailsDao networkserviceOfferingDetailsDao;
|
||||
|
||||
protected DomainChecker() {
|
||||
super();
|
||||
@ -249,6 +253,44 @@ public class DomainChecker extends AdapterBase implements SecurityChecker {
|
||||
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
|
||||
public boolean checkAccess(Account account, DataCenter zone) throws PermissionDeniedException {
|
||||
if (account == null || zone.getDomainId() == null) {//public zone
|
||||
|
||||
@ -175,6 +175,7 @@ import com.cloud.api.query.vo.EventJoinVO;
|
||||
import com.cloud.api.query.vo.HostJoinVO;
|
||||
import com.cloud.api.query.vo.ImageStoreJoinVO;
|
||||
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.ProjectInvitationJoinVO;
|
||||
import com.cloud.api.query.vo.ProjectJoinVO;
|
||||
@ -1913,6 +1914,9 @@ public class ApiResponseHelper implements ResponseGenerator {
|
||||
|
||||
@Override
|
||||
public NetworkOfferingResponse createNetworkOfferingResponse(NetworkOffering offering) {
|
||||
if (!(offering instanceof NetworkOfferingJoinVO)) {
|
||||
offering = ApiDBUtils.newNetworkOfferingView(offering);
|
||||
}
|
||||
NetworkOfferingResponse response = ApiDBUtils.newNetworkOfferingResponse(offering);
|
||||
response.setNetworkRate(ApiDBUtils.getNetworkRate(offering.getId()));
|
||||
Long so = null;
|
||||
|
||||
@ -2631,12 +2631,12 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
||||
}
|
||||
for (Long domainId : existingDomainIds) {
|
||||
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) {
|
||||
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) {
|
||||
@ -5135,11 +5135,11 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
||||
List<Long> filteredDomainIds = filterChildSubDomains(domainIds);
|
||||
List<NetworkOfferingDetailsVO> detailsVO = new ArrayList<>();
|
||||
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)) {
|
||||
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()) {
|
||||
@ -5507,10 +5507,13 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
||||
Availability availability = null;
|
||||
final String state = cmd.getState();
|
||||
final String tags = cmd.getTags();
|
||||
final List<Long> domainIds = cmd.getDomainIds();
|
||||
final List<Long> zoneIds = cmd.getZoneIds();
|
||||
CallContext.current().setEventDetails(" Id: " + id);
|
||||
|
||||
// Verify input parameters
|
||||
final NetworkOfferingVO offeringToUpdate = _networkOfferingDao.findById(id);
|
||||
List<Long> existingDomainIds = networkOfferingDetailsDao.findDomainIds(id);
|
||||
if (offeringToUpdate == null) {
|
||||
throw new InvalidParameterValueException("unable to find network offering " + id);
|
||||
}
|
||||
@ -5520,8 +5523,51 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
||||
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);
|
||||
|
||||
boolean updateNeeded = name != null || displayText != null || sortKey != null ||
|
||||
state != null || tags != null || availabilityStr != null || maxconn != null;
|
||||
|
||||
if(updateNeeded) {
|
||||
if (name != null) {
|
||||
offering.setName(name);
|
||||
}
|
||||
@ -5600,13 +5646,27 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
||||
}
|
||||
}
|
||||
|
||||
if (_networkOfferingDao.update(id, offering)) {
|
||||
return _networkOfferingDao.findById(id);
|
||||
} else {
|
||||
if (!_networkOfferingDao.update(id, offering)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
List<NetworkOfferingDetailsVO> detailsVO = new ArrayList<>();
|
||||
for (Long domainId : filteredDomainIds) {
|
||||
detailsVO.add(new NetworkOfferingDetailsVO(id, Detail.domainid, String.valueOf(domainId), false));
|
||||
}
|
||||
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
|
||||
@ActionEvent(eventType = EventTypes.EVENT_ACCOUNT_MARK_DEFAULT_ZONE, eventDescription = "Marking account with the " + "default zone", async = true)
|
||||
public AccountVO markDefaultZone(final String accountName, final long domainId, final long defaultZoneId) {
|
||||
|
||||
@ -118,6 +118,7 @@ import com.cloud.network.vpc.VpcManager;
|
||||
import com.cloud.network.vpn.RemoteAccessVpnService;
|
||||
import com.cloud.network.vpn.Site2SiteVpnManager;
|
||||
import com.cloud.offering.DiskOffering;
|
||||
import com.cloud.offering.NetworkOffering;
|
||||
import com.cloud.offering.ServiceOffering;
|
||||
import com.cloud.projects.Project;
|
||||
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);
|
||||
}
|
||||
|
||||
@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
|
||||
public void checkAccess(User user, ControlledEntity entity) throws PermissionDeniedException {
|
||||
for (SecurityChecker checker : _securityCheckers) {
|
||||
|
||||
@ -42,6 +42,7 @@ import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.PermissionDeniedException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.offering.DiskOffering;
|
||||
import com.cloud.offering.NetworkOffering;
|
||||
import com.cloud.offering.ServiceOffering;
|
||||
import com.cloud.projects.Project.ListProjectResourcesCriteria;
|
||||
import com.cloud.utils.Pair;
|
||||
@ -222,6 +223,11 @@ public class MockAccountManagerImpl extends ManagerBase implements Manager, Acco
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkAccess(Account account, NetworkOffering nof, DataCenter zone) throws PermissionDeniedException {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long checkAccessAndSpecifyAuthority(Account caller, Long zoneId) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user