mirror of https://github.com/apache/cloudstack.git
Merge branch '4.20' into 4.22
This commit is contained in:
commit
13a2c7793c
|
|
@ -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)) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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<>();
|
||||
|
|
|
|||
|
|
@ -57,8 +57,4 @@ public class Upgrade42020to42030 extends DbUpgradeAbstractImpl implements DbUpgr
|
|||
public InputStream[] getCleanupScripts() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateSystemVmTemplates(Connection conn) {
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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');
|
||||
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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.");
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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()));
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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"));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Reference in New Issue