mirror of
https://github.com/apache/cloudstack.git
synced 2025-11-02 20:02:29 +01:00
Introducing concept of domain VPCs (#7153)
Co-authored-by: Gabriel Ortiga Fernandes <gabriel.fernandes@scclouds.com.br> Co-authored-by: Lopez <rodrigo@scclouds.com.br>
This commit is contained in:
parent
a738204e8a
commit
0bab0db881
@ -235,11 +235,11 @@ public class ListNetworksCmd extends BaseListRetrieveOnlyResourceCountCmd implem
|
||||
private void updateNetworkResponse(List<NetworkResponse> response) {
|
||||
for (NetworkResponse networkResponse : response) {
|
||||
ResourceIcon resourceIcon = resourceIconManager.getByResourceTypeAndUuid(ResourceTag.ResourceObjectType.Network, networkResponse.getId());
|
||||
if (resourceIcon == null) {
|
||||
if (resourceIcon == null && networkResponse.getVpcId() != null) {
|
||||
resourceIcon = resourceIconManager.getByResourceTypeAndUuid(ResourceTag.ResourceObjectType.Vpc, networkResponse.getVpcId());
|
||||
if (resourceIcon == null) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (resourceIcon == null) {
|
||||
continue;
|
||||
}
|
||||
ResourceIconResponse iconResponse = _responseGenerator.createResourceIconResponse(resourceIcon);
|
||||
networkResponse.setResourceIconResponse(iconResponse);
|
||||
|
||||
@ -103,4 +103,5 @@ public interface UserVmDao extends GenericDao<UserVmVO, Long> {
|
||||
|
||||
List<UserVmVO> findByUserDataId(long userdataId);
|
||||
|
||||
List<UserVmVO> listByIds(List<Long> ids);
|
||||
}
|
||||
|
||||
@ -71,6 +71,7 @@ public class UserVmDaoImpl extends GenericDaoBase<UserVmVO, Long> implements Use
|
||||
protected SearchBuilder<UserVmVO> RunningSearch;
|
||||
protected SearchBuilder<UserVmVO> StateChangeSearch;
|
||||
protected SearchBuilder<UserVmVO> AccountHostSearch;
|
||||
protected SearchBuilder<UserVmVO> IdsSearch;
|
||||
|
||||
protected SearchBuilder<UserVmVO> DestroySearch;
|
||||
protected SearchBuilder<UserVmVO> AccountDataCenterVirtualSearch;
|
||||
@ -135,6 +136,10 @@ public class UserVmDaoImpl extends GenericDaoBase<UserVmVO, Long> implements Use
|
||||
AccountSearch.and("account", AccountSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
|
||||
AccountSearch.done();
|
||||
|
||||
IdsSearch = createSearchBuilder();
|
||||
IdsSearch.and("ids", IdsSearch.entity().getId(), SearchCriteria.Op.IN);
|
||||
IdsSearch.done();
|
||||
|
||||
HostSearch = createSearchBuilder();
|
||||
HostSearch.and("host", HostSearch.entity().getHostId(), SearchCriteria.Op.EQ);
|
||||
HostSearch.done();
|
||||
@ -778,4 +783,11 @@ public class UserVmDaoImpl extends GenericDaoBase<UserVmVO, Long> implements Use
|
||||
sc.setParameters("userDataId", userdataId);
|
||||
return listBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UserVmVO> listByIds(List<Long> ids) {
|
||||
SearchCriteria<UserVmVO> sc = IdsSearch.create();
|
||||
sc.setParameters("ids", ids.toArray());
|
||||
return listBy(sc);
|
||||
}
|
||||
}
|
||||
|
||||
@ -33,6 +33,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TimeZone;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.inject.Inject;
|
||||
@ -1019,13 +1020,9 @@ public class ApiResponseHelper implements ResponseGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
if (ipAddr.getVpcId() != null) {
|
||||
Vpc vpc = ApiDBUtils.findVpcById(ipAddr.getVpcId());
|
||||
if (vpc != null) {
|
||||
ipResponse.setVpcId(vpc.getUuid());
|
||||
ipResponse.setVpcName(vpc.getName());
|
||||
}
|
||||
}
|
||||
|
||||
setVpcIdInResponse(ipAddr.getVpcId(), ipResponse::setVpcId, ipResponse::setVpcName);
|
||||
|
||||
|
||||
// Network id the ip is associated with (if associated networkId is
|
||||
// null, try to get this information from vlan)
|
||||
@ -1095,6 +1092,22 @@ public class ApiResponseHelper implements ResponseGenerator {
|
||||
return ipResponse;
|
||||
}
|
||||
|
||||
|
||||
private void setVpcIdInResponse(Long vpcId, Consumer<String> vpcUuidSetter, Consumer<String> vpcNameSetter) {
|
||||
if (vpcId != null) {
|
||||
Vpc vpc = ApiDBUtils.findVpcById(vpcId);
|
||||
if (vpc != null) {
|
||||
try {
|
||||
_accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, false, vpc);
|
||||
vpcUuidSetter.accept(vpc.getUuid());
|
||||
} catch (PermissionDeniedException e) {
|
||||
s_logger.debug("Not setting the vpcId to the response because the caller does not have access to the VPC");
|
||||
}
|
||||
vpcNameSetter.accept(vpc.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void showVmInfoForSharedNetworks(boolean forVirtualNetworks, IpAddress ipAddr, IPAddressResponse ipResponse) {
|
||||
if (!forVirtualNetworks) {
|
||||
NicVO nic = ApiDBUtils.findByIp4AddressAndNetworkId(ipAddr.getAddress().toString(), ipAddr.getNetworkId());
|
||||
@ -2565,13 +2578,9 @@ public class ApiResponseHelper implements ResponseGenerator {
|
||||
}
|
||||
|
||||
response.setSpecifyIpRanges(network.getSpecifyIpRanges());
|
||||
if (network.getVpcId() != null) {
|
||||
Vpc vpc = ApiDBUtils.findVpcById(network.getVpcId());
|
||||
if (vpc != null) {
|
||||
response.setVpcId(vpc.getUuid());
|
||||
response.setVpcName(vpc.getName());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
setVpcIdInResponse(network.getVpcId(), response::setVpcId, response::setVpcName);
|
||||
|
||||
setResponseAssociatedNetworkInformation(response, network.getId());
|
||||
|
||||
|
||||
@ -1471,15 +1471,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
|
||||
throw new InvalidParameterValueException("Ip address can be associated to the network with trafficType " + TrafficType.Guest);
|
||||
}
|
||||
|
||||
// Check that network belongs to IP owner - skip this check
|
||||
// - if zone is basic zone as there is just one guest network,
|
||||
// - if shared network in Advanced zone
|
||||
// - and it belongs to the system
|
||||
if (network.getAccountId() != owner.getId()) {
|
||||
if (zone.getNetworkType() != NetworkType.Basic && !(zone.getNetworkType() == NetworkType.Advanced && network.getGuestType() == Network.GuestType.Shared)) {
|
||||
throw new InvalidParameterValueException("The owner of the network is not the same as owner of the IP");
|
||||
}
|
||||
}
|
||||
validateNetworkAndIpOwnership(owner, ipToAssoc, network, zone);
|
||||
|
||||
if (zone.getNetworkType() == NetworkType.Advanced) {
|
||||
// In Advance zone allow to do IP assoc only for Isolated networks with source nat service enabled
|
||||
@ -1543,6 +1535,21 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that network belongs to IP owner - skip this check
|
||||
* - if the IP belongs to the same VPC as the network
|
||||
* - if zone is basic zone as there is just one guest network,
|
||||
* - if shared network in Advanced zone
|
||||
* - and it belongs to the system
|
||||
*/
|
||||
private static void validateNetworkAndIpOwnership(Account owner, IPAddressVO ipToAssoc, Network network, DataCenter zone) {
|
||||
if (network.getAccountId() != owner.getId()) {
|
||||
if (!network.getVpcId().equals(ipToAssoc.getVpcId()) && zone.getNetworkType() == NetworkType.Advanced && network.getGuestType() != GuestType.Shared) {
|
||||
throw new InvalidParameterValueException("The owner of the network is not the same as owner of the IP");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevents associating an IP address to an allocated (unimplemented network) network, throws an Exception otherwise
|
||||
* @param owner Used to check if the user belongs to the Network
|
||||
@ -1625,15 +1632,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
|
||||
|
||||
DataCenter zone = _entityMgr.findById(DataCenter.class, network.getDataCenterId());
|
||||
|
||||
// Check that network belongs to IP owner - skip this check
|
||||
// - if zone is basic zone as there is just one guest network,
|
||||
// - if shared network in Advanced zone
|
||||
// - and it belongs to the system
|
||||
if (network.getAccountId() != owner.getId()) {
|
||||
if (zone.getNetworkType() != NetworkType.Basic && !(zone.getNetworkType() == NetworkType.Advanced && network.getGuestType() == Network.GuestType.Shared)) {
|
||||
throw new InvalidParameterValueException("The owner of the network is not the same as owner of the IP");
|
||||
}
|
||||
}
|
||||
validateNetworkAndIpOwnership(owner, ipToAssoc, network, zone);
|
||||
|
||||
// Check if IP has any services (rules) associated in the network
|
||||
List<PublicIpAddress> ipList = new ArrayList<PublicIpAddress>();
|
||||
|
||||
@ -2351,7 +2351,7 @@ public class LoadBalancingRulesManagerImpl<Type> extends ManagerBase implements
|
||||
}
|
||||
}
|
||||
|
||||
List<UserVmVO> userVms = _vmDao.listVirtualNetworkInstancesByAcctAndNetwork(loadBalancer.getAccountId(), loadBalancer.getNetworkId());
|
||||
List<UserVmVO> userVms = _vmDao.listByIds(appliedInstanceIdList);
|
||||
|
||||
for (UserVmVO userVm : userVms) {
|
||||
// if the VM is destroyed, being expunged, in an error state, or in
|
||||
|
||||
@ -1855,10 +1855,8 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
|
||||
}
|
||||
}
|
||||
|
||||
// 4) vpc and network should belong to the same owner
|
||||
if (vpc.getAccountId() != networkOwner.getId()) {
|
||||
throw new InvalidParameterValueException("Vpc " + vpc + " owner is different from the network owner " + networkOwner);
|
||||
}
|
||||
// 4) Vpc's account should be able to access network owner's account
|
||||
CheckAccountsAccess(vpc, networkOwner);
|
||||
|
||||
// 5) network domain should be the same as VPC's
|
||||
if (!networkDomain.equalsIgnoreCase(vpc.getNetworkDomain())) {
|
||||
@ -1877,6 +1875,17 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
|
||||
});
|
||||
}
|
||||
|
||||
private void CheckAccountsAccess(Vpc vpc, Account networkAccount) {
|
||||
Account vpcaccount = _accountMgr.getAccount(vpc.getAccountId());
|
||||
try {
|
||||
_accountMgr.checkAccess(vpcaccount, null, false, networkAccount);
|
||||
}
|
||||
catch (PermissionDeniedException e) {
|
||||
s_logger.error(e.getMessage());
|
||||
throw new InvalidParameterValueException(String.format("VPC owner does not have access to account [%s].", networkAccount.getAccountName()));
|
||||
}
|
||||
}
|
||||
|
||||
public List<VpcProvider> getVpcElements() {
|
||||
if (vpcElements == null) {
|
||||
vpcElements = new ArrayList<VpcProvider>();
|
||||
@ -2879,11 +2888,11 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
|
||||
}
|
||||
|
||||
// check permissions
|
||||
_accountMgr.checkAccess(caller, null, true, owner, vpc);
|
||||
_accountMgr.checkAccess(caller, null, false, owner, vpc);
|
||||
|
||||
s_logger.debug("Associating ip " + ipToAssoc + " to vpc " + vpc);
|
||||
|
||||
final boolean isSourceNatFinal = isSrcNatIpRequired(vpc.getVpcOfferingId()) && getExistingSourceNatInVpc(owner.getId(), vpcId) == null;
|
||||
final boolean isSourceNatFinal = isSrcNatIpRequired(vpc.getVpcOfferingId()) && getExistingSourceNatInVpc(vpc.getAccountId(), vpcId) == null;
|
||||
Transaction.execute(new TransactionCallbackNoReturn() {
|
||||
@Override
|
||||
public void doInTransactionWithoutResult(final TransactionStatus status) {
|
||||
|
||||
@ -216,7 +216,10 @@
|
||||
<router-link :to="{ path: '/guestnetwork/' + record.associatednetworkid }">{{ text }}</router-link>
|
||||
</template>
|
||||
<template v-if="column.key === 'vpcname'">
|
||||
<router-link :to="{ path: '/vpc/' + record.vpcid }">{{ text }}</router-link>
|
||||
<a v-if="record.vpcid">
|
||||
<router-link :to="{ path: '/vpc/' + record.vpcid }">{{ text }}</router-link>
|
||||
</a>
|
||||
<span v-else>{{ text }}</span>
|
||||
</template>
|
||||
<template v-if="column.key === 'hostname'">
|
||||
<router-link v-if="record.hostid" :to="{ path: '/host/' + record.hostid }">{{ text }}</router-link>
|
||||
|
||||
@ -60,7 +60,7 @@ export default {
|
||||
}, {
|
||||
name: 'egress.rules',
|
||||
component: shallowRef(defineAsyncComponent(() => import('@/views/network/EgressRulesTab.vue'))),
|
||||
show: (record, route, user) => { return record.type === 'Isolated' && !('vpcid' in record) && 'listEgressFirewallRules' in store.getters.apis && (['Admin', 'DomainAdmin'].includes(user.roletype) || record.account === user.account || record.projectid) }
|
||||
show: (record, route, user) => { return record.type === 'Isolated' && !('vpcname' in record) && 'listEgressFirewallRules' in store.getters.apis && (['Admin', 'DomainAdmin'].includes(user.roletype) || record.account === user.account || record.projectid) }
|
||||
}, {
|
||||
name: 'ip.v6.firewall',
|
||||
component: shallowRef(defineAsyncComponent(() => import('@/views/network/Ipv6FirewallRulesTab.vue'))),
|
||||
@ -68,7 +68,7 @@ export default {
|
||||
}, {
|
||||
name: 'public.ip.addresses',
|
||||
component: shallowRef(defineAsyncComponent(() => import('@/views/network/IpAddressesTab.vue'))),
|
||||
show: (record, route, user) => { return 'listPublicIpAddresses' in store.getters.apis && (record.type === 'Shared' || (record.type === 'Isolated' && !('vpcid' in record) && (['Admin', 'DomainAdmin'].includes(user.roletype) || record.account === user.account || record.projectid))) }
|
||||
show: (record, route, user) => { return 'listPublicIpAddresses' in store.getters.apis && (record.type === 'Shared' || (record.type === 'Isolated' && !('vpcname' in record) && (['Admin', 'DomainAdmin'].includes(user.roletype) || record.account === user.account || record.projectid))) }
|
||||
}, {
|
||||
name: 'virtual.routers',
|
||||
component: shallowRef(defineAsyncComponent(() => import('@/views/network/RoutersTab.vue'))),
|
||||
|
||||
@ -191,8 +191,6 @@ export default {
|
||||
pageSize: this.pageSize,
|
||||
listAll: true,
|
||||
networkid: this.resource.associatednetworkid,
|
||||
account: this.resource.account,
|
||||
domainid: this.resource.domainid,
|
||||
keyword: this.searchQuery
|
||||
}).then(response => {
|
||||
this.vmCount = response.listvirtualmachinesresponse.count
|
||||
@ -210,8 +208,6 @@ export default {
|
||||
pageSize: this.pageSize,
|
||||
listAll: true,
|
||||
networkid: e,
|
||||
account: this.resource.account,
|
||||
domainid: this.resource.domainid,
|
||||
vpcid: this.resource.vpcid,
|
||||
keyword: this.searchQuery
|
||||
}).then(response => {
|
||||
@ -250,8 +246,7 @@ export default {
|
||||
this.loading = true
|
||||
api('listNetworks', {
|
||||
vpcid: this.resource.vpcid,
|
||||
domainid: this.resource.domainid,
|
||||
account: this.resource.account,
|
||||
isrecursive: true,
|
||||
supportedservices: 'StaticNat'
|
||||
}).then(response => {
|
||||
this.networksList = response.listnetworksresponse.network
|
||||
|
||||
@ -875,9 +875,8 @@ export default {
|
||||
this.tiers.loading = true
|
||||
|
||||
api('listNetworks', {
|
||||
account: this.resource.account,
|
||||
domainid: this.resource.domainid,
|
||||
supportedservices: 'Lb',
|
||||
isrecursive: true,
|
||||
vpcid: this.resource.vpcid
|
||||
}).then(json => {
|
||||
this.tiers.data = json.listnetworksresponse.network || []
|
||||
@ -1475,9 +1474,7 @@ export default {
|
||||
keyword: this.searchQuery,
|
||||
page: this.vmPage,
|
||||
pagesize: this.vmPageSize,
|
||||
networkid: networkId,
|
||||
account: this.resource.account,
|
||||
domainid: this.resource.domainid
|
||||
networkid: networkId
|
||||
}).then(response => {
|
||||
this.vmCount = response.listvirtualmachinesresponse.count || 0
|
||||
this.vms = response.listvirtualmachinesresponse.virtualmachine || []
|
||||
|
||||
@ -499,10 +499,9 @@ export default {
|
||||
this.selectedTier = null
|
||||
this.tiers.loading = true
|
||||
api('listNetworks', {
|
||||
account: this.resource.account,
|
||||
domainid: this.resource.domainid,
|
||||
supportedservices: 'PortForwarding',
|
||||
vpcid: this.resource.vpcid
|
||||
vpcid: this.resource.vpcid,
|
||||
listall: this.resource.vpcid !== null
|
||||
}).then(json => {
|
||||
this.tiers.data = json.listnetworksresponse.network || []
|
||||
if (this.tiers.data && this.tiers.data.length > 0) {
|
||||
@ -804,9 +803,7 @@ export default {
|
||||
keyword: this.searchQuery,
|
||||
page: this.vmPage,
|
||||
pagesize: this.vmPageSize,
|
||||
networkid: networkId,
|
||||
account: this.resource.account,
|
||||
domainid: this.resource.domainid
|
||||
networkid: networkId
|
||||
}).then(response => {
|
||||
this.vmCount = response.listvirtualmachinesresponse.count || 0
|
||||
this.vms = response.listvirtualmachinesresponse.virtualmachine
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user