Merge branch '4.20' into 4.22

This commit is contained in:
Suresh Kumar Anaparti 2026-04-17 03:12:33 +05:30
commit 13a2c7793c
No known key found for this signature in database
GPG Key ID: D7CEAE3A9E71D0AA
32 changed files with 1526 additions and 1106 deletions

View File

@ -2776,219 +2776,218 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
boolean ipv6 = false;
try (CheckedReservation networkReservation = new CheckedReservation(owner, domainId, Resource.ResourceType.network, null, null, 1L, reservationDao, _resourceLimitMgr)) {
if (StringUtils.isNoneBlank(ip6Gateway, ip6Cidr)) {
ipv6 = true;
}
// Validate zone
if (zone.getNetworkType() == NetworkType.Basic) {
// In Basic zone the network should have aclType=Domain, domainId=1, subdomainAccess=true
if (aclType == null || aclType != ACLType.Domain) {
throw new InvalidParameterValueException("Only AclType=Domain can be specified for network creation in Basic zone");
if (StringUtils.isNoneBlank(ip6Gateway, ip6Cidr)) {
ipv6 = true;
}
// Validate zone
if (zone.getNetworkType() == NetworkType.Basic) {
// In Basic zone the network should have aclType=Domain, domainId=1, subdomainAccess=true
if (aclType == null || aclType != ACLType.Domain) {
throw new InvalidParameterValueException("Only AclType=Domain can be specified for network creation in Basic zone");
}
// Only one guest network is supported in Basic zone
final List<NetworkVO> guestNetworks = _networksDao.listByZoneAndTrafficType(zone.getId(), TrafficType.Guest);
if (!guestNetworks.isEmpty()) {
throw new InvalidParameterValueException("Can't have more than one Guest network in zone with network type " + NetworkType.Basic);
}
// Only one guest network is supported in Basic zone
final List<NetworkVO> guestNetworks = _networksDao.listByZoneAndTrafficType(zone.getId(), TrafficType.Guest);
if (!guestNetworks.isEmpty()) {
throw new InvalidParameterValueException("Can't have more than one Guest network in zone with network type " + NetworkType.Basic);
}
// if zone is basic, only Shared network offerings w/o source nat service are allowed
if (!(ntwkOff.getGuestType() == GuestType.Shared && !_networkModel.areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SourceNat))) {
throw new InvalidParameterValueException("For zone of type " + NetworkType.Basic + " only offerings of " + "guestType " + GuestType.Shared + " with disabled "
+ Service.SourceNat.getName() + " service are allowed");
}
// if zone is basic, only Shared network offerings w/o source nat service are allowed
if (!(ntwkOff.getGuestType() == GuestType.Shared && !_networkModel.areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SourceNat))) {
throw new InvalidParameterValueException("For zone of type " + NetworkType.Basic + " only offerings of " + "guestType " + GuestType.Shared + " with disabled "
+ Service.SourceNat.getName() + " service are allowed");
}
if (domainId == null || domainId != Domain.ROOT_DOMAIN) {
throw new InvalidParameterValueException("Guest network in Basic zone should be dedicated to ROOT domain");
}
if (domainId == null || domainId != Domain.ROOT_DOMAIN) {
throw new InvalidParameterValueException("Guest network in Basic zone should be dedicated to ROOT domain");
}
if (subdomainAccess == null) {
subdomainAccess = true;
} else if (!subdomainAccess) {
throw new InvalidParameterValueException("Subdomain access should be set to true for the" + " guest network in the Basic zone");
}
if (subdomainAccess == null) {
subdomainAccess = true;
} else if (!subdomainAccess) {
throw new InvalidParameterValueException("Subdomain access should be set to true for the" + " guest network in the Basic zone");
}
if (vlanId == null) {
vlanId = Vlan.UNTAGGED;
} else {
if (!vlanId.equalsIgnoreCase(Vlan.UNTAGGED)) {
throw new InvalidParameterValueException("Only vlan " + Vlan.UNTAGGED + " can be created in " + "the zone of type " + NetworkType.Basic);
if (vlanId == null) {
vlanId = Vlan.UNTAGGED;
} else {
if (!vlanId.equalsIgnoreCase(Vlan.UNTAGGED)) {
throw new InvalidParameterValueException("Only vlan " + Vlan.UNTAGGED + " can be created in " + "the zone of type " + NetworkType.Basic);
}
}
} else if (zone.getNetworkType() == NetworkType.Advanced) {
if (zone.isSecurityGroupEnabled()) {
if (isolatedPvlan != null) {
throw new InvalidParameterValueException("Isolated Private VLAN is not supported with security group!");
}
// Only Account specific Isolated network with sourceNat service disabled are allowed in security group
// enabled zone
if ((ntwkOff.getGuestType() != GuestType.Shared) && (ntwkOff.getGuestType() != GuestType.L2)) {
throw new InvalidParameterValueException("Only shared or L2 guest network can be created in security group enabled zone");
}
if (_networkModel.areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SourceNat)) {
throw new InvalidParameterValueException("Service SourceNat is not allowed in security group enabled zone");
}
}
//don't allow eip/elb networks in Advance zone
if (ntwkOff.isElasticIp() || ntwkOff.isElasticLb()) {
throw new InvalidParameterValueException("Elastic IP and Elastic LB services are supported in zone of type " + NetworkType.Basic);
}
}
} else if (zone.getNetworkType() == NetworkType.Advanced) {
if (zone.isSecurityGroupEnabled()) {
if (isolatedPvlan != null) {
throw new InvalidParameterValueException("Isolated Private VLAN is not supported with security group!");
}
// Only Account specific Isolated network with sourceNat service disabled are allowed in security group
// enabled zone
if ((ntwkOff.getGuestType() != GuestType.Shared) && (ntwkOff.getGuestType() != GuestType.L2)) {
throw new InvalidParameterValueException("Only shared or L2 guest network can be created in security group enabled zone");
}
if (_networkModel.areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SourceNat)) {
throw new InvalidParameterValueException("Service SourceNat is not allowed in security group enabled zone");
if (ipv6 && !GuestType.Shared.equals(ntwkOff.getGuestType())) {
_networkModel.checkIp6CidrSizeEqualTo64(ip6Cidr);
}
//TODO(VXLAN): Support VNI specified
// VlanId can be specified only when network offering supports it
final boolean vlanSpecified = vlanId != null;
if (vlanSpecified != ntwkOff.isSpecifyVlan()) {
if (vlanSpecified) {
if (!isSharedNetworkWithoutSpecifyVlan(ntwkOff) && !isPrivateGatewayWithoutSpecifyVlan(ntwkOff)) {
throw new InvalidParameterValueException("Can't specify vlan; corresponding offering says specifyVlan=false");
}
} else {
throw new InvalidParameterValueException("Vlan has to be specified; corresponding offering says specifyVlan=true");
}
}
//don't allow eip/elb networks in Advance zone
if (ntwkOff.isElasticIp() || ntwkOff.isElasticLb()) {
throw new InvalidParameterValueException("Elastic IP and Elastic LB services are supported in zone of type " + NetworkType.Basic);
}
}
if (ipv6 && !GuestType.Shared.equals(ntwkOff.getGuestType())) {
_networkModel.checkIp6CidrSizeEqualTo64(ip6Cidr);
}
//TODO(VXLAN): Support VNI specified
// VlanId can be specified only when network offering supports it
final boolean vlanSpecified = vlanId != null;
if (vlanSpecified != ntwkOff.isSpecifyVlan()) {
if (vlanSpecified) {
if (!isSharedNetworkWithoutSpecifyVlan(ntwkOff) && !isPrivateGatewayWithoutSpecifyVlan(ntwkOff)) {
throw new InvalidParameterValueException("Can't specify vlan; corresponding offering says specifyVlan=false");
URI uri = encodeVlanIdIntoBroadcastUri(vlanId, pNtwk);
// Aux: generate secondary URI for secondary VLAN ID (if provided) for performing checks
URI secondaryUri = StringUtils.isNotBlank(isolatedPvlan) ? BroadcastDomainType.fromString(isolatedPvlan) : null;
if (isSharedNetworkWithoutSpecifyVlan(ntwkOff) || isPrivateGatewayWithoutSpecifyVlan(ntwkOff)) {
bypassVlanOverlapCheck = true;
}
} else {
throw new InvalidParameterValueException("Vlan has to be specified; corresponding offering says specifyVlan=true");
}
}
if (vlanSpecified) {
URI uri = encodeVlanIdIntoBroadcastUri(vlanId, pNtwk);
// Aux: generate secondary URI for secondary VLAN ID (if provided) for performing checks
URI secondaryUri = StringUtils.isNotBlank(isolatedPvlan) ? BroadcastDomainType.fromString(isolatedPvlan) : null;
if (isSharedNetworkWithoutSpecifyVlan(ntwkOff) || isPrivateGatewayWithoutSpecifyVlan(ntwkOff)) {
bypassVlanOverlapCheck = true;
}
//don't allow to specify vlan tag used by physical network for dynamic vlan allocation
if (!(bypassVlanOverlapCheck && (ntwkOff.getGuestType() == GuestType.Shared || isPrivateNetwork))
&& _dcDao.findVnet(zoneId, pNtwk.getId(), BroadcastDomainType.getValue(uri)).size() > 0) {
throw new InvalidParameterValueException("The VLAN tag to use for new guest network, " + vlanId + " is already being used for dynamic vlan allocation for the guest network in zone "
+ zone.getName());
}
if (secondaryUri != null && !(bypassVlanOverlapCheck && ntwkOff.getGuestType() == GuestType.Shared) &&
_dcDao.findVnet(zoneId, pNtwk.getId(), BroadcastDomainType.getValue(secondaryUri)).size() > 0) {
throw new InvalidParameterValueException(String.format(
"The VLAN tag for isolated PVLAN %s is already being used for dynamic vlan allocation for the guest network in zone %s",
isolatedPvlan, zone));
}
if (!UuidUtils.isUuid(vlanId)) {
// For Isolated and L2 networks, don't allow to create network with vlan that already exists in the zone
if (!hasGuestBypassVlanOverlapCheck(bypassVlanOverlapCheck, ntwkOff, isPrivateNetwork)) {
if (_networksDao.listByZoneAndUriAndGuestType(zoneId, uri.toString(), null).size() > 0) {
throw new InvalidParameterValueException(String.format(
"Network with vlan %s already exists or overlaps with other network vlans in zone %s",
vlanId, zone));
} else if (secondaryUri != null && _networksDao.listByZoneAndUriAndGuestType(zoneId, secondaryUri.toString(), null).size() > 0) {
throw new InvalidParameterValueException(String.format(
"Network with vlan %s already exists or overlaps with other network vlans in zone %s",
isolatedPvlan, zone));
} else {
final List<DataCenterVnetVO> dcVnets = _datacenterVnetDao.findVnet(zoneId, BroadcastDomainType.getValue(uri));
//for the network that is created as part of private gateway,
//the vnet is not coming from the data center vnet table, so the list can be empty
if (!dcVnets.isEmpty()) {
final DataCenterVnetVO dcVnet = dcVnets.get(0);
// Fail network creation if specified vlan is dedicated to a different account
if (dcVnet.getAccountGuestVlanMapId() != null) {
final Long accountGuestVlanMapId = dcVnet.getAccountGuestVlanMapId();
final AccountGuestVlanMapVO map = _accountGuestVlanMapDao.findById(accountGuestVlanMapId);
if (map.getAccountId() != owner.getAccountId()) {
throw new InvalidParameterValueException("Vlan " + vlanId + " is dedicated to a different account");
}
// Fail network creation if owner has a dedicated range of vlans but the specified vlan belongs to the system pool
} else {
final List<AccountGuestVlanMapVO> maps = _accountGuestVlanMapDao.listAccountGuestVlanMapsByAccount(owner.getAccountId());
if (maps != null && !maps.isEmpty()) {
final int vnetsAllocatedToAccount = _datacenterVnetDao.countVnetsAllocatedToAccount(zoneId, owner.getAccountId());
final int vnetsDedicatedToAccount = _datacenterVnetDao.countVnetsDedicatedToAccount(zoneId, owner.getAccountId());
if (vnetsAllocatedToAccount < vnetsDedicatedToAccount) {
throw new InvalidParameterValueException("Specified vlan " + vlanId + " doesn't belong" + " to the vlan range dedicated to the owner "
+ owner.getAccountName());
//don't allow to specify vlan tag used by physical network for dynamic vlan allocation
if (!(bypassVlanOverlapCheck && (ntwkOff.getGuestType() == GuestType.Shared || isPrivateNetwork))
&& _dcDao.findVnet(zoneId, pNtwk.getId(), BroadcastDomainType.getValue(uri)).size() > 0) {
throw new InvalidParameterValueException("The VLAN tag to use for new guest network, " + vlanId + " is already being used for dynamic vlan allocation for the guest network in zone "
+ zone.getName());
}
if (secondaryUri != null && !(bypassVlanOverlapCheck && ntwkOff.getGuestType() == GuestType.Shared) &&
_dcDao.findVnet(zoneId, pNtwk.getId(), BroadcastDomainType.getValue(secondaryUri)).size() > 0) {
throw new InvalidParameterValueException(String.format(
"The VLAN tag for isolated PVLAN %s is already being used for dynamic vlan allocation for the guest network in zone %s",
isolatedPvlan, zone));
}
if (!UuidUtils.isUuid(vlanId)) {
// For Isolated and L2 networks, don't allow to create network with vlan that already exists in the zone
if (!hasGuestBypassVlanOverlapCheck(bypassVlanOverlapCheck, ntwkOff, isPrivateNetwork)) {
if (_networksDao.listByZoneAndUriAndGuestType(zoneId, uri.toString(), null).size() > 0) {
throw new InvalidParameterValueException(String.format(
"Network with vlan %s already exists or overlaps with other network vlans in zone %s",
vlanId, zone));
} else if (secondaryUri != null && _networksDao.listByZoneAndUriAndGuestType(zoneId, secondaryUri.toString(), null).size() > 0) {
throw new InvalidParameterValueException(String.format(
"Network with vlan %s already exists or overlaps with other network vlans in zone %s",
isolatedPvlan, zone));
} else {
final List<DataCenterVnetVO> dcVnets = _datacenterVnetDao.findVnet(zoneId, BroadcastDomainType.getValue(uri));
//for the network that is created as part of private gateway,
//the vnet is not coming from the data center vnet table, so the list can be empty
if (!dcVnets.isEmpty()) {
final DataCenterVnetVO dcVnet = dcVnets.get(0);
// Fail network creation if specified vlan is dedicated to a different account
if (dcVnet.getAccountGuestVlanMapId() != null) {
final Long accountGuestVlanMapId = dcVnet.getAccountGuestVlanMapId();
final AccountGuestVlanMapVO map = _accountGuestVlanMapDao.findById(accountGuestVlanMapId);
if (map.getAccountId() != owner.getAccountId()) {
throw new InvalidParameterValueException("Vlan " + vlanId + " is dedicated to a different account");
}
// Fail network creation if owner has a dedicated range of vlans but the specified vlan belongs to the system pool
} else {
final List<AccountGuestVlanMapVO> maps = _accountGuestVlanMapDao.listAccountGuestVlanMapsByAccount(owner.getAccountId());
if (maps != null && !maps.isEmpty()) {
final int vnetsAllocatedToAccount = _datacenterVnetDao.countVnetsAllocatedToAccount(zoneId, owner.getAccountId());
final int vnetsDedicatedToAccount = _datacenterVnetDao.countVnetsDedicatedToAccount(zoneId, owner.getAccountId());
if (vnetsAllocatedToAccount < vnetsDedicatedToAccount) {
throw new InvalidParameterValueException("Specified vlan " + vlanId + " doesn't belong" + " to the vlan range dedicated to the owner "
+ owner.getAccountName());
}
}
}
}
}
} else {
// don't allow to creating shared network with given Vlan ID, if there already exists a isolated network or
// shared network with same Vlan ID in the zone
if (!bypassVlanOverlapCheck && _networksDao.listByZoneAndUriAndGuestType(zoneId, uri.toString(), GuestType.Isolated).size() > 0) {
throw new InvalidParameterValueException(String.format(
"There is an existing isolated/shared network that overlaps with vlan id:%s in zone %s", vlanId, zone));
}
}
} else {
// don't allow to creating shared network with given Vlan ID, if there already exists a isolated network or
// shared network with same Vlan ID in the zone
if (!bypassVlanOverlapCheck && _networksDao.listByZoneAndUriAndGuestType(zoneId, uri.toString(), GuestType.Isolated).size() > 0) {
}
}
// If networkDomain is not specified, take it from the global configuration
if (_networkModel.areServicesSupportedByNetworkOffering(networkOfferingId, Service.Dns)) {
final Map<Network.Capability, String> dnsCapabilities = _networkModel.getNetworkOfferingServiceCapabilities(_entityMgr.findById(NetworkOffering.class, networkOfferingId),
Service.Dns);
final String isUpdateDnsSupported = dnsCapabilities.get(Capability.AllowDnsSuffixModification);
if (isUpdateDnsSupported == null || !Boolean.valueOf(isUpdateDnsSupported)) {
if (networkDomain != null) {
// TBD: NetworkOfferingId and zoneId. Send uuids instead.
throw new InvalidParameterValueException(String.format(
"There is an existing isolated/shared network that overlaps with vlan id:%s in zone %s", vlanId, zone));
"Domain name change is not supported by network offering id=%d in zone %s",
networkOfferingId, zone));
}
}
}
}
// If networkDomain is not specified, take it from the global configuration
if (_networkModel.areServicesSupportedByNetworkOffering(networkOfferingId, Service.Dns)) {
final Map<Network.Capability, String> dnsCapabilities = _networkModel.getNetworkOfferingServiceCapabilities(_entityMgr.findById(NetworkOffering.class, networkOfferingId),
Service.Dns);
final String isUpdateDnsSupported = dnsCapabilities.get(Capability.AllowDnsSuffixModification);
if (isUpdateDnsSupported == null || !Boolean.valueOf(isUpdateDnsSupported)) {
if (networkDomain != null) {
// TBD: NetworkOfferingId and zoneId. Send uuids instead.
throw new InvalidParameterValueException(String.format(
"Domain name change is not supported by network offering id=%d in zone %s",
networkOfferingId, zone));
}
} else {
if (networkDomain == null) {
// 1) Get networkDomain from the corresponding account/domain/zone
if (aclType == ACLType.Domain) {
networkDomain = _networkModel.getDomainNetworkDomain(domainId, zoneId);
} else if (aclType == ACLType.Account) {
networkDomain = _networkModel.getAccountNetworkDomain(owner.getId(), zoneId);
}
// 2) If null, generate networkDomain using domain suffix from the global config variables
if (networkDomain == null) {
networkDomain = "cs" + Long.toHexString(owner.getId()) + GuestDomainSuffix.valueIn(zoneId);
}
} else {
// validate network domain
if (!NetUtils.verifyDomainName(networkDomain)) {
throw new InvalidParameterValueException("Invalid network domain. Total length shouldn't exceed 190 chars. Each domain "
+ "label must be between 1 and 63 characters long, can contain ASCII letters 'a' through 'z', the digits '0' through '9', "
+ "and the hyphen ('-'); can't start or end with \"-\"");
if (networkDomain == null) {
// 1) Get networkDomain from the corresponding account/domain/zone
if (aclType == ACLType.Domain) {
networkDomain = _networkModel.getDomainNetworkDomain(domainId, zoneId);
} else if (aclType == ACLType.Account) {
networkDomain = _networkModel.getAccountNetworkDomain(owner.getId(), zoneId);
}
// 2) If null, generate networkDomain using domain suffix from the global config variables
if (networkDomain == null) {
networkDomain = "cs" + Long.toHexString(owner.getId()) + GuestDomainSuffix.valueIn(zoneId);
}
} else {
// validate network domain
if (!NetUtils.verifyDomainName(networkDomain)) {
throw new InvalidParameterValueException("Invalid network domain. Total length shouldn't exceed 190 chars. Each domain "
+ "label must be between 1 and 63 characters long, can contain ASCII letters 'a' through 'z', the digits '0' through '9', "
+ "and the hyphen ('-'); can't start or end with \"-\"");
}
}
}
}
}
// In Advance zone Cidr for Shared networks and Isolated networks w/o source nat service can't be NULL - 2.2.x
// limitation, remove after we introduce support for multiple ip ranges
// with different Cidrs for the same Shared network
final boolean cidrRequired = zone.getNetworkType() == NetworkType.Advanced
&& ntwkOff.getTrafficType() == TrafficType.Guest
&& (ntwkOff.getGuestType() == GuestType.Shared || (ntwkOff.getGuestType() == GuestType.Isolated
&& !_networkModel.areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SourceNat)
&& !_networkModel.areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.Gateway)));
if (cidr == null && ip6Cidr == null && cidrRequired) {
if (ntwkOff.getGuestType() == GuestType.Shared) {
throw new InvalidParameterValueException(String.format("Gateway/netmask are required when creating %s networks.", Network.GuestType.Shared));
} else {
throw new InvalidParameterValueException("gateway/netmask are required when create network of" + " type " + GuestType.Isolated + " with service " + Service.SourceNat.getName() + " disabled");
// In Advance zone Cidr for Shared networks and Isolated networks w/o source nat service can't be NULL - 2.2.x
// limitation, remove after we introduce support for multiple ip ranges
// with different Cidrs for the same Shared network
final boolean cidrRequired = zone.getNetworkType() == NetworkType.Advanced
&& ntwkOff.getTrafficType() == TrafficType.Guest
&& (ntwkOff.getGuestType() == GuestType.Shared || (ntwkOff.getGuestType() == GuestType.Isolated
&& !_networkModel.areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SourceNat)
&& !_networkModel.areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.Gateway)));
if (cidr == null && ip6Cidr == null && cidrRequired) {
if (ntwkOff.getGuestType() == GuestType.Shared) {
throw new InvalidParameterValueException(String.format("Gateway/netmask are required when creating %s networks.", Network.GuestType.Shared));
} else {
throw new InvalidParameterValueException("gateway/netmask are required when create network of" + " type " + GuestType.Isolated + " with service " + Service.SourceNat.getName() + " disabled");
}
}
}
checkL2OfferingServices(ntwkOff);
checkL2OfferingServices(ntwkOff);
// No cidr can be specified in Basic zone
if (zone.getNetworkType() == NetworkType.Basic && cidr != null) {
throw new InvalidParameterValueException("StartIp/endIp/gateway/netmask can't be specified for zone of type " + NetworkType.Basic);
}
// No cidr can be specified in Basic zone
if (zone.getNetworkType() == NetworkType.Basic && cidr != null) {
throw new InvalidParameterValueException("StartIp/endIp/gateway/netmask can't be specified for zone of type " + NetworkType.Basic);
}
// Check if cidr is RFC1918 compliant if the network is Guest Isolated for IPv4
if (cidr != null && (ntwkOff.getGuestType() == Network.GuestType.Isolated && ntwkOff.getTrafficType() == TrafficType.Guest) &&
!NetUtils.validateGuestCidr(cidr, !ConfigurationManager.AllowNonRFC1918CompliantIPs.value())) {
// Check if cidr is RFC1918 compliant if the network is Guest Isolated for IPv4
if (cidr != null && (ntwkOff.getGuestType() == Network.GuestType.Isolated && ntwkOff.getTrafficType() == TrafficType.Guest) &&
!NetUtils.validateGuestCidr(cidr, !ConfigurationManager.AllowNonRFC1918CompliantIPs.value())) {
throw new InvalidParameterValueException("Virtual Guest Cidr " + cidr + " is not RFC 1918 or 6598 compliant");
}
}
final String networkDomainFinal = networkDomain;
final String vlanIdFinal = vlanId;
@ -3004,75 +3003,75 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
final NetworkVO userNetwork = new NetworkVO();
userNetwork.setNetworkDomain(networkDomainFinal);
if (cidr != null && gateway != null) {
userNetwork.setCidr(cidr);
userNetwork.setGateway(gateway);
}
if (cidr != null && gateway != null) {
userNetwork.setCidr(cidr);
userNetwork.setGateway(gateway);
}
if (StringUtils.isNoneBlank(ip6Gateway, ip6Cidr)) {
userNetwork.setIp6Cidr(ip6Cidr);
userNetwork.setIp6Gateway(ip6Gateway);
}
if (StringUtils.isNoneBlank(ip6Gateway, ip6Cidr)) {
userNetwork.setIp6Cidr(ip6Cidr);
userNetwork.setIp6Gateway(ip6Gateway);
}
if (externalId != null) {
userNetwork.setExternalId(externalId);
}
if (externalId != null) {
userNetwork.setExternalId(externalId);
}
if (StringUtils.isNotBlank(routerIp)) {
userNetwork.setRouterIp(routerIp);
}
if (StringUtils.isNotBlank(routerIp)) {
userNetwork.setRouterIp(routerIp);
}
if (StringUtils.isNotBlank(routerIpv6)) {
userNetwork.setRouterIpv6(routerIpv6);
}
if (StringUtils.isNotBlank(routerIpv6)) {
userNetwork.setRouterIpv6(routerIpv6);
}
if (vrIfaceMTUs != null) {
if (vrIfaceMTUs.first() != null && vrIfaceMTUs.first() > 0) {
userNetwork.setPublicMtu(vrIfaceMTUs.first());
if (vrIfaceMTUs != null) {
if (vrIfaceMTUs.first() != null && vrIfaceMTUs.first() > 0) {
userNetwork.setPublicMtu(vrIfaceMTUs.first());
} else {
userNetwork.setPublicMtu(Integer.valueOf(NetworkService.VRPublicInterfaceMtu.defaultValue()));
}
if (vrIfaceMTUs.second() != null && vrIfaceMTUs.second() > 0) {
userNetwork.setPrivateMtu(vrIfaceMTUs.second());
} else {
userNetwork.setPrivateMtu(Integer.valueOf(NetworkService.VRPrivateInterfaceMtu.defaultValue()));
}
} else {
userNetwork.setPublicMtu(Integer.valueOf(NetworkService.VRPublicInterfaceMtu.defaultValue()));
}
if (vrIfaceMTUs.second() != null && vrIfaceMTUs.second() > 0) {
userNetwork.setPrivateMtu(vrIfaceMTUs.second());
} else {
userNetwork.setPrivateMtu(Integer.valueOf(NetworkService.VRPrivateInterfaceMtu.defaultValue()));
}
} else {
userNetwork.setPublicMtu(Integer.valueOf(NetworkService.VRPublicInterfaceMtu.defaultValue()));
userNetwork.setPrivateMtu(Integer.valueOf(NetworkService.VRPrivateInterfaceMtu.defaultValue()));
}
if (!GuestType.L2.equals(userNetwork.getGuestType())) {
if (StringUtils.isNotBlank(ip4Dns1)) {
userNetwork.setDns1(ip4Dns1);
}
if (StringUtils.isNotBlank(ip4Dns2)) {
userNetwork.setDns2(ip4Dns2);
}
if (StringUtils.isNotBlank(ip6Dns1)) {
userNetwork.setIp6Dns1(ip6Dns1);
}
if (StringUtils.isNotBlank(ip6Dns2)) {
userNetwork.setIp6Dns2(ip6Dns2);
}
}
if (vlanIdFinal != null) {
if (isolatedPvlan == null) {
URI uri = null;
if (UuidUtils.isUuid(vlanIdFinal)) {
//Logical router's UUID provided as VLAN_ID
userNetwork.setVlanIdAsUUID(vlanIdFinal); //Set transient field
} else {
uri = encodeVlanIdIntoBroadcastUri(vlanIdFinal, pNtwk);
if (!GuestType.L2.equals(userNetwork.getGuestType())) {
if (StringUtils.isNotBlank(ip4Dns1)) {
userNetwork.setDns1(ip4Dns1);
}
if (_networksDao.listByPhysicalNetworkPvlan(physicalNetworkId, uri.toString()).size() > 0) {
throw new InvalidParameterValueException(String.format(
"Network with vlan %s already exists or overlaps with other network pvlans in zone %s",
vlanIdFinal, zone));
if (StringUtils.isNotBlank(ip4Dns2)) {
userNetwork.setDns2(ip4Dns2);
}
if (StringUtils.isNotBlank(ip6Dns1)) {
userNetwork.setIp6Dns1(ip6Dns1);
}
if (StringUtils.isNotBlank(ip6Dns2)) {
userNetwork.setIp6Dns2(ip6Dns2);
}
}
if (vlanIdFinal != null) {
if (isolatedPvlan == null) {
URI uri = null;
if (UuidUtils.isUuid(vlanIdFinal)) {
//Logical router's UUID provided as VLAN_ID
userNetwork.setVlanIdAsUUID(vlanIdFinal); //Set transient field
} else {
uri = encodeVlanIdIntoBroadcastUri(vlanIdFinal, pNtwk);
}
if (_networksDao.listByPhysicalNetworkPvlan(physicalNetworkId, uri.toString()).size() > 0) {
throw new InvalidParameterValueException(String.format(
"Network with vlan %s already exists or overlaps with other network pvlans in zone %s",
vlanIdFinal, zone));
}
userNetwork.setBroadcastUri(uri);
if (!vlanIdFinal.equalsIgnoreCase(Vlan.UNTAGGED)) {

View File

@ -16,6 +16,7 @@
// under the License.
package com.cloud.upgrade;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@ -96,7 +97,9 @@ public final class DatabaseVersionHierarchy {
// we cannot find the version specified, so get the
// most recent one immediately before this version
if (!contains(fromVersion)) {
return getPath(getRecentVersion(fromVersion), toVersion);
DbUpgrade[] dbUpgrades = getPath(getRecentVersion(fromVersion), toVersion);
return Arrays.stream(dbUpgrades).filter(up -> CloudStackVersion.compare(up.getUpgradedVersion(), fromVersion.toString()) > 0)
.toArray(DbUpgrade[]::new);
}
final Predicate<? super VersionNode> predicate;

View File

@ -315,11 +315,11 @@ public class SystemVmTemplateRegistration {
public static final List<Pair<Hypervisor.HypervisorType, CPU.CPUArch>> hypervisorList = Arrays.asList(
new Pair<>(Hypervisor.HypervisorType.KVM, CPU.CPUArch.amd64),
new Pair<>(Hypervisor.HypervisorType.KVM, CPU.CPUArch.arm64),
new Pair<>(Hypervisor.HypervisorType.VMware, null),
new Pair<>(Hypervisor.HypervisorType.XenServer, null),
new Pair<>(Hypervisor.HypervisorType.Hyperv, null),
new Pair<>(Hypervisor.HypervisorType.LXC, null),
new Pair<>(Hypervisor.HypervisorType.Ovm3, null)
new Pair<>(Hypervisor.HypervisorType.VMware, CPU.CPUArch.amd64),
new Pair<>(Hypervisor.HypervisorType.XenServer, CPU.CPUArch.amd64),
new Pair<>(Hypervisor.HypervisorType.Hyperv, CPU.CPUArch.amd64),
new Pair<>(Hypervisor.HypervisorType.LXC, CPU.CPUArch.amd64),
new Pair<>(Hypervisor.HypervisorType.Ovm3, CPU.CPUArch.amd64)
);
public static final Map<String, MetadataTemplateDetails> NewTemplateMap = new HashMap<>();

View File

@ -57,8 +57,4 @@ public class Upgrade42020to42030 extends DbUpgradeAbstractImpl implements DbUpgr
public InputStream[] getCleanupScripts() {
return null;
}
@Override
public void updateSystemVmTemplates(Connection conn) {
}
}

View File

@ -31,7 +31,7 @@ CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.account', 'api_key_access', 'boolean
CALL `cloud_usage`.`IDEMPOTENT_ADD_COLUMN`('cloud_usage.account', 'api_key_access', 'boolean DEFAULT NULL COMMENT "is api key access allowed for the account" ');
-- Create a new group for Usage Server related configurations
INSERT INTO `cloud`.`configuration_group` (`name`, `description`, `precedence`) VALUES ('Usage Server', 'Usage Server related configuration', 9);
INSERT IGNORE INTO `cloud`.`configuration_group` (`name`, `description`, `precedence`) VALUES ('Usage Server', 'Usage Server related configuration', 9);
UPDATE `cloud`.`configuration_subgroup` set `group_id` = (SELECT `id` FROM `cloud`.`configuration_group` WHERE `name` = 'Usage Server'), `precedence` = 1 WHERE `name`='Usage';
UPDATE `cloud`.`configuration` SET `group_id` = (SELECT `id` FROM `cloud`.`configuration_group` WHERE `name` = 'Usage Server') where `subgroup_id` = (SELECT `id` FROM `cloud`.`configuration_subgroup` WHERE `name` = 'Usage');

View File

@ -44,6 +44,7 @@ import com.cloud.upgrade.dao.Upgrade41120to41130;
import com.cloud.upgrade.dao.Upgrade41120to41200;
import com.cloud.upgrade.dao.Upgrade41510to41520;
import com.cloud.upgrade.dao.Upgrade41610to41700;
import com.cloud.upgrade.dao.Upgrade42010to42100;
import com.cloud.upgrade.dao.Upgrade452to453;
import com.cloud.upgrade.dao.Upgrade453to460;
import com.cloud.upgrade.dao.Upgrade460to461;
@ -380,4 +381,23 @@ public class DatabaseUpgradeCheckerTest {
assertFalse("DatabaseUpgradeChecker should not be a standalone component", checker.isStandalone());
}
@Test
public void testCalculateUpgradePath42010to42100() {
final CloudStackVersion dbVersion = CloudStackVersion.parse("4.20.1.0");
assertNotNull(dbVersion);
final CloudStackVersion currentVersion = CloudStackVersion.parse("4.21.0.0");
assertNotNull(currentVersion);
final DatabaseUpgradeChecker checker = new DatabaseUpgradeChecker();
final DbUpgrade[] upgrades = checker.calculateUpgradePath(dbVersion, currentVersion);
assertNotNull(upgrades);
assertEquals(1, upgrades.length);
assertTrue(upgrades[0] instanceof Upgrade42010to42100);
assertArrayEquals(new String[]{"4.20.1.0", "4.21.0.0"}, upgrades[0].getUpgradableVersionRange());
assertEquals(currentVersion.toString(), upgrades[0].getUpgradedVersion());
}
}

View File

@ -155,7 +155,7 @@ public class SystemVmTemplateRegistrationTest {
templateDetails =
SystemVmTemplateRegistration.NewTemplateMap.get("vmware");
assertNotNull(templateDetails);
assertNull(templateDetails.getArch());
assertEquals(CPU.CPUArch.amd64, templateDetails.getArch());
assertEquals(Hypervisor.HypervisorType.VMware, templateDetails.getHypervisorType());
}

View File

@ -1,51 +1,51 @@
<!--
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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-plugins</artifactId>
<version>4.22.1.0-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<artifactId>cloud-plugin-hypervisor-baremetal</artifactId>
<name>Apache CloudStack Plugin - Hypervisor Baremetal</name>
<dependencies>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>${cs.jaxb.version}</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>${cs.jaxb.version}</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>${cs.jaxb.impl.version}</version>
</dependency>
</dependencies>
</project>
<!--
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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-plugins</artifactId>
<version>4.22.1.0-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<artifactId>cloud-plugin-hypervisor-baremetal</artifactId>
<name>Apache CloudStack Plugin - Hypervisor Baremetal</name>
<dependencies>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>${cs.jaxb.version}</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>${cs.jaxb.version}</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>${cs.jaxb.impl.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -548,7 +548,7 @@ public class KubernetesClusterResourceModifierActionWorker extends KubernetesClu
List<FirewallRuleVO> firewallRules = firewallRulesDao.listByIpPurposeProtocolAndNotRevoked(publicIp.getId(), FirewallRule.Purpose.Firewall, NetUtils.TCP_PROTO);
for (FirewallRuleVO firewallRule : firewallRules) {
PortForwardingRuleVO pfRule = portForwardingRulesDao.findByNetworkAndPorts(networkId, firewallRule.getSourcePortStart(), firewallRule.getSourcePortEnd());
if (firewallRule.getSourcePortStart() == CLUSTER_NODES_DEFAULT_START_SSH_PORT || (Objects.nonNull(pfRule) && pfRule.getDestinationPortStart() == DEFAULT_SSH_PORT) ) {
if (Objects.equals(firewallRule.getSourcePortStart(), CLUSTER_NODES_DEFAULT_START_SSH_PORT) || (Objects.nonNull(pfRule) && pfRule.getDestinationPortStart() == DEFAULT_SSH_PORT) ) {
rule = firewallRule;
firewallService.revokeIngressFwRule(firewallRule.getId(), true);
logger.debug("The SSH firewall rule {} with the id {} was revoked", firewallRule.getName(), firewallRule.getId());

View File

@ -139,10 +139,14 @@ public class KubernetesClusterScaleWorker extends KubernetesClusterResourceModif
// Remove existing SSH firewall rules
FirewallRule firewallRule = removeSshFirewallRule(publicIp, network.getId());
int existingFirewallRuleSourcePortEnd;
if (firewallRule == null) {
throw new ManagementServerException("Firewall rule for node SSH access can't be provisioned");
logger.warn("SSH firewall rule not found for Kubernetes cluster: {}. It may have been manually deleted or modified.", kubernetesCluster.getName());
existingFirewallRuleSourcePortEnd = CLUSTER_NODES_DEFAULT_START_SSH_PORT + clusterVMIds.size() - 1;
} else {
existingFirewallRuleSourcePortEnd = firewallRule.getSourcePortEnd();
}
int existingFirewallRuleSourcePortEnd = firewallRule.getSourcePortEnd();
try {
removePortForwardingRules(publicIp, network, owner, CLUSTER_NODES_DEFAULT_START_SSH_PORT, existingFirewallRuleSourcePortEnd);
} catch (ResourceUnavailableException e) {

View File

@ -1159,21 +1159,19 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
long reservedIpAddressesAmount = ipDedicatedAccountId == null ? 1L : 0L;
try (CheckedReservation publicIpAddressReservation = new CheckedReservation(account, Resource.ResourceType.public_ip, reservedIpAddressesAmount, reservationDao, _resourceLimitMgr)) {
List<AccountVlanMapVO> maps = _accountVlanMapDao.listAccountVlanMapsByVlan(ipVO.getVlanId());
ipVO.setAllocatedTime(new Date());
ipVO.setAllocatedToAccountId(account.getAccountId());
ipVO.setAllocatedInDomainId(account.getDomainId());
ipVO.setState(State.Reserved);
if (displayIp != null) {
ipVO.setDisplay(displayIp);
}
ipVO = _ipAddressDao.persist(ipVO);
if (reservedIpAddressesAmount > 0) {
_resourceLimitMgr.incrementResourceCount(account.getId(), Resource.ResourceType.public_ip);
}
return ipVO;
List<AccountVlanMapVO> maps = _accountVlanMapDao.listAccountVlanMapsByVlan(ipVO.getVlanId());
ipVO.setAllocatedTime(new Date());
ipVO.setAllocatedToAccountId(account.getAccountId());
ipVO.setAllocatedInDomainId(account.getDomainId());
ipVO.setState(State.Reserved);
if (displayIp != null) {
ipVO.setDisplay(displayIp);
}
ipVO = _ipAddressDao.persist(ipVO);
if (reservedIpAddressesAmount > 0) {
_resourceLimitMgr.incrementResourceCount(account.getId(), Resource.ResourceType.public_ip);
}
return ipVO;
} catch (ResourceAllocationException ex) {
logger.warn("Failed to allocate resource of type " + ex.getResourceType() + " for account " + account);
throw new AccountLimitException("Maximum number of public IP addresses for account: " + account.getAccountName() + " has been exceeded.");

View File

@ -1317,25 +1317,25 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
vpc.setUseRouterIpResolver(Boolean.TRUE.equals(useVrIpResolver));
try (CheckedReservation vpcReservation = new CheckedReservation(owner, ResourceType.vpc, null, null, 1L, reservationDao, _resourceLimitMgr)) {
if (vpc.getCidr() == null && cidrSize != null) {
// Allocate a CIDR for VPC
Ipv4GuestSubnetNetworkMap subnet = routedIpv4Manager.getOrCreateIpv4SubnetForVpc(vpc, cidrSize);
if (subnet != null) {
vpc.setCidr(subnet.getSubnet());
} else {
throw new CloudRuntimeException("Failed to allocate a CIDR with requested size for VPC.");
if (vpc.getCidr() == null && cidrSize != null) {
// Allocate a CIDR for VPC
Ipv4GuestSubnetNetworkMap subnet = routedIpv4Manager.getOrCreateIpv4SubnetForVpc(vpc, cidrSize);
if (subnet != null) {
vpc.setCidr(subnet.getSubnet());
} else {
throw new CloudRuntimeException("Failed to allocate a CIDR with requested size for VPC.");
}
}
}
Vpc newVpc = createVpc(displayVpc, vpc);
// assign Ipv4 subnet to Routed VPC
if (routedIpv4Manager.isRoutedVpc(vpc)) {
routedIpv4Manager.assignIpv4SubnetToVpc(newVpc);
}
if (CollectionUtils.isNotEmpty(bgpPeerIds)) {
routedIpv4Manager.persistBgpPeersForVpc(newVpc.getId(), bgpPeerIds);
}
return newVpc;
Vpc newVpc = createVpc(displayVpc, vpc);
// assign Ipv4 subnet to Routed VPC
if (routedIpv4Manager.isRoutedVpc(vpc)) {
routedIpv4Manager.assignIpv4SubnetToVpc(newVpc);
}
if (CollectionUtils.isNotEmpty(bgpPeerIds)) {
routedIpv4Manager.persistBgpPeersForVpc(newVpc.getId(), bgpPeerIds);
}
return newVpc;
}
}

View File

@ -277,40 +277,39 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager, C
}
try (CheckedReservation projectReservation = new CheckedReservation(owner, ResourceType.project, null, null, 1L, reservationDao, _resourceLimitMgr)) {
final Account ownerFinal = owner;
User finalUser = user;
Project project = Transaction.execute(new TransactionCallback<Project>() {
@Override
public Project doInTransaction(TransactionStatus status) {
final Account ownerFinal = owner;
User finalUser = user;
Project project = Transaction.execute(new TransactionCallback<Project>() {
@Override
public Project doInTransaction(TransactionStatus status) {
//Create an account associated with the project
StringBuilder acctNm = new StringBuilder("PrjAcct-");
acctNm.append(name).append("-").append(ownerFinal.getDomainId());
//Create an account associated with the project
StringBuilder acctNm = new StringBuilder("PrjAcct-");
acctNm.append(name).append("-").append(ownerFinal.getDomainId());
Account projectAccount = _accountMgr.createAccount(acctNm.toString(), Account.Type.PROJECT, null, domainId, null, null, UUID.randomUUID().toString());
Account projectAccount = _accountMgr.createAccount(acctNm.toString(), Account.Type.PROJECT, null, domainId, null, null, UUID.randomUUID().toString());
Project project = _projectDao.persist(new ProjectVO(name, displayText, ownerFinal.getDomainId(), projectAccount.getId()));
Project project = _projectDao.persist(new ProjectVO(name, displayText, ownerFinal.getDomainId(), projectAccount.getId()));
//assign owner to the project
assignAccountToProject(project, ownerFinal.getId(), ProjectAccount.Role.Admin,
Optional.ofNullable(finalUser).map(User::getId).orElse(null), null);
//assign owner to the project
assignAccountToProject(project, ownerFinal.getId(), ProjectAccount.Role.Admin,
Optional.ofNullable(finalUser).map(User::getId).orElse(null), null);
if (project != null) {
CallContext.current().setEventDetails("Project id=" + project.getId());
CallContext.current().putContextParameter(Project.class, project.getUuid());
}
if (project != null) {
CallContext.current().setEventDetails("Project id=" + project.getId());
CallContext.current().putContextParameter(Project.class, project.getUuid());
//Increment resource count
_resourceLimitMgr.incrementResourceCount(ownerFinal.getId(), ResourceType.project);
return project;
}
});
//Increment resource count
_resourceLimitMgr.incrementResourceCount(ownerFinal.getId(), ResourceType.project);
messageBus.publish(_name, ProjectManager.MESSAGE_CREATE_TUNGSTEN_PROJECT_EVENT, PublishScope.LOCAL, project);
return project;
}
});
messageBus.publish(_name, ProjectManager.MESSAGE_CREATE_TUNGSTEN_PROJECT_EVENT, PublishScope.LOCAL, project);
return project;
return project;
}
}
@ -604,16 +603,16 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager, C
boolean shouldIncrementResourceCount = projectRole != null && Role.Admin == projectRole;
try (CheckedReservation cr = new CheckedReservation(userAccount, ResourceType.project, shouldIncrementResourceCount ? 1L : 0L, reservationDao, _resourceLimitMgr)) {
if (assignUserToProject(project, user.getId(), user.getAccountId(), projectRole,
Optional.ofNullable(role).map(ProjectRole::getId).orElse(null)) != null) {
if (shouldIncrementResourceCount) {
_resourceLimitMgr.incrementResourceCount(userAccount.getId(), ResourceType.project);
if (assignUserToProject(project, user.getId(), user.getAccountId(), projectRole,
Optional.ofNullable(role).map(ProjectRole::getId).orElse(null)) != null) {
if (shouldIncrementResourceCount) {
_resourceLimitMgr.incrementResourceCount(userAccount.getId(), ResourceType.project);
}
return true;
} else {
logger.warn("Failed to add user to project: {}", project);
return false;
}
return true;
} else {
logger.warn("Failed to add user to project: {}", project);
return false;
}
}
}
}
@ -671,13 +670,13 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager, C
boolean shouldIncrementResourceCount = Role.Admin == newAccRole;
try (CheckedReservation checkedReservation = new CheckedReservation(account, ResourceType.project, shouldIncrementResourceCount ? 1L : 0L, reservationDao, _resourceLimitMgr)) {
futureOwner.setAccountRole(newAccRole);
_projectAccountDao.update(futureOwner.getId(), futureOwner);
if (shouldIncrementResourceCount) {
_resourceLimitMgr.incrementResourceCount(accountId, ResourceType.project);
} else {
_resourceLimitMgr.decrementResourceCount(accountId, ResourceType.project);
}
futureOwner.setAccountRole(newAccRole);
_projectAccountDao.update(futureOwner.getId(), futureOwner);
if (shouldIncrementResourceCount) {
_resourceLimitMgr.incrementResourceCount(accountId, ResourceType.project);
} else {
_resourceLimitMgr.decrementResourceCount(accountId, ResourceType.project);
}
}
}
@ -721,16 +720,16 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager, C
}
try (CheckedReservation checkedReservation = new CheckedReservation(futureOwnerAccount, ResourceType.project, null, null, 1L, reservationDao, _resourceLimitMgr)) {
//unset the role for the old owner
ProjectAccountVO currentOwner = _projectAccountDao.findByProjectIdAccountId(projectId, currentOwnerAccount.getId());
currentOwner.setAccountRole(Role.Regular);
_projectAccountDao.update(currentOwner.getId(), currentOwner);
_resourceLimitMgr.decrementResourceCount(currentOwnerAccount.getId(), ResourceType.project);
//unset the role for the old owner
ProjectAccountVO currentOwner = _projectAccountDao.findByProjectIdAccountId(projectId, currentOwnerAccount.getId());
currentOwner.setAccountRole(Role.Regular);
_projectAccountDao.update(currentOwner.getId(), currentOwner);
_resourceLimitMgr.decrementResourceCount(currentOwnerAccount.getId(), ResourceType.project);
//set new owner
futureOwner.setAccountRole(Role.Admin);
_projectAccountDao.update(futureOwner.getId(), futureOwner);
_resourceLimitMgr.incrementResourceCount(futureOwnerAccount.getId(), ResourceType.project);
//set new owner
futureOwner.setAccountRole(Role.Admin);
_projectAccountDao.update(futureOwner.getId(), futureOwner);
_resourceLimitMgr.incrementResourceCount(futureOwnerAccount.getId(), ResourceType.project);
}
} else {
logger.trace("Future owner {}is already the owner of the project {}", newOwnerName, project);
@ -877,16 +876,16 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager, C
boolean shouldIncrementResourceCount = projectRoleType != null && Role.Admin == projectRoleType;
try (CheckedReservation cr = new CheckedReservation(account, ResourceType.project, shouldIncrementResourceCount ? 1L : 0L, reservationDao, _resourceLimitMgr)) {
if (assignAccountToProject(project, account.getId(), projectRoleType, null,
Optional.ofNullable(projectRole).map(ProjectRole::getId).orElse(null)) != null) {
if (shouldIncrementResourceCount) {
_resourceLimitMgr.incrementResourceCount(account.getId(), ResourceType.project);
if (assignAccountToProject(project, account.getId(), projectRoleType, null,
Optional.ofNullable(projectRole).map(ProjectRole::getId).orElse(null)) != null) {
if (shouldIncrementResourceCount) {
_resourceLimitMgr.incrementResourceCount(account.getId(), ResourceType.project);
}
return true;
} else {
logger.warn("Failed to add account {} to project {}", accountName, project);
return false;
}
return true;
} else {
logger.warn("Failed to add account {} to project {}", accountName, project);
return false;
}
}
}
}

View File

@ -361,7 +361,7 @@ public class ImageStoreUploadMonitorImpl extends ManagerBase implements ImageSto
boolean success = true;
Long currentSize = answer.getVirtualSize() != 0 ? answer.getVirtualSize() : answer.getPhysicalSize();
Long lastSize = volume.getSize() != null ? volume.getSize() : 0L;
if (!checkAndUpdateSecondaryStorageResourceLimit(volume.getAccountId(), volume.getSize(), currentSize)) {
if (!checkAndUpdateSecondaryStorageResourceLimit(volume.getAccountId(), lastSize, currentSize)) {
volumeDataStore.setDownloadState(VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR);
volumeDataStore.setState(State.Failed);
volumeDataStore.setErrorString("Storage Limit Reached");

View File

@ -16,6 +16,7 @@
// under the License.
package com.cloud.storage;
import static com.cloud.configuration.ConfigurationManagerImpl.SystemVMUseLocalStorage;
import static com.cloud.utils.NumbersUtil.toHumanReadableSize;
import java.io.UnsupportedEncodingException;
@ -152,6 +153,7 @@ import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.time.DateUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.EnumUtils;
import org.springframework.stereotype.Component;
@ -184,7 +186,6 @@ import com.cloud.capacity.dao.CapacityDao;
import com.cloud.cluster.ClusterManagerListener;
import com.cloud.configuration.Config;
import com.cloud.configuration.ConfigurationManager;
import com.cloud.configuration.ConfigurationManagerImpl;
import com.cloud.configuration.Resource.ResourceType;
import com.cloud.cpu.CPU;
import com.cloud.dc.ClusterVO;
@ -819,6 +820,10 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
return createLocalStorage(host, pInfo);
}
private boolean isLocalStorageEnabledForZone(DataCenterVO zone) {
return zone.isLocalStorageEnabled() || BooleanUtils.toBoolean(SystemVMUseLocalStorage.valueIn(zone.getId()));
}
@DB
@Override
public DataStore createLocalStorage(Host host, StoragePoolInfo pInfo) throws ConnectionException {
@ -826,12 +831,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
if (dc == null) {
return null;
}
boolean useLocalStorageForSystemVM = false;
Boolean isLocal = ConfigurationManagerImpl.SystemVMUseLocalStorage.valueIn(dc.getId());
if (isLocal != null) {
useLocalStorageForSystemVM = isLocal.booleanValue();
}
if (!(dc.isLocalStorageEnabled() || useLocalStorageForSystemVM)) {
if (!isLocalStorageEnabledForZone(dc)) {
return null;
}
DataStore store = null;
@ -1033,6 +1033,10 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(account.getId())) {
throw new PermissionDeniedException(String.format("Cannot perform this operation, Zone is currently disabled: %s", zone));
}
// Check if it's local storage and if it's enabled on the zone
if (isFileScheme && !isLocalStorageEnabledForZone(zone)) {
throw new InvalidParameterValueException("Local storage is not enabled for zone: " + zone);
}
managementService.checkJsInterpretationAllowedIfNeededForParameterValue(ApiConstants.IS_TAG_A_RULE,
Boolean.TRUE.equals(cmd.isTagARule()));

View File

@ -2761,13 +2761,13 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
try (CheckedReservation primaryStorageReservation = new CheckedReservation(owner, ResourceType.primary_storage, resourceLimitStorageTags, requiredPrimaryStorageSpace, reservationDao, _resourceLimitMgr)) {
_jobMgr.updateAsyncJobAttachment(job.getId(), "Volume", volumeId);
_jobMgr.updateAsyncJobAttachment(job.getId(), "Volume", volumeId);
if (asyncExecutionContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
return safelyOrchestrateAttachVolume(vmId, volumeId, deviceId);
} else {
return getVolumeAttachJobResult(vmId, volumeId, deviceId);
}
if (asyncExecutionContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
return safelyOrchestrateAttachVolume(vmId, volumeId, deviceId);
} else {
return getVolumeAttachJobResult(vmId, volumeId, deviceId);
}
} catch (ResourceAllocationException e) {
logger.error("primary storage resource limit check failed", e);
@ -4400,12 +4400,12 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
try {
_resourceLimitMgr.checkVolumeResourceLimit(newAccount, true, volume.getSize(), _diskOfferingDao.findById(volume.getDiskOfferingId()), reservations);
Transaction.execute(new TransactionCallbackNoReturn() {
@Override
public void doInTransactionWithoutResult(TransactionStatus status) {
updateVolumeAccount(oldAccount, volume, newAccount);
}
});
Transaction.execute(new TransactionCallbackNoReturn() {
@Override
public void doInTransactionWithoutResult(TransactionStatus status) {
updateVolumeAccount(oldAccount, volume, newAccount);
}
});
return volume;

View File

@ -280,7 +280,7 @@ public class DownloadListener implements Listener {
}
private Long getSizeFromDB() {
Long lastSize = 0L;
Long lastSize = null;
if (DataObjectType.TEMPLATE.equals(object.getType())) {
TemplateDataStoreVO t = _templateDataStoreDao.findByStoreTemplate(object.getDataStore().getId(), object.getId());
lastSize = t.getSize();
@ -288,7 +288,7 @@ public class DownloadListener implements Listener {
VolumeVO v = _volumeDao.findById(object.getId());
lastSize = v.getSize();
}
return lastSize;
return lastSize == null ? 0L : lastSize;
}
private Boolean checkAndUpdateResourceLimits(DownloadAnswer answer) {

View File

@ -35,7 +35,6 @@ import javax.inject.Inject;
import javax.naming.ConfigurationException;
import org.apache.cloudstack.acl.SecurityChecker;
import com.cloud.api.ApiDBUtils;
import org.apache.cloudstack.annotation.AnnotationService;
import org.apache.cloudstack.annotation.dao.AnnotationDao;
import org.apache.cloudstack.api.ApiCommandResourceType;
@ -94,6 +93,7 @@ import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.DeleteSnapshotsDirCommand;
import com.cloud.alert.AlertManager;
import com.cloud.api.ApiDBUtils;
import com.cloud.api.commands.ListRecurringSnapshotScheduleCmd;
import com.cloud.api.query.MutualExclusiveIdsManagerBase;
import com.cloud.configuration.Config;
@ -2048,17 +2048,17 @@ public class SnapshotManagerImpl extends MutualExclusiveIdsManagerBase implement
try (CheckedReservation volumeSnapshotReservation = new CheckedReservation(owner, ResourceType.snapshot, null, null, 1L, reservationDao, _resourceLimitMgr);
CheckedReservation storageReservation = new CheckedReservation(owner, storeResourceType, null, null, volume.getSize(), reservationDao, _resourceLimitMgr)) {
SnapshotVO snapshotVO = new SnapshotVO(volume.getDataCenterId(), volume.getAccountId(), volume.getDomainId(), volume.getId(), volume.getDiskOfferingId(), snapshotName,
(short)snapshotType.ordinal(), snapshotType.name(), volume.getSize(), volume.getMinIops(), volume.getMaxIops(), hypervisorType, locationType);
SnapshotVO snapshotVO = new SnapshotVO(volume.getDataCenterId(), volume.getAccountId(), volume.getDomainId(), volume.getId(), volume.getDiskOfferingId(), snapshotName,
(short)snapshotType.ordinal(), snapshotType.name(), volume.getSize(), volume.getMinIops(), volume.getMaxIops(), hypervisorType, locationType);
SnapshotVO snapshot = _snapshotDao.persist(snapshotVO);
if (snapshot == null) {
throw new CloudRuntimeException(String.format("Failed to create snapshot for volume: %s", volume));
}
CallContext.current().putContextParameter(Snapshot.class, snapshot.getUuid());
_resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.snapshot);
_resourceLimitMgr.incrementResourceCount(volume.getAccountId(), storeResourceType, volume.getSize());
return snapshot;
SnapshotVO snapshot = _snapshotDao.persist(snapshotVO);
if (snapshot == null) {
throw new CloudRuntimeException(String.format("Failed to create snapshot for volume: %s", volume));
}
CallContext.current().putContextParameter(Snapshot.class, snapshot.getUuid());
_resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.snapshot);
_resourceLimitMgr.incrementResourceCount(volume.getAccountId(), storeResourceType, volume.getSize());
return snapshot;
} catch (ResourceAllocationException e) {
if (snapshotType != Type.MANUAL) {
String msg = String.format("Snapshot resource limit exceeded for account id : %s. Failed to create recurring snapshots", owner.getId());

View File

@ -375,10 +375,10 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
if (template != null) {
CallContext.current().putContextParameter(VirtualMachineTemplate.class, template.getUuid());
return template;
} else {
throw new CloudRuntimeException("Failed to create ISO");
}
}
throw new CloudRuntimeException("Failed to create ISO");
}
@Override
@ -407,7 +407,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
TemplateProfile profile = adapter.prepare(cmd);
VMTemplateVO template = adapter.create(profile);
// Secondary storage resource usage will be recalculated in com.cloud.template.HypervisorTemplateAdapter.createTemplateAsyncCallBack
// Secondary storage resource usage will be incremented in com.cloud.template.HypervisorTemplateAdapter.createTemplateAsyncCallBack
// for HypervisorTemplateAdapter
_resourceLimitMgr.incrementResourceCount(profile.getAccountId(), ResourceType.template);
if (secondaryStorageUsage > 0) {
@ -420,10 +420,9 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
vnfTemplateManager.persistVnfTemplate(template.getId(), (RegisterVnfTemplateCmd) cmd);
}
return template;
} else {
throw new CloudRuntimeException("Failed to create a Template");
}
}
throw new CloudRuntimeException("Failed to create a Template");
}
/**
@ -1034,12 +1033,14 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
logger.debug("There is Template {} in secondary storage {} in zone {} , don't need to copy", template, dstSecStore, dataCenterVOs.get(destZoneId));
continue;
}
try (CheckedReservation secondaryStorageReservation = new CheckedReservation(templateOwner, ResourceType.secondary_storage, null, null, template.getSize(), reservationDao, _resourceLimitMgr)) {
if (!copy(userId, template, srcSecStore, dataCenterVOs.get(destZoneId))) {
failedZones.add(dataCenterVOs.get(destZoneId).getName());
continue;
if (template.getSize() != null) {
try (CheckedReservation secondaryStorageReservation = new CheckedReservation(templateOwner, ResourceType.secondary_storage, null, null, template.getSize(), reservationDao, _resourceLimitMgr)) {
if (!copy(userId, template, srcSecStore, dataCenterVOs.get(destZoneId))) {
failedZones.add(dataCenterVOs.get(destZoneId).getName());
continue;
}
_resourceLimitMgr.incrementResourceCount(templateOwner.getId(), ResourceType.secondary_storage, template.getSize());
}
_resourceLimitMgr.incrementResourceCount(templateOwner.getId(), ResourceType.secondary_storage, template.getSize());
}
}
}

View File

@ -60,7 +60,6 @@ import javax.naming.ConfigurationException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.ParserConfigurationException;
import com.cloud.resourcelimit.ReservationHelper;
import org.apache.cloudstack.acl.ControlledEntity;
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
@ -314,6 +313,7 @@ import com.cloud.org.Grouping;
import com.cloud.resource.ResourceManager;
import com.cloud.resource.ResourceState;
import com.cloud.resourcelimit.CheckedReservation;
import com.cloud.resourcelimit.ReservationHelper;
import com.cloud.server.ManagementService;
import com.cloud.server.ResourceTag;
import com.cloud.server.StatsCollector;
@ -1325,46 +1325,45 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
@Override
public void validateCustomParameters(ServiceOfferingVO serviceOffering, Map<String, String> customParameters) {
//TODO need to validate custom cpu, and memory against min/max CPU/Memory ranges from service_offering_details table
if (customParameters.size() != 0) {
Map<String, String> offeringDetails = serviceOfferingDetailsDao.listDetailsKeyPairs(serviceOffering.getId());
if (serviceOffering.getCpu() == null) {
int minCPU = NumbersUtil.parseInt(offeringDetails.get(ApiConstants.MIN_CPU_NUMBER), 1);
int maxCPU = NumbersUtil.parseInt(offeringDetails.get(ApiConstants.MAX_CPU_NUMBER), Integer.MAX_VALUE);
int cpuNumber = NumbersUtil.parseInt(customParameters.get(UsageEventVO.DynamicParameters.cpuNumber.name()), -1);
Integer maxCPUCores = ConfigurationManagerImpl.VM_SERVICE_OFFERING_MAX_CPU_CORES.value() == 0 ? Integer.MAX_VALUE: ConfigurationManagerImpl.VM_SERVICE_OFFERING_MAX_CPU_CORES.value();
if (cpuNumber < minCPU || cpuNumber > maxCPU || cpuNumber > maxCPUCores) {
throw new InvalidParameterValueException(String.format("Invalid CPU cores value, specify a value between %d and %d", minCPU, Math.min(maxCPUCores, maxCPU)));
}
} else if (customParameters.containsKey(UsageEventVO.DynamicParameters.cpuNumber.name())) {
throw new InvalidParameterValueException("The CPU cores of this offering id:" + serviceOffering.getUuid()
+ " is not customizable. This is predefined in the Template.");
}
if (serviceOffering.getSpeed() == null) {
String cpuSpeed = customParameters.get(UsageEventVO.DynamicParameters.cpuSpeed.name());
if ((cpuSpeed == null) || (NumbersUtil.parseInt(cpuSpeed, -1) <= 0)) {
throw new InvalidParameterValueException("Invalid CPU speed value, specify a value between 1 and " + Integer.MAX_VALUE);
}
} else if (!serviceOffering.isCustomCpuSpeedSupported() && customParameters.containsKey(UsageEventVO.DynamicParameters.cpuSpeed.name())) {
throw new InvalidParameterValueException("The CPU speed of this offering id:" + serviceOffering.getUuid()
+ " is not customizable. This is predefined in the Template.");
}
if (serviceOffering.getRamSize() == null) {
int minMemory = NumbersUtil.parseInt(offeringDetails.get(ApiConstants.MIN_MEMORY), 32);
int maxMemory = NumbersUtil.parseInt(offeringDetails.get(ApiConstants.MAX_MEMORY), Integer.MAX_VALUE);
int memory = NumbersUtil.parseInt(customParameters.get(UsageEventVO.DynamicParameters.memory.name()), -1);
Integer maxRAMSize = ConfigurationManagerImpl.VM_SERVICE_OFFERING_MAX_RAM_SIZE.value() == 0 ? Integer.MAX_VALUE: ConfigurationManagerImpl.VM_SERVICE_OFFERING_MAX_RAM_SIZE.value();
if (memory < minMemory || memory > maxMemory || memory > maxRAMSize) {
throw new InvalidParameterValueException(String.format("Invalid memory value, specify a value between %d and %d", minMemory, Math.min(maxRAMSize, maxMemory)));
}
} else if (customParameters.containsKey(UsageEventVO.DynamicParameters.memory.name())) {
throw new InvalidParameterValueException("The memory of this offering id:" + serviceOffering.getUuid() + " is not customizable. This is predefined in the Template.");
}
} else {
if (MapUtils.isEmpty(customParameters) && serviceOffering.isDynamic()) {
throw new InvalidParameterValueException("Need to specify custom parameter values cpu, cpu speed and memory when using custom offering");
}
Map<String, String> offeringDetails = serviceOfferingDetailsDao.listDetailsKeyPairs(serviceOffering.getId());
if (serviceOffering.getCpu() == null) {
int minCPU = NumbersUtil.parseInt(offeringDetails.get(ApiConstants.MIN_CPU_NUMBER), 1);
int maxCPU = NumbersUtil.parseInt(offeringDetails.get(ApiConstants.MAX_CPU_NUMBER), Integer.MAX_VALUE);
int cpuNumber = NumbersUtil.parseInt(customParameters.get(UsageEventVO.DynamicParameters.cpuNumber.name()), -1);
int maxCPUCores = ConfigurationManagerImpl.VM_SERVICE_OFFERING_MAX_CPU_CORES.value() == 0 ? Integer.MAX_VALUE: ConfigurationManagerImpl.VM_SERVICE_OFFERING_MAX_CPU_CORES.value();
if (cpuNumber < minCPU || cpuNumber > maxCPU || cpuNumber > maxCPUCores) {
throw new InvalidParameterValueException(String.format("Invalid CPU cores value, specify a value between %d and %d", minCPU, Math.min(maxCPUCores, maxCPU)));
}
} else if (customParameters.containsKey(UsageEventVO.DynamicParameters.cpuNumber.name())) {
throw new InvalidParameterValueException("The CPU cores of this offering id:" + serviceOffering.getUuid()
+ " is not customizable. This is predefined in the Template.");
}
if (serviceOffering.getSpeed() == null) {
String cpuSpeed = customParameters.get(UsageEventVO.DynamicParameters.cpuSpeed.name());
if ((cpuSpeed == null) || (NumbersUtil.parseInt(cpuSpeed, -1) <= 0)) {
throw new InvalidParameterValueException("Invalid CPU speed value, specify a value between 1 and " + Integer.MAX_VALUE);
}
} else if (!serviceOffering.isCustomCpuSpeedSupported() && customParameters.containsKey(UsageEventVO.DynamicParameters.cpuSpeed.name())) {
throw new InvalidParameterValueException(String.format("The CPU speed of this offering id:%s"
+ " is not customizable. This is predefined as %d MHz.",
serviceOffering.getUuid(), serviceOffering.getSpeed()));
}
if (serviceOffering.getRamSize() == null) {
int minMemory = NumbersUtil.parseInt(offeringDetails.get(ApiConstants.MIN_MEMORY), 32);
int maxMemory = NumbersUtil.parseInt(offeringDetails.get(ApiConstants.MAX_MEMORY), Integer.MAX_VALUE);
int memory = NumbersUtil.parseInt(customParameters.get(UsageEventVO.DynamicParameters.memory.name()), -1);
int maxRAMSize = ConfigurationManagerImpl.VM_SERVICE_OFFERING_MAX_RAM_SIZE.value() == 0 ? Integer.MAX_VALUE: ConfigurationManagerImpl.VM_SERVICE_OFFERING_MAX_RAM_SIZE.value();
if (memory < minMemory || memory > maxMemory || memory > maxRAMSize) {
throw new InvalidParameterValueException(String.format("Invalid memory value, specify a value between %d and %d", minMemory, Math.min(maxRAMSize, maxMemory)));
}
} else if (customParameters.containsKey(UsageEventVO.DynamicParameters.memory.name())) {
throw new InvalidParameterValueException("The memory of this offering id:" + serviceOffering.getUuid() + " is not customizable. This is predefined in the Template.");
}
}
private UserVm upgradeStoppedVirtualMachine(Long vmId, Long svcOffId, Map<String, String> customParameters) throws ResourceAllocationException {
@ -1396,30 +1395,30 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
List<Reserver> reservations = new ArrayList<>();
try {
if (!VirtualMachineManager.ResourceCountRunningVMsonly.value()) {
_resourceLimitMgr.checkVmResourceLimitsForServiceOfferingChange(owner, vmInstance.isDisplay(), (long) currentCpu, (long) newCpu,
(long) currentMemory, (long) newMemory, currentServiceOffering, newServiceOffering, template, reservations);
}
if (!VirtualMachineManager.ResourceCountRunningVMsonly.value()) {
_resourceLimitMgr.checkVmResourceLimitsForServiceOfferingChange(owner, vmInstance.isDisplay(), (long) currentCpu, (long) newCpu,
(long) currentMemory, (long) newMemory, currentServiceOffering, newServiceOffering, template, reservations);
}
// Check that the specified service offering ID is valid
_itMgr.checkIfCanUpgrade(vmInstance, newServiceOffering);
// Check that the specified service offering ID is valid
_itMgr.checkIfCanUpgrade(vmInstance, newServiceOffering);
// Check if the new service offering can be applied to vm instance
_accountMgr.checkAccess(owner, newServiceOffering, _dcDao.findById(vmInstance.getDataCenterId()));
// Check if the new service offering can be applied to vm instance
_accountMgr.checkAccess(owner, newServiceOffering, _dcDao.findById(vmInstance.getDataCenterId()));
// resize and migrate the root volume if required
DiskOfferingVO newDiskOffering = _diskOfferingDao.findById(newServiceOffering.getDiskOfferingId());
changeDiskOfferingForRootVolume(vmId, newDiskOffering, customParameters, vmInstance.getDataCenterId());
// resize and migrate the root volume if required
DiskOfferingVO newDiskOffering = _diskOfferingDao.findById(newServiceOffering.getDiskOfferingId());
changeDiskOfferingForRootVolume(vmId, newDiskOffering, customParameters, vmInstance.getDataCenterId());
_itMgr.upgradeVmDb(vmId, newServiceOffering, currentServiceOffering);
_itMgr.upgradeVmDb(vmId, newServiceOffering, currentServiceOffering);
// Increment or decrement CPU and Memory count accordingly.
if (!VirtualMachineManager.ResourceCountRunningVMsonly.value()) {
_resourceLimitMgr.updateVmResourceCountForServiceOfferingChange(owner.getAccountId(), vmInstance.isDisplay(), (long) currentCpu, (long) newCpu,
(long) currentMemory, (long) newMemory, currentServiceOffering, newServiceOffering, template);
}
// Increment or decrement CPU and Memory count accordingly.
if (!VirtualMachineManager.ResourceCountRunningVMsonly.value()) {
_resourceLimitMgr.updateVmResourceCountForServiceOfferingChange(owner.getAccountId(), vmInstance.isDisplay(), (long) currentCpu, (long) newCpu,
(long) currentMemory, (long) newMemory, currentServiceOffering, newServiceOffering, template);
}
return _vmDao.findById(vmInstance.getId());
return _vmDao.findById(vmInstance.getId());
} finally {
ReservationHelper.closeAll(reservations);
@ -2384,34 +2383,34 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
List<Reserver> reservations = new ArrayList<>();
try {
// First check that the maximum number of UserVMs, CPU and Memory limit for the given
// accountId will not be exceeded
if (!VirtualMachineManager.ResourceCountRunningVMsonly.value()) {
resourceLimitService.checkVmResourceLimit(account, vm.isDisplayVm(), serviceOffering, template, reservations);
}
// First check that the maximum number of UserVMs, CPU and Memory limit for the given
// accountId will not be exceeded
if (!VirtualMachineManager.ResourceCountRunningVMsonly.value()) {
resourceLimitService.checkVmResourceLimit(account, vm.isDisplayVm(), serviceOffering, template, reservations);
}
_haMgr.cancelDestroy(vm, vm.getHostId());
_haMgr.cancelDestroy(vm, vm.getHostId());
try {
if (!_itMgr.stateTransitTo(vm, VirtualMachine.Event.RecoveryRequested, null)) {
logger.debug("Unable to recover the vm {} because it is not in the correct state. current state: {}", vm, vm.getState());
try {
if (!_itMgr.stateTransitTo(vm, VirtualMachine.Event.RecoveryRequested, null)) {
logger.debug("Unable to recover the vm {} because it is not in the correct state. current state: {}", vm, vm.getState());
throw new InvalidParameterValueException(String.format("Unable to recover the vm %s because it is not in the correct state. current state: %s", vm, vm.getState()));
}
} catch (NoTransitionException e) {
throw new InvalidParameterValueException(String.format("Unable to recover the vm %s because it is not in the correct state. current state: %s", vm, vm.getState()));
}
} catch (NoTransitionException e) {
throw new InvalidParameterValueException(String.format("Unable to recover the vm %s because it is not in the correct state. current state: %s", vm, vm.getState()));
}
// Recover the VM's disks
List<VolumeVO> volumes = _volsDao.findByInstance(vmId);
for (VolumeVO volume : volumes) {
if (volume.getVolumeType().equals(Volume.Type.ROOT)) {
recoverRootVolume(volume, vmId);
break;
// Recover the VM's disks
List<VolumeVO> volumes = _volsDao.findByInstance(vmId);
for (VolumeVO volume : volumes) {
if (volume.getVolumeType().equals(Volume.Type.ROOT)) {
recoverRootVolume(volume, vmId);
break;
}
}
}
//Update Resource Count for the given account
resourceCountIncrement(account.getId(), vm.isDisplayVm(), serviceOffering, template);
//Update Resource Count for the given account
resourceCountIncrement(account.getId(), vm.isDisplayVm(), serviceOffering, template);
} finally {
ReservationHelper.closeAll(reservations);
@ -2839,10 +2838,16 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
Map<String, String> customParameters = new HashMap<>();
customParameters.put(VmDetailConstants.CPU_NUMBER, String.valueOf(newCpu));
customParameters.put(VmDetailConstants.MEMORY, String.valueOf(newMemory));
if (svcOffering.isCustomCpuSpeedSupported()) {
if (details.containsKey(VmDetailConstants.CPU_SPEED)) {
customParameters.put(VmDetailConstants.CPU_SPEED, details.get(VmDetailConstants.CPU_SPEED));
}
validateCustomParameters(svcOffering, customParameters);
} else {
if (details.containsKey(VmDetailConstants.CPU_NUMBER) || details.containsKey(VmDetailConstants.MEMORY) ||
details.containsKey(VmDetailConstants.CPU_SPEED)) {
throw new InvalidParameterValueException("CPU number, Memory and CPU speed cannot be updated for a " +
"non-dynamic offering");
}
}
if (VirtualMachineManager.ResourceCountRunningVMsonly.value()) {
return;

View File

@ -757,11 +757,17 @@ public class VMSnapshotManagerImpl extends MutualExclusiveIdsManagerBase impleme
"Instance Snapshot reverting failed because the Instance is not in Running or Stopped state.");
}
if (userVm.getState() == VirtualMachine.State.Running && vmSnapshotVo.getType() == VMSnapshot.Type.Disk || userVm.getState() == VirtualMachine.State.Stopped
&& vmSnapshotVo.getType() == VMSnapshot.Type.DiskAndMemory) {
if (userVm.getState() == VirtualMachine.State.Running && vmSnapshotVo.getType() == VMSnapshot.Type.Disk) {
throw new InvalidParameterValueException(
"Reverting to the Instance Snapshot is not allowed for running Instances as this would result in a Instance state change. For running Instances only Snapshots with memory can be reverted. In order to revert to a Snapshot without memory you need to first stop the Instance."
+ " Snapshot");
"Reverting to the Instance Snapshot is not allowed for running Instances as this would result in an Instance state change. " +
"For running Instances only Snapshots with memory can be reverted. " +
"In order to revert to a Snapshot without memory you need to first stop the Instance.");
}
if (userVm.getState() == VirtualMachine.State.Stopped && vmSnapshotVo.getType() == VMSnapshot.Type.DiskAndMemory) {
throw new InvalidParameterValueException(
"Reverting to the Instance Snapshot is not allowed for stopped Instances when the Snapshot contains memory as this would result in an Instance state change. " +
"In order to revert to a Snapshot with memory you need to first start the Instance.");
}
// if snapshot is not created, error out
@ -814,20 +820,36 @@ public class VMSnapshotManagerImpl extends MutualExclusiveIdsManagerBase impleme
}
/**
* If snapshot was taken with a different service offering than actual used in vm, should change it back to it.
* We also call <code>changeUserVmServiceOffering</code> in case the service offering is dynamic in order to
* perform resource limit validation, as the amount of CPUs or memory may have been changed.
* @param vmSnapshotVo vm snapshot
* Check if service offering change is needed for user vm when reverting to vm snapshot.
* Service offering change is needed when snapshot was taken with a different service offering than actual used in vm.
* Service offering change is also needed when service offering is dynamic and the amount of cpu, memory or cpu speed
* has been changed since snapshot was taken.
* @param userVm
* @param vmSnapshotVo
* @return true if service offering change is needed; false otherwise
*/
protected void updateUserVmServiceOffering(UserVm userVm, VMSnapshotVO vmSnapshotVo) {
protected boolean userVmServiceOfferingNeedsChange(UserVm userVm, VMSnapshotVO vmSnapshotVo) {
if (vmSnapshotVo.getServiceOfferingId() != userVm.getServiceOfferingId()) {
changeUserVmServiceOffering(userVm, vmSnapshotVo);
return;
return true;
}
ServiceOfferingVO serviceOffering = _serviceOfferingDao.findById(userVm.getServiceOfferingId());
if (serviceOffering.isDynamic()) {
changeUserVmServiceOffering(userVm, vmSnapshotVo);
ServiceOfferingVO currentServiceOffering = _serviceOfferingDao.findByIdIncludingRemoved(userVm.getId(), userVm.getServiceOfferingId());
if (currentServiceOffering.isDynamic()) {
Map<String, String> vmDetails = getVmMapDetails(vmSnapshotVo);
ServiceOfferingVO newServiceOffering = _serviceOfferingDao.getComputeOffering(currentServiceOffering, vmDetails);
int newCpu = newServiceOffering.getCpu();
int newMemory = newServiceOffering.getRamSize();
int newSpeed = newServiceOffering.getSpeed();
int currentCpu = currentServiceOffering.getCpu();
int currentMemory = currentServiceOffering.getRamSize();
int currentSpeed = currentServiceOffering.getSpeed();
if (newCpu != currentCpu || newMemory != currentMemory || newSpeed != currentSpeed) {
return true;
}
}
return false;
}
/**
@ -947,8 +969,10 @@ public class VMSnapshotManagerImpl extends MutualExclusiveIdsManagerBase impleme
Transaction.execute(new TransactionCallbackWithExceptionNoReturn<CloudRuntimeException>() {
@Override
public void doInTransactionWithoutResult(TransactionStatus status) throws CloudRuntimeException {
if (userVmServiceOfferingNeedsChange(userVm, vmSnapshotVo)) {
changeUserVmServiceOffering(userVm, vmSnapshotVo);
}
revertCustomServiceOfferingDetailsFromVmSnapshot(userVm, vmSnapshotVo);
updateUserVmServiceOffering(userVm, vmSnapshotVo);
}
});
return userVm;

View File

@ -212,20 +212,20 @@ public class VolumeImportUnmanageManagerImpl implements VolumeImportUnmanageServ
List<Reserver> reservations = new ArrayList<>();
try {
// 6. check resource limitation
checkResourceLimitForImportVolume(owner, volume, diskOffering, reservations);
// 6. check resource limitation
checkResourceLimitForImportVolume(owner, volume, diskOffering, reservations);
// 7. create records
String volumeName = StringUtils.isNotBlank(cmd.getName()) ? cmd.getName().trim() : volumePath;
VolumeVO volumeVO = importVolumeInternal(volume, diskOffering, owner, pool, volumeName);
// 7. create records
String volumeName = StringUtils.isNotBlank(cmd.getName()) ? cmd.getName().trim() : volumePath;
VolumeVO volumeVO = importVolumeInternal(volume, diskOffering, owner, pool, volumeName);
// 8. Update resource count
updateResourceLimitForVolumeImport(volumeVO);
// 8. Update resource count
updateResourceLimitForVolumeImport(volumeVO);
// 9. Publish event
publicUsageEventForVolumeImportAndUnmanage(volumeVO, true);
// 9. Publish event
publicUsageEventForVolumeImportAndUnmanage(volumeVO, true);
return responseGenerator.createVolumeResponse(ResponseObject.ResponseView.Full, volumeVO);
return responseGenerator.createVolumeResponse(ResponseObject.ResponseView.Full, volumeVO);
} finally {
ReservationHelper.closeAll(reservations);

View File

@ -1500,7 +1500,7 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
String hostName, Account caller, Account owner, long userId,
ServiceOfferingVO serviceOffering, Map<String, Long> dataDiskOfferingMap,
Map<String, Long> nicNetworkMap, Map<String, Network.IpAddresses> nicIpAddressMap,
Map<String, String> details, Boolean migrateAllowed, List<String> managedVms, boolean forced) {
Map<String, String> details, Boolean migrateAllowed, List<String> managedVms, boolean forced) throws ResourceAllocationException {
UserVm userVm = null;
for (HostVO host : hosts) {
HashMap<String, UnmanagedInstanceTO> unmanagedInstances = getUnmanagedInstancesForHost(host, instanceName, managedVms);
@ -1544,11 +1544,18 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
template.setGuestOSId(guestOSHypervisor.getGuestOsId());
}
userVm = importVirtualMachineInternal(unmanagedInstance, instanceName, zone, cluster, host,
template, displayName, hostName, CallContext.current().getCallingAccount(), owner, userId,
serviceOffering, dataDiskOfferingMap,
nicNetworkMap, nicIpAddressMap, null,
details, migrateAllowed, forced, true);
List<Reserver> reservations = new ArrayList<>();
try {
checkVmResourceLimitsForUnmanagedInstanceImport(owner, unmanagedInstance, serviceOffering, template, reservations);
userVm = importVirtualMachineInternal(unmanagedInstance, instanceName, zone, cluster, host,
template, displayName, hostName, CallContext.current().getCallingAccount(), owner, userId,
serviceOffering, dataDiskOfferingMap,
nicNetworkMap, nicIpAddressMap, null,
details, migrateAllowed, forced, true);
} finally {
ReservationHelper.closeAll(reservations);
}
break;
}
if (userVm != null) {
@ -1558,6 +1565,36 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
return userVm;
}
protected void checkVmResourceLimitsForUnmanagedInstanceImport(Account owner, UnmanagedInstanceTO unmanagedInstance, ServiceOfferingVO serviceOffering, VMTemplateVO template, List<Reserver> reservations) throws ResourceAllocationException {
// When importing an unmanaged instance, the amount of CPUs and memory is obtained from the hypervisor unless powered off
// and not using a dynamic offering, unlike the external VM import that always obtains it from the compute offering
Integer cpu = serviceOffering.getCpu();
Integer memory = serviceOffering.getRamSize();
if (serviceOffering.isDynamic() || !UnmanagedInstanceTO.PowerState.PowerOff.equals(unmanagedInstance.getPowerState())) {
cpu = unmanagedInstance.getCpuCores();
memory = unmanagedInstance.getMemory();
}
if (cpu == null || cpu == 0) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("CPU cores [%s] is not valid for importing VM [%s].", cpu, unmanagedInstance.getName()));
}
if (memory == null || memory == 0) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Memory [%s] is not valid for importing VM [%s].", memory, unmanagedInstance.getName()));
}
List<String> resourceLimitHostTags = resourceLimitService.getResourceLimitHostTags(serviceOffering, template);
CheckedReservation vmReservation = new CheckedReservation(owner, Resource.ResourceType.user_vm, resourceLimitHostTags, 1L, reservationDao, resourceLimitService);
reservations.add(vmReservation);
CheckedReservation cpuReservation = new CheckedReservation(owner, Resource.ResourceType.cpu, resourceLimitHostTags, cpu.longValue(), reservationDao, resourceLimitService);
reservations.add(cpuReservation);
CheckedReservation memReservation = new CheckedReservation(owner, Resource.ResourceType.memory, resourceLimitHostTags, memory.longValue(), reservationDao, resourceLimitService);
reservations.add(memReservation);
}
private Pair<UnmanagedInstanceTO, Boolean> getSourceVmwareUnmanagedInstance(String vcenter, String datacenterName, String username,
String password, String clusterName, String sourceHostName,
String sourceVM, ServiceOfferingVO serviceOffering) {
@ -1614,7 +1651,7 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
Account caller, Account owner, long userId,
ServiceOfferingVO serviceOffering, Map<String, Long> dataDiskOfferingMap,
Map<String, Long> nicNetworkMap, Map<String, Network.IpAddresses> nicIpAddressMap,
Map<String, String> details, ImportVmCmd cmd, boolean forced) {
Map<String, String> details, ImportVmCmd cmd, boolean forced) throws ResourceAllocationException {
Long existingVcenterId = cmd.getExistingVcenterId();
String vcenter = cmd.getVcenter();
String datacenterName = cmd.getDatacenterName();
@ -1668,6 +1705,7 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
DataStoreTO temporaryConvertLocation = null;
String ovfTemplateOnConvertLocation = null;
ImportVmTask importVMTask = null;
List<Reserver> reservations = new ArrayList<>();
try {
HostVO convertHost = selectKVMHostForConversionInCluster(destinationCluster, convertInstanceHostId, useVddk);
HostVO importHost = (useVddk && importInstanceHostId == null)
@ -1697,6 +1735,10 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
Pair<UnmanagedInstanceTO, Boolean> sourceInstanceDetails = getSourceVmwareUnmanagedInstance(vcenter, datacenterName, username, password, clusterName, sourceHostName, sourceVMName, serviceOffering);
sourceVMwareInstance = sourceInstanceDetails.first();
isClonedInstance = sourceInstanceDetails.second();
// Ensure that the configured resource limits will not be exceeded before beginning the conversion process
checkVmResourceLimitsForUnmanagedInstanceImport(owner, sourceVMwareInstance, serviceOffering, template, reservations);
boolean isWindowsVm = sourceVMwareInstance.getOperatingSystem().toLowerCase().contains("windows");
if (isWindowsVm) {
checkConversionSupportOnHost(convertHost, sourceVMName, true, useVddk, details);
@ -1749,6 +1791,7 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
if (temporaryConvertLocation != null && StringUtils.isNotBlank(ovfTemplateOnConvertLocation)) {
removeTemplate(temporaryConvertLocation, ovfTemplateOnConvertLocation);
}
ReservationHelper.closeAll(reservations);
}
}
@ -2696,6 +2739,7 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
List<Reserver> reservations = new ArrayList<>();
try {
checkVmResourceLimitsForExternalKvmVmImport(owner, serviceOffering, (VMTemplateVO) template, details, reservations);
checkVolumeResourceLimitsForExternalKvmVmImport(owner, rootDisk, dataDisks, diskOffering, dataDiskOfferingMap, reservations);
// Check NICs and supplied networks
@ -2860,101 +2904,138 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
profiles.add(nicProfile);
networkNicMap.put(network.getUuid(), profiles);
List<Reserver> reservations = new ArrayList<>();
try {
checkVmResourceLimitsForExternalKvmVmImport(owner, serviceOffering, (VMTemplateVO) template, details, reservations);
userVm = userVmManager.importVM(zone, null, template, null, displayName, owner,
null, caller, true, null, owner.getAccountId(), userId,
serviceOffering, null, null, hostName,
Hypervisor.HypervisorType.KVM, allDetails, powerState, networkNicMap);
} catch (InsufficientCapacityException ice) {
if (userVm == null) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Failed to import vm name: %s", instanceName));
}
DiskOfferingVO diskOffering = diskOfferingDao.findById(serviceOffering.getDiskOfferingId());
List<String> resourceLimitStorageTags = resourceLimitService.getResourceLimitStorageTagsForResourceCountOperation(true, diskOffering);
CheckedReservation volumeReservation = new CheckedReservation(owner, Resource.ResourceType.volume, resourceLimitStorageTags,
CollectionUtils.isNotEmpty(resourceLimitStorageTags) ? 1L : 0L, reservationDao, resourceLimitService);
reservations.add(volumeReservation);
String rootVolumeName = String.format("ROOT-%s", userVm.getId());
DiskProfile diskProfile = volumeManager.allocateRawVolume(Volume.Type.ROOT, rootVolumeName, diskOffering, null, null, null, userVm, template, owner, null, false);
final VirtualMachineProfile profile = new VirtualMachineProfileImpl(userVm, template, serviceOffering, owner, null);
ServiceOfferingVO dummyOffering = serviceOfferingDao.findById(userVm.getId(), serviceOffering.getId());
profile.setServiceOffering(dummyOffering);
DeploymentPlanner.ExcludeList excludeList = new DeploymentPlanner.ExcludeList();
final DataCenterDeployment plan = new DataCenterDeployment(zone.getId(), null, null, hostId, poolId, null);
DeployDestination dest = null;
try {
dest = deploymentPlanningManager.planDeployment(profile, plan, excludeList, null);
} catch (Exception e) {
logger.warn("Import failed for Vm: {} while finding deployment destination", userVm, e);
cleanupFailedImportVM(userVm);
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Import failed for Vm: %s while finding deployment destination", userVm.getInstanceName()));
}
if(dest == null) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Import failed for Vm: %s. Suitable deployment destination not found", userVm.getInstanceName()));
}
Map<Volume, StoragePool> storage = dest.getStorageForDisks();
Volume volume = volumeDao.findById(diskProfile.getVolumeId());
StoragePool storagePool = storage.get(volume);
CheckVolumeCommand checkVolumeCommand = new CheckVolumeCommand();
checkVolumeCommand.setSrcFile(diskPath);
StorageFilerTO storageTO = new StorageFilerTO(storagePool);
checkVolumeCommand.setStorageFilerTO(storageTO);
Answer answer = agentManager.easySend(dest.getHost().getId(), checkVolumeCommand);
if (!(answer instanceof CheckVolumeAnswer)) {
cleanupFailedImportVM(userVm);
throw new CloudRuntimeException("Disk not found or is invalid");
}
CheckVolumeAnswer checkVolumeAnswer = (CheckVolumeAnswer) answer;
try {
checkVolume(checkVolumeAnswer.getVolumeDetails());
} catch (CloudRuntimeException e) {
cleanupFailedImportVM(userVm);
throw e;
}
if (!checkVolumeAnswer.getResult()) {
cleanupFailedImportVM(userVm);
throw new CloudRuntimeException("Disk not found or is invalid");
}
diskProfile.setSize(checkVolumeAnswer.getSize());
CheckedReservation primaryStorageReservation = new CheckedReservation(owner, Resource.ResourceType.primary_storage, resourceLimitStorageTags,
CollectionUtils.isNotEmpty(resourceLimitStorageTags) ? diskProfile.getSize() : 0L, reservationDao, resourceLimitService);
reservations.add(primaryStorageReservation);
List<Pair<DiskProfile, StoragePool>> diskProfileStoragePoolList = new ArrayList<>();
try {
long deviceId = 1L;
if(ImportSource.SHARED == importSource) {
diskProfileStoragePoolList.add(importKVMSharedDisk(userVm, diskOffering, Volume.Type.ROOT,
template, deviceId, poolId, diskPath, diskProfile));
} else if(ImportSource.LOCAL == importSource) {
diskProfileStoragePoolList.add(importKVMLocalDisk(userVm, diskOffering, Volume.Type.ROOT,
template, deviceId, hostId, diskPath, diskProfile));
}
} catch (Exception e) {
logger.error(String.format("Failed to import volumes while importing vm: %s", instanceName), e);
cleanupFailedImportVM(userVm);
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Failed to import volumes while importing vm: %s. %s", instanceName, StringUtils.defaultString(e.getMessage())));
}
networkOrchestrationService.importNic(macAddress, 0, network, true, userVm, requestedIpPair, zone, true);
publishVMUsageUpdateResourceCount(userVm, dummyOffering, template);
return userVm;
} catch (InsufficientCapacityException ice) { // This will be thrown by com.cloud.vm.UserVmService.importVM
logger.error(String.format("Failed to import vm name: %s", instanceName), ice);
throw new ServerApiException(ApiErrorCode.INSUFFICIENT_CAPACITY_ERROR, ice.getMessage());
}
if (userVm == null) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Failed to import vm name: %s", instanceName));
}
DiskOfferingVO diskOffering = diskOfferingDao.findById(serviceOffering.getDiskOfferingId());
List<Reserver> reservations = new ArrayList<>();
List<String> resourceLimitStorageTags = resourceLimitService.getResourceLimitStorageTagsForResourceCountOperation(true, diskOffering);
try {
CheckedReservation volumeReservation = new CheckedReservation(owner, Resource.ResourceType.volume, resourceLimitStorageTags,
CollectionUtils.isNotEmpty(resourceLimitStorageTags) ? 1L : 0L, reservationDao, resourceLimitService);
reservations.add(volumeReservation);
String rootVolumeName = String.format("ROOT-%s", userVm.getId());
DiskProfile diskProfile = volumeManager.allocateRawVolume(Volume.Type.ROOT, rootVolumeName, diskOffering, null, null, null, userVm, template, owner, null, false);
final VirtualMachineProfile profile = new VirtualMachineProfileImpl(userVm, template, serviceOffering, owner, null);
ServiceOfferingVO dummyOffering = serviceOfferingDao.findById(userVm.getId(), serviceOffering.getId());
profile.setServiceOffering(dummyOffering);
DeploymentPlanner.ExcludeList excludeList = new DeploymentPlanner.ExcludeList();
final DataCenterDeployment plan = new DataCenterDeployment(zone.getId(), null, null, hostId, poolId, null);
DeployDestination dest = null;
try {
dest = deploymentPlanningManager.planDeployment(profile, plan, excludeList, null);
} catch (Exception e) {
logger.warn("Import failed for Vm: {} while finding deployment destination", userVm, e);
cleanupFailedImportVM(userVm);
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Import failed for Vm: %s while finding deployment destination", userVm.getInstanceName()));
}
if(dest == null) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Import failed for Vm: %s. Suitable deployment destination not found", userVm.getInstanceName()));
}
Map<Volume, StoragePool> storage = dest.getStorageForDisks();
Volume volume = volumeDao.findById(diskProfile.getVolumeId());
StoragePool storagePool = storage.get(volume);
CheckVolumeCommand checkVolumeCommand = new CheckVolumeCommand();
checkVolumeCommand.setSrcFile(diskPath);
StorageFilerTO storageTO = new StorageFilerTO(storagePool);
checkVolumeCommand.setStorageFilerTO(storageTO);
Answer answer = agentManager.easySend(dest.getHost().getId(), checkVolumeCommand);
if (!(answer instanceof CheckVolumeAnswer)) {
cleanupFailedImportVM(userVm);
throw new CloudRuntimeException("Disk not found or is invalid");
}
CheckVolumeAnswer checkVolumeAnswer = (CheckVolumeAnswer) answer;
try {
checkVolume(checkVolumeAnswer.getVolumeDetails());
} catch (CloudRuntimeException e) {
} catch (ResourceAllocationException e) {
cleanupFailedImportVM(userVm);
throw e;
}
if (!checkVolumeAnswer.getResult()) {
cleanupFailedImportVM(userVm);
throw new CloudRuntimeException("Disk not found or is invalid");
}
diskProfile.setSize(checkVolumeAnswer.getSize());
CheckedReservation primaryStorageReservation = new CheckedReservation(owner, Resource.ResourceType.primary_storage, resourceLimitStorageTags,
CollectionUtils.isNotEmpty(resourceLimitStorageTags) ? diskProfile.getSize() : 0L, reservationDao, resourceLimitService);
reservations.add(primaryStorageReservation);
List<Pair<DiskProfile, StoragePool>> diskProfileStoragePoolList = new ArrayList<>();
try {
long deviceId = 1L;
if(ImportSource.SHARED == importSource) {
diskProfileStoragePoolList.add(importKVMSharedDisk(userVm, diskOffering, Volume.Type.ROOT,
template, deviceId, poolId, diskPath, diskProfile));
} else if(ImportSource.LOCAL == importSource) {
diskProfileStoragePoolList.add(importKVMLocalDisk(userVm, diskOffering, Volume.Type.ROOT,
template, deviceId, hostId, diskPath, diskProfile));
}
} catch (Exception e) {
logger.error(String.format("Failed to import volumes while importing vm: %s", instanceName), e);
cleanupFailedImportVM(userVm);
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Failed to import volumes while importing vm: %s. %s", instanceName, StringUtils.defaultString(e.getMessage())));
}
networkOrchestrationService.importNic(macAddress, 0, network, true, userVm, requestedIpPair, zone, true);
publishVMUsageUpdateResourceCount(userVm, dummyOffering, template);
return userVm;
} finally {
ReservationHelper.closeAll(reservations);
}
}
protected void checkVmResourceLimitsForExternalKvmVmImport(Account owner, ServiceOfferingVO serviceOffering, VMTemplateVO template, Map<String, String> details, List<Reserver> reservations) throws ResourceAllocationException {
// When importing an external VM, the amount of CPUs and memory is always obtained from the compute offering,
// unlike the unmanaged instance import that obtains it from the hypervisor unless the VM is powered off and the offering is fixed
Integer cpu = serviceOffering.getCpu();
Integer memory = serviceOffering.getRamSize();
if (serviceOffering.isDynamic()) {
cpu = getDetailAsInteger(VmDetailConstants.CPU_NUMBER, details);
memory = getDetailAsInteger(VmDetailConstants.MEMORY, details);
}
List<String> resourceLimitHostTags = resourceLimitService.getResourceLimitHostTags(serviceOffering, template);
CheckedReservation vmReservation = new CheckedReservation(owner, Resource.ResourceType.user_vm, resourceLimitHostTags, 1L, reservationDao, resourceLimitService);
reservations.add(vmReservation);
CheckedReservation cpuReservation = new CheckedReservation(owner, Resource.ResourceType.cpu, resourceLimitHostTags, cpu.longValue(), reservationDao, resourceLimitService);
reservations.add(cpuReservation);
CheckedReservation memReservation = new CheckedReservation(owner, Resource.ResourceType.memory, resourceLimitHostTags, memory.longValue(), reservationDao, resourceLimitService);
reservations.add(memReservation);
}
protected Integer getDetailAsInteger(String key, Map<String, String> details) {
String detail = details.get(key);
if (detail == null) {
throw new InvalidParameterValueException(String.format("Detail '%s' must be provided.", key));
}
try {
return Integer.valueOf(detail);
} catch (NumberFormatException e) {
throw new InvalidParameterValueException(String.format("Please provide a valid integer value for detail '%s'.", key));
}
}
private void checkVolume(Map<VolumeOnStorageTO.Detail, String> volumeDetails) {
if (MapUtils.isEmpty(volumeDetails)) {
return;

View File

@ -16,6 +16,25 @@
// under the License.
package com.cloud.hypervisor;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.framework.config.ConfigKey;
import org.apache.cloudstack.utils.bytescale.ByteScaleUtils;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnitRunner;
import com.cloud.agent.api.to.NicTO;
import com.cloud.agent.api.to.VirtualMachineTO;
import com.cloud.configuration.ConfigurationManagerImpl;
@ -34,23 +53,6 @@ import com.cloud.storage.dao.GuestOSHypervisorDao;
import com.cloud.utils.Pair;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachineProfile;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.framework.config.ConfigKey;
import org.apache.cloudstack.utils.bytescale.ByteScaleUtils;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnitRunner;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@RunWith(MockitoJUnitRunner.class)
public class KVMGuruTest {
@ -111,8 +113,15 @@ public class KVMGuruTest {
private static final String detail2Key = "detail2";
private static final String detail2Value = "value2";
private ConfigKey<Integer> originalVmServiceOfferingMaxCpuCores;
private ConfigKey<Integer> originalVmServiceOfferingMaxRAMSize;
@Before
public void setup() throws UnsupportedEncodingException {
// Preserve the original value for restoration in tearDown
originalVmServiceOfferingMaxCpuCores = ConfigurationManagerImpl.VM_SERVICE_OFFERING_MAX_CPU_CORES;
originalVmServiceOfferingMaxRAMSize = ConfigurationManagerImpl.VM_SERVICE_OFFERING_MAX_RAM_SIZE;
Mockito.when(vmTO.isLimitCpuUse()).thenReturn(true);
Mockito.when(vmProfile.getVirtualMachine()).thenReturn(vm);
Mockito.when(vm.getHostId()).thenReturn(hostId);
@ -134,6 +143,13 @@ public class KVMGuruTest {
Arrays.asList(detail1, detail2));
}
@After
public void tearDown() {
// Restore the original value
ConfigurationManagerImpl.VM_SERVICE_OFFERING_MAX_CPU_CORES = originalVmServiceOfferingMaxCpuCores;
ConfigurationManagerImpl.VM_SERVICE_OFFERING_MAX_RAM_SIZE = originalVmServiceOfferingMaxRAMSize;
}
@Test
public void testSetVmQuotaPercentage() {
guru.setVmQuotaPercentage(vmTO, vmProfile);

View File

@ -554,6 +554,7 @@ public class VpcManagerImplTest {
doReturn(ipv4GuestSubnetNetworkMap).when(routedIpv4Manager).getOrCreateIpv4SubnetForVpc(any(), anyInt());
List<Long> bgpPeerIds = Arrays.asList(11L, 12L);
try (MockedConstruction<CheckedReservation> mockCheckedReservation = Mockito.mockConstruction(CheckedReservation.class)) {
manager.createVpc(zoneId, vpcOfferingId, vpcOwnerId, vpcName, vpcName, null, vpcDomain,
ip4Dns[0], ip4Dns[1], null, null, true, 1500, 24, null, bgpPeerIds, false);
} catch (ResourceAllocationException e) {

View File

@ -107,8 +107,8 @@ import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
import org.apache.cloudstack.storage.heuristics.HeuristicRuleHelper;
import org.apache.cloudstack.storage.template.VnfTemplateManager;
import org.apache.cloudstack.test.utils.SpringUtils;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;

View File

@ -59,20 +59,12 @@ import java.util.Map;
import java.util.TimeZone;
import java.util.UUID;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockedConstruction;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.test.util.ReflectionTestUtils;
import com.cloud.network.as.AutoScaleManager;
import com.cloud.network.dao.FirewallRulesDao;
import com.cloud.network.dao.IPAddressDao;
import com.cloud.network.dao.IPAddressVO;
import com.cloud.network.dao.LoadBalancerVMMapDao;
import com.cloud.network.dao.LoadBalancerVMMapVO;
import org.apache.cloudstack.acl.ControlledEntity;
import org.apache.cloudstack.acl.SecurityChecker;
import org.apache.cloudstack.api.ApiCommandResourceType;
@ -107,6 +99,19 @@ import org.apache.cloudstack.storage.template.VnfTemplateManager;
import org.apache.cloudstack.userdata.UserDataManager;
import org.apache.cloudstack.vm.UnmanagedVMsManager;
import org.apache.cloudstack.vm.lease.VMLeaseManager;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockedConstruction;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.test.util.ReflectionTestUtils;
import com.cloud.api.query.dao.ServiceOfferingJoinDao;
import com.cloud.api.query.vo.ServiceOfferingJoinVO;
@ -136,12 +141,6 @@ import com.cloud.hypervisor.Hypervisor;
import com.cloud.kubernetes.cluster.KubernetesServiceHelper;
import com.cloud.network.Network;
import com.cloud.network.NetworkModel;
import com.cloud.network.as.AutoScaleManager;
import com.cloud.network.dao.FirewallRulesDao;
import com.cloud.network.dao.IPAddressDao;
import com.cloud.network.dao.IPAddressVO;
import com.cloud.network.dao.LoadBalancerVMMapDao;
import com.cloud.network.dao.LoadBalancerVMMapVO;
import com.cloud.network.dao.NetworkDao;
import com.cloud.network.dao.NetworkVO;
import com.cloud.network.element.UserDataServiceProvider;
@ -162,6 +161,7 @@ import com.cloud.resourcelimit.CheckedReservation;
import com.cloud.server.ManagementService;
import com.cloud.service.ServiceOfferingVO;
import com.cloud.service.dao.ServiceOfferingDao;
import com.cloud.service.dao.ServiceOfferingDetailsDao;
import com.cloud.storage.DiskOfferingVO;
import com.cloud.storage.GuestOSVO;
import com.cloud.storage.ScopeType;
@ -452,6 +452,9 @@ public class UserVmManagerImplTest {
MockedStatic<UnmanagedVMsManager> unmanagedVMsManagerMockedStatic;
@Mock
ServiceOfferingDetailsDao serviceOfferingDetailsDao;
private static final long vmId = 1l;
private static final long zoneId = 2L;
private static final long accountId = 3L;
@ -4224,4 +4227,96 @@ public class UserVmManagerImplTest {
method.setAccessible(true);
method.invoke(userVmManagerImpl, vmId);
}
private ServiceOfferingVO getMockedServiceOffering(boolean custom, boolean customSpeed) {
ServiceOfferingVO serviceOffering = mock(ServiceOfferingVO.class);
when(serviceOffering.getUuid()).thenReturn("offering-uuid");
when(serviceOffering.isDynamic()).thenReturn(custom);
when(serviceOffering.isCustomCpuSpeedSupported()).thenReturn(customSpeed);
if (custom) {
when(serviceOffering.getCpu()).thenReturn(null);
when(serviceOffering.getRamSize()).thenReturn(null);
}
if (customSpeed) {
when(serviceOffering.getSpeed()).thenReturn(null);
} else {
when(serviceOffering.isCustomCpuSpeedSupported()).thenReturn(false);
when(serviceOffering.getSpeed()).thenReturn(1000);
}
return serviceOffering;
}
@Test
public void customOfferingNeedsCustomizationThrowsException() {
ServiceOfferingVO serviceOffering = getMockedServiceOffering(true, true);
InvalidParameterValueException ex = Assert.assertThrows(InvalidParameterValueException.class, () ->
userVmManagerImpl.validateCustomParameters(serviceOffering, Collections.emptyMap()));
assertEquals("Need to specify custom parameter values cpu, cpu speed and memory when using custom offering", ex.getMessage());
}
@Test
public void cpuSpeedCustomizationNotAllowedThrowsException() {
ServiceOfferingVO serviceOffering = getMockedServiceOffering(true, false);
Map<String, String> customParameters = new HashMap<>();
customParameters.put(VmDetailConstants.CPU_NUMBER, "1");
customParameters.put(VmDetailConstants.CPU_SPEED, "2500");
InvalidParameterValueException ex = Assert.assertThrows(InvalidParameterValueException.class, () ->
userVmManagerImpl.validateCustomParameters(serviceOffering, customParameters));
Assert.assertTrue(ex.getMessage().startsWith("The CPU speed of this offering"));
}
@Test
public void cpuSpeedCustomizationAllowedDoesNotThrowException() {
ServiceOfferingVO serviceOffering = getMockedServiceOffering(true, true);
when(serviceOfferingDetailsDao.listDetailsKeyPairs(anyLong())).thenReturn(
Map.of(ApiConstants.MIN_CPU_NUMBER, "1",
ApiConstants.MAX_CPU_NUMBER, "4",
ApiConstants.MIN_MEMORY, "256",
ApiConstants.MAX_MEMORY, "8192"));
Map<String, String> customParameters = new HashMap<>();
customParameters.put(VmDetailConstants.CPU_NUMBER, "1");
customParameters.put(VmDetailConstants.CPU_SPEED, "2500");
customParameters.put(VmDetailConstants.MEMORY, "256");
userVmManagerImpl.validateCustomParameters(serviceOffering, customParameters);
}
@Test
public void verifyVmLimits_fixedOffering_throwsException() {
when(userVmVoMock.getId()).thenReturn(1L);
when(userVmVoMock.getServiceOfferingId()).thenReturn(1L);
when(accountDao.findById(anyLong())).thenReturn(callerAccount);
ServiceOfferingVO serviceOffering = getMockedServiceOffering(false, false);
when(_serviceOfferingDao.findById(anyLong())).thenReturn(serviceOffering);
when(_serviceOfferingDao.findByIdIncludingRemoved(anyLong(), anyLong())).thenReturn(serviceOffering);
Map<String, String> customParameters = new HashMap<>();
customParameters.put(VmDetailConstants.CPU_SPEED, "2500");
InvalidParameterValueException ex = Assert.assertThrows(InvalidParameterValueException.class, () ->
userVmManagerImpl.verifyVmLimits(userVmVoMock, customParameters));
assertEquals("CPU number, Memory and CPU speed cannot be updated for a non-dynamic offering", ex.getMessage());
}
@Test
public void verifyVmLimits_constrainedOffering_throwsException() {
when(userVmVoMock.getId()).thenReturn(1L);
when(userVmVoMock.getServiceOfferingId()).thenReturn(1L);
when(accountDao.findById(anyLong())).thenReturn(callerAccount);
ServiceOfferingVO serviceOffering = getMockedServiceOffering(true, false);
when(_serviceOfferingDao.findById(anyLong())).thenReturn(serviceOffering);
when(_serviceOfferingDao.findByIdIncludingRemoved(anyLong(), anyLong())).thenReturn(serviceOffering);
Map<String, String> customParameters = new HashMap<>();
customParameters.put(VmDetailConstants.CPU_NUMBER, "1");
customParameters.put(VmDetailConstants.CPU_SPEED, "2500");
InvalidParameterValueException ex = Assert.assertThrows(InvalidParameterValueException.class, () ->
userVmManagerImpl.verifyVmLimits(userVmVoMock, customParameters));
Assert.assertTrue(ex.getMessage().startsWith("The CPU speed of this offering"));
}
}

View File

@ -228,6 +228,7 @@ public class VMSnapshotManagerTest {
when(vmSnapshotVO.getId()).thenReturn(VM_SNAPSHOT_ID);
when(serviceOffering.isDynamic()).thenReturn(false);
when(_serviceOfferingDao.findById(SERVICE_OFFERING_ID)).thenReturn(serviceOffering);
when(_serviceOfferingDao.findByIdIncludingRemoved(TEST_VM_ID, SERVICE_OFFERING_ID)).thenReturn(serviceOffering);
for (ResourceDetail detail : Arrays.asList(userVmDetailCpuNumber, vmSnapshotDetailCpuNumber)) {
when(detail.getName()).thenReturn(VmDetailConstants.CPU_NUMBER);
@ -345,20 +346,51 @@ public class VMSnapshotManagerTest {
}
@Test
public void testUpdateUserVmServiceOfferingSameServiceOffering() {
_vmSnapshotMgr.updateUserVmServiceOffering(userVm, vmSnapshotVO);
verify(_vmSnapshotMgr, never()).changeUserVmServiceOffering(userVm, vmSnapshotVO);
public void testUserVmServiceOfferingNeedsChangeWhenSnapshotOfferingDiffers() {
when(userVm.getServiceOfferingId()).thenReturn(SERVICE_OFFERING_DIFFERENT_ID);
when(vmSnapshotVO.getServiceOfferingId()).thenReturn(SERVICE_OFFERING_ID);
assertTrue(_vmSnapshotMgr.userVmServiceOfferingNeedsChange(userVm, vmSnapshotVO));
verify(_serviceOfferingDao, never()).findByIdIncludingRemoved(anyLong(), anyLong());
verify(_serviceOfferingDao, never()).getComputeOffering(any(ServiceOfferingVO.class), any());
}
@Test
public void testUpdateUserVmServiceOfferingDifferentServiceOffering() throws ConcurrentOperationException, ResourceUnavailableException, ManagementServerException, VirtualMachineMigrationException {
when(userVm.getServiceOfferingId()).thenReturn(SERVICE_OFFERING_DIFFERENT_ID);
when(_userVmManager.upgradeVirtualMachine(eq(TEST_VM_ID), eq(SERVICE_OFFERING_ID), mapDetailsCaptor.capture())).thenReturn(true);
_vmSnapshotMgr.updateUserVmServiceOffering(userVm, vmSnapshotVO);
public void testUserVmServiceOfferingNeedsChangeWhenSameNonDynamicOffering() {
assertFalse(_vmSnapshotMgr.userVmServiceOfferingNeedsChange(userVm, vmSnapshotVO));
verify(_vmSnapshotMgr).changeUserVmServiceOffering(userVm, vmSnapshotVO);
verify(_serviceOfferingDao).findByIdIncludingRemoved(TEST_VM_ID, SERVICE_OFFERING_ID);
verify(_serviceOfferingDao, never()).getComputeOffering(any(ServiceOfferingVO.class), any());
}
@Test
public void testUserVmServiceOfferingNeedsChangeWhenDynamicOfferingMatchesSnapshot() {
when(serviceOffering.isDynamic()).thenReturn(true);
when(serviceOffering.getCpu()).thenReturn(2);
when(serviceOffering.getRamSize()).thenReturn(2048);
when(serviceOffering.getSpeed()).thenReturn(1000);
when(_serviceOfferingDao.getComputeOffering(eq(serviceOffering), any())).thenReturn(serviceOffering);
assertFalse(_vmSnapshotMgr.userVmServiceOfferingNeedsChange(userVm, vmSnapshotVO));
verify(_serviceOfferingDao).getComputeOffering(eq(serviceOffering), any());
verify(_vmSnapshotMgr).getVmMapDetails(vmSnapshotVO);
verify(_vmSnapshotMgr).upgradeUserVmServiceOffering(eq(userVm), eq(SERVICE_OFFERING_ID), mapDetailsCaptor.capture());
}
@Test
public void testUserVmServiceOfferingNeedsChangeWhenDynamicCpuDiffersFromSnapshot() {
when(serviceOffering.isDynamic()).thenReturn(true);
when(serviceOffering.getCpu()).thenReturn(2);
when(serviceOffering.getRamSize()).thenReturn(2048);
when(serviceOffering.getSpeed()).thenReturn(1000);
ServiceOfferingVO fromSnapshot = mock(ServiceOfferingVO.class);
when(fromSnapshot.getCpu()).thenReturn(4);
when(fromSnapshot.getRamSize()).thenReturn(2048);
when(fromSnapshot.getSpeed()).thenReturn(1000);
when(_serviceOfferingDao.getComputeOffering(eq(serviceOffering), any())).thenReturn(fromSnapshot);
assertTrue(_vmSnapshotMgr.userVmServiceOfferingNeedsChange(userVm, vmSnapshotVO));
}
@Test

View File

@ -39,22 +39,6 @@ import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.jetbrains.annotations.NotNull;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.BDDMockito;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockedConstruction;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnitRunner;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ResponseGenerator;
import org.apache.cloudstack.api.ResponseObject;
@ -73,10 +57,26 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
import org.apache.cloudstack.framework.config.ConfigKey;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.cloudstack.resourcelimit.Reserver;
import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
import org.jetbrains.annotations.NotNull;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.BDDMockito;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockedConstruction;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnitRunner;
import com.cloud.agent.AgentManager;
import com.cloud.agent.api.Answer;
@ -110,6 +110,7 @@ import com.cloud.exception.AgentUnavailableException;
import com.cloud.exception.InsufficientServerCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.OperationTimedoutException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.exception.UnsupportedServiceException;
import com.cloud.host.Host;
@ -182,7 +183,7 @@ public class UnmanagedVMsManagerImplTest {
@Spy
@InjectMocks
private UnmanagedVMsManagerImpl unmanagedVMsManager = new UnmanagedVMsManagerImpl();
private UnmanagedVMsManagerImpl unmanagedVMsManager;
@Mock
private UserVmManager userVmManager;
@ -264,6 +265,14 @@ public class UnmanagedVMsManagerImplTest {
private ConfigKey<Boolean> configKeyMockParamsAllowed;
@Mock
private ConfigKey<String> configKeyMockParamsAllowedList;
@Mock
private Account accountMock;
@Mock
private ServiceOfferingVO serviceOfferingMock;
@Mock
private VMTemplateVO templateMock;
@Mock
private UnmanagedInstanceTO unmanagedInstanceMock;
private static final long virtualMachineId = 1L;
@ -390,6 +399,11 @@ public class UnmanagedVMsManagerImplTest {
when(vmDao.findById(virtualMachineId)).thenReturn(virtualMachine);
when(virtualMachine.getState()).thenReturn(VirtualMachine.State.Running);
when(unmanagedInstanceMock.getCpuCores()).thenReturn(8);
when(unmanagedInstanceMock.getMemory()).thenReturn(4096);
when(serviceOfferingMock.getCpu()).thenReturn(4);
when(serviceOfferingMock.getRamSize()).thenReturn(2048);
}
@NotNull
@ -467,7 +481,9 @@ public class UnmanagedVMsManagerImplTest {
ImportUnmanagedInstanceCmd importUnmanageInstanceCmd = Mockito.mock(ImportUnmanagedInstanceCmd.class);
when(importUnmanageInstanceCmd.getName()).thenReturn("SomeInstance");
when(importUnmanageInstanceCmd.getDomainId()).thenReturn(null);
unmanagedVMsManager.importUnmanagedInstance(importUnmanageInstanceCmd);
try (MockedConstruction<CheckedReservation> mockCheckedReservation = Mockito.mockConstruction(CheckedReservation.class)) {
unmanagedVMsManager.importUnmanagedInstance(importUnmanageInstanceCmd);
}
}
@Test(expected = InvalidParameterValueException.class)
@ -1496,4 +1512,102 @@ public class UnmanagedVMsManagerImplTest {
Assert.assertFalse(params.containsKey(VmDetailConstants.CPU_SPEED));
Assert.assertFalse(params.containsKey(VmDetailConstants.MEMORY));
}
@Test
public void checkVmResourceLimitsForUnmanagedInstanceImportTestUsesInformationFromHypervisorWhenOfferingIsDynamic() throws Exception {
when(serviceOfferingMock.isDynamic()).thenReturn(true);
List<Reserver> reservations = new ArrayList<>();
try (MockedConstruction<CheckedReservation> mockedConstruction = Mockito.mockConstruction(CheckedReservation.class)) {
unmanagedVMsManager.checkVmResourceLimitsForUnmanagedInstanceImport(accountMock, unmanagedInstanceMock, serviceOfferingMock, templateMock, reservations);
Assert.assertEquals(3, mockedConstruction.constructed().size());
Assert.assertEquals(3, reservations.size());
verify(unmanagedInstanceMock).getCpuCores();
verify(unmanagedInstanceMock).getMemory();
}
}
@Test
public void checkVmResourceLimitsForUnmanagedInstanceImportTestUsesInformationFromHypervisorWhenVmIsPoweredOn() throws Exception {
when(unmanagedInstanceMock.getPowerState()).thenReturn(UnmanagedInstanceTO.PowerState.PowerOn);
when(serviceOfferingMock.isDynamic()).thenReturn(false);
List<Reserver> reservations = new ArrayList<>();
try (MockedConstruction<CheckedReservation> mockedConstruction = Mockito.mockConstruction(CheckedReservation.class)) {
unmanagedVMsManager.checkVmResourceLimitsForUnmanagedInstanceImport(accountMock, unmanagedInstanceMock, serviceOfferingMock, templateMock, reservations);
Assert.assertEquals(3, mockedConstruction.constructed().size());
Assert.assertEquals(3, reservations.size());
verify(unmanagedInstanceMock).getCpuCores();
verify(unmanagedInstanceMock).getMemory();
}
}
@Test
public void checkVmResourceLimitsForUnmanagedInstanceImportTestUsesInformationFromOfferingWhenOfferingIsNotDynamicAndVmIsPoweredOff() throws Exception {
when(unmanagedInstanceMock.getPowerState()).thenReturn(UnmanagedInstanceTO.PowerState.PowerOff);
when(serviceOfferingMock.isDynamic()).thenReturn(false);
List<Reserver> reservations = new ArrayList<>();
try (MockedConstruction<CheckedReservation> mockedConstruction = Mockito.mockConstruction(CheckedReservation.class)) {
unmanagedVMsManager.checkVmResourceLimitsForUnmanagedInstanceImport(accountMock, unmanagedInstanceMock, serviceOfferingMock, templateMock, reservations);
Assert.assertEquals(3, mockedConstruction.constructed().size());
Assert.assertEquals(3, reservations.size());
verify(serviceOfferingMock).getCpu();
verify(serviceOfferingMock).getRamSize();
verify(unmanagedInstanceMock, Mockito.never()).getCpuCores();
verify(unmanagedInstanceMock, Mockito.never()).getMemory();
}
}
@Test
public void checkVmResourceLimitsForExternalKvmVmImportTestUsesInformationFromOfferingWhenOfferingIsNotDynamic() throws ResourceAllocationException {
when(serviceOfferingMock.isDynamic()).thenReturn(false);
Map<String, String> details = new HashMap<>();
List<Reserver> reservations = new ArrayList<>();
try (MockedConstruction<CheckedReservation> mockedConstruction = Mockito.mockConstruction(CheckedReservation.class)) {
unmanagedVMsManager.checkVmResourceLimitsForExternalKvmVmImport(accountMock, serviceOfferingMock, templateMock, details, reservations);
Assert.assertEquals(3, mockedConstruction.constructed().size());
Assert.assertEquals(3, reservations.size());
verify(serviceOfferingMock).getCpu();
verify(serviceOfferingMock).getRamSize();
verify(unmanagedVMsManager, Mockito.never()).getDetailAsInteger(VmDetailConstants.CPU_NUMBER, details);
verify(unmanagedVMsManager, Mockito.never()).getDetailAsInteger(VmDetailConstants.MEMORY, details);
}
}
@Test
public void checkVmResourceLimitsForExternalKvmVmImportTestUsesInformationFromDetailsWhenOfferingIsDynamic() throws ResourceAllocationException {
when(serviceOfferingMock.isDynamic()).thenReturn(true);
Map<String, String> details = new HashMap<>();
details.put(VmDetailConstants.CPU_NUMBER, "8");
details.put(VmDetailConstants.MEMORY, "4096");
List<Reserver> reservations = new ArrayList<>();
try (MockedConstruction<CheckedReservation> mockedConstruction = Mockito.mockConstruction(CheckedReservation.class)) {
unmanagedVMsManager.checkVmResourceLimitsForExternalKvmVmImport(accountMock, serviceOfferingMock, templateMock, details, reservations);
Assert.assertEquals(3, mockedConstruction.constructed().size());
Assert.assertEquals(3, reservations.size());
verify(unmanagedVMsManager).getDetailAsInteger(VmDetailConstants.CPU_NUMBER, details);
verify(unmanagedVMsManager).getDetailAsInteger(VmDetailConstants.MEMORY, details);
}
}
@Test(expected = InvalidParameterValueException.class)
public void getDetailAsIntegerTestThrowsInvalidParameterValueExceptionWhenDetailIsNull() {
Map<String, String> details = new HashMap<>();
unmanagedVMsManager.getDetailAsInteger("non-existent", details);
}
@Test(expected = InvalidParameterValueException.class)
public void getDetailAsIntegerTestThrowsInvalidParameterValueExceptionWhenValueIsInvalid() {
Map<String, String> details = new HashMap<>();
details.put("key", "not-a-number");
unmanagedVMsManager.getDetailAsInteger("key", details);
}
}

View File

@ -244,6 +244,8 @@ class CsNetfilters(object):
CsHelper.execute("nft add chain %s %s %s '{ %s }'" % (address_family, table, chain, chain_policy))
if hook == "input" or hook == "output":
CsHelper.execute("nft add rule %s %s %s icmp type { echo-request, echo-reply } accept" % (address_family, table, chain))
elif hook == "forward":
CsHelper.execute("nft add rule %s %s %s ct state established,related accept" % (address_family, table, chain))
def apply_nft_ipv4_rules(self, rules, type):
if len(rules) == 0:

View File

@ -398,141 +398,146 @@ class TestRvRDeploymentPlanning(cloudstackTestCase):
self.apiclient.updatePod(cmd)
self.debug("Enabled first pod for testing..")
# Creating network using the network offering created
self.debug("Creating network with network offering: %s" %
self.network_offering.id)
network = Network.create(
self.apiclient,
self.services["network"],
accountid=self.account.name,
domainid=self.account.domainid,
networkofferingid=self.network_offering.id,
zoneid=self.zone.id
)
self.debug("Created network with ID: %s" % network.id)
try:
# Creating network using the network offering created
self.debug("Creating network with network offering: %s" %
self.network_offering.id)
network = Network.create(
self.apiclient,
self.services["network"],
accountid=self.account.name,
domainid=self.account.domainid,
networkofferingid=self.network_offering.id,
zoneid=self.zone.id
)
self.debug("Created network with ID: %s" % network.id)
networks = Network.list(
self.apiclient,
id=network.id,
listall=True
)
self.assertEqual(
isinstance(networks, list),
True,
"List networks should return a valid response for created network"
)
nw_response = networks[0]
networks = Network.list(
self.apiclient,
id=network.id,
listall=True
)
self.assertEqual(
isinstance(networks, list),
True,
"List networks should return a valid response for created network"
)
nw_response = networks[0]
self.debug("Network state: %s" % nw_response.state)
self.assertEqual(
nw_response.state,
"Allocated",
"The network should be in allocated state after creation"
)
self.debug("Listing routers for network: %s" % network.name)
routers = Router.list(
self.apiclient,
networkid=network.id,
listall=True
)
self.assertEqual(
routers,
None,
"Routers should not be spawned when network is in allocated state"
)
self.debug("Deploying VM in account: %s" % self.account.name)
# Spawn an instance in that network
virtual_machine = VirtualMachine.create(
self.apiclient,
self.services["virtual_machine"],
accountid=self.account.name,
domainid=self.account.domainid,
serviceofferingid=self.service_offering.id,
networkids=[str(network.id)]
)
self.debug("Deployed VM in network: %s" % network.id)
vms = VirtualMachine.list(
self.apiclient,
id=virtual_machine.id,
listall=True
)
self.assertEqual(
isinstance(vms, list),
True,
"List Vms should return a valid list"
)
vm = vms[0]
self.assertEqual(
vm.state,
"Running",
"Vm should be in running state after deployment"
)
self.debug("Listing routers for network: %s" % network.name)
routers = Router.list(
self.apiclient,
networkid=network.id,
listall=True
)
self.assertEqual(
isinstance(routers, list),
True,
"list router should return Primary and backup routers"
)
self.assertEqual(
len(routers),
2,
"Length of the list router should be 2 (Backup & Primary)"
)
hosts = Host.list(
self.apiclient,
id=routers[0].hostid,
listall=True
)
self.assertEqual(
isinstance(hosts, list),
True,
"List host should return a valid data"
)
first_host = hosts[0]
hosts = Host.list(
self.apiclient,
id=routers[1].hostid,
listall=True
)
self.assertEqual(
isinstance(hosts, list),
True,
"List host should return a valid data"
)
second_host = hosts[0]
# Checking if the cluster IDs of both routers are different?
self.assertNotEqual(
first_host.clusterid,
second_host.clusterid,
"Both the routers should be in different clusters"
)
self.debug("Enabling remaining pods if any..")
pods = Pod.list(
self.apiclient,
zoneid=self.zone.id,
listall=True,
allocationstate="Disabled"
self.debug("Network state: %s" % nw_response.state)
self.assertEqual(
nw_response.state,
"Allocated",
"The network should be in allocated state after creation"
)
if pods is not None:
for pod in pods:
cmd = updatePod.updatePodCmd()
cmd.id = pod.id
cmd.allocationstate = 'Enabled'
self.apiclient.updatePod(cmd)
self.debug("Listing routers for network: %s" % network.name)
routers = Router.list(
self.apiclient,
networkid=network.id,
listall=True
)
self.assertEqual(
routers,
None,
"Routers should not be spawned when network is in allocated state"
)
self.debug("Deploying VM in account: %s" % self.account.name)
# Spawn an instance in that network
virtual_machine = VirtualMachine.create(
self.apiclient,
self.services["virtual_machine"],
accountid=self.account.name,
domainid=self.account.domainid,
serviceofferingid=self.service_offering.id,
networkids=[str(network.id)]
)
self.debug("Deployed VM in network: %s" % network.id)
vms = VirtualMachine.list(
self.apiclient,
id=virtual_machine.id,
listall=True
)
self.assertEqual(
isinstance(vms, list),
True,
"List Vms should return a valid list"
)
vm = vms[0]
self.assertEqual(
vm.state,
"Running",
"Vm should be in running state after deployment"
)
self.debug("Listing routers for network: %s" % network.name)
routers = Router.list(
self.apiclient,
networkid=network.id,
listall=True
)
self.assertEqual(
isinstance(routers, list),
True,
"list router should return Primary and backup routers"
)
self.assertEqual(
len(routers),
2,
"Length of the list router should be 2 (Backup & Primary)"
)
hosts = Host.list(
self.apiclient,
id=routers[0].hostid,
listall=True
)
self.assertEqual(
isinstance(hosts, list),
True,
"List host should return a valid data"
)
first_host = hosts[0]
hosts = Host.list(
self.apiclient,
id=routers[1].hostid,
listall=True
)
self.assertEqual(
isinstance(hosts, list),
True,
"List host should return a valid data"
)
second_host = hosts[0]
# Checking if the cluster IDs of both routers are different?
self.assertNotEqual(
first_host.clusterid,
second_host.clusterid,
"Both the routers should be in different clusters"
)
finally:
try:
self.debug("Enabling remaining pods if any..")
pods = Pod.list(
self.apiclient,
zoneid=self.zone.id,
listall=True,
allocationstate="Disabled"
)
if pods is not None:
for pod in pods:
cmd = updatePod.updatePodCmd()
cmd.id = pod.id
cmd.allocationstate = 'Enabled'
self.apiclient.updatePod(cmd)
except Exception as e:
self.debug("Warning: Exception during pod re-enablement: %s" % e)
return
# @attr(tags=["advanced", "advancedns"])
@ -557,7 +562,7 @@ class TestRvRDeploymentPlanning(cloudstackTestCase):
# 3. VM should be deployed and in Running state and on the specified
# host
# 4. There should be two routers (PRIMARY and BACKUP) for this network
# ensure both routers should be on different storage pools
# ensure both routers should be on different hosts
self.debug(
"Checking if the current zone has multiple active pods in it..")
@ -636,144 +641,150 @@ class TestRvRDeploymentPlanning(cloudstackTestCase):
self.apiclient.updateCluster(cmd)
self.debug("Enabled first cluster for testing..")
# Creating network using the network offering created
self.debug("Creating network with network offering: %s" %
self.network_offering.id)
network = Network.create(
self.apiclient,
self.services["network"],
accountid=self.account.name,
domainid=self.account.domainid,
networkofferingid=self.network_offering.id,
zoneid=self.zone.id
)
self.debug("Created network with ID: %s" % network.id)
try:
# Creating network using the network offering created
self.debug("Creating network with network offering: %s" %
self.network_offering.id)
network = Network.create(
self.apiclient,
self.services["network"],
accountid=self.account.name,
domainid=self.account.domainid,
networkofferingid=self.network_offering.id,
zoneid=self.zone.id
)
self.debug("Created network with ID: %s" % network.id)
networks = Network.list(
self.apiclient,
id=network.id,
listall=True
)
self.assertEqual(
isinstance(networks, list),
True,
"List networks should return a valid response for created network"
)
nw_response = networks[0]
networks = Network.list(
self.apiclient,
id=network.id,
listall=True
)
self.assertEqual(
isinstance(networks, list),
True,
"List networks should return a valid response for created network"
)
nw_response = networks[0]
self.debug("Network state: %s" % nw_response.state)
self.assertEqual(
nw_response.state,
"Allocated",
"The network should be in allocated state after creation"
)
self.debug("Network state: %s" % nw_response.state)
self.assertEqual(
nw_response.state,
"Allocated",
"The network should be in allocated state after creation"
)
self.debug("Listing routers for network: %s" % network.name)
routers = Router.list(
self.apiclient,
networkid=network.id,
listall=True
)
self.assertEqual(
routers,
None,
"Routers should not be spawned when network is in allocated state"
)
self.debug("Retrieving the list of hosts in the cluster")
hosts = Host.list(
self.apiclient,
clusterid=enabled_cluster.id,
listall=True
)
self.assertEqual(
isinstance(hosts, list),
True,
"List hosts should not return an empty response"
)
host = hosts[0]
self.debug("Deploying VM in account: %s" % self.account.name)
# Spawn an instance in that network
virtual_machine = VirtualMachine.create(
self.debug("Listing routers for network: %s" % network.name)
routers = Router.list(
self.apiclient,
self.services["virtual_machine"],
accountid=self.account.name,
domainid=self.account.domainid,
serviceofferingid=self.service_offering.id,
networkids=[str(network.id)],
hostid=host.id
)
self.debug("Deployed VM in network: %s" % network.id)
vms = VirtualMachine.list(
self.apiclient,
id=virtual_machine.id,
networkid=network.id,
listall=True
)
self.assertEqual(
isinstance(vms, list),
True,
"List Vms should return a valid list"
)
vm = vms[0]
self.assertEqual(
vm.state,
"Running",
"Vm should be in running state after deployment"
)
self.assertEqual(
routers,
None,
"Routers should not be spawned when network is in allocated state"
)
self.debug("Listing routers for network: %s" % network.name)
routers = Router.list(
self.debug("Retrieving the list of hosts in the cluster")
hosts = Host.list(
self.apiclient,
networkid=network.id,
clusterid=enabled_cluster.id,
listall=True
)
self.assertEqual(
isinstance(routers, list),
True,
"list router should return Primary and backup routers"
)
self.assertEqual(
len(routers),
2,
"Length of the list router should be 2 (Backup & Primary)"
)
self.assertNotEqual(
routers[0].hostid,
routers[1].hostid,
"Both the routers should be in different storage pools"
)
self.debug("Enabling remaining pods if any..")
pods = Pod.list(
self.apiclient,
zoneid=self.zone.id,
listall=True,
allocationstate="Disabled"
self.assertEqual(
isinstance(hosts, list),
True,
"List hosts should not return an empty response"
)
host = hosts[0]
self.debug("Deploying VM in account: %s" % self.account.name)
# Spawn an instance in that network
virtual_machine = VirtualMachine.create(
self.apiclient,
self.services["virtual_machine"],
accountid=self.account.name,
domainid=self.account.domainid,
serviceofferingid=self.service_offering.id,
networkids=[str(network.id)],
hostid=host.id
)
self.debug("Deployed VM in network: %s" % network.id)
vms = VirtualMachine.list(
self.apiclient,
id=virtual_machine.id,
listall=True
)
self.assertEqual(
isinstance(vms, list),
True,
"List Vms should return a valid list"
)
vm = vms[0]
self.assertEqual(
vm.state,
"Running",
"Vm should be in running state after deployment"
)
self.debug("Listing routers for network: %s" % network.name)
routers = Router.list(
self.apiclient,
networkid=network.id,
listall=True
)
self.assertEqual(
isinstance(routers, list),
True,
"list router should return Primary and backup routers"
)
if pods is not None:
for pod in pods:
cmd = updatePod.updatePodCmd()
cmd.id = pod.id
cmd.allocationstate = 'Enabled'
self.apiclient.updatePod(cmd)
clusters = Cluster.list(
self.apiclient,
allocationstate="Disabled",
podid=enabled_pod.id,
listall=True
self.assertEqual(
len(routers),
2,
"Length of the list router should be 2 (Backup & Primary)"
)
self.assertNotEqual(
routers[0].hostid,
routers[1].hostid,
"Both the routers should be in different hosts"
)
finally:
try:
self.debug("Enabling remaining pods if any..")
pods = Pod.list(
self.apiclient,
zoneid=self.zone.id,
listall=True,
allocationstate="Disabled"
)
if pods is not None:
for pod in pods:
cmd = updatePod.updatePodCmd()
cmd.id = pod.id
cmd.allocationstate = 'Enabled'
self.apiclient.updatePod(cmd)
if clusters is not None:
for cluster in clusters:
cmd = updateCluster.updateClusterCmd()
cmd.id = cluster.id
cmd.allocationstate = 'Enabled'
self.apiclient.updateCluster(cmd)
clusters = Cluster.list(
self.apiclient,
allocationstate="Disabled",
podid=enabled_pod.id,
listall=True
)
if clusters is not None:
for cluster in clusters:
cmd = updateCluster.updateClusterCmd()
cmd.id = cluster.id
cmd.allocationstate = 'Enabled'
self.apiclient.updateCluster(cmd)
except Exception as e:
self.debug("Warning: Exception during resource re-enablement: %s" % e)
return
# @attr(tags=["advanced", "advancedns", "ssh"])
@attr(tags=["TODO"])
def test_RvR_multihosts(self):
@ -874,140 +885,145 @@ class TestRvRDeploymentPlanning(cloudstackTestCase):
self.apiclient.updateCluster(cmd)
self.debug("Enabled first cluster for testing..")
# Creating network using the network offering created
self.debug("Creating network with network offering: %s" %
self.network_offering.id)
network = Network.create(
self.apiclient,
self.services["network"],
accountid=self.account.name,
domainid=self.account.domainid,
networkofferingid=self.network_offering.id,
zoneid=self.zone.id
)
self.debug("Created network with ID: %s" % network.id)
try:
# Creating network using the network offering created
self.debug("Creating network with network offering: %s" %
self.network_offering.id)
network = Network.create(
self.apiclient,
self.services["network"],
accountid=self.account.name,
domainid=self.account.domainid,
networkofferingid=self.network_offering.id,
zoneid=self.zone.id
)
self.debug("Created network with ID: %s" % network.id)
networks = Network.list(
self.apiclient,
id=network.id,
listall=True
)
self.assertEqual(
isinstance(networks, list),
True,
"List networks should return a valid response for created network"
)
nw_response = networks[0]
networks = Network.list(
self.apiclient,
id=network.id,
listall=True
)
self.assertEqual(
isinstance(networks, list),
True,
"List networks should return a valid response for created network"
)
nw_response = networks[0]
self.debug("Network state: %s" % nw_response.state)
self.assertEqual(
nw_response.state,
"Allocated",
"The network should be in allocated state after creation"
)
self.debug("Listing routers for network: %s" % network.name)
routers = Router.list(
self.apiclient,
networkid=network.id,
listall=True
)
self.assertEqual(
routers,
None,
"Routers should not be spawned when network is in allocated state"
)
self.debug("Retrieving the list of hosts in the cluster")
hosts = Host.list(
self.apiclient,
clusterid=enabled_cluster.id,
listall=True
)
self.assertEqual(
isinstance(hosts, list),
True,
"List hosts should not return an empty response"
)
host = hosts[0]
self.debug("Deploying VM in account: %s" % self.account.name)
# Spawn an instance in that network
virtual_machine = VirtualMachine.create(
self.apiclient,
self.services["virtual_machine"],
accountid=self.account.name,
domainid=self.account.domainid,
serviceofferingid=self.service_offering.id,
networkids=[str(network.id)],
hostid=host.id
)
self.debug("Deployed VM in network: %s" % network.id)
vms = VirtualMachine.list(
self.apiclient,
id=virtual_machine.id,
listall=True
)
self.assertEqual(
isinstance(vms, list),
True,
"List Vms should return a valid list"
)
vm = vms[0]
self.assertEqual(
vm.state,
"Running",
"Vm should be in running state after deployment"
)
self.debug("Listing routers for network: %s" % network.name)
routers = Router.list(
self.apiclient,
networkid=network.id,
listall=True
)
self.assertEqual(
isinstance(routers, list),
True,
"list router should return Primary and backup routers"
)
self.assertEqual(
len(routers),
2,
"Length of the list router should be 2 (Backup & Primary)"
)
self.assertNotEqual(
routers[0].hostid,
routers[1].hostid,
"Both the routers should be in different hosts"
)
self.debug("Enabling remaining pods if any..")
pods = Pod.list(
self.apiclient,
zoneid=self.zone.id,
listall=True,
allocationstate="Disabled"
self.debug("Network state: %s" % nw_response.state)
self.assertEqual(
nw_response.state,
"Allocated",
"The network should be in allocated state after creation"
)
if pods is not None:
for pod in pods:
cmd = updatePod.updatePodCmd()
cmd.id = pod.id
cmd.allocationstate = 'Enabled'
self.apiclient.updatePod(cmd)
self.debug("Listing routers for network: %s" % network.name)
routers = Router.list(
self.apiclient,
networkid=network.id,
listall=True
)
self.assertEqual(
routers,
None,
"Routers should not be spawned when network is in allocated state"
)
clusters = Cluster.list(
self.apiclient,
allocationstate="Disabled",
podid=enabled_pod.id,
listall=True
self.debug("Retrieving the list of hosts in the cluster")
hosts = Host.list(
self.apiclient,
clusterid=enabled_cluster.id,
listall=True
)
self.assertEqual(
isinstance(hosts, list),
True,
"List hosts should not return an empty response"
)
host = hosts[0]
self.debug("Deploying VM in account: %s" % self.account.name)
# Spawn an instance in that network
virtual_machine = VirtualMachine.create(
self.apiclient,
self.services["virtual_machine"],
accountid=self.account.name,
domainid=self.account.domainid,
serviceofferingid=self.service_offering.id,
networkids=[str(network.id)],
hostid=host.id
)
self.debug("Deployed VM in network: %s" % network.id)
vms = VirtualMachine.list(
self.apiclient,
id=virtual_machine.id,
listall=True
)
self.assertEqual(
isinstance(vms, list),
True,
"List Vms should return a valid list"
)
vm = vms[0]
self.assertEqual(
vm.state,
"Running",
"Vm should be in running state after deployment"
)
self.debug("Listing routers for network: %s" % network.name)
routers = Router.list(
self.apiclient,
networkid=network.id,
listall=True
)
self.assertEqual(
isinstance(routers, list),
True,
"list router should return Primary and backup routers"
)
self.assertEqual(
len(routers),
2,
"Length of the list router should be 2 (Backup & Primary)"
)
self.assertNotEqual(
routers[0].hostid,
routers[1].hostid,
"Both the routers should be in different hosts"
)
if clusters is not None:
for cluster in clusters:
cmd = updateCluster.updateClusterCmd()
cmd.id = cluster.id
cmd.allocationstate = 'Enabled'
self.apiclient.updateCluster(cmd)
finally:
try:
self.debug("Enabling remaining pods if any..")
pods = Pod.list(
self.apiclient,
zoneid=self.zone.id,
listall=True,
allocationstate="Disabled"
)
if pods is not None:
for pod in pods:
cmd = updatePod.updatePodCmd()
cmd.id = pod.id
cmd.allocationstate = 'Enabled'
self.apiclient.updatePod(cmd)
clusters = Cluster.list(
self.apiclient,
allocationstate="Disabled",
podid=enabled_pod.id,
listall=True
)
if clusters is not None:
for cluster in clusters:
cmd = updateCluster.updateClusterCmd()
cmd.id = cluster.id
cmd.allocationstate = 'Enabled'
self.apiclient.updateCluster(cmd)
except Exception as e:
self.debug("Warning: Exception during resource re-enablement: %s" % e)
return

View File

@ -286,20 +286,25 @@ class TestDedicatePublicIPRange(cloudstackTestCase):
cmd.allocationstate = 'Disabled'
self.apiclient.updateZone(cmd)
# Delete System VM and IP range, so System VM can get IP from original ranges
self.debug("Destroying System VM: %s" % systemvm_id)
cmd = destroySystemVm.destroySystemVmCmd()
cmd.id = systemvm_id
self.apiclient.destroySystemVm(cmd)
try:
# Delete System VM and IP range, so System VM can get IP from original ranges
self.debug("Destroying System VM: %s" % systemvm_id)
cmd = destroySystemVm.destroySystemVmCmd()
cmd.id = systemvm_id
self.apiclient.destroySystemVm(cmd)
domain_id = self.public_ip_range.vlan.domainid
self.public_ip_range.delete(self.apiclient)
domain_id = self.public_ip_range.vlan.domainid
self.public_ip_range.delete(self.apiclient)
# Enable Zone
cmd = updateZone.updateZoneCmd()
cmd.id = self.zone.id
cmd.allocationstate = 'Enabled'
self.apiclient.updateZone(cmd)
finally:
# Enable Zone
try:
cmd = updateZone.updateZoneCmd()
cmd.id = self.zone.id
cmd.allocationstate = 'Enabled'
self.apiclient.updateZone(cmd)
except Exception as e:
self.debug("Warning: Exception during zone re-enablement in base_system_vm: %s" % e)
# Wait for System VM to start and check System VM public IP
systemvm_id = self.wait_for_system_vm_start(
@ -399,18 +404,23 @@ class TestDedicatePublicIPRange(cloudstackTestCase):
cmd.allocationstate = 'Disabled'
self.apiclient.updateZone(cmd)
# Delete System VM and IP range, so System VM can get IP from original ranges
if system_vms:
for v in system_vms:
self.debug("Destroying System VM: %s" % v.id)
cmd = destroySystemVm.destroySystemVmCmd()
cmd.id = v.id
self.apiclient.destroySystemVm(cmd)
try:
# Delete System VM and IP range, so System VM can get IP from original ranges
if system_vms:
for v in system_vms:
self.debug("Destroying System VM: %s" % v.id)
cmd = destroySystemVm.destroySystemVmCmd()
cmd.id = v.id
self.apiclient.destroySystemVm(cmd)
self.public_ip_range.delete(self.apiclient)
self.public_ip_range.delete(self.apiclient)
# Enable Zone
cmd = updateZone.updateZoneCmd()
cmd.id = self.zone.id
cmd.allocationstate = 'Enabled'
self.apiclient.updateZone(cmd)
finally:
# Enable Zone
try:
cmd = updateZone.updateZoneCmd()
cmd.id = self.zone.id
cmd.allocationstate = 'Enabled'
self.apiclient.updateZone(cmd)
except Exception as e:
self.debug("Warning: Exception during zone re-enablement in delete_range: %s" % e)