mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
CLOUDSTACK-10109: Enable dedication of public IPs to SSVM and CPVM (#2295)
This feature allow admins to dedicate a range of public IP addresses to the SSVM and CPVM, such that they can be subject to specific external firewall rules. The option to dedicate a public IP range to the System VMs (SSVM & CPVM) is added to the createVlanIpRange API method and the UI. Solution: Global setting 'system.vm.public.ip.reservation.mode.strictness' is added to determine if the use of the system VM reservation is strict (when true) or preferred (false), false by default. When a range has been dedicated to System VMs, CloudStack should apply IPs from that range to the public interfaces of the CPVM and the SSVM depending on global setting's value: If the global setting is set to false: then CloudStack will use any unused and unreserved public IP addresses for system VMs only when the pool of reserved IPs has been exhausted If the global setting is set to true: then CloudStack will fail to deploy the system VM when the pool of reserved IPs has been exhausted, citing the lack of available IPs. UI Changes Under Infrastructure -> Zone -> Physical Network -> Public -> IP Ranges, button 'Account' label is refactored to 'Set reservation'. When that button is clicked, dialog displayed is also refactored, including a new checkbox 'System VMs' which indicates if range should be dedicated for CPVM and SSVM, and a note indicating its usage. When clicking on button for any created range, UI dialog displayed indicates whether IP range is dedicated for system vms or not.
This commit is contained in:
parent
45df928e04
commit
90ef67bab9
@ -112,6 +112,9 @@ public class CreateVlanIpRangeCmd extends BaseCmd {
|
||||
@Parameter(name = ApiConstants.IP6_CIDR, type = CommandType.STRING, description = "the CIDR of IPv6 network, must be at least /64")
|
||||
private String ip6Cidr;
|
||||
|
||||
@Parameter(name = ApiConstants.FOR_SYSTEM_VMS, type = CommandType.BOOLEAN, description = "true if IP range is set to system vms, false if not")
|
||||
private Boolean forSystemVms;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
@ -136,6 +139,10 @@ public class CreateVlanIpRangeCmd extends BaseCmd {
|
||||
return gateway;
|
||||
}
|
||||
|
||||
public Boolean isForSystemVms() {
|
||||
return forSystemVms == null ? Boolean.FALSE : forSystemVms;
|
||||
}
|
||||
|
||||
public String getNetmask() {
|
||||
return netmask;
|
||||
}
|
||||
|
||||
@ -116,10 +116,22 @@ public class VlanIpRangeResponse extends BaseResponse implements ControlledEntit
|
||||
@Param(description = "the cidr of IPv6 network")
|
||||
private String ip6Cidr;
|
||||
|
||||
@SerializedName(ApiConstants.FOR_SYSTEM_VMS)
|
||||
@Param(description = "indicates whether VLAN IP range is dedicated to system vms or not")
|
||||
private Boolean forSystemVms;
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Boolean getForSystemVms() {
|
||||
return forSystemVms;
|
||||
}
|
||||
|
||||
public void setForSystemVms(Boolean forSystemVms) {
|
||||
this.forSystemVms = forSystemVms;
|
||||
}
|
||||
|
||||
public void setForVirtualNetwork(Boolean forVirtualNetwork) {
|
||||
this.forVirtualNetwork = forVirtualNetwork;
|
||||
}
|
||||
|
||||
@ -213,7 +213,7 @@ public interface ConfigurationManager {
|
||||
boolean conserveMode, Map<Service, Map<Capability, String>> serviceCapabilityMap, boolean specifyIpRanges, boolean isPersistent,
|
||||
Map<NetworkOffering.Detail, String> details, boolean egressDefaultPolicy, Integer maxconn, boolean enableKeepAlive, Boolean forVpc);
|
||||
|
||||
Vlan createVlanAndPublicIpRange(long zoneId, long networkId, long physicalNetworkId, boolean forVirtualNetwork, Long podId, String startIP, String endIP,
|
||||
Vlan createVlanAndPublicIpRange(long zoneId, long networkId, long physicalNetworkId, boolean forVirtualNetwork, boolean forSystemVms, Long podId, String startIP, String endIP,
|
||||
String vlanGateway, String vlanNetmask, String vlanId, boolean bypassVlanOverlapCheck, Domain domain, Account vlanOwner, String startIPv6, String endIPv6, String vlanIp6Gateway, String vlanIp6Cidr)
|
||||
throws InsufficientCapacityException, ConcurrentOperationException, InvalidParameterValueException;
|
||||
|
||||
|
||||
@ -61,7 +61,7 @@ public interface IpAddressManager {
|
||||
* @return
|
||||
* @throws InsufficientAddressCapacityException
|
||||
*/
|
||||
PublicIp assignPublicIpAddress(long dcId, Long podId, Account owner, VlanType type, Long networkId, String requestedIp, boolean isSystem)
|
||||
PublicIp assignPublicIpAddress(long dcId, Long podId, Account owner, VlanType type, Long networkId, String requestedIp, boolean isSystem, boolean forSystemVms)
|
||||
throws InsufficientAddressCapacityException;
|
||||
|
||||
/**
|
||||
|
||||
@ -524,6 +524,10 @@ ADD COLUMN `forsystemvms` TINYINT(1) NOT NULL DEFAULT '0' COMMENT 'Indicates if
|
||||
ALTER TABLE `cloud`.`op_dc_ip_address_alloc`
|
||||
ADD COLUMN `vlan` INT(10) UNSIGNED NULL COMMENT 'Vlan the management network range is on';
|
||||
|
||||
-- CLOUDSTACK-10109: Enable dedication of public IPs to SSVM and CPVM
|
||||
ALTER TABLE `cloud`.`user_ip_address`
|
||||
ADD COLUMN `forsystemvms` TINYINT(1) NOT NULL DEFAULT '0' COMMENT 'true if IP is set to system vms, false if not';
|
||||
|
||||
-- ldap binding on domain level
|
||||
CREATE TABLE IF NOT EXISTS `cloud`.`domain_details` (
|
||||
`id` bigint unsigned NOT NULL auto_increment,
|
||||
@ -539,4 +543,3 @@ ALTER TABLE cloud.ldap_trust_map ADD COLUMN account_id BIGINT(20) DEFAULT 0;
|
||||
ALTER TABLE cloud.ldap_trust_map DROP FOREIGN KEY fk_ldap_trust_map__domain_id;
|
||||
DROP INDEX uk_ldap_trust_map__domain_id ON cloud.ldap_trust_map;
|
||||
CREATE UNIQUE INDEX uk_ldap_trust_map__bind_location ON ldap_trust_map (domain_id, account_id);
|
||||
|
||||
|
||||
@ -122,6 +122,9 @@ public class IPAddressVO implements IpAddress {
|
||||
@Column(name = "rule_state")
|
||||
State ruleState;
|
||||
|
||||
@Column(name = "forsystemvms")
|
||||
private boolean forSystemVms = false;
|
||||
|
||||
@Column(name= GenericDao.REMOVED_COLUMN)
|
||||
private Date removed;
|
||||
|
||||
@ -382,4 +385,8 @@ public class IPAddressVO implements IpAddress {
|
||||
public void setRuleState(State ruleState) {
|
||||
this.ruleState = ruleState;
|
||||
}
|
||||
|
||||
public boolean isForSystemVms() {
|
||||
return forSystemVms;
|
||||
}
|
||||
}
|
||||
|
||||
@ -154,7 +154,7 @@ public class BaremetaNetworkGuru extends DirectPodBasedNetworkGuru {
|
||||
DataCenter dc = _dcDao.findById(pod.getDataCenterId());
|
||||
if (nic.getIPv4Address() == null) {
|
||||
s_logger.debug(String.format("Requiring ip address: %s", nic.getIPv4Address()));
|
||||
PublicIp ip = _ipAddrMgr.assignPublicIpAddress(dc.getId(), pod.getId(), vm.getOwner(), VlanType.DirectAttached, network.getId(), requiredIp, false);
|
||||
PublicIp ip = _ipAddrMgr.assignPublicIpAddress(dc.getId(), pod.getId(), vm.getOwner(), VlanType.DirectAttached, network.getId(), requiredIp, false, false);
|
||||
nic.setIPv4Address(ip.getAddress().toString());
|
||||
nic.setFormat(AddressFormat.Ip4);
|
||||
nic.setIPv4Gateway(ip.getGateway());
|
||||
|
||||
@ -446,7 +446,7 @@ public class LoadBalanceRuleHandler {
|
||||
public PublicIp doInTransaction(final TransactionStatus status) throws InsufficientAddressCapacityException {
|
||||
final Network frontEndNetwork = _networkModel.getNetwork(guestNetworkId);
|
||||
|
||||
final PublicIp ip = _ipAddrMgr.assignPublicIpAddress(frontEndNetwork.getDataCenterId(), null, account, VlanType.DirectAttached, frontEndNetwork.getId(), null, true);
|
||||
final PublicIp ip = _ipAddrMgr.assignPublicIpAddress(frontEndNetwork.getDataCenterId(), null, account, VlanType.DirectAttached, frontEndNetwork.getId(), null, true, false);
|
||||
final IPAddressVO ipvo = _ipAddressDao.findById(ip.getId());
|
||||
ipvo.setAssociatedWithNetworkId(frontEndNetwork.getId());
|
||||
_ipAddressDao.update(ipvo.getId(), ipvo);
|
||||
|
||||
@ -98,6 +98,7 @@ import com.cloud.network.as.AutoScaleVmProfileVO;
|
||||
import com.cloud.network.as.Condition;
|
||||
import com.cloud.network.as.ConditionVO;
|
||||
import com.cloud.network.as.Counter;
|
||||
import com.cloud.network.dao.IPAddressDao;
|
||||
import com.cloud.network.dao.IPAddressVO;
|
||||
import com.cloud.network.dao.LoadBalancerVO;
|
||||
import com.cloud.network.dao.NetworkVO;
|
||||
@ -163,6 +164,8 @@ import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.StringUtils;
|
||||
import com.cloud.utils.db.EntityManager;
|
||||
import com.cloud.utils.net.Dhcp;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.utils.net.Ip;
|
||||
import com.cloud.utils.net.NetUtils;
|
||||
@ -356,6 +359,8 @@ public class ApiResponseHelper implements ResponseGenerator {
|
||||
private ResourceTagDao _resourceTagDao;
|
||||
@Inject
|
||||
private NicExtraDhcpOptionDao _nicExtraDhcpOptionDao;
|
||||
@Inject
|
||||
private IPAddressDao userIpAddressDao;
|
||||
|
||||
@Override
|
||||
public UserResponse createUserResponse(User user) {
|
||||
@ -745,6 +750,7 @@ public class ApiResponseHelper implements ResponseGenerator {
|
||||
vlanResponse.setPhysicalNetworkId(pnw.getUuid());
|
||||
}
|
||||
}
|
||||
vlanResponse.setForSystemVms(isForSystemVms(vlan.getId()));
|
||||
vlanResponse.setObjectName("vlan");
|
||||
return vlanResponse;
|
||||
} catch (InstantiationException | IllegalAccessException e) {
|
||||
@ -752,6 +758,20 @@ public class ApiResponseHelper implements ResponseGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if vlan IP range is dedicated for system vms (SSVM and CPVM), false if not
|
||||
* @param vlanId vlan id
|
||||
* @return true if VLAN IP range is dedicated to system vms
|
||||
*/
|
||||
private boolean isForSystemVms(long vlanId){
|
||||
SearchBuilder<IPAddressVO> sb = userIpAddressDao.createSearchBuilder();
|
||||
sb.and("vlanId", sb.entity().getVlanId(), SearchCriteria.Op.EQ);
|
||||
SearchCriteria<IPAddressVO> sc = sb.create();
|
||||
sc.setParameters("vlanId", vlanId);
|
||||
IPAddressVO userIpAddresVO = userIpAddressDao.findOneBy(sc);
|
||||
return userIpAddresVO.isForSystemVms();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPAddressResponse createIPAddressResponse(ResponseView view, IpAddress ipAddr) {
|
||||
VlanVO vlan = ApiDBUtils.findVlanById(ipAddr.getVlanId());
|
||||
|
||||
@ -2908,9 +2908,14 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
||||
String endIPv6 = cmd.getEndIpv6();
|
||||
final String ip6Gateway = cmd.getIp6Gateway();
|
||||
final String ip6Cidr = cmd.getIp6Cidr();
|
||||
final Boolean forSystemVms = cmd.isForSystemVms();
|
||||
|
||||
Account vlanOwner = null;
|
||||
|
||||
if (forSystemVms && accountName != null) {
|
||||
throw new InvalidParameterValueException("Account name should not be provided when ForSystemVMs is enabled");
|
||||
}
|
||||
|
||||
final boolean ipv4 = startIP != null;
|
||||
final boolean ipv6 = startIPv6 != null;
|
||||
|
||||
@ -3118,12 +3123,12 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
||||
checkOverlapPrivateIpRange(zoneId, startIP, endIP);
|
||||
}
|
||||
|
||||
return commitVlan(zoneId, podId, startIP, endIP, newVlanGateway, newVlanNetmask, vlanId, forVirtualNetwork, networkId, physicalNetworkId, startIPv6, endIPv6, ip6Gateway,
|
||||
return commitVlan(zoneId, podId, startIP, endIP, newVlanGateway, newVlanNetmask, vlanId, forVirtualNetwork, forSystemVms, networkId, physicalNetworkId, startIPv6, endIPv6, ip6Gateway,
|
||||
ip6Cidr, domain, vlanOwner, network, sameSubnet);
|
||||
}
|
||||
|
||||
private Vlan commitVlan(final Long zoneId, final Long podId, final String startIP, final String endIP, final String newVlanGatewayFinal, final String newVlanNetmaskFinal,
|
||||
final String vlanId, final Boolean forVirtualNetwork, final Long networkId, final Long physicalNetworkId, final String startIPv6, final String endIPv6,
|
||||
final String vlanId, final Boolean forVirtualNetwork, final Boolean forSystemVms, final Long networkId, final Long physicalNetworkId, final String startIPv6, final String endIPv6,
|
||||
final String ip6Gateway, final String ip6Cidr, final Domain domain, final Account vlanOwner, final Network network, final Pair<Boolean, Pair<String, String>> sameSubnet) {
|
||||
final GlobalLock commitVlanLock = GlobalLock.getInternLock("CommitVlan");
|
||||
commitVlanLock.lock(5);
|
||||
@ -3151,7 +3156,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
||||
newVlanGateway = sameSubnet.second().first();
|
||||
newVlanNetmask = sameSubnet.second().second();
|
||||
}
|
||||
final Vlan vlan = createVlanAndPublicIpRange(zoneId, networkId, physicalNetworkId, forVirtualNetwork, podId, startIP, endIP, newVlanGateway, newVlanNetmask, vlanId,
|
||||
final Vlan vlan = createVlanAndPublicIpRange(zoneId, networkId, physicalNetworkId, forVirtualNetwork, forSystemVms, podId, startIP, endIP, newVlanGateway, newVlanNetmask, vlanId,
|
||||
false, domain, vlanOwner, startIPv6, endIPv6, ip6Gateway, ip6Cidr);
|
||||
// create an entry in the nic_secondary table. This will be the new
|
||||
// gateway that will be configured on the corresponding routervm.
|
||||
@ -3271,7 +3276,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
||||
|
||||
@Override
|
||||
@DB
|
||||
public Vlan createVlanAndPublicIpRange(final long zoneId, final long networkId, final long physicalNetworkId, final boolean forVirtualNetwork, final Long podId, final String startIP, final String endIP,
|
||||
public Vlan createVlanAndPublicIpRange(final long zoneId, final long networkId, final long physicalNetworkId, final boolean forVirtualNetwork, final boolean forSystemVms, final Long podId, final String startIP, final String endIP,
|
||||
final String vlanGateway, final String vlanNetmask, String vlanId, boolean bypassVlanOverlapCheck, Domain domain, final Account vlanOwner, final String startIPv6, final String endIPv6, final String vlanIp6Gateway, final String vlanIp6Cidr) {
|
||||
final Network network = _networkModel.getNetwork(networkId);
|
||||
|
||||
@ -3521,14 +3526,14 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
||||
|
||||
// Everything was fine, so persist the VLAN
|
||||
final VlanVO vlan = commitVlanAndIpRange(zoneId, networkId, physicalNetworkId, podId, startIP, endIP, vlanGateway, vlanNetmask, vlanId, domain, vlanOwner, vlanIp6Gateway, vlanIp6Cidr,
|
||||
ipv4, zone, vlanType, ipv6Range, ipRange);
|
||||
ipv4, zone, vlanType, ipv6Range, ipRange, forSystemVms);
|
||||
|
||||
return vlan;
|
||||
}
|
||||
|
||||
private VlanVO commitVlanAndIpRange(final long zoneId, final long networkId, final long physicalNetworkId, final Long podId, final String startIP, final String endIP,
|
||||
final String vlanGateway, final String vlanNetmask, final String vlanId, final Domain domain, final Account vlanOwner, final String vlanIp6Gateway, final String vlanIp6Cidr,
|
||||
final boolean ipv4, final DataCenterVO zone, final VlanType vlanType, final String ipv6Range, final String ipRange) {
|
||||
final boolean ipv4, final DataCenterVO zone, final VlanType vlanType, final String ipv6Range, final String ipRange, final boolean forSystemVms) {
|
||||
return Transaction.execute(new TransactionCallback<VlanVO>() {
|
||||
@Override
|
||||
public VlanVO doInTransaction(final TransactionStatus status) {
|
||||
@ -3539,7 +3544,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
||||
// IPv6 use a used ip map, is different from ipv4, no need to save
|
||||
// public ip range
|
||||
if (ipv4) {
|
||||
if (!savePublicIPRange(startIP, endIP, zoneId, vlan.getId(), networkId, physicalNetworkId)) {
|
||||
if (!savePublicIPRange(startIP, endIP, zoneId, vlan.getId(), networkId, physicalNetworkId, forSystemVms)) {
|
||||
throw new CloudRuntimeException("Failed to save IPv4 range. Please contact Cloud Support.");
|
||||
}
|
||||
}
|
||||
@ -3561,8 +3566,8 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
||||
_resourceLimitMgr.incrementResourceCount(vlanOwner.getId(), ResourceType.public_ip, new Long(ips.size()));
|
||||
} else if (domain != null) {
|
||||
// This VLAN is domain-wide, so create a DomainVlanMapVO entry
|
||||
final DomainVlanMapVO domainVlanMapVO = new DomainVlanMapVO(domain.getId(), vlan.getId());
|
||||
_domainVlanMapDao.persist(domainVlanMapVO);
|
||||
//final DomainVlanMapVO domainVlanMapVO = new DomainVlanMapVO(domain.getId(), vlan.getId());
|
||||
//_domainVlanMapDao.persist(domainVlanMapVO);
|
||||
} else if (podId != null) {
|
||||
// This VLAN is pod-wide, so create a PodVlanMapVO entry
|
||||
final PodVlanMapVO podVlanMapVO = new PodVlanMapVO(podId, vlan.getId());
|
||||
@ -3873,7 +3878,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
||||
}
|
||||
|
||||
@DB
|
||||
protected boolean savePublicIPRange(final String startIP, final String endIP, final long zoneId, final long vlanDbId, final long sourceNetworkid, final long physicalNetworkId) {
|
||||
protected boolean savePublicIPRange(final String startIP, final String endIP, final long zoneId, final long vlanDbId, final long sourceNetworkid, final long physicalNetworkId, final boolean forSystemVms) {
|
||||
final long startIPLong = NetUtils.ip2Long(startIP);
|
||||
final long endIPLong = NetUtils.ip2Long(endIP);
|
||||
|
||||
@ -3881,7 +3886,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
||||
@Override
|
||||
public List<String> doInTransaction(final TransactionStatus status) {
|
||||
final IPRangeConfig config = new IPRangeConfig();
|
||||
return config.savePublicIPRange(TransactionLegacy.currentTxn(), startIPLong, endIPLong, zoneId, vlanDbId, sourceNetworkid, physicalNetworkId);
|
||||
return config.savePublicIPRange(TransactionLegacy.currentTxn(), startIPLong, endIPLong, zoneId, vlanDbId, sourceNetworkid, physicalNetworkId, forSystemVms);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@ -538,7 +538,7 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase
|
||||
// acquire a public IP to associate with lb appliance (used as subnet IP to make the appliance part of private network)
|
||||
PublicIp publicIp =
|
||||
_ipAddrMgr.assignPublicIpAddress(guestConfig.getDataCenterId(), null, _accountMgr.getSystemAccount(), VlanType.VirtualNetwork, null,
|
||||
null, false);
|
||||
null, false, false);
|
||||
String publicIPNetmask = publicIp.getVlanNetmask();
|
||||
String publicIPgateway = publicIp.getVlanGateway();
|
||||
String publicIP = publicIp.getAddress().toString();
|
||||
@ -813,7 +813,7 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase
|
||||
try {
|
||||
PublicIp directIp =
|
||||
_ipAddrMgr.assignPublicIpAddress(network.getDataCenterId(), null, _accountDao.findById(network.getAccountId()), VlanType.DirectAttached,
|
||||
network.getId(), null, true);
|
||||
network.getId(), null, true, false);
|
||||
loadBalancingIpAddress = directIp.getAddress().addr();
|
||||
} catch (InsufficientCapacityException capException) {
|
||||
String msg = "Ran out of guest IP addresses from the shared network.";
|
||||
|
||||
@ -295,6 +295,10 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
|
||||
|
||||
static Boolean rulesContinueOnErrFlag = true;
|
||||
|
||||
private static final ConfigKey<Boolean> SystemVmPublicIpReservationModeStrictness = new ConfigKey<Boolean>("Advanced",
|
||||
Boolean.class, "system.vm.public.ip.reservation.mode.strictness", "false",
|
||||
"If enabled, the use of System VMs public IP reservation is strict, preferred if not.", false, ConfigKey.Scope.Global);
|
||||
|
||||
@Override
|
||||
public boolean configure(String name, Map<String, Object> params) {
|
||||
// populate providers
|
||||
@ -395,6 +399,9 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
|
||||
AssignIpAddressSearch.and("dc", AssignIpAddressSearch.entity().getDataCenterId(), Op.EQ);
|
||||
AssignIpAddressSearch.and("allocated", AssignIpAddressSearch.entity().getAllocatedTime(), Op.NULL);
|
||||
AssignIpAddressSearch.and("vlanId", AssignIpAddressSearch.entity().getVlanId(), Op.IN);
|
||||
if (SystemVmPublicIpReservationModeStrictness.value()) {
|
||||
AssignIpAddressSearch.and("forSystemVms", AssignIpAddressSearch.entity().isForSystemVms(), Op.EQ);
|
||||
}
|
||||
SearchBuilder<VlanVO> vlanSearch = _vlanDao.createSearchBuilder();
|
||||
vlanSearch.and("type", vlanSearch.entity().getVlanType(), Op.EQ);
|
||||
vlanSearch.and("networkId", vlanSearch.entity().getNetworkId(), Op.EQ);
|
||||
@ -675,20 +682,20 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
|
||||
}
|
||||
|
||||
@Override
|
||||
public PublicIp assignPublicIpAddress(long dcId, Long podId, Account owner, VlanType type, Long networkId, String requestedIp, boolean isSystem)
|
||||
public PublicIp assignPublicIpAddress(long dcId, Long podId, Account owner, VlanType type, Long networkId, String requestedIp, boolean isSystem, boolean forSystemVms)
|
||||
throws InsufficientAddressCapacityException {
|
||||
return fetchNewPublicIp(dcId, podId, null, owner, type, networkId, false, true, requestedIp, isSystem, null, null);
|
||||
return fetchNewPublicIp(dcId, podId, null, owner, type, networkId, false, true, requestedIp, isSystem, null, null, forSystemVms);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PublicIp assignPublicIpAddressFromVlans(long dcId, Long podId, Account owner, VlanType type, List<Long> vlanDbIds, Long networkId, String requestedIp, boolean isSystem)
|
||||
throws InsufficientAddressCapacityException {
|
||||
return fetchNewPublicIp(dcId, podId, vlanDbIds, owner, type, networkId, false, true, requestedIp, isSystem, null, null);
|
||||
return fetchNewPublicIp(dcId, podId, vlanDbIds, owner, type, networkId, false, true, requestedIp, isSystem, null, null, false);
|
||||
}
|
||||
|
||||
@DB
|
||||
public PublicIp fetchNewPublicIp(final long dcId, final Long podId, final List<Long> vlanDbIds, final Account owner, final VlanType vlanUse, final Long guestNetworkId,
|
||||
final boolean sourceNat, final boolean assign, final String requestedIp, final boolean isSystem, final Long vpcId, final Boolean displayIp)
|
||||
final boolean sourceNat, final boolean assign, final String requestedIp, final boolean isSystem, final Long vpcId, final Boolean displayIp, final boolean forSystemVms)
|
||||
throws InsufficientAddressCapacityException {
|
||||
IPAddressVO addr = Transaction.execute(new TransactionCallbackWithException<IPAddressVO, InsufficientAddressCapacityException>() {
|
||||
@Override
|
||||
@ -758,7 +765,13 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
|
||||
errorMessage.append(": requested ip " + requestedIp + " is not available");
|
||||
}
|
||||
|
||||
Filter filter = new Filter(IPAddressVO.class, "vlanId", true, 0l, 1l);
|
||||
boolean ascOrder = ! forSystemVms;
|
||||
Filter filter = new Filter(IPAddressVO.class, "forSystemVms", ascOrder, 0l, 1l);
|
||||
if (SystemVmPublicIpReservationModeStrictness.value()) {
|
||||
sc.setParameters("forSystemVms", forSystemVms);
|
||||
}
|
||||
|
||||
filter.addOrderBy(IPAddressVO.class,"vlanId", true);
|
||||
|
||||
List<IPAddressVO> addrs = _ipAddressDao.search(sc, filter, false);
|
||||
|
||||
@ -951,7 +964,13 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
|
||||
VpcVO vpc = _vpcDao.findById(vpcId);
|
||||
displayIp = vpc.isDisplay();
|
||||
}
|
||||
return fetchNewPublicIp(dcId, null, null, owner, VlanType.VirtualNetwork, guestNtwkId, isSourceNat, true, null, false, vpcId, displayIp);
|
||||
PublicIp ip = fetchNewPublicIp(dcId, null, null, owner, VlanType.VirtualNetwork, guestNtwkId, isSourceNat, false, null, false, vpcId, displayIp, false);
|
||||
IPAddressVO publicIp = ip.ip();
|
||||
|
||||
markPublicIpAsAllocated(publicIp);
|
||||
_ipAddressDao.update(publicIp.getId(), publicIp);
|
||||
|
||||
return ip;
|
||||
}
|
||||
});
|
||||
if (ip.getState() != State.Allocated) {
|
||||
@ -1147,7 +1166,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
|
||||
ip = Transaction.execute(new TransactionCallbackWithException<PublicIp, InsufficientAddressCapacityException>() {
|
||||
@Override
|
||||
public PublicIp doInTransaction(TransactionStatus status) throws InsufficientAddressCapacityException {
|
||||
PublicIp ip = fetchNewPublicIp(zone.getId(), null, null, ipOwner, vlanType, null, false, assign, null, isSystem, null, displayIp);
|
||||
PublicIp ip = fetchNewPublicIp(zone.getId(), null, null, ipOwner, vlanType, null, false, assign, null, isSystem, null, displayIp, false);
|
||||
|
||||
if (ip == null) {
|
||||
InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Unable to find available public IP addresses", DataCenter.class, zone
|
||||
@ -2009,7 +2028,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
|
||||
}
|
||||
|
||||
if (ip == null) {
|
||||
ip = assignPublicIpAddress(dc.getId(), null, vm.getOwner(), VlanType.DirectAttached, network.getId(), requestedIpv4, false);
|
||||
ip = assignPublicIpAddress(dc.getId(), null, vm.getOwner(), VlanType.DirectAttached, network.getId(), requestedIpv4, false, false);
|
||||
}
|
||||
|
||||
nic.setIPv4Address(ip.getAddress().toString());
|
||||
@ -2142,7 +2161,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
|
||||
|
||||
@Override
|
||||
public String allocatePublicIpForGuestNic(Network network, Long podId, Account owner, String requestedIp) throws InsufficientAddressCapacityException {
|
||||
PublicIp ip = assignPublicIpAddress(network.getDataCenterId(), podId, owner, VlanType.DirectAttached, network.getId(), requestedIp, false);
|
||||
PublicIp ip = assignPublicIpAddress(network.getDataCenterId(), podId, owner, VlanType.DirectAttached, network.getId(), requestedIp, false, false);
|
||||
if (ip == null) {
|
||||
s_logger.debug("There is no free public ip address");
|
||||
return null;
|
||||
@ -2163,6 +2182,6 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
|
||||
|
||||
@Override
|
||||
public ConfigKey<?>[] getConfigKeys() {
|
||||
return new ConfigKey<?>[] {UseSystemPublicIps, RulesContinueOnError};
|
||||
return new ConfigKey<?>[] {UseSystemPublicIps, RulesContinueOnError, SystemVmPublicIpReservationModeStrictness};
|
||||
}
|
||||
}
|
||||
|
||||
@ -1386,7 +1386,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
|
||||
|
||||
if (_accountMgr.isRootAdmin(caller.getId()) && createVlan && network != null) {
|
||||
// Create vlan ip range
|
||||
_configMgr.createVlanAndPublicIpRange(pNtwk.getDataCenterId(), network.getId(), physicalNetworkId, false, null, startIP, endIP, gateway, netmask, vlanId,
|
||||
_configMgr.createVlanAndPublicIpRange(pNtwk.getDataCenterId(), network.getId(), physicalNetworkId, false, false, null, startIP, endIP, gateway, netmask, vlanId,
|
||||
bypassVlanOverlapCheck, null, null, startIPv6, endIPv6, ip6Gateway, ip6Cidr);
|
||||
}
|
||||
return network;
|
||||
|
||||
@ -194,7 +194,7 @@ public class DirectPodBasedNetworkGuru extends DirectNetworkGuru {
|
||||
}
|
||||
|
||||
if (ip == null) {
|
||||
ip = _ipAddrMgr.assignPublicIpAddress(dc.getId(), pod.getId(), vm.getOwner(), VlanType.DirectAttached, network.getId(), null, false);
|
||||
ip = _ipAddrMgr.assignPublicIpAddress(dc.getId(), pod.getId(), vm.getOwner(), VlanType.DirectAttached, network.getId(), null, false, false);
|
||||
}
|
||||
|
||||
nic.setIPv4Address(ip.getAddress().toString());
|
||||
|
||||
@ -115,7 +115,11 @@ public class PublicNetworkGuru extends AdapterBase implements NetworkGuru {
|
||||
protected void getIp(NicProfile nic, DataCenter dc, VirtualMachineProfile vm, Network network) throws InsufficientVirtualNetworkCapacityException,
|
||||
InsufficientAddressCapacityException, ConcurrentOperationException {
|
||||
if (nic.getIPv4Address() == null) {
|
||||
PublicIp ip = _ipAddrMgr.assignPublicIpAddress(dc.getId(), null, vm.getOwner(), VlanType.VirtualNetwork, null, null, false);
|
||||
boolean forSystemVms = false;
|
||||
if (vm.getType().equals(VirtualMachine.Type.ConsoleProxy) || vm.getType().equals(VirtualMachine.Type.SecondaryStorageVm)) {
|
||||
forSystemVms = true;
|
||||
}
|
||||
PublicIp ip = _ipAddrMgr.assignPublicIpAddress(dc.getId(), null, vm.getOwner(), VlanType.VirtualNetwork, null, null, false, forSystemVms);
|
||||
nic.setIPv4Address(ip.getAddress().toString());
|
||||
nic.setIPv4Gateway(ip.getGateway());
|
||||
nic.setIPv4Netmask(ip.getNetmask());
|
||||
|
||||
@ -290,7 +290,7 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio
|
||||
long startIPLong = NetUtils.ip2Long(startIp);
|
||||
long endIPLong = NetUtils.ip2Long(endIp);
|
||||
config.savePublicIPRange(TransactionLegacy.currentTxn(), startIPLong, endIPLong, vlan.getDataCenterId(), vlan.getId(), vlan.getNetworkId(),
|
||||
vlan.getPhysicalNetworkId());
|
||||
vlan.getPhysicalNetworkId(), false);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@ -431,7 +431,7 @@ public class IPRangeConfig {
|
||||
List<String> problemIPs = null;
|
||||
|
||||
if (type.equals("public")) {
|
||||
problemIPs = savePublicIPRange(txn, startIPLong, endIPLong, zoneId, vlanDbId, sourceNetworkId, physicalNetworkId);
|
||||
problemIPs = savePublicIPRange(txn, startIPLong, endIPLong, zoneId, vlanDbId, sourceNetworkId, physicalNetworkId, false);
|
||||
} else if (type.equals("private")) {
|
||||
problemIPs = savePrivateIPRange(txn, startIPLong, endIPLong, podId, zoneId);
|
||||
}
|
||||
@ -445,9 +445,9 @@ public class IPRangeConfig {
|
||||
return problemIPs;
|
||||
}
|
||||
|
||||
public Vector<String> savePublicIPRange(TransactionLegacy txn, long startIP, long endIP, long zoneId, long vlanDbId, Long sourceNetworkId, long physicalNetworkId) {
|
||||
public Vector<String> savePublicIPRange(TransactionLegacy txn, long startIP, long endIP, long zoneId, long vlanDbId, Long sourceNetworkId, long physicalNetworkId, boolean forSystemVms) {
|
||||
String insertSql =
|
||||
"INSERT INTO `cloud`.`user_ip_address` (public_ip_address, data_center_id, vlan_db_id, mac_address, source_network_id, physical_network_id, uuid) VALUES (?, ?, ?, (select mac_address from `cloud`.`data_center` where id=?), ?, ?, ?)";
|
||||
"INSERT INTO `cloud`.`user_ip_address` (public_ip_address, data_center_id, vlan_db_id, mac_address, source_network_id, physical_network_id, uuid, forsystemvms) VALUES (?, ?, ?, (select mac_address from `cloud`.`data_center` where id=?), ?, ?, ?, ?)";
|
||||
String updateSql = "UPDATE `cloud`.`data_center` set mac_address = mac_address+1 where id=?";
|
||||
Vector<String> problemIPs = new Vector<String>();
|
||||
|
||||
@ -468,6 +468,7 @@ public class IPRangeConfig {
|
||||
insert_stmt.setLong(5, sourceNetworkId);
|
||||
insert_stmt.setLong(6, physicalNetworkId);
|
||||
insert_stmt.setString(7, UUID.randomUUID().toString());
|
||||
insert_stmt.setBoolean(8, forSystemVms);
|
||||
insert_stmt.executeUpdate();
|
||||
update_stmt.setLong(1, zoneId);
|
||||
update_stmt.executeUpdate();
|
||||
|
||||
@ -459,7 +459,7 @@ public class MockConfigurationManagerImpl extends ManagerBase implements Configu
|
||||
* @see com.cloud.configuration.ConfigurationManager#createVlanAndPublicIpRange(long, long, long, boolean, java.lang.Long, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, com.cloud.user.Account)
|
||||
*/
|
||||
@Override
|
||||
public Vlan createVlanAndPublicIpRange(long zoneId, long networkId, long physicalNetworkId, boolean forVirtualNetwork, Long podId, String startIP, String endIP,
|
||||
public Vlan createVlanAndPublicIpRange(long zoneId, long networkId, long physicalNetworkId, boolean forVirtualNetwork, boolean forSystemVms, Long podId, String startIP, String endIP,
|
||||
String vlanGateway, String vlanNetmask, String vlanId, boolean bypassVlanOverlapCheck, Domain domain, Account vlanOwner, String startIPv6, String endIPv6, String vlanGatewayv6, String vlanCidrv6)
|
||||
throws InsufficientCapacityException, ConcurrentOperationException, InvalidParameterValueException {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
@ -25,6 +25,8 @@ from marvin.lib.utils import *
|
||||
from marvin.lib.base import *
|
||||
from marvin.lib.common import *
|
||||
import datetime
|
||||
from socket import inet_aton
|
||||
from struct import unpack
|
||||
|
||||
class TestDedicatePublicIPRange(cloudstackTestCase):
|
||||
|
||||
@ -147,3 +149,241 @@ class TestDedicatePublicIPRange(cloudstackTestCase):
|
||||
|
||||
return
|
||||
|
||||
@attr(tags = ["advanced", "publiciprange", "dedicate", "release"], required_hardware="false")
|
||||
def test_dedicate_public_ip_range_for_system_vms(self):
|
||||
"""Test public IP range dedication for SSVM and CPVM
|
||||
"""
|
||||
|
||||
# Validate the following:
|
||||
# 1. Create a Public IP range for system vms
|
||||
# 2. Created IP range should be present and marked as forsystemvms=true, verify with listVlanIpRanges
|
||||
# 7. Delete the Public IP range
|
||||
|
||||
services = {
|
||||
"gateway":"192.168.99.1",
|
||||
"netmask":"255.255.255.0",
|
||||
"startip":"192.168.99.2",
|
||||
"endip":"192.168.99.200",
|
||||
"forvirtualnetwork":self.services["forvirtualnetwork"],
|
||||
"zoneid":self.services["zoneid"],
|
||||
"vlan":self.services["vlan"]
|
||||
}
|
||||
public_ip_range = PublicIpRange.create(
|
||||
self.apiclient,
|
||||
services,
|
||||
forsystemvms = True
|
||||
)
|
||||
created_ip_range_response = PublicIpRange.list(
|
||||
self.apiclient,
|
||||
id = public_ip_range.vlan.id
|
||||
)
|
||||
self.assertEqual(
|
||||
len(created_ip_range_response),
|
||||
1,
|
||||
"Check listVlanIpRanges response"
|
||||
)
|
||||
self.assertTrue(
|
||||
created_ip_range_response[0].forsystemvms,
|
||||
"Check forsystemvms parameter in created vlan ip range"
|
||||
)
|
||||
|
||||
# Delete range
|
||||
public_ip_range.delete(self.apiclient)
|
||||
|
||||
def get_ip_as_number(self, ip_string):
|
||||
""" Return numeric value for ip (passed as a string)
|
||||
"""
|
||||
packed_ip = inet_aton(ip_string)
|
||||
return unpack(">L", packed_ip)[0]
|
||||
|
||||
def is_ip_in_range(self, start_ip, end_ip, ip_to_test):
|
||||
""" Check whether ip_to_test belongs to IP range between start_ip and end_ip
|
||||
"""
|
||||
start = self.get_ip_as_number(start_ip)
|
||||
end = self.get_ip_as_number(end_ip)
|
||||
ip = self.get_ip_as_number(ip_to_test)
|
||||
return start <= ip and ip <= end
|
||||
|
||||
def wait_for_system_vm_start(self, domain_id, srv_timeout, srv_sleep, systemvmtype):
|
||||
""" Wait until system vm is Running
|
||||
"""
|
||||
timeout = srv_timeout
|
||||
while True:
|
||||
list_systemvm_response = list_ssvms(
|
||||
self.apiclient,
|
||||
systemvmtype=systemvmtype,
|
||||
domainid=domain_id
|
||||
)
|
||||
if isinstance(list_systemvm_response, list):
|
||||
if list_systemvm_response[0].state == 'Running':
|
||||
return list_systemvm_response[0].id
|
||||
if timeout == 0:
|
||||
raise Exception("List System VM call failed!")
|
||||
|
||||
time.sleep(srv_sleep)
|
||||
timeout = timeout - 1
|
||||
return None
|
||||
|
||||
def base_system_vm(self, services, systemvmtype):
|
||||
"""
|
||||
Base for CPVM or SSVM depending on systemvmtype parameter
|
||||
"""
|
||||
|
||||
# Create range for system vms
|
||||
self.debug("Creating Public IP range for system vms")
|
||||
public_ip_range = PublicIpRange.create(
|
||||
self.apiclient,
|
||||
services,
|
||||
forsystemvms = True
|
||||
)
|
||||
|
||||
# List Running System VM
|
||||
list_systemvm_response = list_ssvms(
|
||||
self.apiclient,
|
||||
systemvmtype=systemvmtype,
|
||||
state='Running',
|
||||
domainid=public_ip_range.vlan.domainid
|
||||
)
|
||||
self.assertTrue(
|
||||
isinstance(list_systemvm_response, list),
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
self.assertEqual(
|
||||
len(list_systemvm_response),
|
||||
1,
|
||||
"Check list response size"
|
||||
)
|
||||
|
||||
# Delete System VM
|
||||
systemvm = list_systemvm_response[0]
|
||||
self.debug("Destroying System VM: %s" % systemvm.id)
|
||||
cmd = destroySystemVm.destroySystemVmCmd()
|
||||
cmd.id = systemvm.id
|
||||
self.apiclient.destroySystemVm(cmd)
|
||||
|
||||
# Wait for CPVM to start
|
||||
systemvm_id = self.wait_for_system_vm_start(
|
||||
public_ip_range.vlan.domainid,
|
||||
self.services["timeout"],
|
||||
self.services["sleep"],
|
||||
systemvmtype
|
||||
)
|
||||
self.assertNotEqual(
|
||||
systemvm_id,
|
||||
None,
|
||||
"Check CPVM id is not none"
|
||||
)
|
||||
list_systemvm_response = list_ssvms(
|
||||
self.apiclient,
|
||||
id=systemvm_id
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_systemvm_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
systemvm_response = list_systemvm_response[0]
|
||||
self.debug("System VM state after debug: %s" % systemvm_response.state)
|
||||
self.assertEqual(
|
||||
systemvm_response.state,
|
||||
'Running',
|
||||
"Check whether System VM is running or not"
|
||||
)
|
||||
|
||||
# Verify System VM got IP in the created range
|
||||
startip = services["startip"]
|
||||
endip = services["endip"]
|
||||
cpvm_ip = systemvm_response.publicip
|
||||
|
||||
self.assertTrue(
|
||||
self.is_ip_in_range(startip, endip, cpvm_ip),
|
||||
"Check whether System VM Public IP is in range dedicated to system vms"
|
||||
)
|
||||
|
||||
# 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 = public_ip_range.vlan.domainid
|
||||
public_ip_range.delete(self.apiclient)
|
||||
|
||||
# Wait for System VM to start and check System VM public IP
|
||||
systemvm_id = self.wait_for_system_vm_start(
|
||||
domain_id,
|
||||
self.services["timeout"],
|
||||
self.services["sleep"],
|
||||
systemvmtype
|
||||
)
|
||||
list_systemvm_response = list_ssvms(
|
||||
self.apiclient,
|
||||
id=systemvm_id
|
||||
)
|
||||
self.assertFalse(
|
||||
self.is_ip_in_range(startip, endip, list_systemvm_response[0].publicip),
|
||||
"Check System VM Public IP is not in range dedicated to system vms"
|
||||
)
|
||||
|
||||
return True
|
||||
|
||||
def exists_public_ip_range_for_system_vms(self, zoneid):
|
||||
"""
|
||||
Return True if there exists a public IP range dedicated for system vms in zoneid
|
||||
"""
|
||||
existing_ip_ranges_response = PublicIpRange.list(
|
||||
self.apiclient,
|
||||
zoneid=zoneid
|
||||
)
|
||||
for r in existing_ip_ranges_response:
|
||||
if r.forsystemvms:
|
||||
return True
|
||||
return False
|
||||
|
||||
@attr(tags = ["advanced", "publiciprange", "dedicate", "release"], required_hardware="false")
|
||||
def test_dedicate_public_ip_range_for_system_vms_cpvm(self):
|
||||
"""Test CPVM Public IP
|
||||
"""
|
||||
self.debug("Precondition: No public IP range dedicated for system vms in the environment")
|
||||
if self.exists_public_ip_range_for_system_vms(self.services["zoneid"]):
|
||||
self.skipTest("An existing IP range defined for system vms, aborting test")
|
||||
|
||||
services = {
|
||||
"gateway":"192.168.100.1",
|
||||
"netmask":"255.255.255.0",
|
||||
"startip":"192.168.100.2",
|
||||
"endip":"192.168.100.200",
|
||||
"forvirtualnetwork":self.services["forvirtualnetwork"],
|
||||
"zoneid":self.services["zoneid"],
|
||||
"vlan":self.services["vlan"]
|
||||
}
|
||||
|
||||
self.base_system_vm(
|
||||
services,
|
||||
'consoleproxy'
|
||||
)
|
||||
return
|
||||
|
||||
@attr(tags = ["advanced", "publiciprange", "dedicate", "release"], required_hardware="false")
|
||||
def test_dedicate_public_ip_range_for_system_vms_ssvm(self):
|
||||
"""Test SSVM Public IP
|
||||
"""
|
||||
self.debug("Precondition: No public IP range dedicated for system vms in the environment")
|
||||
if self.exists_public_ip_range_for_system_vms(self.services["zoneid"]):
|
||||
self.skipTest("An existing IP range defined for system vms, aborting test")
|
||||
|
||||
services = {
|
||||
"gateway":"192.168.200.1",
|
||||
"netmask":"255.255.255.0",
|
||||
"startip":"192.168.200.2",
|
||||
"endip":"192.168.200.200",
|
||||
"forvirtualnetwork":self.services["forvirtualnetwork"],
|
||||
"zoneid":self.services["zoneid"],
|
||||
"vlan":self.services["vlan"]
|
||||
}
|
||||
|
||||
self.base_system_vm(
|
||||
services,
|
||||
'secondarystoragevm'
|
||||
)
|
||||
return
|
||||
@ -3383,7 +3383,7 @@ class PublicIpRange:
|
||||
self.__dict__.update(items)
|
||||
|
||||
@classmethod
|
||||
def create(cls, apiclient, services, account=None, domainid=None):
|
||||
def create(cls, apiclient, services, account=None, domainid=None, forsystemvms=None):
|
||||
"""Create VlanIpRange"""
|
||||
|
||||
cmd = createVlanIpRange.createVlanIpRangeCmd()
|
||||
@ -3401,6 +3401,8 @@ class PublicIpRange:
|
||||
cmd.account = account
|
||||
if domainid:
|
||||
cmd.domainid = domainid
|
||||
if forsystemvms:
|
||||
cmd.forsystemvms = forsystemvms
|
||||
|
||||
return PublicIpRange(apiclient.createVlanIpRange(cmd).__dict__)
|
||||
|
||||
|
||||
@ -1488,6 +1488,8 @@ var dictionary = {
|
||||
"label.services": "Services",
|
||||
"label.session.expired": "Session Expired",
|
||||
"label.set.default.NIC": "Set default NIC",
|
||||
"label.set.reservation": "Set reservation",
|
||||
"label.set.reservation.desc": "(optional) Please specify an account to be associated with this IP range.<br/><br/>System VMs: Enable dedication of public IP range for SSVM and CPVM, account field disabled. Reservation strictness defined on 'system.vm.public.ip.reservation.mode.strictness'",
|
||||
"label.set.up.zone.type": "Set up zone type",
|
||||
"label.settings": "Settings",
|
||||
"label.setup": "التثبيت",
|
||||
|
||||
@ -1488,6 +1488,8 @@ var dictionary = {
|
||||
"label.services": "Services",
|
||||
"label.session.expired": "Session Expired",
|
||||
"label.set.default.NIC": "Set default NIC",
|
||||
"label.set.reservation": "Set reservation",
|
||||
"label.set.reservation.desc": "(optional) Please specify an account to be associated with this IP range.<br/><br/>System VMs: Enable dedication of public IP range for SSVM and CPVM, account field disabled. Reservation strictness defined on 'system.vm.public.ip.reservation.mode.strictness'",
|
||||
"label.set.up.zone.type": "Set up zone type",
|
||||
"label.settings": "Settings",
|
||||
"label.setup": "Configuració",
|
||||
|
||||
@ -1488,6 +1488,8 @@ var dictionary = {
|
||||
"label.services": "Dienste",
|
||||
"label.session.expired": "Sitzung abgelaufen",
|
||||
"label.set.default.NIC": "Standard-NIC festlegen",
|
||||
"label.set.reservation": "Set reservation",
|
||||
"label.set.reservation.desc": "(optional) Please specify an account to be associated with this IP range.<br/><br/>System VMs: Enable dedication of public IP range for SSVM and CPVM, account field disabled. Reservation strictness defined on 'system.vm.public.ip.reservation.mode.strictness'",
|
||||
"label.set.up.zone.type": "Zonentyp einrichten",
|
||||
"label.settings": "Einstellungen",
|
||||
"label.setup": "Konfiguration",
|
||||
|
||||
@ -1528,6 +1528,8 @@ var dictionary = {"ICMP.code":"ICMP Code",
|
||||
"label.services":"Services",
|
||||
"label.session.expired":"Session Expired",
|
||||
"label.set.default.NIC":"Set default NIC",
|
||||
"label.set.reservation": "Set reservation",
|
||||
"label.set.reservation.desc": "(optional) Please specify an account to be associated with this IP range.<br/><br/>System VMs: Enable dedication of public IP range for SSVM and CPVM, account field disabled. Reservation strictness defined on 'system.vm.public.ip.reservation.mode.strictness'",
|
||||
"label.set.up.zone.type":"Set up zone type",
|
||||
"label.settings":"Settings",
|
||||
"label.setup":"Setup",
|
||||
|
||||
@ -1488,6 +1488,8 @@ var dictionary = {
|
||||
"label.services": "Servicios",
|
||||
"label.session.expired": "Session Caducada",
|
||||
"label.set.default.NIC": "Definir NIC por defecto",
|
||||
"label.set.reservation": "Set reservation",
|
||||
"label.set.reservation.desc": "(optional) Please specify an account to be associated with this IP range.<br/><br/>System VMs: Enable dedication of public IP range for SSVM and CPVM, account field disabled. Reservation strictness defined on 'system.vm.public.ip.reservation.mode.strictness'",
|
||||
"label.set.up.zone.type": "Definir tipo de zona",
|
||||
"label.settings": "Configuración",
|
||||
"label.setup": "Configuración",
|
||||
|
||||
@ -1488,6 +1488,8 @@ var dictionary = {
|
||||
"label.services": "Services",
|
||||
"label.session.expired": "Session expirée",
|
||||
"label.set.default.NIC": "Définir NIC par défaut",
|
||||
"label.set.reservation": "Set reservation",
|
||||
"label.set.reservation.desc": "(optional) Please specify an account to be associated with this IP range.<br/><br/>System VMs: Enable dedication of public IP range for SSVM and CPVM, account field disabled. Reservation strictness defined on 'system.vm.public.ip.reservation.mode.strictness'",
|
||||
"label.set.up.zone.type": "Configurer le type de zone",
|
||||
"label.settings": "Paramètres",
|
||||
"label.setup": "Configuration",
|
||||
|
||||
@ -1488,6 +1488,8 @@ var dictionary = {
|
||||
"label.services": "Szolgáltatások",
|
||||
"label.session.expired": "A munkamenet lejárt",
|
||||
"label.set.default.NIC": "Alapértelmezett NIC beállítása",
|
||||
"label.set.reservation": "Set reservation",
|
||||
"label.set.reservation.desc": "(optional) Please specify an account to be associated with this IP range.<br/><br/>System VMs: Enable dedication of public IP range for SSVM and CPVM, account field disabled. Reservation strictness defined on 'system.vm.public.ip.reservation.mode.strictness'",
|
||||
"label.set.up.zone.type": "Zóna-típus beállítása",
|
||||
"label.settings": "Beállítások",
|
||||
"label.setup": "Beállítások",
|
||||
|
||||
@ -1488,6 +1488,8 @@ var dictionary = {
|
||||
"label.services": "Services",
|
||||
"label.session.expired": "Session Expired",
|
||||
"label.set.default.NIC": "Set default NIC",
|
||||
"label.set.reservation": "Set reservation",
|
||||
"label.set.reservation.desc": "(optional) Please specify an account to be associated with this IP range.<br/><br/>System VMs: Enable dedication of public IP range for SSVM and CPVM, account field disabled. Reservation strictness defined on 'system.vm.public.ip.reservation.mode.strictness'",
|
||||
"label.set.up.zone.type": "Configurazione del tipo di Zona",
|
||||
"label.settings": "Settings",
|
||||
"label.setup": "Installazione",
|
||||
|
||||
@ -1489,6 +1489,8 @@ var dictionary = {
|
||||
"label.services": "サービス",
|
||||
"label.session.expired": "セッションの有効期限が切れました",
|
||||
"label.set.default.NIC": "デフォルト NIC の設定",
|
||||
"label.set.reservation": "Set reservation",
|
||||
"label.set.reservation.desc": "(optional) Please specify an account to be associated with this IP range.<br/><br/>System VMs: Enable dedication of public IP range for SSVM and CPVM, account field disabled. Reservation strictness defined on 'system.vm.public.ip.reservation.mode.strictness'",
|
||||
"label.set.up.zone.type": "ゾーンの種類のセットアップ",
|
||||
"label.settings": "設定",
|
||||
"label.setup": "セットアップ",
|
||||
|
||||
@ -1488,6 +1488,8 @@ var dictionary = {
|
||||
"label.services": "Services",
|
||||
"label.session.expired": "세션 유효기간이 끊어짐",
|
||||
"label.set.default.NIC": "Set default NIC",
|
||||
"label.set.reservation": "Set reservation",
|
||||
"label.set.reservation.desc": "(optional) Please specify an account to be associated with this IP range.<br/><br/>System VMs: Enable dedication of public IP range for SSVM and CPVM, account field disabled. Reservation strictness defined on 'system.vm.public.ip.reservation.mode.strictness'",
|
||||
"label.set.up.zone.type": "Zone 종류 설정",
|
||||
"label.settings": "Settings",
|
||||
"label.setup": "설정",
|
||||
|
||||
@ -1488,6 +1488,8 @@ var dictionary = {
|
||||
"label.services": "Tjenester",
|
||||
"label.session.expired": "Sesjon utløpt",
|
||||
"label.set.default.NIC": "Sett som standard NIC",
|
||||
"label.set.reservation": "Set reservation",
|
||||
"label.set.reservation.desc": "(optional) Please specify an account to be associated with this IP range.<br/><br/>System VMs: Enable dedication of public IP range for SSVM and CPVM, account field disabled. Reservation strictness defined on 'system.vm.public.ip.reservation.mode.strictness'",
|
||||
"label.set.up.zone.type": "Oppsett av sonetype",
|
||||
"label.settings": "Innstillinger",
|
||||
"label.setup": "Oppsett",
|
||||
|
||||
@ -1488,6 +1488,8 @@ var dictionary = {
|
||||
"label.services": "Diensten",
|
||||
"label.session.expired": "Sessie Verlopen",
|
||||
"label.set.default.NIC": "Stel standaard NIC in",
|
||||
"label.set.reservation": "Set reservation",
|
||||
"label.set.reservation.desc": "(optional) Please specify an account to be associated with this IP range.<br/><br/>System VMs: Enable dedication of public IP range for SSVM and CPVM, account field disabled. Reservation strictness defined on 'system.vm.public.ip.reservation.mode.strictness'",
|
||||
"label.set.up.zone.type": "Stel zone type in",
|
||||
"label.settings": "Instellingen",
|
||||
"label.setup": "Instellen",
|
||||
|
||||
@ -1488,6 +1488,8 @@ var dictionary = {
|
||||
"label.services": "Services",
|
||||
"label.session.expired": "Session Expired",
|
||||
"label.set.default.NIC": "Set default NIC",
|
||||
"label.set.reservation": "Set reservation",
|
||||
"label.set.reservation.desc": "(optional) Please specify an account to be associated with this IP range.<br/><br/>System VMs: Enable dedication of public IP range for SSVM and CPVM, account field disabled. Reservation strictness defined on 'system.vm.public.ip.reservation.mode.strictness'",
|
||||
"label.set.up.zone.type": "Set up zone type",
|
||||
"label.settings": "Settings",
|
||||
"label.setup": "Konfiguracja",
|
||||
|
||||
@ -1488,6 +1488,8 @@ var dictionary = {
|
||||
"label.services": "Serviços",
|
||||
"label.session.expired": "Sessão Expirada",
|
||||
"label.set.default.NIC": "Configurar para NIC padrão",
|
||||
"label.set.reservation": "Set reservation",
|
||||
"label.set.reservation.desc": "(optional) Please specify an account to be associated with this IP range.<br/><br/>System VMs: Enable dedication of public IP range for SSVM and CPVM, account field disabled. Reservation strictness defined on 'system.vm.public.ip.reservation.mode.strictness'",
|
||||
"label.set.up.zone.type": "Configurar tipo de zona",
|
||||
"label.settings": "Ajustes",
|
||||
"label.setup": "Configuração",
|
||||
|
||||
@ -1488,6 +1488,8 @@ var dictionary = {
|
||||
"label.services": "Services",
|
||||
"label.session.expired": "Сеанс завершен",
|
||||
"label.set.default.NIC": "Установить NIC по умолчанию",
|
||||
"label.set.reservation": "Set reservation",
|
||||
"label.set.reservation.desc": "(optional) Please specify an account to be associated with this IP range.<br/><br/>System VMs: Enable dedication of public IP range for SSVM and CPVM, account field disabled. Reservation strictness defined on 'system.vm.public.ip.reservation.mode.strictness'",
|
||||
"label.set.up.zone.type": "Настроить тип зоны",
|
||||
"label.settings": "Настройки",
|
||||
"label.setup": "Настройка",
|
||||
|
||||
@ -1489,6 +1489,8 @@ var dictionary = {
|
||||
"label.services": "服务",
|
||||
"label.session.expired": "会话已过期",
|
||||
"label.set.default.NIC": "设置默认 NIC",
|
||||
"label.set.reservation": "Set reservation",
|
||||
"label.set.reservation.desc": "(optional) Please specify an account to be associated with this IP range.<br/><br/>System VMs: Enable dedication of public IP range for SSVM and CPVM, account field disabled. Reservation strictness defined on 'system.vm.public.ip.reservation.mode.strictness'",
|
||||
"label.set.up.zone.type": "设置资源域类型",
|
||||
"label.settings": "设置",
|
||||
"label.setup": "设置",
|
||||
|
||||
@ -1340,5 +1340,8 @@ cloudStack.docs = {
|
||||
},
|
||||
helpLdapLinkDomainAdmin: {
|
||||
desc: 'domain admin of the linked domain. Specify a username in GROUP/OU of LDAP'
|
||||
},
|
||||
helpSetReservationSystemVms: {
|
||||
desc: 'If enabled, IP range reservation is set for SSVM & CPVM. Global setting "system.vm.public.ip.reservation.mode.strictness" is used to control whether reservation is strict or not (preferred)'
|
||||
}
|
||||
};
|
||||
|
||||
@ -54,6 +54,12 @@
|
||||
var data = args.data ? args.data: {
|
||||
};
|
||||
var fields = {
|
||||
systemvms: {
|
||||
label: 'label.system.vms',
|
||||
isBoolean: true,
|
||||
docID: 'helpSetReservationSystemVms',
|
||||
defaultValue: data.systemvms
|
||||
},
|
||||
account: {
|
||||
label: 'label.account',
|
||||
defaultValue: data.account
|
||||
@ -96,22 +102,40 @@
|
||||
success: function (json) {
|
||||
var domain = json.listdomainsresponse.domain[0];
|
||||
|
||||
if (data.forSystemVms != null) {
|
||||
systemvms = '<li>' + _l('label.system.vms') + ': ' + data.forSystemVms + '</li>'
|
||||
}
|
||||
if (data.account != null)
|
||||
cloudStack.dialog.notice({
|
||||
message: '<ul><li>' + _l('label.account') + ': ' + data.account + '</li>' + '<li>' + _l('label.domain') + ': ' + domain.path + '</li></ul>'
|
||||
message: '<ul><li>' + _l('label.account') + ': ' + data.account + '</li>' + '<li>' + _l('label.domain') + ': ' + domain.path + '</li>' + systemvms + '</ul>'
|
||||
});
|
||||
else
|
||||
cloudStack.dialog.notice({
|
||||
message: '<ul><li>' + _l('label.domain') + ': ' + domain.path + '</li></ul>'
|
||||
message: '<ul><li>' + _l('label.domain') + ': ' + domain.path + '</li>' + systemvms + '</ul>'
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
cloudStack.dialog.createForm({
|
||||
form: {
|
||||
title: 'label.add.account',
|
||||
desc: '(optional) Please specify an account to be associated with this IP range.',
|
||||
fields: fields
|
||||
title: 'label.set.reservation',
|
||||
desc: 'label.set.reservation.desc',
|
||||
fields: fields,
|
||||
preFilter: function(args) {
|
||||
var $systemvms = args.$form.find('.form-item[rel=systemvms]');
|
||||
var $systemvmsCb = $systemvms.find('input[type=checkbox]');
|
||||
var $account = args.$form.find('.form-item[rel=account]');
|
||||
var $accountTxt = args.$form.find('input[name=account]');
|
||||
$systemvmsCb.change(function() {
|
||||
if ($systemvmsCb.is(':checked')) {
|
||||
$accountTxt.val('');
|
||||
$accountTxt.attr('disabled', true);
|
||||
}
|
||||
else {
|
||||
$accountTxt.attr('disabled', false);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
after: function (args) {
|
||||
var data = cloudStack.serializeForm(args.$form);
|
||||
@ -438,7 +462,7 @@
|
||||
'account': {
|
||||
label: 'label.account',
|
||||
custom: {
|
||||
buttonLabel: 'label.add.account',
|
||||
buttonLabel: 'label.set.reservation',
|
||||
action: cloudStack.publicIpRangeAccount.dialog()
|
||||
}
|
||||
},
|
||||
@ -466,6 +490,10 @@
|
||||
if (args.data.account) {
|
||||
if (args.data.account.account)
|
||||
array1.push("&account=" + args.data.account.account);
|
||||
if (args.data.account.systemvms) {
|
||||
systvmsval = args.data.account.systemvms == "on" ? "true" : "false"
|
||||
array1.push("&forsystemvms=" + systvmsval);
|
||||
}
|
||||
array1.push("&domainid=" + args.data.account.domainid);
|
||||
}
|
||||
|
||||
@ -627,7 +655,8 @@
|
||||
account: {
|
||||
_buttonLabel: item.account ? '[' + item.domain + '] ' + item.account: item.domain,
|
||||
account: item.account,
|
||||
domainid: item.domainid
|
||||
domainid: item.domainid,
|
||||
forSystemVms: item.forsystemvms
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user