Merge branch 'master' of ssh://git.cloud.com/var/lib/git/cloudstack-oss

This commit is contained in:
Likitha Shetty 2012-02-22 10:18:57 +05:30
commit 2f8181de5e
77 changed files with 2660 additions and 2474 deletions

View File

@ -4,13 +4,6 @@
<dao name="Configuration configuration server" class="com.cloud.configuration.dao.ConfigurationDaoImpl">
<param name="premium">true</param>
</dao>
<system-integrity-checker class="com.cloud.upgrade.DatabaseUpgradeChecker">
<checker name="ManagementServerNode" class="com.cloud.cluster.ManagementServerNode"/>
<checker name="EncryptionSecretKeyChecker" class="com.cloud.utils.crypt.EncryptionSecretKeyChecker"/>
<checker name="DatabaseIntegrityChecker" class="com.cloud.upgrade.DatabaseIntegrityChecker"/>
<checker name="DatabaseUpgradeChecker" class="com.cloud.upgrade.DatabaseUpgradeChecker"/>
</system-integrity-checker>
<adapters key="com.cloud.ha.Investigator">
<adapter name="SimpleInvestigator" class="com.cloud.ha.CheckOnAgentInvestigator"/>
<adapter name="PingInvestigator" class="com.cloud.ha.UserVmDomRInvestigator"/>

View File

@ -325,7 +325,6 @@ public class ApiConstants {
public static final String TRAFFIC_TYPE_IMPLEMENTOR = "traffictypeimplementor";
public static final String KEYWORD = "keyword";
public static final String LIST_ALL = "listall";
public static final String IS_ELASTIC = "iselastic";
public static final String SPECIFY_IP_RANGES = "specifyipranges";
public static final String IS_SOURCE_NAT = "issourcenat";
public static final String IS_STATIC_NAT = "isstaticnat";

View File

@ -124,7 +124,7 @@ public class CreateIpForwardingRuleCmd extends BaseAsyncCreateCmd implements Sta
result = result && _rulesService.applyStaticNatRules(ipAddressId, UserContext.current().getCaller());
rule = _entityMgr.findById(FirewallRule.class, getEntityId());
StaticNatRule staticNatRule = _rulesService.buildStaticNatRule(rule);
StaticNatRule staticNatRule = _rulesService.buildStaticNatRule(rule, false);
IpForwardingRuleResponse fwResponse = _responseGenerator.createIpForwardingRuleResponse(staticNatRule);
fwResponse.setResponseName(getCommandName());
this.setResponseObject(fwResponse);

View File

@ -87,7 +87,7 @@ public class ListIpForwardingRulesCmd extends BaseListProjectAndAccountResources
ListResponse<IpForwardingRuleResponse> response = new ListResponse<IpForwardingRuleResponse>();
List<IpForwardingRuleResponse> ipForwardingResponses = new ArrayList<IpForwardingRuleResponse>();
for (FirewallRule rule : result) {
StaticNatRule staticNatRule = _rulesService.buildStaticNatRule(rule);
StaticNatRule staticNatRule = _rulesService.buildStaticNatRule(rule, false);
IpForwardingRuleResponse resp = _responseGenerator.createIpForwardingRuleResponse(staticNatRule);
if (resp != null) {
ipForwardingResponses.add(resp);

View File

@ -84,11 +84,12 @@ public class ListNetworkOfferingsCmd extends BaseListCmd {
@Parameter(name=ApiConstants.SOURCE_NAT_SUPPORTED, type=CommandType.BOOLEAN, description="true if need to list only netwok offerings where source nat is supported, false otherwise")
private Boolean sourceNatSupported;
@Parameter(name=ApiConstants.SPECIFY_IP_RANGES, type=CommandType.BOOLEAN, description="true if need to list only network offerings which support specifying ip ranges")
private Boolean specifyIpRanges;
@Parameter(name=ApiConstants.TAGS, type=CommandType.STRING, description="list network offerings by tags", length=4096)
private String tags;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@ -149,7 +150,11 @@ public class ListNetworkOfferingsCmd extends BaseListCmd {
return specifyIpRanges;
}
/////////////////////////////////////////////////////
public String getTags() {
return tags;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override

View File

@ -71,8 +71,8 @@ public class IPAddressResponse extends BaseResponse implements ControlledEntityR
@SerializedName("isstaticnat") @Param(description="true if this ip is for static nat, false otherwise")
private Boolean staticNat;
@SerializedName(ApiConstants.IS_ELASTIC) @Param(description="true if this ip is elastic ip (was allocated as a part of deployVm or createLbRule)")
private Boolean isElastic;
@SerializedName(ApiConstants.IS_SYSTEM) @Param(description="true if this ip is system ip (was allocated as a part of deployVm or createLbRule)")
private Boolean isSystem;
@SerializedName(ApiConstants.VIRTUAL_MACHINE_ID) @Param(description="virutal machine id the ip address is assigned to (not null only for static nat Ip)")
private IdentityProxy virtualMachineId = new IdentityProxy("vm_instance");
@ -95,7 +95,7 @@ public class IPAddressResponse extends BaseResponse implements ControlledEntityR
@SerializedName(ApiConstants.PHYSICAL_NETWORK_ID) @Param(description="the physical network this belongs to")
private IdentityProxy physicalNetworkId = new IdentityProxy("physical_network");
@SerializedName(ApiConstants.PURPOSE) @Param(description="purpose of the IP address. In Acton this value is not null for Elastic IPs only, and can have either StaticNat or LB value")
@SerializedName(ApiConstants.PURPOSE) @Param(description="purpose of the IP address. In Acton this value is not null for Ips with isSystem=true, and can have either StaticNat or LB value")
private String purpose;
/*
@ -210,8 +210,8 @@ public class IPAddressResponse extends BaseResponse implements ControlledEntityR
this.physicalNetworkId.setValue(physicalNetworkId);
}
public void setIsElastic(Boolean isElastic) {
this.isElastic = isElastic;
public void setIsSystem(Boolean isSystem) {
this.isSystem = isSystem;
}
public void setPurpose(String purpose) {

View File

@ -1,146 +0,0 @@
/**
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
*
* This software is licensed under the GNU General Public License v3 or later.
*
* It is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.cloud.api.response;
import com.cloud.api.IdentityProxy;
import com.cloud.serializer.Param;
import com.google.gson.annotations.SerializedName;
public class IsoVmResponse extends BaseResponse {
@SerializedName("id") @Param(description="the ISO ID")
private IdentityProxy id = new IdentityProxy("vm_template");
@SerializedName("name") @Param(description="the ISO name")
private String name;
@SerializedName("displaytext") @Param(description="the ISO display text")
private String displayText;
@SerializedName("bootable") @Param(description="true if the ISO is bootable, false otherwise")
private Boolean bootable;
@SerializedName("isfeatured") @Param(description="true if this template is a featured template, false otherwise")
private Boolean featured;
@SerializedName("ostypeid") @Param(description="the ID of the OS type for this template.")
private IdentityProxy osTypeId = new IdentityProxy("guest_os");
@SerializedName("ostypename") @Param(description="the name of the OS type for this template.")
private String osTypeName;
@SerializedName("virtualmachineid") @Param(description="id of the virtual machine")
private IdentityProxy virtualMachineId = new IdentityProxy("vm_instance");
@SerializedName("vmname") @Param(description="name of the virtual machine")
private String virtualMachineName;
@SerializedName("vmdisplayname") @Param(description="display name of the virtual machine")
private String virtualMachineDisplayName;
@SerializedName("vmstate") @Param(description="state of the virtual machine")
private String virtualMachineState;
public Long getOsTypeId() {
return osTypeId.getValue();
}
public void setOsTypeId(Long osTypeId) {
this.osTypeId.setValue(osTypeId);
}
public String getOsTypeName() {
return osTypeName;
}
public void setOsTypeName(String osTypeName) {
this.osTypeName = osTypeName;
}
public Long getId() {
return id.getValue();
}
public void setId(Long id) {
this.id.setValue(id);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDisplayText() {
return displayText;
}
public void setDisplayText(String displayText) {
this.displayText = displayText;
}
public Boolean isBootable() {
return bootable;
}
public void setBootable(Boolean bootable) {
this.bootable = bootable;
}
public Boolean isFeatured() {
return featured;
}
public void setFeatured(Boolean featured) {
this.featured = featured;
}
public Long getVirtualMachineId() {
return virtualMachineId.getValue();
}
public void setVirtualMachineId(Long virtualMachineId) {
this.virtualMachineId.setValue(virtualMachineId);
}
public String getVirtualMachineName() {
return virtualMachineName;
}
public void setVirtualMachineName(String virtualMachineName) {
this.virtualMachineName = virtualMachineName;
}
public String getVirtualMachineDisplayName() {
return virtualMachineDisplayName;
}
public void setVirtualMachineDisplayName(String virtualMachineDisplayName) {
this.virtualMachineDisplayName = virtualMachineDisplayName;
}
public String getVirtualMachineState() {
return virtualMachineState;
}
public void setVirtualMachineState(String virtualMachineState) {
this.virtualMachineState = virtualMachineState;
}
}

View File

@ -83,6 +83,6 @@ public interface IpAddress extends ControlledEntity {
Long getAllocatedInDomainId();
boolean getElastic();
boolean getSystem();
}

View File

@ -42,7 +42,7 @@ public interface NetworkService {
List<? extends Network> getIsolatedNetworksOwnedByAccountInZone(long zoneId, Account owner);
IpAddress allocateIP(long networkId, Account ipOwner, boolean isElastic) throws ResourceAllocationException, InsufficientAddressCapacityException, ConcurrentOperationException;
IpAddress allocateIP(long networkId, Account ipOwner, boolean isSystem) throws ResourceAllocationException, InsufficientAddressCapacityException, ConcurrentOperationException;
/**
* Associates a public IP address for a router.

View File

@ -77,7 +77,7 @@ public interface RulesService {
boolean applyStaticNatRules(long ipAdddressId, Account caller) throws ResourceUnavailableException;
StaticNatRule buildStaticNatRule(FirewallRule rule);
StaticNatRule buildStaticNatRule(FirewallRule rule, boolean forRevoke);
List<String> getSourceCidrs(long ruleId);

View File

@ -1,4 +1,27 @@
#new labels (begin) **********************************************************************************************
label.add.compute.offering=Add compute offering
label.compute.offering=Compute offering
label.compute.offerings=Compute offerings
label.select.offering=Select offering
label.menu.infrastructure=Infrastructure
label.sticky.tablesize=Table size
label.sticky.expire=Expires
label.sticky.cookie-name=Cookie name
label.sticky.mode=Mode
label.sticky.length=Length
label.sticky.holdtime=Hold time
label.sticky.request-learn=Request learn
label.sticky.prefix=Prefix
label.sticky.nocache=No cache
label.sticky.indirect=Indirect
label.sticky.postonly=Post only
label.sticky.domain=Domain
state.Allocating=Allocating
state.Migrating=Migrating
error.please.specify.physical.network.tags=Network offerings is not available until you specify tags for this physical network.
#new labels (end) ************************************************************************************************
state.Stopping=Stopping
message.add.load.balancer.under.ip=The load balancer rule has been added under IP:
message.select.instance=Please select an instance.
@ -182,7 +205,7 @@ message.disable.vpn=Are you sure you want to disable VPN?
label.disable.vpn=Disable VPN
message.enable.vpn=Please confirm that you want VPN access enabled for this IP address.
label.enable.vpn=Enable VPN
message.acquire.new.ip=Please confirm that you would like to acquire a net IP for this network.
message.acquire.new.ip=Please confirm that you would like to acquire a new IP for this network.
label.elastic=Elastic
label.my.network=My network
label.add.vms=Add VMs
@ -299,7 +322,7 @@ label.guest.type=Guest Type
label.specify.IP.ranges=Specify IP ranges
label.conserve.mode=Conserve mode
label.created.by.system=Created by system
label.menu.system.service.offerings=System Service Offerings
label.menu.system.service.offerings=System Offerings
label.add.system.service.offering=Add System Service Offering
label.redundant.router.capability=Redundant router capability
label.supported.source.NAT.type=Supported Source NAT type
@ -420,7 +443,7 @@ label.physical.network=Physical Network
label.public.traffic=Public traffic
label.guest.traffic=Guest Traffic
label.storage.traffic=Storage Traffic
message.setup.physical.network.during.zone.creation=When adding an advanced zone, you need to set up one or more physical networks. Each network corresponds to a NIC on the management server. Each physical network can carry one or more types of traffic, with certain restrictions on how they may be combined.<br/><br/><strong>Drag and drop one or more traffic types</strong> onto each physical network.
message.setup.physical.network.during.zone.creation=When adding an advanced zone, you need to set up one or more physical networks. Each network corresponds to a NIC on the hypervisor. Each physical network can carry one or more types of traffic, with certain restrictions on how they may be combined.<br/><br/><strong>Drag and drop one or more traffic types</strong> onto each physical network.
label.add.physical.network=Add physical network
label.traffic.types=Traffic Types
label.management=Management
@ -451,8 +474,8 @@ label.total.hosts=Total Hosts
label.total.CPU=Total CPU
label.total.memory=Total Memory
label.total.storage=Total Storage
label.purpose=Purpose
#new labels (end) **********************************************************************************************
@ -1236,7 +1259,7 @@ message.add.pod=Add a new pod for zone <b><span id="add_pod_zone_name"></span></
message.add.primary.storage=Add a new Primary Storage for zone <b><span id="zone_name"></span></b>, pod <b><span id="pod_name"></span></b>
message.add.primary=Please specify the following parameters to add a new primary storage
message.add.secondary.storage=Add a new storage for zone <b><span id="zone_name"></span></b>
message.add.service.offering=Please fill in the following data to add a new service offering.
message.add.service.offering=Please fill in the following data to add a new compute offering.
message.add.template=Please enter the following data to create your new template
message.add.volume=Please fill in the following data to add a new volume.
message.additional.networks.desc=Please select additional network(s) that your virtual instance will be connected to.

File diff suppressed because it is too large Load Diff

View File

@ -94,7 +94,7 @@ public class UsageEventVO implements UsageEvent {
}
//IPAddress usage event
public UsageEventVO(String usageType, long accountId, long zoneId, long ipAddressId, String ipAddress, boolean isSourceNat, String guestType, boolean isElastic) {
public UsageEventVO(String usageType, long accountId, long zoneId, long ipAddressId, String ipAddress, boolean isSourceNat, String guestType, boolean isSystem) {
this.type = usageType;
this.accountId = accountId;
this.zoneId = zoneId;
@ -102,7 +102,7 @@ public class UsageEventVO implements UsageEvent {
this.resourceName = ipAddress;
this.size = (isSourceNat ? 1L : 0L);
this.resourceType = guestType;
this.templateId = (isElastic ? 1L : 0L);
this.templateId = (isSystem ? 1L : 0L);
}
public UsageEventVO(String usageType, long accountId, long zoneId, long resourceId, String resourceName, Long offeringId, Long templateId, String resourceType) {

View File

@ -124,7 +124,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
copyTemplateFromSecondaryToPrimary(hyperHost,
primaryStorageDatastoreMo, secondaryStorageUrl,
mountPoint, templateUuidName);
mountPoint, templateName, templateUuidName);
} else {
s_logger.info("Template " + templateName + " has already been setup, skip the template setup process in primary storage");
}
@ -410,9 +410,11 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
return new CreateVolumeFromSnapshotAnswer(cmd, success, details, newVolumeName);
}
// templateName: name in secondary storage
// templateUuid: will be used at hypervisor layer
private void copyTemplateFromSecondaryToPrimary(VmwareHypervisorHost hyperHost, DatastoreMO datastoreMo, String secondaryStorageUrl,
String templatePathAtSecondaryStorage, String templateName) throws Exception {
String templatePathAtSecondaryStorage, String templateName, String templateUuid) throws Exception {
s_logger.info("Executing copyTemplateFromSecondaryToPrimary. secondaryStorage: "
+ secondaryStorageUrl + ", templatePathAtSecondaryStorage: " + templatePathAtSecondaryStorage
@ -425,30 +427,45 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
templateName + "." + ImageFormat.OVA.getFileExtension();
String srcFileName = getOVFFilePath(srcOVAFileName);
if(srcFileName == null) {
if(srcFileName == null) {
Script command = new Script("tar", 0, s_logger);
command.add("--no-same-owner");
command.add("-xf", srcOVAFileName);
command.setWorkDir(secondaryMountPoint + "/" + templatePathAtSecondaryStorage);
s_logger.info("Executing command: " + command.toString());
String result = command.execute();
if(result != null) {
String msg = "Unable to unpack snapshot OVA file at: " + srcOVAFileName;
s_logger.error(msg);
throw new Exception(msg);
}
}
srcFileName = getOVFFilePath(srcOVAFileName);
if(srcFileName == null) {
String msg = "Unable to locate OVF file in template package directory: " + srcOVAFileName;
s_logger.error(msg);
throw new Exception(msg);
}
String vmName = templateName;
String vmName = templateUuid;
hyperHost.importVmFromOVF(srcFileName, vmName, datastoreMo, "thin");
VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(vmName);
if(vmMo == null) {
String msg = "Failed to import OVA template. secondaryStorage: "
+ secondaryStorageUrl + ", templatePathAtSecondaryStorage: " + templatePathAtSecondaryStorage
+ ", templateName: " + templateName;
+ ", templateName: " + templateName + ", templateUuid: " + templateUuid;
s_logger.error(msg);
throw new Exception(msg);
}
if(vmMo.createSnapshot("cloud.template.base", "Base snapshot", false, false)) {
vmMo.setCustomFieldValue(CustomFieldConstants.CLOUD_UUID, templateName);
vmMo.setCustomFieldValue(CustomFieldConstants.CLOUD_UUID, templateUuid);
vmMo.markAsTemplate();
} else {
vmMo.destroy();
String msg = "Unable to create base snapshot for template: " + templateName;
String msg = "Unable to create base snapshot for template, templateName: " + templateName + ", templateUuid: " + templateUuid;
s_logger.error(msg);
throw new Exception(msg);
}

View File

@ -27,8 +27,11 @@ import iControl.CommonVirtualServerDefinition;
import iControl.Interfaces;
import iControl.LocalLBLBMethod;
import iControl.LocalLBNodeAddressBindingStub;
import iControl.LocalLBPersistenceMode;
import iControl.LocalLBPoolBindingStub;
import iControl.LocalLBProfileContextType;
import iControl.LocalLBProfilePersistenceBindingStub;
import iControl.LocalLBProfileULong;
import iControl.LocalLBVirtualServerBindingStub;
import iControl.LocalLBVirtualServerVirtualServerPersistence;
import iControl.LocalLBVirtualServerVirtualServerProfile;
@ -78,6 +81,7 @@ import com.cloud.host.Host;
import com.cloud.network.rules.LbStickinessMethod.StickinessMethodType;
import com.cloud.resource.ServerResource;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.Pair;
import com.cloud.utils.exception.ExecutionException;
import com.cloud.utils.net.NetUtils;
@ -128,6 +132,7 @@ public class F5BigIpResource implements ServerResource {
private NetworkingSelfIPBindingStub _selfIpApi;
private NetworkingRouteDomainBindingStub _routeDomainApi;
private SystemConfigSyncBindingStub _configSyncApi;
private LocalLBProfilePersistenceBindingStub _persistenceProfileApi;
private String _objectNamePathSep = "-";
private String _routeDomainIdentifier = "%";
@ -614,6 +619,7 @@ public class F5BigIpResource implements ServerResource {
_selfIpApi = _interfaces.getNetworkingSelfIP();
_routeDomainApi = _interfaces.getNetworkingRouteDomain();
_configSyncApi = _interfaces.getSystemConfigSync();
_persistenceProfileApi = _interfaces.getLocalLBProfilePersistence();
} catch (Exception e) {
throw new ExecutionException("Failed to log in to BigIp appliance due to " + e.getMessage());
}
@ -635,9 +641,28 @@ public class F5BigIpResource implements ServerResource {
if ((stickyPolicies != null) && (stickyPolicies.length > 0) && (stickyPolicies[0] != null)){
StickinessPolicyTO stickinessPolicy = stickyPolicies[0];
if (StickinessMethodType.LBCookieBased.getName().equalsIgnoreCase(stickinessPolicy.getMethodName())) {
_virtualServerApi.add_persistence_profile(genStringArray(virtualServerName), genPersistenceProfile("cookie"));
} else if (StickinessMethodType.SourceBased.getName().equalsIgnoreCase(stickinessPolicy.getMethodName())) {
_virtualServerApi.add_persistence_profile(genStringArray(virtualServerName), genPersistenceProfile("source_addr"));
String[] profileNames = genStringArray("Cookie-profile-" + virtualServerName);
if (!persistenceProfileExists(profileNames[0])) {
LocalLBPersistenceMode[] lbPersistenceMode = new iControl.LocalLBPersistenceMode[1];
lbPersistenceMode[0] = iControl.LocalLBPersistenceMode.PERSISTENCE_MODE_COOKIE;
_persistenceProfileApi.create(profileNames, lbPersistenceMode);
_virtualServerApi.add_persistence_profile(genStringArray(virtualServerName), genPersistenceProfile(profileNames[0]));
}
List<Pair<String, String>> paramsList = stickinessPolicy.getParams();
for(Pair<String,String> param : paramsList) {
if ("holdtime".equalsIgnoreCase(param.first())) {
long timeout = 180; //F5 default
if (param.second() != null) {
timeout = Long.parseLong(param.second());
}
LocalLBProfileULong[] cookieTimeout = new LocalLBProfileULong[1];
cookieTimeout[0] = new LocalLBProfileULong();
cookieTimeout[0].setValue(timeout);
_persistenceProfileApi.set_cookie_expiration(profileNames, cookieTimeout);
}
}
}
} else {
_virtualServerApi.remove_all_persistence_profiles(genStringArray(virtualServerName));
@ -697,7 +722,24 @@ public class F5BigIpResource implements ServerResource {
throw new ExecutionException(e.getMessage());
}
}
private boolean persistenceProfileExists(String profileName) throws ExecutionException {
try {
String[] persistenceProfileArray = _persistenceProfileApi.get_list();
if (persistenceProfileArray == null) {
return false;
}
for (String profile: persistenceProfileArray) {
if (profile.equalsIgnoreCase(profileName)) {
return true;
}
}
return false;
} catch (RemoteException e) {
throw new ExecutionException(e.getMessage());
}
}
private iControl.CommonVirtualServerDefinition[] genVirtualServerDefinition(String name, LbProtocol protocol, String srcIp, long srcPort) {
CommonVirtualServerDefinition vsDefs[] = {new CommonVirtualServerDefinition()};
vsDefs[0].setName(name);

View File

@ -622,7 +622,7 @@ public class JuniperSrxResource implements ServerResource {
String guestVlanSubnet = NetUtils.getCidrSubNet(guestVlanGateway, cidrSize);
Long publicVlanTag = null;
if (!ip.getVlanId().equals("untagged")) {
if (ip.getVlanId() != null && !ip.getVlanId().equals("untagged")) {
try {
publicVlanTag = Long.parseLong(ip.getVlanId());
} catch (Exception e) {

View File

@ -229,11 +229,13 @@ public class TrafficSentinelResource implements ServerResource {
in.close();
} catch (MalformedURLException e1) {
s_logger.info("Invalid Traffic Sentinel URL",e1);
throw new ExecutionException(e1.getMessage());
} catch (IOException e) {
s_logger.debug("Error in direct network usage accounting",e);
throw new ExecutionException(e.getMessage());
}
} catch (Exception e) {
s_logger.error(e);
s_logger.debug(e);
throw new ExecutionException(e.getMessage());
}
return answer;

View File

@ -205,10 +205,14 @@ class OvmHost(OvmObject):
dct = {}
host = OvmHost()
for name, id in l:
vmPath = host._getVmPathFromPrimaryStorage(name)
vmStatus = db_get_vm(vmPath)
dct[name] = vmStatus['status']
try:
vmPath = host._getVmPathFromPrimaryStorage(name)
vmStatus = db_get_vm(vmPath)
dct[name] = vmStatus['status']
except Exception, e:
logger.debug(OvmHost.getAllVms, "Cannot find link for %s on primary storage, treat it as Error"%name)
dct[name] = 'ERROR'
scanStoppedVmOnPrimaryStorage(dct)
rs = toGson(dct)
logger.info(OvmHost.getAllVms, rs)

View File

@ -374,6 +374,7 @@ if this doesn't resolve the problem, please check oracle manual to see how to of
def copyToPrimary(secMountPoint, volumeFolderOnSecStorage, volumePath, primaryMountPath):
srcPath = join(secMountPoint, volumeFolderOnSecStorage.lstrip("/"), volumePath.lstrip("/"))
if not srcPath.endswith(".raw"): srcPath = srcPath + ".raw"
if not isfile(srcPath): raise Exception("Cannot find volume at %s"%srcPath)
if not exists(primaryMountPath): raise Exception("Primary storage(%s) seems to have gone"%primaryMountPath)
OvmStoragePool()._checkDirSizeForImage(primaryMountPath, srcPath)

View File

@ -298,8 +298,13 @@ class OvmVm(OvmObject):
return SUCC()
logger.info(OvmVm.stop, "Stop vm %s"%vmName)
vmPath = OvmHost()._vmNameToPath(vmName)
# set the VM to RUNNING before starting, OVS agent will check this status
try:
vmPath = OvmHost()._vmNameToPath(vmName)
except Exception, e:
errmsg = fmt_err_msg(e)
logger.info(OvmVm.stop, "Cannot find link for vm %s on primary storage, treating it as stopped\n %s"%(vmName, errmsg))
return SUCC()
# set the VM to RUNNING before stopping, OVS agent will check this status
set_vm_status(vmPath, 'RUNNING')
raiseExceptionIfFail(stop_vm(vmPath))
return SUCC()

View File

@ -695,7 +695,14 @@ public class OvmResourceBase implements ServerResource, HypervisorResource {
}
try {
OvmVm.Details vm = OvmVm.getDetails(_conn, vmName);
OvmVm.Details vm = null;
try {
vm = OvmVm.getDetails(_conn, vmName);
} catch (XmlRpcException e) {
s_logger.debug("Unable to get details of vm: " + vmName + ", treating it as stopped", e);
return new StopAnswer(cmd, "success", 0, 0L, 0L);
}
deleteAllNetworkRulesForVm(vmName);
OvmVm.stop(_conn, vmName);
cleanup(vm);

View File

@ -22,6 +22,8 @@ COMMIT
-A FORWARD -i eth0 -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i eth0 -o eth2 -j ACCEPT
-A FORWARD -i eth2 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i eth0 -o eth0 -m state --state NEW -j ACCEPT
-A FORWARD -i eth0 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
COMMIT
*mangle
:PREROUTING ACCEPT [0:0]

View File

@ -48,6 +48,22 @@ ip_to_dev() {
return 1
}
doHairpinNat () {
local vrGuestIPNetwork=$(sudo ip addr show dev eth0 | grep inet | grep eth0 | awk '{print $2}' )
local vrGuestIP=$(echo $vrGuestIPNetwork | awk -F'/' '{print $1}')
local publicIp=$1
local prot=$2
local port=$3
local guestVmIp=$4
local guestPort=$(echo $5 | sed 's/:/-/')
local op=$6
logger -t cloud "$(basename $0): create HairPin entry : public ip=$publicIp \
instance ip=$guestVmIp proto=$proto portRange=$guestPort op=$op"
(sudo iptables -t nat $op PREROUTING -d $publicIp -i eth0 -p $prot --dport $port -j DNAT --to-destination $guestVmIp:$guestPort &>> $OUTFILE || [ "$op" == "-D" ]) &&
(sudo iptables -t nat $op POSTROUTING -s $vrGuestIPNetwork -p $prot --dport $port -d $guestVmIp -j SNAT -o eth0 --to-source $vrGuestIP &>> $OUTFILE || [ "$op" == "-D" ])
}
#Port (address translation) forwarding for tcp or udp
tcp_or_udp_entry() {
@ -78,6 +94,7 @@ tcp_or_udp_entry() {
--destination-port $port -j MARK --set-mark $tableNo &>> $OUTFILE || [ "$op" == "-D" ]) &&
(sudo iptables -t mangle $op PREROUTING --proto $proto -i $dev -d $publicIp \
--destination-port $port -m state --state NEW -j CONNMARK --save-mark &>> $OUTFILE || [ "$op" == "-D" ]) &&
(doHairpinNat $publicIp $proto $port $instIp $dport0 $op) &&
(sudo iptables -t nat $op OUTPUT --proto $proto -d $publicIp \
--destination-port $port -j DNAT \
--to-destination $instIp:$dport &>> $OUTFILE || [ "$op" == "-D" ]) &&
@ -141,6 +158,7 @@ one_to_one_fw_entry() {
(sudo iptables -t nat $op PREROUTING -i $dev -d $publicIp --proto $proto \
--destination-port $portRange -j DNAT \
--to-destination $instIp &>> $OUTFILE || [ "$op" == "-D" ]) &&
(doHairpinNat $publicIp $proto $portRange $instIp $portRange $op) &&
(sudo iptables $op FORWARD -i $dev -o eth0 -d $instIp --proto $proto \
--destination-port $portRange -m state \
--state NEW -j ACCEPT &>> $OUTFILE )

View File

@ -214,7 +214,7 @@ add_snat() {
local ipNoMask=$(echo $1 | awk -F'/' '{print $1}')
logger -t cloud "$(basename $0):Added SourceNAT $pubIp on interface $ethDev"
sudo iptables -t nat -D POSTROUTING -j SNAT -o $ethDev --to-source $ipNoMask ;
sudo iptables -t nat -I POSTROUTING -j SNAT -o $ethDev --to-source $ipNoMask ;
sudo iptables -t nat -A POSTROUTING -j SNAT -o $ethDev --to-source $ipNoMask ;
return $?
}
remove_snat() {

View File

@ -715,7 +715,7 @@ public class ApiResponseHelper implements ResponseGenerator {
ipResponse.setZoneId(zoneId);
ipResponse.setZoneName(ApiDBUtils.findZoneById(ipAddress.getDataCenterId()).getName());
ipResponse.setSourceNat(ipAddress.isSourceNat());
ipResponse.setIsElastic(ipAddress.getElastic());
ipResponse.setIsSystem(ipAddress.getSystem());
// get account information
populateOwner(ipResponse, ipAddress);
@ -727,7 +727,11 @@ public class ApiResponseHelper implements ResponseGenerator {
UserVm vm = ApiDBUtils.findUserVmById(ipAddress.getAssociatedWithVmId());
ipResponse.setVirtualMachineId(vm.getId());
ipResponse.setVirtualMachineName(vm.getHostName());
ipResponse.setVirtualMachineDisplayName(vm.getDisplayName());
if (vm.getDisplayName() != null) {
ipResponse.setVirtualMachineDisplayName(vm.getDisplayName());
} else {
ipResponse.setVirtualMachineDisplayName(vm.getHostName());
}
}
ipResponse.setAssociatedNetworkId(ipAddress.getAssociatedWithNetworkId());
@ -760,7 +764,7 @@ public class ApiResponseHelper implements ResponseGenerator {
ipResponse.setVlanName(ApiDBUtils.findVlanById(ipAddress.getVlanId()).getVlanTag());
}
if (ipAddress.getElastic()) {
if (ipAddress.getSystem()) {
if (ipAddress.isOneToOneNat()) {
ipResponse.setPurpose(IpAddress.Purpose.StaticNat.toString());
} else {
@ -972,7 +976,11 @@ public class ApiResponseHelper implements ResponseGenerator {
volResponse.setVirtualMachineName(vm.getHostName());
UserVm userVm = ApiDBUtils.findUserVmById(vm.getId());
if (userVm != null) {
volResponse.setVirtualMachineDisplayName(userVm.getDisplayName());
if (userVm.getDisplayName() != null) {
volResponse.setVirtualMachineDisplayName(userVm.getDisplayName());
} else {
volResponse.setVirtualMachineDisplayName(userVm.getHostName());
}
volResponse.setVirtualMachineState(vm.getState().toString());
} else {
s_logger.error("User Vm with Id: " + instanceId + " does not exist for volume " + volume.getId());
@ -1175,7 +1183,12 @@ public class ApiResponseHelper implements ResponseGenerator {
if (vm != null) {
response.setVirtualMachineId(vm.getId());
response.setVirtualMachineName(vm.getHostName());
response.setVirtualMachineDisplayName(vm.getDisplayName());
if (vm.getDisplayName() != null) {
response.setVirtualMachineDisplayName(vm.getDisplayName());
} else {
response.setVirtualMachineDisplayName(vm.getHostName());
}
}
}
FirewallRule.State state = fwRule.getState();
@ -1203,7 +1216,11 @@ public class ApiResponseHelper implements ResponseGenerator {
if (vm != null) {// vm might be destroyed
response.setVirtualMachineId(vm.getId());
response.setVirtualMachineName(vm.getHostName());
response.setVirtualMachineDisplayName(vm.getDisplayName());
if (vm.getDisplayName() != null) {
response.setVirtualMachineDisplayName(vm.getDisplayName());
} else {
response.setVirtualMachineDisplayName(vm.getHostName());
}
}
}
FirewallRule.State state = fwRule.getState();

View File

@ -261,8 +261,8 @@ public class GetUsageRecordsCmd extends BaseListCmd {
} else if(usageRecord.getUsageType() == UsageTypes.IP_ADDRESS){
//isSourceNAT
usageRecResponse.setSourceNat((usageRecord.getType().equals("SourceNat"))?true:false);
//isElastic
usageRecResponse.setElastic((usageRecord.getSize() == 1)?true:false);
//isSystem
usageRecResponse.setSystem((usageRecord.getSize() == 1)?true:false);
//IP Address ID
usageRecResponse.setUsageId(identityDao.getIdentityUuid("user_ip_address", usageRecord.getUsageId().toString()));

View File

@ -633,7 +633,7 @@ public class CapacityManagerImpl implements CapacityManager, StateListener<State
releaseVmCapacity(vm, false, false, oldHostId);
}
} else if (oldState == State.Stopped) {
if (event == Event.DestroyRequested) {
if (event == Event.DestroyRequested || event == Event.ExpungeOperation) {
releaseVmCapacity(vm, true, false, vm.getLastHostId());
} else if(event == Event.AgentReportMigrated) {
releaseVmCapacity(vm, false, false, oldHostId);

View File

@ -212,7 +212,7 @@ public enum Config {
CapacitySkipcountingHours("Advanced", ManagementServer.class, Integer.class, "capacity.skipcounting.hours", "3600", "Time (in seconds) to wait before release VM's cpu and memory when VM in stopped state", null),
VmStatsInterval("Advanced", ManagementServer.class, Integer.class, "vm.stats.interval", "60000", "The interval (in milliseconds) when vm stats are retrieved from agents.", null),
VmTransitionWaitInterval("Advanced", ManagementServer.class, Integer.class, "vm.tranisition.wait.interval", "3600", "Time (in seconds) to wait before taking over a VM in transition state", null),
VmDestroyForcestop("Advanced", ManagementServer.class, Boolean.class, "vm.destory.forcestop", "false", "On destory, force-stop takes this value ", null),
VmDestroyForcestop("Advanced", ManagementServer.class, Boolean.class, "vm.destroy.forcestop", "false", "On destroy, force-stop takes this value ", null),
ControlCidr("Advanced", ManagementServer.class, String.class, "control.cidr", "169.254.0.0/16", "Changes the cidr for the control network traffic. Defaults to using link local. Must be unique within pods", null),
ControlGateway("Advanced", ManagementServer.class, String.class, "control.gateway", "169.254.0.1", "gateway for the control network traffic", null),

View File

@ -3213,7 +3213,7 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura
boolean perAccount = value.contains("peraccount");
boolean perZone = value.contains("perzone");
if ((perAccount && perZone) || (!perAccount && !perZone)) {
throw new InvalidParameterValueException("Either perAccount or perZone source NAT type can be specified for " + Capability.SupportedSourceNatTypes.getName());
throw new InvalidParameterValueException("Either peraccount or perzone source NAT type can be specified for " + Capability.SupportedSourceNatTypes.getName());
}
} else if (capability == Capability.RedundantRouter) {
boolean enabled = value.contains("true");
@ -3311,7 +3311,7 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura
boolean sharedSourceNat = false;
boolean redundantRouter = false;
if ((sourceNatServiceCapabilityMap != null) && (!sourceNatServiceCapabilityMap.isEmpty())) {
String sourceNatType = sourceNatServiceCapabilityMap.get(Capability.SupportedSourceNatTypes.getName());
String sourceNatType = sourceNatServiceCapabilityMap.get(Capability.SupportedSourceNatTypes);
if (sourceNatType != null) {
_networkMgr.checkCapabilityForProvider(serviceProviderMap.get(Service.SourceNat), Service.SourceNat, Capability.SupportedSourceNatTypes, sourceNatType);
sharedSourceNat = sourceNatType.contains("perzone");
@ -3391,6 +3391,7 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura
String guestIpType = cmd.getGuestIpType();
List<String> supportedServicesStr = cmd.getSupportedServices();
Object specifyIpRanges = cmd.getSpecifyIpRanges();
String tags = cmd.getTags();
if (zoneId != null) {
zone = getZone(zoneId);
@ -3483,6 +3484,14 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura
if (id != null) {
sc.addAnd("id", SearchCriteria.Op.EQ, id);
}
if (tags != null) {
if (tags.isEmpty()) {
sc.addAnd("tags", SearchCriteria.Op.NULL);
} else {
sc.addAnd("tags", SearchCriteria.Op.EQ, tags);
}
}
List<NetworkOfferingVO> offerings = _networkOfferingDao.search(sc, searchFilter);
Boolean sourceNatSupported = cmd.getSourceNatSupported();

View File

@ -72,7 +72,7 @@ import com.cloud.keystore.KeystoreDaoImpl;
import com.cloud.keystore.KeystoreManagerImpl;
import com.cloud.maint.UpgradeManagerImpl;
import com.cloud.maint.dao.AgentUpgradeDaoImpl;
import com.cloud.network.ExternalLoadBalancerDeviceManagerImpl;
import com.cloud.network.ExternalLoadBalancerUsageManagerImpl;
import com.cloud.network.NetworkManagerImpl;
import com.cloud.network.StorageNetworkManagerImpl;
import com.cloud.network.dao.ExternalFirewallDeviceDaoImpl;
@ -388,7 +388,7 @@ public class DefaultComponentLibrary extends ComponentLibraryBase implements Com
addManager("ElasticLoadBalancerManager", ElasticLoadBalancerManagerImpl.class);
addManager("SwiftManager", SwiftManagerImpl.class);
addManager("StorageNetworkManager", StorageNetworkManagerImpl.class);
addManager("ExternalLoadBalancerDeviceManager", ExternalLoadBalancerDeviceManagerImpl.class);
addManager("ExternalLoadBalancerUsageManager", ExternalLoadBalancerUsageManagerImpl.class);
addManager("HA Manager", HighAvailabilityManagerImpl.class);
}

View File

@ -101,11 +101,4 @@ public interface ExternalLoadBalancerDeviceManager extends Manager{
public boolean manageGuestNetworkWithExternalLoadBalancer(boolean add, Network guestConfig) throws ResourceUnavailableException,
InsufficientCapacityException;
/**
* updates the network usage stats for a LB rule, associated with an external LB device, that is being revoked as part of Delete LB rule or release IP actions
* @param loadBalancerRuleId
*/
public void updateExternalLoadBalancerNetworkUsageStats(long loadBalancerRuleId);
}

View File

@ -25,19 +25,13 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.ejb.Local;
import javax.naming.ConfigurationException;
import org.apache.log4j.Logger;
import com.cloud.agent.AgentManager;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.ExternalNetworkResourceUsageAnswer;
import com.cloud.agent.api.ExternalNetworkResourceUsageCommand;
import com.cloud.agent.api.StartupCommand;
import com.cloud.agent.api.StartupExternalLoadBalancerCommand;
import com.cloud.agent.api.routing.CreateLoadBalancerApplianceCommand;
@ -108,28 +102,22 @@ import com.cloud.resource.UnableDeleteHostException;
import com.cloud.server.api.response.ExternalLoadBalancerResponse;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.AccountVO;
import com.cloud.user.UserStatisticsVO;
import com.cloud.user.dao.AccountDao;
import com.cloud.user.dao.UserStatisticsDao;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.component.AdapterBase;
import com.cloud.utils.component.Inject;
import com.cloud.utils.concurrency.NamedThreadFactory;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.GlobalLock;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.exception.ExecutionException;
import com.cloud.utils.net.NetUtils;
import com.cloud.utils.net.UrlUtil;
import com.cloud.vm.DomainRouterVO;
import com.cloud.vm.Nic.ReservationStrategy;
import com.cloud.vm.Nic.State;
import com.cloud.vm.NicVO;
import com.cloud.vm.dao.DomainRouterDao;
import com.cloud.vm.dao.NicDao;
@Local(value = { ExternalLoadBalancerDeviceManager.class })
public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase implements ExternalLoadBalancerDeviceManager, ResourceStateAdapter {
@Inject
@ -189,8 +177,6 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase
@Inject
protected HostPodDao _podDao = null;
ScheduledExecutorService _executor;
private int _externalNetworkStatsInterval;
private long _defaultLbCapacity;
private static final org.apache.log4j.Logger s_logger = Logger.getLogger(ExternalLoadBalancerDeviceManagerImpl.class);
@ -1005,11 +991,6 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase
@Override
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
super.configure(name, params);
_externalNetworkStatsInterval = NumbersUtil.parseInt(_configDao.getValue(Config.ExternalNetworkStatsInterval.key()), 300);
if (_externalNetworkStatsInterval > 0) {
_executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("ExternalNetworkMonitor"));
}
_defaultLbCapacity = NumbersUtil.parseLong(_configDao.getValue(Config.DefaultExternalLoadBalancerCapacity.key()), 50);
_resourceMgr.registerResourceStateAdapter(this.getClass().getSimpleName(), this);
return true;
@ -1017,9 +998,6 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase
@Override
public boolean start() {
if (_externalNetworkStatsInterval > 0) {
_executor.scheduleAtFixedRate(new ExternalLoadBalancerDeviceNetworkUsageTask(), _externalNetworkStatsInterval, _externalNetworkStatsInterval, TimeUnit.SECONDS);
}
return true;
}
@ -1028,382 +1006,6 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase
return true;
}
protected class ExternalLoadBalancerDeviceNetworkUsageTask implements Runnable {
public ExternalLoadBalancerDeviceNetworkUsageTask() {
}
@Override
public void run() {
GlobalLock scanLock = GlobalLock.getInternLock("ExternalLoadBalancerDeviceManagerImpl");
try {
if (scanLock.lock(20)) {
try {
runExternalLoadBalancerNetworkUsageTask();
} finally {
scanLock.unlock();
}
}
} catch (Exception e) {
s_logger.warn("Problems while getting external load balancer device usage", e);
} finally {
scanLock.releaseRef();
}
}
private void runExternalLoadBalancerNetworkUsageTask() {
s_logger.debug("External load balancer devices stats collector is running...");
for (DataCenterVO zone : _dcDao.listAll()) {
List<DomainRouterVO> domainRoutersInZone = _routerDao.listByDataCenter(zone.getId());
if (domainRoutersInZone == null) {
continue;
}
Map<Long, ExternalNetworkResourceUsageAnswer> lbDeviceUsageAnswerMap = new HashMap<Long, ExternalNetworkResourceUsageAnswer>();
List<Long> accountsProcessed = new ArrayList<Long>();
for (DomainRouterVO domainRouter : domainRoutersInZone) {
long accountId = domainRouter.getAccountId();
if (accountsProcessed.contains(new Long(accountId))) {
if (s_logger.isTraceEnabled()) {
s_logger.trace("Networks for Account " + accountId + " are already processed for external network usage, so skipping usage check.");
}
continue;
}
long zoneId = zone.getId();
List<NetworkVO> networksForAccount = _networkDao.listBy(accountId, zoneId, Network.GuestType.Isolated);
if (networksForAccount == null) {
continue;
}
for (NetworkVO network : networksForAccount) {
if (!_networkMgr.networkIsConfiguredForExternalNetworking(zoneId, network.getId())) {
s_logger.debug("Network " + network.getId() + " is not configured for external networking, so skipping usage check.");
continue;
}
ExternalLoadBalancerDeviceVO lbDeviceVO = getExternalLoadBalancerForNetwork(network);
if (lbDeviceVO == null) {
continue;
}
// Get network stats from the external load balancer
ExternalNetworkResourceUsageAnswer lbAnswer = null;
HostVO externalLoadBalancer = _hostDao.findById(lbDeviceVO.getHostId());
if (externalLoadBalancer != null) {
Long lbDeviceId = new Long(externalLoadBalancer.getId());
if (!lbDeviceUsageAnswerMap.containsKey(lbDeviceId)) {
ExternalNetworkResourceUsageCommand cmd = new ExternalNetworkResourceUsageCommand();
lbAnswer = (ExternalNetworkResourceUsageAnswer) _agentMgr.easySend(externalLoadBalancer.getId(), cmd);
if (lbAnswer == null || !lbAnswer.getResult()) {
String details = (lbAnswer != null) ? lbAnswer.getDetails() : "details unavailable";
String msg = "Unable to get external load balancer stats for " + zone.getName() + " due to: " + details + ".";
s_logger.error(msg);
continue;
}
lbDeviceUsageAnswerMap.put(lbDeviceId, lbAnswer);
} else {
if (s_logger.isTraceEnabled()) {
s_logger.trace("Reusing usage Answer for device id " + lbDeviceId + "for Network " + network.getId());
}
lbAnswer = lbDeviceUsageAnswerMap.get(lbDeviceId);
}
}
AccountVO account = _accountDao.findById(accountId);
if (account == null) {
s_logger.debug("Skipping stats update for account with ID " + accountId);
continue;
}
if (!manageStatsEntries(true, accountId, zoneId, network, externalLoadBalancer, lbAnswer)) {
continue;
}
manageStatsEntries(false, accountId, zoneId, network, externalLoadBalancer, lbAnswer);
}
accountsProcessed.add(new Long(accountId));
}
}
}
private boolean updateBytes(UserStatisticsVO userStats, long newCurrentBytesSent, long newCurrentBytesReceived) {
long oldNetBytesSent = userStats.getNetBytesSent();
long oldNetBytesReceived = userStats.getNetBytesReceived();
long oldCurrentBytesSent = userStats.getCurrentBytesSent();
long oldCurrentBytesReceived = userStats.getCurrentBytesReceived();
String warning = "Received an external network stats byte count that was less than the stored value. Zone ID: " + userStats.getDataCenterId() + ", account ID: " + userStats.getAccountId() + ".";
userStats.setCurrentBytesSent(newCurrentBytesSent);
if (oldCurrentBytesSent > newCurrentBytesSent) {
s_logger.warn(warning + "Stored bytes sent: " + oldCurrentBytesSent + ", new bytes sent: " + newCurrentBytesSent + ".");
userStats.setNetBytesSent(oldNetBytesSent + oldCurrentBytesSent);
}
userStats.setCurrentBytesReceived(newCurrentBytesReceived);
if (oldCurrentBytesReceived > newCurrentBytesReceived) {
s_logger.warn(warning + "Stored bytes received: " + oldCurrentBytesReceived + ", new bytes received: " + newCurrentBytesReceived + ".");
userStats.setNetBytesReceived(oldNetBytesReceived + oldCurrentBytesReceived);
}
return _userStatsDao.update(userStats.getId(), userStats);
}
// Creates a new stats entry for the specified parameters, if one doesn't already exist.
private boolean createStatsEntry(long accountId, long zoneId, long networkId, String publicIp, long hostId) {
HostVO host = _hostDao.findById(hostId);
UserStatisticsVO userStats = _userStatsDao.findBy(accountId, zoneId, networkId, publicIp, hostId, host.getType().toString());
if (userStats == null) {
return (_userStatsDao.persist(new UserStatisticsVO(accountId, zoneId, publicIp, hostId, host.getType().toString(), networkId)) != null);
} else {
return true;
}
}
// Updates an existing stats entry with new data from the specified usage answer.
private boolean updateStatsEntry(long accountId, long zoneId, long networkId, String publicIp, long hostId, ExternalNetworkResourceUsageAnswer answer) {
AccountVO account = _accountDao.findById(accountId);
DataCenterVO zone = _dcDao.findById(zoneId);
NetworkVO network = _networkDao.findById(networkId);
HostVO host = _hostDao.findById(hostId);
String statsEntryIdentifier = "account " + account.getAccountName() + ", zone " + zone.getName() + ", network ID " + networkId + ", host ID " + host.getName();
long newCurrentBytesSent = 0;
long newCurrentBytesReceived = 0;
if (publicIp != null) {
long[] bytesSentAndReceived = null;
statsEntryIdentifier += ", public IP: " + publicIp;
if (host.getType().equals(Host.Type.ExternalLoadBalancer) && externalLoadBalancerIsInline(host)) {
// Look up stats for the guest IP address that's mapped to the public IP address
InlineLoadBalancerNicMapVO mapping = _inlineLoadBalancerNicMapDao.findByPublicIpAddress(publicIp);
if (mapping != null) {
NicVO nic = _nicDao.findById(mapping.getNicId());
String loadBalancingIpAddress = nic.getIp4Address();
bytesSentAndReceived = answer.ipBytes.get(loadBalancingIpAddress);
if (bytesSentAndReceived != null) {
bytesSentAndReceived[0] = 0;
}
}
} else {
bytesSentAndReceived = answer.ipBytes.get(publicIp);
}
if (bytesSentAndReceived == null) {
s_logger.debug("Didn't get an external network usage answer for public IP " + publicIp);
} else {
newCurrentBytesSent += bytesSentAndReceived[0];
newCurrentBytesReceived += bytesSentAndReceived[1];
}
} else {
URI broadcastURI = network.getBroadcastUri();
if (broadcastURI == null) {
s_logger.debug("Not updating stats for guest network with ID " + network.getId() + " because the network is not implemented.");
return true;
} else {
long vlanTag = Integer.parseInt(broadcastURI.getHost());
long[] bytesSentAndReceived = answer.guestVlanBytes.get(String.valueOf(vlanTag));
if (bytesSentAndReceived == null) {
s_logger.warn("Didn't get an external network usage answer for guest VLAN " + vlanTag);
} else {
newCurrentBytesSent += bytesSentAndReceived[0];
newCurrentBytesReceived += bytesSentAndReceived[1];
}
}
}
UserStatisticsVO userStats;
try {
userStats = _userStatsDao.lock(accountId, zoneId, networkId, publicIp, hostId, host.getType().toString());
} catch (Exception e) {
s_logger.warn("Unable to find user stats entry for " + statsEntryIdentifier);
return false;
}
if (updateBytes(userStats, newCurrentBytesSent, newCurrentBytesReceived)) {
s_logger.debug("Successfully updated stats for " + statsEntryIdentifier);
return true;
} else {
s_logger.debug("Failed to update stats for " + statsEntryIdentifier);
return false;
}
}
private boolean createOrUpdateStatsEntry(boolean create, long accountId, long zoneId, long networkId, String publicIp, long hostId, ExternalNetworkResourceUsageAnswer answer) {
if (create) {
return createStatsEntry(accountId, zoneId, networkId, publicIp, hostId);
} else {
return updateStatsEntry(accountId, zoneId, networkId, publicIp, hostId, answer);
}
}
/*
* Creates/updates all necessary stats entries for an account and zone.
* Stats entries are created for source NAT IP addresses, static NAT rules, port forwarding rules, and load
* balancing rules
*/
private boolean manageStatsEntries(boolean create, long accountId, long zoneId, Network network,
HostVO externalLoadBalancer, ExternalNetworkResourceUsageAnswer lbAnswer) {
String accountErrorMsg = "Failed to update external network stats entry. Details: account ID = " + accountId;
Transaction txn = Transaction.open(Transaction.CLOUD_DB);
try {
txn.start();
String networkErrorMsg = accountErrorMsg + ", network ID = " + network.getId();
// If an external load balancer is added, manage one entry for each load balancing rule in this network
if (externalLoadBalancer != null && lbAnswer != null) {
List<LoadBalancerVO> loadBalancers = _loadBalancerDao.listByNetworkId(network.getId());
for (LoadBalancerVO loadBalancer : loadBalancers) {
String publicIp = _networkMgr.getIp(loadBalancer.getSourceIpAddressId()).getAddress().addr();
if (!createOrUpdateStatsEntry(create, accountId, zoneId, network.getId(), publicIp, externalLoadBalancer.getId(), lbAnswer)) {
throw new ExecutionException(networkErrorMsg + ", load balancing rule public IP = " + publicIp);
}
}
}
return txn.commit();
} catch (Exception e) {
s_logger.warn("Exception: ", e);
txn.rollback();
return false;
} finally {
txn.close();
}
}
}
@Override
public void updateExternalLoadBalancerNetworkUsageStats(long loadBalancerRuleId){
LoadBalancerVO lb = _loadBalancerDao.findById(loadBalancerRuleId);
if(lb == null){
if(s_logger.isDebugEnabled()){
s_logger.debug("Cannot update usage stats, LB rule is not found");
}
return;
}
long networkId = lb.getNetworkId();
Network network = _networkDao.findById(networkId);
if(network == null){
if(s_logger.isDebugEnabled()){
s_logger.debug("Cannot update usage stats, Network is not found");
}
return;
}
ExternalLoadBalancerDeviceVO lbDeviceVO = getExternalLoadBalancerForNetwork(network);
if (lbDeviceVO == null) {
if(s_logger.isDebugEnabled()){
s_logger.debug("Cannot update usage stats, No external LB device found");
}
return;
}
// Get network stats from the external load balancer
ExternalNetworkResourceUsageAnswer lbAnswer = null;
HostVO externalLoadBalancer = _hostDao.findById(lbDeviceVO.getHostId());
if (externalLoadBalancer != null) {
ExternalNetworkResourceUsageCommand cmd = new ExternalNetworkResourceUsageCommand();
lbAnswer = (ExternalNetworkResourceUsageAnswer) _agentMgr.easySend(externalLoadBalancer.getId(), cmd);
if (lbAnswer == null || !lbAnswer.getResult()) {
String details = (lbAnswer != null) ? lbAnswer.getDetails() : "details unavailable";
String msg = "Unable to get external load balancer stats for network" + networkId + " due to: " + details + ".";
s_logger.error(msg);
return;
}
}
long accountId = lb.getAccountId();
AccountVO account = _accountDao.findById(accountId);
if (account == null) {
s_logger.debug("Skipping stats update for external LB for account with ID " + accountId);
return;
}
String publicIp = _networkMgr.getIp(lb.getSourceIpAddressId()).getAddress().addr();
DataCenterVO zone = _dcDao.findById(network.getDataCenterId());
String statsEntryIdentifier = "account " + account.getAccountName() + ", zone " + zone.getName() + ", network ID " + networkId + ", host ID " + externalLoadBalancer.getName();
long newCurrentBytesSent = 0;
long newCurrentBytesReceived = 0;
if (publicIp != null) {
long[] bytesSentAndReceived = null;
statsEntryIdentifier += ", public IP: " + publicIp;
if (externalLoadBalancer.getType().equals(Host.Type.ExternalLoadBalancer) && externalLoadBalancerIsInline(externalLoadBalancer)) {
// Look up stats for the guest IP address that's mapped to the public IP address
InlineLoadBalancerNicMapVO mapping = _inlineLoadBalancerNicMapDao.findByPublicIpAddress(publicIp);
if (mapping != null) {
NicVO nic = _nicDao.findById(mapping.getNicId());
String loadBalancingIpAddress = nic.getIp4Address();
bytesSentAndReceived = lbAnswer.ipBytes.get(loadBalancingIpAddress);
if (bytesSentAndReceived != null) {
bytesSentAndReceived[0] = 0;
}
}
} else {
bytesSentAndReceived = lbAnswer.ipBytes.get(publicIp);
}
if (bytesSentAndReceived == null) {
s_logger.debug("Didn't get an external network usage answer for public IP " + publicIp);
} else {
newCurrentBytesSent += bytesSentAndReceived[0];
newCurrentBytesReceived += bytesSentAndReceived[1];
}
UserStatisticsVO userStats;
final Transaction txn = Transaction.currentTxn();
try {
txn.start();
userStats = _userStatsDao.lock(accountId, zone.getId(), networkId, publicIp, externalLoadBalancer.getId(), externalLoadBalancer.getType().toString());
if(userStats != null){
long oldNetBytesSent = userStats.getNetBytesSent();
long oldNetBytesReceived = userStats.getNetBytesReceived();
long oldCurrentBytesSent = userStats.getCurrentBytesSent();
long oldCurrentBytesReceived = userStats.getCurrentBytesReceived();
String warning = "Received an external network stats byte count that was less than the stored value. Zone ID: " + userStats.getDataCenterId() + ", account ID: " + userStats.getAccountId() + ".";
userStats.setCurrentBytesSent(newCurrentBytesSent);
if (oldCurrentBytesSent > newCurrentBytesSent) {
s_logger.warn(warning + "Stored bytes sent: " + oldCurrentBytesSent + ", new bytes sent: " + newCurrentBytesSent + ".");
userStats.setNetBytesSent(oldNetBytesSent + oldCurrentBytesSent);
}
userStats.setCurrentBytesReceived(newCurrentBytesReceived);
if (oldCurrentBytesReceived > newCurrentBytesReceived) {
s_logger.warn(warning + "Stored bytes received: " + oldCurrentBytesReceived + ", new bytes received: " + newCurrentBytesReceived + ".");
userStats.setNetBytesReceived(oldNetBytesReceived + oldCurrentBytesReceived);
}
if (_userStatsDao.update(userStats.getId(), userStats)) {
s_logger.debug("Successfully updated stats for " + statsEntryIdentifier);
} else {
s_logger.debug("Failed to update stats for " + statsEntryIdentifier);
}
}else {
s_logger.warn("Unable to find user stats entry for " + statsEntryIdentifier);
}
txn.commit();
}catch (final Exception e) {
txn.rollback();
throw new CloudRuntimeException("Problem getting stats after reboot/stop ", e);
}
}
}
@Override
public HostVO createHostVOForConnectedAgent(HostVO host, StartupCommand[] cmd) {
// TODO Auto-generated method stub

View File

@ -0,0 +1,36 @@
/**
* * Copyright (C) 2011 Citrix Systems, Inc. All rights reserved
*
*
* This software is licensed under the GNU General Public License v3 or later.
*
* It is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.cloud.network;
import com.cloud.utils.component.Manager;
/* ExternalLoadBalancerUsageManager implements a periodic task that retrieves and updates the network usage stats from all external load balancer devices.
*/
public interface ExternalLoadBalancerUsageManager extends Manager{
/**
* updates the network usage stats for a LB rule, associated with an external LB device, that is being revoked as part of Delete LB rule or release IP actions
* @param loadBalancerRuleId
*/
public void updateExternalLoadBalancerNetworkUsageStats(long loadBalancerRuleId);
}

View File

@ -0,0 +1,546 @@
package com.cloud.network;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.ejb.Local;
import javax.naming.ConfigurationException;
import org.apache.log4j.Logger;
import com.cloud.agent.AgentManager;
import com.cloud.agent.api.ExternalNetworkResourceUsageAnswer;
import com.cloud.agent.api.ExternalNetworkResourceUsageCommand;
import com.cloud.configuration.Config;
import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.dc.dao.HostPodDao;
import com.cloud.dc.dao.VlanDao;
import com.cloud.host.DetailVO;
import com.cloud.host.Host;
import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao;
import com.cloud.host.dao.HostDetailsDao;
import com.cloud.network.dao.ExternalFirewallDeviceDao;
import com.cloud.network.dao.ExternalLoadBalancerDeviceDao;
import com.cloud.network.dao.IPAddressDao;
import com.cloud.network.dao.InlineLoadBalancerNicMapDao;
import com.cloud.network.dao.LoadBalancerDao;
import com.cloud.network.dao.NetworkDao;
import com.cloud.network.dao.NetworkExternalFirewallDao;
import com.cloud.network.dao.NetworkExternalLoadBalancerDao;
import com.cloud.network.dao.NetworkServiceMapDao;
import com.cloud.network.dao.PhysicalNetworkDao;
import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
import com.cloud.network.rules.dao.PortForwardingRulesDao;
import com.cloud.offerings.dao.NetworkOfferingDao;
import com.cloud.resource.ResourceManager;
import com.cloud.user.AccountManager;
import com.cloud.user.AccountVO;
import com.cloud.user.UserStatisticsVO;
import com.cloud.user.dao.AccountDao;
import com.cloud.user.dao.UserStatisticsDao;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.component.Inject;
import com.cloud.utils.concurrency.NamedThreadFactory;
import com.cloud.utils.db.GlobalLock;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.exception.ExecutionException;
import com.cloud.vm.DomainRouterVO;
import com.cloud.vm.NicVO;
import com.cloud.vm.dao.DomainRouterDao;
import com.cloud.vm.dao.NicDao;
@Local(value = { ExternalLoadBalancerUsageManager.class })
public class ExternalLoadBalancerUsageManagerImpl implements ExternalLoadBalancerUsageManager {
String _name;
@Inject
NetworkExternalLoadBalancerDao _networkExternalLBDao;
@Inject
ExternalLoadBalancerDeviceDao _externalLoadBalancerDeviceDao;
@Inject
HostDao _hostDao;
@Inject
DataCenterDao _dcDao;
@Inject
NetworkManager _networkMgr;
@Inject
InlineLoadBalancerNicMapDao _inlineLoadBalancerNicMapDao;
@Inject
NicDao _nicDao;
@Inject
AgentManager _agentMgr;
@Inject
ResourceManager _resourceMgr;
@Inject
IPAddressDao _ipAddressDao;
@Inject
VlanDao _vlanDao;
@Inject
NetworkOfferingDao _networkOfferingDao;
@Inject
AccountDao _accountDao;
@Inject
PhysicalNetworkDao _physicalNetworkDao;
@Inject
PhysicalNetworkServiceProviderDao _physicalNetworkServiceProviderDao;
@Inject
AccountManager _accountMgr;
@Inject
UserStatisticsDao _userStatsDao;
@Inject
NetworkDao _networkDao;
@Inject
DomainRouterDao _routerDao;
@Inject
LoadBalancerDao _loadBalancerDao;
@Inject
PortForwardingRulesDao _portForwardingRulesDao;
@Inject
ConfigurationDao _configDao;
@Inject
HostDetailsDao _hostDetailDao;
@Inject
NetworkExternalLoadBalancerDao _networkLBDao;
@Inject
NetworkServiceMapDao _ntwkSrvcProviderDao;
@Inject
NetworkExternalFirewallDao _networkExternalFirewallDao;
@Inject
ExternalFirewallDeviceDao _externalFirewallDeviceDao;
@Inject
protected HostPodDao _podDao = null;
ScheduledExecutorService _executor;
private int _externalNetworkStatsInterval;
private static final org.apache.log4j.Logger s_logger = Logger.getLogger(ExternalLoadBalancerUsageManagerImpl.class);
@Override
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
_externalNetworkStatsInterval = NumbersUtil.parseInt(_configDao.getValue(Config.ExternalNetworkStatsInterval.key()), 300);
if (_externalNetworkStatsInterval > 0) {
_executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("ExternalNetworkMonitor"));
}
return true;
}
@Override
public boolean start() {
if (_externalNetworkStatsInterval > 0) {
_executor.scheduleAtFixedRate(new ExternalLoadBalancerDeviceNetworkUsageTask(), _externalNetworkStatsInterval, _externalNetworkStatsInterval, TimeUnit.SECONDS);
}
return true;
}
@Override
public boolean stop() {
return true;
}
@Override
public String getName() {
return _name;
}
private ExternalLoadBalancerDeviceVO getExternalLoadBalancerForNetwork(Network network) {
NetworkExternalLoadBalancerVO lbDeviceForNetwork = _networkExternalLBDao.findByNetworkId(network.getId());
if (lbDeviceForNetwork != null) {
long lbDeviceId = lbDeviceForNetwork.getExternalLBDeviceId();
ExternalLoadBalancerDeviceVO lbDeviceVo = _externalLoadBalancerDeviceDao.findById(lbDeviceId);
assert (lbDeviceVo != null);
return lbDeviceVo;
}
return null;
}
private boolean externalLoadBalancerIsInline(HostVO externalLoadBalancer) {
DetailVO detail = _hostDetailDao.findDetail(externalLoadBalancer.getId(), "inline");
return (detail != null && detail.getValue().equals("true"));
}
@Override
public void updateExternalLoadBalancerNetworkUsageStats(long loadBalancerRuleId){
LoadBalancerVO lb = _loadBalancerDao.findById(loadBalancerRuleId);
if(lb == null){
if(s_logger.isDebugEnabled()){
s_logger.debug("Cannot update usage stats, LB rule is not found");
}
return;
}
long networkId = lb.getNetworkId();
Network network = _networkDao.findById(networkId);
if(network == null){
if(s_logger.isDebugEnabled()){
s_logger.debug("Cannot update usage stats, Network is not found");
}
return;
}
ExternalLoadBalancerDeviceVO lbDeviceVO = getExternalLoadBalancerForNetwork(network);
if (lbDeviceVO == null) {
if(s_logger.isDebugEnabled()){
s_logger.debug("Cannot update usage stats, No external LB device found");
}
return;
}
// Get network stats from the external load balancer
ExternalNetworkResourceUsageAnswer lbAnswer = null;
HostVO externalLoadBalancer = _hostDao.findById(lbDeviceVO.getHostId());
if (externalLoadBalancer != null) {
ExternalNetworkResourceUsageCommand cmd = new ExternalNetworkResourceUsageCommand();
lbAnswer = (ExternalNetworkResourceUsageAnswer) _agentMgr.easySend(externalLoadBalancer.getId(), cmd);
if (lbAnswer == null || !lbAnswer.getResult()) {
String details = (lbAnswer != null) ? lbAnswer.getDetails() : "details unavailable";
String msg = "Unable to get external load balancer stats for network" + networkId + " due to: " + details + ".";
s_logger.error(msg);
return;
}
}
long accountId = lb.getAccountId();
AccountVO account = _accountDao.findById(accountId);
if (account == null) {
s_logger.debug("Skipping stats update for external LB for account with ID " + accountId);
return;
}
String publicIp = _networkMgr.getIp(lb.getSourceIpAddressId()).getAddress().addr();
DataCenterVO zone = _dcDao.findById(network.getDataCenterId());
String statsEntryIdentifier = "account " + account.getAccountName() + ", zone " + zone.getName() + ", network ID " + networkId + ", host ID " + externalLoadBalancer.getName();
long newCurrentBytesSent = 0;
long newCurrentBytesReceived = 0;
if (publicIp != null) {
long[] bytesSentAndReceived = null;
statsEntryIdentifier += ", public IP: " + publicIp;
if (externalLoadBalancer.getType().equals(Host.Type.ExternalLoadBalancer) && externalLoadBalancerIsInline(externalLoadBalancer)) {
// Look up stats for the guest IP address that's mapped to the public IP address
InlineLoadBalancerNicMapVO mapping = _inlineLoadBalancerNicMapDao.findByPublicIpAddress(publicIp);
if (mapping != null) {
NicVO nic = _nicDao.findById(mapping.getNicId());
String loadBalancingIpAddress = nic.getIp4Address();
bytesSentAndReceived = lbAnswer.ipBytes.get(loadBalancingIpAddress);
if (bytesSentAndReceived != null) {
bytesSentAndReceived[0] = 0;
}
}
} else {
bytesSentAndReceived = lbAnswer.ipBytes.get(publicIp);
}
if (bytesSentAndReceived == null) {
s_logger.debug("Didn't get an external network usage answer for public IP " + publicIp);
} else {
newCurrentBytesSent += bytesSentAndReceived[0];
newCurrentBytesReceived += bytesSentAndReceived[1];
}
UserStatisticsVO userStats;
final Transaction txn = Transaction.currentTxn();
try {
txn.start();
userStats = _userStatsDao.lock(accountId, zone.getId(), networkId, publicIp, externalLoadBalancer.getId(), externalLoadBalancer.getType().toString());
if(userStats != null){
long oldNetBytesSent = userStats.getNetBytesSent();
long oldNetBytesReceived = userStats.getNetBytesReceived();
long oldCurrentBytesSent = userStats.getCurrentBytesSent();
long oldCurrentBytesReceived = userStats.getCurrentBytesReceived();
String warning = "Received an external network stats byte count that was less than the stored value. Zone ID: " + userStats.getDataCenterId() + ", account ID: " + userStats.getAccountId() + ".";
userStats.setCurrentBytesSent(newCurrentBytesSent);
if (oldCurrentBytesSent > newCurrentBytesSent) {
s_logger.warn(warning + "Stored bytes sent: " + oldCurrentBytesSent + ", new bytes sent: " + newCurrentBytesSent + ".");
userStats.setNetBytesSent(oldNetBytesSent + oldCurrentBytesSent);
}
userStats.setCurrentBytesReceived(newCurrentBytesReceived);
if (oldCurrentBytesReceived > newCurrentBytesReceived) {
s_logger.warn(warning + "Stored bytes received: " + oldCurrentBytesReceived + ", new bytes received: " + newCurrentBytesReceived + ".");
userStats.setNetBytesReceived(oldNetBytesReceived + oldCurrentBytesReceived);
}
if (_userStatsDao.update(userStats.getId(), userStats)) {
s_logger.debug("Successfully updated stats for " + statsEntryIdentifier);
} else {
s_logger.debug("Failed to update stats for " + statsEntryIdentifier);
}
}else {
s_logger.warn("Unable to find user stats entry for " + statsEntryIdentifier);
}
txn.commit();
}catch (final Exception e) {
txn.rollback();
throw new CloudRuntimeException("Problem getting stats after reboot/stop ", e);
}
}
}
protected class ExternalLoadBalancerDeviceNetworkUsageTask implements Runnable {
public ExternalLoadBalancerDeviceNetworkUsageTask() {
}
@Override
public void run() {
GlobalLock scanLock = GlobalLock.getInternLock("ExternalLoadBalancerUsageManagerImpl");
try {
if (scanLock.lock(20)) {
try {
runExternalLoadBalancerNetworkUsageTask();
} finally {
scanLock.unlock();
}
}
} catch (Exception e) {
s_logger.warn("Problems while getting external load balancer device usage", e);
} finally {
scanLock.releaseRef();
}
}
private void runExternalLoadBalancerNetworkUsageTask() {
s_logger.debug("External load balancer devices stats collector is running...");
for (DataCenterVO zone : _dcDao.listAll()) {
List<DomainRouterVO> domainRoutersInZone = _routerDao.listByDataCenter(zone.getId());
if (domainRoutersInZone == null) {
continue;
}
Map<Long, ExternalNetworkResourceUsageAnswer> lbDeviceUsageAnswerMap = new HashMap<Long, ExternalNetworkResourceUsageAnswer>();
List<Long> accountsProcessed = new ArrayList<Long>();
for (DomainRouterVO domainRouter : domainRoutersInZone) {
long accountId = domainRouter.getAccountId();
if (accountsProcessed.contains(new Long(accountId))) {
if (s_logger.isTraceEnabled()) {
s_logger.trace("Networks for Account " + accountId + " are already processed for external network usage, so skipping usage check.");
}
continue;
}
long zoneId = zone.getId();
List<NetworkVO> networksForAccount = _networkDao.listBy(accountId, zoneId, Network.GuestType.Isolated);
if (networksForAccount == null) {
continue;
}
for (NetworkVO network : networksForAccount) {
if (!_networkMgr.networkIsConfiguredForExternalNetworking(zoneId, network.getId())) {
s_logger.debug("Network " + network.getId() + " is not configured for external networking, so skipping usage check.");
continue;
}
ExternalLoadBalancerDeviceVO lbDeviceVO = getExternalLoadBalancerForNetwork(network);
if (lbDeviceVO == null) {
continue;
}
// Get network stats from the external load balancer
ExternalNetworkResourceUsageAnswer lbAnswer = null;
HostVO externalLoadBalancer = _hostDao.findById(lbDeviceVO.getHostId());
if (externalLoadBalancer != null) {
Long lbDeviceId = new Long(externalLoadBalancer.getId());
if (!lbDeviceUsageAnswerMap.containsKey(lbDeviceId)) {
ExternalNetworkResourceUsageCommand cmd = new ExternalNetworkResourceUsageCommand();
lbAnswer = (ExternalNetworkResourceUsageAnswer) _agentMgr.easySend(externalLoadBalancer.getId(), cmd);
if (lbAnswer == null || !lbAnswer.getResult()) {
String details = (lbAnswer != null) ? lbAnswer.getDetails() : "details unavailable";
String msg = "Unable to get external load balancer stats for " + zone.getName() + " due to: " + details + ".";
s_logger.error(msg);
continue;
}
lbDeviceUsageAnswerMap.put(lbDeviceId, lbAnswer);
} else {
if (s_logger.isTraceEnabled()) {
s_logger.trace("Reusing usage Answer for device id " + lbDeviceId + "for Network " + network.getId());
}
lbAnswer = lbDeviceUsageAnswerMap.get(lbDeviceId);
}
}
AccountVO account = _accountDao.findById(accountId);
if (account == null) {
s_logger.debug("Skipping stats update for account with ID " + accountId);
continue;
}
if (!manageStatsEntries(true, accountId, zoneId, network, externalLoadBalancer, lbAnswer)) {
continue;
}
manageStatsEntries(false, accountId, zoneId, network, externalLoadBalancer, lbAnswer);
}
accountsProcessed.add(new Long(accountId));
}
}
}
private boolean updateBytes(UserStatisticsVO userStats, long newCurrentBytesSent, long newCurrentBytesReceived) {
long oldNetBytesSent = userStats.getNetBytesSent();
long oldNetBytesReceived = userStats.getNetBytesReceived();
long oldCurrentBytesSent = userStats.getCurrentBytesSent();
long oldCurrentBytesReceived = userStats.getCurrentBytesReceived();
String warning = "Received an external network stats byte count that was less than the stored value. Zone ID: " + userStats.getDataCenterId() + ", account ID: " + userStats.getAccountId() + ".";
userStats.setCurrentBytesSent(newCurrentBytesSent);
if (oldCurrentBytesSent > newCurrentBytesSent) {
s_logger.warn(warning + "Stored bytes sent: " + oldCurrentBytesSent + ", new bytes sent: " + newCurrentBytesSent + ".");
userStats.setNetBytesSent(oldNetBytesSent + oldCurrentBytesSent);
}
userStats.setCurrentBytesReceived(newCurrentBytesReceived);
if (oldCurrentBytesReceived > newCurrentBytesReceived) {
s_logger.warn(warning + "Stored bytes received: " + oldCurrentBytesReceived + ", new bytes received: " + newCurrentBytesReceived + ".");
userStats.setNetBytesReceived(oldNetBytesReceived + oldCurrentBytesReceived);
}
return _userStatsDao.update(userStats.getId(), userStats);
}
// Creates a new stats entry for the specified parameters, if one doesn't already exist.
private boolean createStatsEntry(long accountId, long zoneId, long networkId, String publicIp, long hostId) {
HostVO host = _hostDao.findById(hostId);
UserStatisticsVO userStats = _userStatsDao.findBy(accountId, zoneId, networkId, publicIp, hostId, host.getType().toString());
if (userStats == null) {
return (_userStatsDao.persist(new UserStatisticsVO(accountId, zoneId, publicIp, hostId, host.getType().toString(), networkId)) != null);
} else {
return true;
}
}
// Updates an existing stats entry with new data from the specified usage answer.
private boolean updateStatsEntry(long accountId, long zoneId, long networkId, String publicIp, long hostId, ExternalNetworkResourceUsageAnswer answer) {
AccountVO account = _accountDao.findById(accountId);
DataCenterVO zone = _dcDao.findById(zoneId);
NetworkVO network = _networkDao.findById(networkId);
HostVO host = _hostDao.findById(hostId);
String statsEntryIdentifier = "account " + account.getAccountName() + ", zone " + zone.getName() + ", network ID " + networkId + ", host ID " + host.getName();
long newCurrentBytesSent = 0;
long newCurrentBytesReceived = 0;
if (publicIp != null) {
long[] bytesSentAndReceived = null;
statsEntryIdentifier += ", public IP: " + publicIp;
if (host.getType().equals(Host.Type.ExternalLoadBalancer) && externalLoadBalancerIsInline(host)) {
// Look up stats for the guest IP address that's mapped to the public IP address
InlineLoadBalancerNicMapVO mapping = _inlineLoadBalancerNicMapDao.findByPublicIpAddress(publicIp);
if (mapping != null) {
NicVO nic = _nicDao.findById(mapping.getNicId());
String loadBalancingIpAddress = nic.getIp4Address();
bytesSentAndReceived = answer.ipBytes.get(loadBalancingIpAddress);
if (bytesSentAndReceived != null) {
bytesSentAndReceived[0] = 0;
}
}
} else {
bytesSentAndReceived = answer.ipBytes.get(publicIp);
}
if (bytesSentAndReceived == null) {
s_logger.debug("Didn't get an external network usage answer for public IP " + publicIp);
} else {
newCurrentBytesSent += bytesSentAndReceived[0];
newCurrentBytesReceived += bytesSentAndReceived[1];
}
} else {
URI broadcastURI = network.getBroadcastUri();
if (broadcastURI == null) {
s_logger.debug("Not updating stats for guest network with ID " + network.getId() + " because the network is not implemented.");
return true;
} else {
long vlanTag = Integer.parseInt(broadcastURI.getHost());
long[] bytesSentAndReceived = answer.guestVlanBytes.get(String.valueOf(vlanTag));
if (bytesSentAndReceived == null) {
s_logger.warn("Didn't get an external network usage answer for guest VLAN " + vlanTag);
} else {
newCurrentBytesSent += bytesSentAndReceived[0];
newCurrentBytesReceived += bytesSentAndReceived[1];
}
}
}
UserStatisticsVO userStats;
try {
userStats = _userStatsDao.lock(accountId, zoneId, networkId, publicIp, hostId, host.getType().toString());
} catch (Exception e) {
s_logger.warn("Unable to find user stats entry for " + statsEntryIdentifier);
return false;
}
if (updateBytes(userStats, newCurrentBytesSent, newCurrentBytesReceived)) {
s_logger.debug("Successfully updated stats for " + statsEntryIdentifier);
return true;
} else {
s_logger.debug("Failed to update stats for " + statsEntryIdentifier);
return false;
}
}
private boolean createOrUpdateStatsEntry(boolean create, long accountId, long zoneId, long networkId, String publicIp, long hostId, ExternalNetworkResourceUsageAnswer answer) {
if (create) {
return createStatsEntry(accountId, zoneId, networkId, publicIp, hostId);
} else {
return updateStatsEntry(accountId, zoneId, networkId, publicIp, hostId, answer);
}
}
/*
* Creates/updates all necessary stats entries for an account and zone.
* Stats entries are created for source NAT IP addresses, static NAT rules, port forwarding rules, and load
* balancing rules
*/
private boolean manageStatsEntries(boolean create, long accountId, long zoneId, Network network,
HostVO externalLoadBalancer, ExternalNetworkResourceUsageAnswer lbAnswer) {
String accountErrorMsg = "Failed to update external network stats entry. Details: account ID = " + accountId;
Transaction txn = Transaction.open(Transaction.CLOUD_DB);
try {
txn.start();
String networkErrorMsg = accountErrorMsg + ", network ID = " + network.getId();
// If an external load balancer is added, manage one entry for each load balancing rule in this network
if (externalLoadBalancer != null && lbAnswer != null) {
List<LoadBalancerVO> loadBalancers = _loadBalancerDao.listByNetworkId(network.getId());
for (LoadBalancerVO loadBalancer : loadBalancers) {
String publicIp = _networkMgr.getIp(loadBalancer.getSourceIpAddressId()).getAddress().addr();
if (!createOrUpdateStatsEntry(create, accountId, zoneId, network.getId(), publicIp, externalLoadBalancer.getId(), lbAnswer)) {
throw new ExecutionException(networkErrorMsg + ", load balancing rule public IP = " + publicIp);
}
}
}
return txn.commit();
} catch (Exception e) {
s_logger.warn("Exception: ", e);
txn.rollback();
return false;
} finally {
txn.close();
}
}
}
}

View File

@ -96,8 +96,8 @@ public class IPAddressVO implements IpAddress, Identity {
@Column(name="physical_network_id")
private Long physicalNetworkId;
@Column(name="is_elastic")
private boolean elastic;
@Column(name="is_system")
private boolean system;
@Column(name="account_id")
@Transient
@ -269,14 +269,12 @@ public class IPAddressVO implements IpAddress, Identity {
this.physicalNetworkId = physicalNetworkId;
}
@Override
public boolean getElastic() {
return elastic;
public boolean getSystem() {
return system;
}
public void setElastic(boolean isElastic) {
this.elastic = isElastic;
public void setSystem(boolean isSystem) {
this.system = isSystem;
}
}

View File

@ -81,7 +81,7 @@ public interface NetworkManager extends NetworkService {
* @throws InsufficientAddressCapacityException
*/
PublicIp assignPublicIpAddress(long dcId, Long podId, Account owner, VlanType type, Long networkId, String requestedIp, boolean isElastic) throws InsufficientAddressCapacityException;
PublicIp assignPublicIpAddress(long dcId, Long podId, Account owner, VlanType type, Long networkId, String requestedIp, boolean isSystem) throws InsufficientAddressCapacityException;
/**
* assigns a source nat ip address to an account within a network.
@ -289,11 +289,11 @@ public interface NetworkManager extends NetworkService {
Provider getDefaultUniqueProviderForService(String serviceName);
IpAddress assignElasticIp(long networkId, Account owner,
IpAddress assignSystemIp(long networkId, Account owner,
boolean forElasticLb, boolean forElasticIp)
throws InsufficientAddressCapacityException;
boolean handleElasticIpRelease(IpAddress ip);
boolean handleSystemIpRelease(IpAddress ip);
void checkNetworkPermissions(Account owner, Network network);

View File

@ -354,12 +354,12 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
}
@Override
public PublicIp assignPublicIpAddress(long dcId, Long podId, Account owner, VlanType type, Long networkId, String requestedIp, boolean isElastic) throws InsufficientAddressCapacityException {
return fetchNewPublicIp(dcId, podId, null, owner, type, networkId, false, true, requestedIp, isElastic);
public PublicIp assignPublicIpAddress(long dcId, Long podId, Account owner, VlanType type, Long networkId, String requestedIp, boolean isSystem) throws InsufficientAddressCapacityException {
return fetchNewPublicIp(dcId, podId, null, owner, type, networkId, false, true, requestedIp, isSystem);
}
@DB
public PublicIp fetchNewPublicIp(long dcId, Long podId, Long vlanDbId, Account owner, VlanType vlanUse, Long networkId, boolean sourceNat, boolean assign, String requestedIp, boolean isElastic)
public PublicIp fetchNewPublicIp(long dcId, Long podId, Long vlanDbId, Account owner, VlanType vlanUse, Long networkId, boolean sourceNat, boolean assign, String requestedIp, boolean isSystem)
throws InsufficientAddressCapacityException {
StringBuilder errorMessage = new StringBuilder("Unable to get ip adress in ");
Transaction txn = Transaction.currentTxn();
@ -414,7 +414,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
addr.setAllocatedTime(new Date());
addr.setAllocatedInDomainId(owner.getDomainId());
addr.setAllocatedToAccountId(owner.getId());
addr.setElastic(isElastic);
addr.setSystem(isSystem);
if (assign) {
markPublicIpAsAllocated(addr);
@ -459,7 +459,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
String guestType = vlan.getVlanType().toString();
UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_NET_IP_ASSIGN, owner.getId(), addr.getDataCenterId(), addr.getId(), addr.getAddress().toString(), addr.isSourceNat(), guestType, addr.getElastic());
UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_NET_IP_ASSIGN, owner.getId(), addr.getDataCenterId(), addr.getId(), addr.getAddress().toString(), addr.isSourceNat(), guestType, addr.getSystem());
_usageEventDao.persist(usageEvent);
// don't increment resource count for direct ip addresses
if (addr.getAssociatedWithNetworkId() != null) {
@ -946,7 +946,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
@Override
@DB
@ActionEvent(eventType = EventTypes.EVENT_NET_IP_ASSIGN, eventDescription = "allocating Ip", create = true)
public IpAddress allocateIP(long networkId, Account ipOwner, boolean isElastic) throws ResourceAllocationException, InsufficientAddressCapacityException, ConcurrentOperationException {
public IpAddress allocateIP(long networkId, Account ipOwner, boolean isSystem) throws ResourceAllocationException, InsufficientAddressCapacityException, ConcurrentOperationException {
Account caller = UserContext.current().getCaller();
long userId = UserContext.current().getCallerUserId();
@ -1025,7 +1025,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
}
}
ip = fetchNewPublicIp(zone.getId(), null, null, ipOwner, vlanType, network.getId(), isSourceNat, assign, null, isElastic);
ip = fetchNewPublicIp(zone.getId(), null, null, ipOwner, vlanType, network.getId(), isSourceNat, assign, null, isSystem);
if (ip == null) {
throw new InsufficientAddressCapacityException("Unable to find available public IP addresses", DataCenter.class, zone.getId());
@ -1953,9 +1953,9 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
throw new InvalidParameterValueException("Ip address id=" + ipAddressId + " belongs to Account wide IP pool and cannot be disassociated");
}
// don't allow releasing elastic ip address
if (ipVO.getElastic()) {
throw new InvalidParameterValueException("Can't release elastic IP address " + ipVO);
// don't allow releasing system ip address
if (ipVO.getSystem()) {
throw new InvalidParameterValueException("Can't release system IP address " + ipVO);
}
boolean success = releasePublicIpAddress(ipAddressId, userId, caller);
@ -1964,7 +1964,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
NetworkOffering offering = _configMgr.getNetworkOffering(guestNetwork.getNetworkOfferingId());
Long vmId = ipVO.getAssociatedWithVmId();
if (offering.getElasticIp() && vmId != null) {
_rulesMgr.enableElasticIpAndStaticNatForVm(_userVmDao.findById(vmId), true);
_rulesMgr.getSystemIpAndEnableStaticNatForVm(_userVmDao.findById(vmId), true);
return true;
}
return true;
@ -3569,7 +3569,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
addr.setAllocatedTime(new Date());
addr.setAllocatedInDomainId(owner.getDomainId());
addr.setAllocatedToAccountId(owner.getId());
addr.setElastic(false);
addr.setSystem(false);
addr.setState(IpAddress.State.Allocating);
markPublicIpAsAllocated(addr);
}
@ -3798,7 +3798,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
String guestType = vlan.getVlanType().toString();
UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_NET_IP_RELEASE, ip.getAllocatedToAccountId(), ip.getDataCenterId(), addrId, ip.getAddress().addr(), ip.isSourceNat(), guestType, ip.getElastic());
UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_NET_IP_RELEASE, ip.getAllocatedToAccountId(), ip.getDataCenterId(), addrId, ip.getAddress().addr(), ip.isSourceNat(), guestType, ip.getSystem());
_usageEventDao.persist(usageEvent);
}
@ -6130,28 +6130,28 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
}
}
public IpAddress assignElasticIp(long networkId, Account owner, boolean forElasticLb, boolean forElasticIp) throws InsufficientAddressCapacityException {
public IpAddress assignSystemIp(long networkId, Account owner, boolean forElasticLb, boolean forElasticIp) throws InsufficientAddressCapacityException {
Network guestNetwork = getNetwork(networkId);
NetworkOffering off = _configMgr.getNetworkOffering(guestNetwork.getNetworkOfferingId());
IpAddress ip = null;
if ((off.getElasticLb() && forElasticLb) || (off.getElasticIp() && forElasticIp)) {
try {
s_logger.debug("Allocating elastic IP address for load balancer rule...");
s_logger.debug("Allocating system IP address for load balancer rule...");
// allocate ip
ip = allocateIP(networkId, owner, true);
// apply ip associations
ip = associateIP(ip.getId());
} catch (ResourceAllocationException ex) {
throw new CloudRuntimeException("Failed to allocate elastic ip due to ", ex);
throw new CloudRuntimeException("Failed to allocate system ip due to ", ex);
} catch (ConcurrentOperationException ex) {
throw new CloudRuntimeException("Failed to allocate elastic lb ip due to ", ex);
throw new CloudRuntimeException("Failed to allocate system lb ip due to ", ex);
} catch (ResourceUnavailableException ex) {
throw new CloudRuntimeException("Failed to allocate elastic lb ip due to ", ex);
throw new CloudRuntimeException("Failed to allocate system lb ip due to ", ex);
}
if (ip == null) {
throw new CloudRuntimeException("Failed to allocate elastic ip");
throw new CloudRuntimeException("Failed to allocate system ip");
}
}
@ -6159,17 +6159,17 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
}
@Override
public boolean handleElasticIpRelease(IpAddress ip) {
public boolean handleSystemIpRelease(IpAddress ip) {
boolean success = true;
Long networkId = ip.getAssociatedWithNetworkId();
if (networkId != null) {
if (ip.getElastic()) {
if (ip.getSystem()) {
UserContext ctx = UserContext.current();
if (!releasePublicIpAddress(ip.getId(), ctx.getCallerUserId(), ctx.getCaller())) {
s_logger.warn("Unable to release elastic ip address id=" + ip.getId());
s_logger.warn("Unable to release system ip address id=" + ip.getId());
success = false;
} else {
s_logger.warn("Successfully released elastic ip address id=" + ip.getId());
s_logger.warn("Successfully released system ip address id=" + ip.getId());
}
}
}

View File

@ -372,8 +372,8 @@ public class NetworkUsageManagerImpl implements NetworkUsageManager, ResourceSta
}
List<UserStatisticsVO> collectedStats = new ArrayList<UserStatisticsVO>();
//Get usage for Ips for which were assigned for the entire duration
//Get usage for Ips which were assigned for the entire duration
if(fullDurationIpUsage.size() > 0){
DirectNetworkUsageCommand cmd = new DirectNetworkUsageCommand(IpList, lastCollection, now);
DirectNetworkUsageAnswer answer = (DirectNetworkUsageAnswer) _agentMgr.easySend(host.getId(), cmd);
@ -381,6 +381,7 @@ public class NetworkUsageManagerImpl implements NetworkUsageManager, ResourceSta
String details = (answer != null) ? answer.getDetails() : "details unavailable";
String msg = "Unable to get network usage stats from " + host.getId() + " due to: " + details + ".";
s_logger.error(msg);
return false;
} else {
for(UsageIPAddressVO usageIp : fullDurationIpUsage){
String publicIp = usageIp.getAddress();
@ -403,7 +404,7 @@ public class NetworkUsageManagerImpl implements NetworkUsageManager, ResourceSta
}
}
//Get usage for Ips for which were assigned for part of the duration period
//Get usage for Ips which were assigned for part of the duration period
for(UsageIPAddressVO usageIp : IpPartialUsage){
IpList = new ArrayList<String>() ;
IpList.add(usageIp.getAddress());
@ -413,6 +414,7 @@ public class NetworkUsageManagerImpl implements NetworkUsageManager, ResourceSta
String details = (answer != null) ? answer.getDetails() : "details unavailable";
String msg = "Unable to get network usage stats from " + host.getId() + " due to: " + details + ".";
s_logger.error(msg);
return false;
} else {
String publicIp = usageIp.getAddress();
long[] bytesSentRcvd = answer.get(publicIp);
@ -434,6 +436,10 @@ public class NetworkUsageManagerImpl implements NetworkUsageManager, ResourceSta
}
}
if(collectedStats.size() == 0){
s_logger.debug("No new direct network stats. No need to persist");
return false;
}
//Persist all the stats and last_collection time in a single transaction
Transaction txn = Transaction.open(Transaction.CLOUD_DB);
try {

View File

@ -183,7 +183,7 @@ public class PublicIp implements PublicIpAddress {
}
@Override
public boolean getElastic() {
return _addr.getElastic();
public boolean getSystem() {
return _addr.getSystem();
}
}

View File

@ -146,7 +146,7 @@ public class IPAddressDaoImpl extends GenericDaoBase<IPAddressVO, Long> implemen
address.setAssociatedWithVmId(null);
address.setState(State.Free);
address.setAssociatedWithNetworkId(null);
address.setElastic(false);
address.setSystem(false);
update(ipAddressId, address);
}

View File

@ -213,11 +213,7 @@ public class F5ExternalLoadBalancerElement extends ExternalLoadBalancerDeviceMan
List<LbStickinessMethod> methodList = new ArrayList<LbStickinessMethod>();
method = new LbStickinessMethod(StickinessMethodType.LBCookieBased, "This is cookie based sticky method, can be used only for http");
methodList.add(method);
method.addParam("holdtime", false, "time period for which persistence is in effect.", false);
method = new LbStickinessMethod(StickinessMethodType.SourceBased, "This is source based sticky method, can be used for any type of protocol.");
methodList.add(method);
method.addParam("holdtime", false, "time period for which persistence is in effect.", false);
method.addParam("holdtime", false, "time period (in seconds) for which persistence is in effect.", false);
Gson gson = new Gson();
String stickyMethodList = gson.toJson(methodList);

View File

@ -286,7 +286,7 @@ public class JuniperSRXExternalFirewallElement extends ExternalFirewallDeviceMan
Map<Capability, String> sourceNatCapabilities = new HashMap<Capability, String>();
// Specifies that this element supports either one source NAT rule per account, or no source NAT rules at all;
// in the latter case a shared interface NAT rule will be used
sourceNatCapabilities.put(Capability.SupportedSourceNatTypes, "per account, per zone");
sourceNatCapabilities.put(Capability.SupportedSourceNatTypes, "peraccount, perzone");
capabilities.put(Service.SourceNat, sourceNatCapabilities);
// Specifies that port forwarding rules are supported by this element

View File

@ -521,7 +521,7 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl
capabilities.put(Service.Gateway, null);
Map<Capability, String> sourceNatCapabilities = new HashMap<Capability, String>();
sourceNatCapabilities.put(Capability.SupportedSourceNatTypes, "per account");
sourceNatCapabilities.put(Capability.SupportedSourceNatTypes, "peraccount");
sourceNatCapabilities.put(Capability.RedundantRouter, "true");
capabilities.put(Service.SourceNat, sourceNatCapabilities);

View File

@ -52,8 +52,8 @@ import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.NetworkRuleConflictException;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.ExternalLoadBalancerDeviceManager;
import com.cloud.network.dao.NetworkServiceMapDao;
import com.cloud.network.ExternalLoadBalancerUsageManager;
import com.cloud.network.IPAddressVO;
import com.cloud.network.IpAddress;
import com.cloud.network.LBStickinessPolicyVO;
@ -161,7 +161,7 @@ public class LoadBalancingRulesManagerImpl<Type> implements LoadBalancingRulesMa
@Inject
ConfigurationManager _configMgr;
@Inject
ExternalLoadBalancerDeviceManager _externalLBMgr;
ExternalLoadBalancerUsageManager _externalLBUsageMgr;
@Inject
NetworkServiceMapDao _ntwkSrvcDao;
@ -637,7 +637,7 @@ public class LoadBalancingRulesManagerImpl<Type> implements LoadBalancingRulesMa
NetworkVO network = _networkDao.findById(lb.getNetworkId());
if (network != null) {
if (_networkMgr.networkIsConfiguredForExternalNetworking(network.getDataCenterId(), network.getId())) {
_externalLBMgr.updateExternalLoadBalancerNetworkUsageStats(loadBalancerId);
_externalLBUsageMgr.updateExternalLoadBalancerNetworkUsageStats(loadBalancerId);
}
}
@ -721,17 +721,20 @@ public class LoadBalancingRulesManagerImpl<Type> implements LoadBalancingRulesMa
Network guestNetwork = _networkMgr.getNetwork(lb.getNetworkId());
NetworkOffering off = _configMgr.getNetworkOffering(guestNetwork.getNetworkOfferingId());
if (off.getElasticLb() && ipAddressVo == null) {
ip = _networkMgr.assignElasticIp(lb.getNetworkId(), lbOwner, true, false);
ip = _networkMgr.assignSystemIp(lb.getNetworkId(), lbOwner, true, false);
lb.setSourceIpAddressId(ip.getId());
}
try {
result = createLoadBalancer(lb, openFirewall);
} catch (Exception ex) {
s_logger.warn("Failed to create load balancer due to ", ex);
if (ex instanceof NetworkRuleConflictException) {
throw (NetworkRuleConflictException) ex;
}
} finally {
if (result == null && ip != null) {
s_logger.debug("Releasing elastic IP address " + ip + " as corresponding lb rule failed to create");
_networkMgr.handleElasticIpRelease(ip);
s_logger.debug("Releasing system IP address " + ip + " as corresponding lb rule failed to create");
_networkMgr.handleSystemIpRelease(ip);
}
}
}
@ -911,13 +914,13 @@ public class LoadBalancingRulesManagerImpl<Type> implements LoadBalancingRulesMa
long count = _firewallDao.countRulesByIpId(lb.getSourceIpAddressId());
if (count == 0) {
try {
success = handleElasticLBIpRelease(lb);
success = handleSystemLBIpRelease(lb);
} catch (Exception ex) {
s_logger.warn("Failed to release elastic ip as a part of lb rule " + lb + " deletion due to exception ", ex);
s_logger.warn("Failed to release system ip as a part of lb rule " + lb + " deletion due to exception ", ex);
success = false;
} finally {
if (!success) {
s_logger.warn("Failed to release elastic ip as a part of lb rule " + lb + " deletion");
s_logger.warn("Failed to release system ip as a part of lb rule " + lb + " deletion");
}
}
}
@ -928,16 +931,16 @@ public class LoadBalancingRulesManagerImpl<Type> implements LoadBalancingRulesMa
return true;
}
protected boolean handleElasticLBIpRelease(LoadBalancerVO lb) {
protected boolean handleSystemLBIpRelease(LoadBalancerVO lb) {
IpAddress ip = _ipAddressDao.findById(lb.getSourceIpAddressId());
boolean success = true;
if (ip.getElastic()) {
s_logger.debug("Releasing elastic ip address " + lb.getSourceIpAddressId() + " as a part of delete lb rule");
if (ip.getSystem()) {
s_logger.debug("Releasing system ip address " + lb.getSourceIpAddressId() + " as a part of delete lb rule");
if (!_networkMgr.releasePublicIpAddress(lb.getSourceIpAddressId(), UserContext.current().getCallerUserId(), UserContext.current().getCaller())) {
s_logger.warn("Unable to release elastic ip address id=" + lb.getSourceIpAddressId() + " as a part of delete lb rule");
s_logger.warn("Unable to release system ip address id=" + lb.getSourceIpAddressId() + " as a part of delete lb rule");
success = false;
} else {
s_logger.warn("Successfully released elastic ip address id=" + lb.getSourceIpAddressId() + " as a part of delete lb rule");
s_logger.warn("Successfully released system ip address id=" + lb.getSourceIpAddressId() + " as a part of delete lb rule");
}
}

View File

@ -1188,7 +1188,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
DataCenterDeployment plan = new DataCenterDeployment(dcId);
boolean isPodBased = (dest.getDataCenter().getNetworkType() == NetworkType.Basic || _networkMgr.areServicesSupportedInNetwork(guestNetwork.getId(), Service.SecurityGroup)) && guestNetwork.getTrafficType() == TrafficType.Guest;
boolean publicNetwork = false;
if (_networkMgr.areServicesSupportedInNetwork(guestNetwork.getId(), Service.SourceNat)) {
if (_networkMgr.isProviderSupportServiceInNetwork(guestNetwork.getId(), Service.SourceNat, Provider.VirtualRouter)) {
publicNetwork = true;
}
if (isRedundant && !publicNetwork) {
@ -1882,7 +1882,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
if (!staticNatFirewallRules.isEmpty()) {
List<StaticNatRule> staticNatRules = new ArrayList<StaticNatRule>();
for (FirewallRule rule : staticNatFirewallRules) {
staticNatRules.add(_rulesMgr.buildStaticNatRule(rule));
staticNatRules.add(_rulesMgr.buildStaticNatRule(rule, false));
}
createApplyStaticNatRulesCommands(staticNatRules, router, cmds);
}

View File

@ -33,7 +33,7 @@ public interface RulesManager extends RulesService {
boolean applyPortForwardingRules(long ipAddressId, boolean continueOnError, Account caller);
boolean applyStaticNatRules(long sourceIpId, boolean continueOnError, Account caller);
boolean applyStaticNatRulesForIp(long sourceIpId, boolean continueOnError, Account caller, boolean forRevoke);
boolean applyPortForwardingRulesForNetwork(long networkId, boolean continueOnError, Account caller);
@ -74,7 +74,7 @@ public interface RulesManager extends RulesService {
boolean applyStaticNatsForNetwork(long networkId, boolean continueOnError, Account caller);
void enableElasticIpAndStaticNatForVm(UserVm vm, boolean getNewIp) throws InsufficientAddressCapacityException;
void getSystemIpAndEnableStaticNatForVm(UserVm vm, boolean getNewIp) throws InsufficientAddressCapacityException;
boolean disableStaticNat(long ipAddressId, Account caller, long callerUserId, boolean releaseIpIfElastic) throws ResourceUnavailableException;

View File

@ -495,7 +495,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
boolean success = false;
if (apply) {
success = applyStaticNatRules(rule.getSourceIpAddressId(), true, caller);
success = applyStaticNatRulesForIp(rule.getSourceIpAddressId(), true, caller, true);
} else {
success = true;
}
@ -563,7 +563,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
// apply rules for all ip addresses
for (Long ipId : ipsToReprogram) {
s_logger.debug("Applying static nat rules for ip address id=" + ipId + " as a part of vm expunge");
if (!applyStaticNatRules(ipId, true, _accountMgr.getSystemAccount())) {
if (!applyStaticNatRulesForIp(ipId, true, _accountMgr.getSystemAccount(), true)) {
success = false;
s_logger.warn("Failed to apply static nat rules for ip id=" + ipId);
}
@ -654,7 +654,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
}
@Override
public boolean applyStaticNatRules(long sourceIpId, boolean continueOnError, Account caller) {
public boolean applyStaticNatRulesForIp(long sourceIpId, boolean continueOnError, Account caller, boolean forRevoke) {
List<? extends FirewallRule> rules = _firewallDao.listByIpAndPurpose(sourceIpId, Purpose.StaticNat);
List<StaticNatRule> staticNatRules = new ArrayList<StaticNatRule>();
@ -664,7 +664,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
}
for (FirewallRule rule : rules) {
staticNatRules.add(buildStaticNatRule(rule));
staticNatRules.add(buildStaticNatRule(rule, forRevoke));
}
if (caller != null) {
@ -722,7 +722,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
}
for (FirewallRuleVO rule : rules) {
staticNatRules.add(buildStaticNatRule(rule));
staticNatRules.add(buildStaticNatRule(rule, false));
}
try {
@ -833,7 +833,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
@Override
@ActionEvent(eventType = EventTypes.EVENT_NET_RULE_ADD, eventDescription = "applying static nat rule", async = true)
public boolean applyStaticNatRules(long ipId, Account caller) throws ResourceUnavailableException {
if (!applyStaticNatRules(ipId, false, caller)) {
if (!applyStaticNatRulesForIp(ipId, false, caller, false)) {
throw new CloudRuntimeException("Failed to apply static nat rule");
}
return true;
@ -869,7 +869,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
success = success && applyPortForwardingRules(ipId, true, caller);
// revoke all all static nat rules
success = success && applyStaticNatRules(ipId, true, caller);
success = success && applyStaticNatRulesForIp(ipId, true, caller, true);
// revoke static nat for the ip address
success = success && applyStaticNatForIp(ipId, false, caller, true);
@ -1028,8 +1028,8 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
IPAddressVO ipAddress = _ipAddressDao.findById(ipId);
checkIpAndUserVm(ipAddress, null, caller);
if (ipAddress.getElastic()) {
throw new InvalidParameterValueException("Can't disable static nat for elastic IP address " + ipAddress);
if (ipAddress.getSystem()) {
throw new InvalidParameterValueException("Can't disable static nat for system IP address " + ipAddress);
}
Long vmId = ipAddress.getAssociatedWithVmId();
@ -1043,7 +1043,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
Network guestNetwork = _networkMgr.getNetwork(ipAddress.getAssociatedWithNetworkId());
NetworkOffering offering = _configMgr.getNetworkOffering(guestNetwork.getNetworkOfferingId());
if (offering.getElasticIp()) {
enableElasticIpAndStaticNatForVm(_vmDao.findById(vmId), true);
getSystemIpAndEnableStaticNatForVm(_vmDao.findById(vmId), true);
return true;
} else {
return disableStaticNat(ipId, caller, ctx.getCallerUserId(), false);
@ -1080,17 +1080,17 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
}
if (success) {
boolean isIpElastic = ipAddress.getElastic();
boolean isIpSystem = ipAddress.getSystem();
ipAddress.setOneToOneNat(false);
ipAddress.setAssociatedWithVmId(null);
if (isIpElastic && !releaseIpIfElastic) {
ipAddress.setElastic(false);
if (isIpSystem && !releaseIpIfElastic) {
ipAddress.setSystem(false);
}
_ipAddressDao.update(ipAddress.getId(), ipAddress);
if (isIpElastic && releaseIpIfElastic && !_networkMgr.handleElasticIpRelease(ipAddress)) {
s_logger.warn("Failed to release elastic ip address " + ipAddress);
if (isIpSystem && releaseIpIfElastic && !_networkMgr.handleSystemIpRelease(ipAddress)) {
s_logger.warn("Failed to release system ip address " + ipAddress);
success = false;
}
@ -1112,15 +1112,20 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
}
@Override
public StaticNatRule buildStaticNatRule(FirewallRule rule) {
public StaticNatRule buildStaticNatRule(FirewallRule rule, boolean forRevoke) {
IpAddress ip = _ipAddressDao.findById(rule.getSourceIpAddressId());
FirewallRuleVO ruleVO = _firewallDao.findById(rule.getId());
if (ip == null || !ip.isOneToOneNat() || ip.getAssociatedWithVmId() == null) {
throw new InvalidParameterValueException("Source ip address of the rule id=" + rule.getId() + " is not static nat enabled");
}
String dstIp = _networkMgr.getIpInNetwork(ip.getAssociatedWithVmId(), rule.getNetworkId());
String dstIp;
if (forRevoke) {
dstIp = _networkMgr.getIpInNetworkIncludingRemoved(ip.getAssociatedWithVmId(), rule.getNetworkId());
} else {
dstIp = _networkMgr.getIpInNetwork(ip.getAssociatedWithVmId(), rule.getNetworkId());
}
return new StaticNatRuleImpl(ruleVO, dstIp);
}
@ -1177,7 +1182,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
}
@Override
public void enableElasticIpAndStaticNatForVm(UserVm vm, boolean getNewIp) throws InsufficientAddressCapacityException {
public void getSystemIpAndEnableStaticNatForVm(UserVm vm, boolean getNewIp) throws InsufficientAddressCapacityException {
boolean success = true;
// enable static nat if eIp capability is supported
@ -1189,17 +1194,17 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
// check if there is already static nat enabled
if (_ipAddressDao.findByAssociatedVmId(vm.getId()) != null && !getNewIp) {
s_logger.debug("Vm " + vm + " already has elastic ip associated with it in guest network " + guestNetwork);
s_logger.debug("Vm " + vm + " already has ip associated with it in guest network " + guestNetwork);
continue;
}
s_logger.debug("Allocating elastic ip and enabling static nat for it for the vm " + vm + " in guest network " + guestNetwork);
IpAddress ip = _networkMgr.assignElasticIp(guestNetwork.getId(), _accountMgr.getAccount(vm.getAccountId()), false, true);
s_logger.debug("Allocating system ip and enabling static nat for it for the vm " + vm + " in guest network " + guestNetwork);
IpAddress ip = _networkMgr.assignSystemIp(guestNetwork.getId(), _accountMgr.getAccount(vm.getAccountId()), false, true);
if (ip == null) {
throw new CloudRuntimeException("Failed to allocate elastic ip for vm " + vm + " in guest network " + guestNetwork);
throw new CloudRuntimeException("Failed to allocate system ip for vm " + vm + " in guest network " + guestNetwork);
}
s_logger.debug("Allocated elastic ip " + ip + ", now enabling static nat on it for vm " + vm);
s_logger.debug("Allocated system ip " + ip + ", now enabling static nat on it for vm " + vm);
try {
success = enableStaticNat(ip.getId(), vm.getId());
@ -1212,11 +1217,11 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
}
if (!success) {
s_logger.warn("Failed to enable static nat on elastic ip " + ip + " for the vm " + vm + ", releasing the ip...");
_networkMgr.handleElasticIpRelease(ip);
throw new CloudRuntimeException("Failed to enable static nat on elastic ip for the vm " + vm);
s_logger.warn("Failed to enable static nat on system ip " + ip + " for the vm " + vm + ", releasing the ip...");
_networkMgr.handleSystemIpRelease(ip);
throw new CloudRuntimeException("Failed to enable static nat on system ip for the vm " + vm);
} else {
s_logger.warn("Succesfully enabled static nat on elastic ip " + ip + " for the vm " + vm);
s_logger.warn("Succesfully enabled static nat on system ip " + ip + " for the vm " + vm);
}
}
}

View File

@ -91,8 +91,8 @@ public class UsageRecordResponse extends BaseResponse implements ControlledEntit
@SerializedName("issourcenat") @Param(description="True if the IPAddress is source NAT")
private Boolean isSourceNat;
@SerializedName("iselastic") @Param(description="True if the IPAddress is elastic")
private Boolean isElastic;
@SerializedName(ApiConstants.IS_SYSTEM) @Param(description="True if the IPAddress is system IP - allocated during vm deploy or lb rule create")
private Boolean isSystem;
@SerializedName("networkid") @Param(description="id of the network")
private String networkId;
@ -174,8 +174,8 @@ public class UsageRecordResponse extends BaseResponse implements ControlledEntit
this.isSourceNat = isSourceNat;
}
public void setElastic(Boolean isElastic) {
this.isElastic = isElastic;
public void setSystem(Boolean isSystem) {
this.isSystem = isSystem;
}
@Override

View File

@ -48,8 +48,8 @@ public class UsageIPAddressVO {
@Column(name="is_source_nat")
private boolean isSourceNat = false;
@Column(name="is_elastic")
private boolean isElastic = false;
@Column(name="is_system")
private boolean isSystem = false;
@Column(name="assigned")
@Temporal(value=TemporalType.TIMESTAMP)
@ -62,14 +62,14 @@ public class UsageIPAddressVO {
protected UsageIPAddressVO() {
}
public UsageIPAddressVO(long id, long accountId, long domainId, long zoneId, String address, boolean isSourceNat, boolean isElastic, Date assigned, Date released) {
public UsageIPAddressVO(long id, long accountId, long domainId, long zoneId, String address, boolean isSourceNat, boolean isSystem, Date assigned, Date released) {
this.id = id;
this.accountId = accountId;
this.domainId = domainId;
this.zoneId = zoneId;
this.address = address;
this.isSourceNat = isSourceNat;
this.isElastic = isElastic;
this.isSystem = isSystem;
this.assigned = assigned;
this.released = released;
}
@ -105,8 +105,8 @@ public class UsageIPAddressVO {
return isSourceNat;
}
public boolean isElastic() {
return isElastic;
public boolean isSystem() {
return isSystem;
}
public Date getAssigned() {

View File

@ -41,15 +41,15 @@ public class UsageIPAddressDaoImpl extends GenericDaoBase<UsageIPAddressVO, Long
public static final Logger s_logger = Logger.getLogger(UsageIPAddressDaoImpl.class.getName());
protected static final String UPDATE_RELEASED = "UPDATE usage_ip_address SET released = ? WHERE account_id = ? AND public_ip_address = ? and released IS NULL";
protected static final String GET_USAGE_RECORDS_BY_ACCOUNT = "SELECT id, account_id, domain_id, zone_id, public_ip_address, is_source_nat, is_elastic, assigned, released " +
protected static final String GET_USAGE_RECORDS_BY_ACCOUNT = "SELECT id, account_id, domain_id, zone_id, public_ip_address, is_source_nat, is_system, assigned, released " +
"FROM usage_ip_address " +
"WHERE account_id = ? AND ((released IS NULL AND assigned <= ?) OR (assigned BETWEEN ? AND ?) OR " +
" (released BETWEEN ? AND ?) OR ((assigned <= ?) AND (released >= ?)))";
protected static final String GET_USAGE_RECORDS_BY_DOMAIN = "SELECT id, account_id, domain_id, zone_id, public_ip_address, is_source_nat, is_elastic, assigned, released " +
protected static final String GET_USAGE_RECORDS_BY_DOMAIN = "SELECT id, account_id, domain_id, zone_id, public_ip_address, is_source_nat, is_system, assigned, released " +
"FROM usage_ip_address " +
"WHERE domain_id = ? AND ((released IS NULL AND assigned <= ?) OR (assigned BETWEEN ? AND ?) OR " +
" (released BETWEEN ? AND ?) OR ((assigned <= ?) AND (released >= ?)))";
protected static final String GET_ALL_USAGE_RECORDS = "SELECT id, account_id, domain_id, zone_id, public_ip_address, is_source_nat, is_elastic, assigned, released " +
protected static final String GET_ALL_USAGE_RECORDS = "SELECT id, account_id, domain_id, zone_id, public_ip_address, is_source_nat, is_system, assigned, released " +
"FROM usage_ip_address " +
"WHERE (released IS NULL AND assigned <= ?) OR (assigned BETWEEN ? AND ?) OR " +
" (released BETWEEN ? AND ?) OR ((assigned <= ?) AND (released >= ?))";
@ -119,7 +119,7 @@ public class UsageIPAddressDaoImpl extends GenericDaoBase<UsageIPAddressVO, Long
Long zId = Long.valueOf(rs.getLong(4));
String addr = rs.getString(5);
Boolean isSourceNat = Boolean.valueOf(rs.getBoolean(6));
Boolean isElastic = Boolean.valueOf(rs.getBoolean(7));
Boolean isSystem = Boolean.valueOf(rs.getBoolean(7));
Date assignedDate = null;
Date releasedDate = null;
String assignedTS = rs.getString(8);
@ -132,7 +132,7 @@ public class UsageIPAddressDaoImpl extends GenericDaoBase<UsageIPAddressVO, Long
releasedDate = DateUtil.parseDateString(s_gmtTimeZone, releasedTS);
}
usageRecords.add(new UsageIPAddressVO(id, acctId, dId, zId, addr, isSourceNat, isElastic, assignedDate, releasedDate));
usageRecords.add(new UsageIPAddressVO(id, acctId, dId, zId, addr, isSourceNat, isSystem, assignedDate, releasedDate));
}
} catch (Exception e) {
txn.rollback();

View File

@ -2727,8 +2727,8 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
}
}
//enable elastic ip for vm
_rulesMgr.enableElasticIpAndStaticNatForVm(profile.getVirtualMachine(), false);
//get system ip and create static nat rule for the vm
_rulesMgr.getSystemIpAndEnableStaticNatForVm(profile.getVirtualMachine(), false);
return true;
}
@ -2790,12 +2790,12 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
public void finalizeStop(VirtualMachineProfile<UserVmVO> profile, StopAnswer answer) {
//release elastic IP here
IPAddressVO ip = _ipAddressDao.findByAssociatedVmId(profile.getId());
if (ip != null && ip.getElastic()) {
if (ip != null && ip.getSystem()) {
UserContext ctx = UserContext.current();
try {
_rulesMgr.disableStaticNat(ip.getId(), ctx.getCaller(), ctx.getCallerUserId(), true);
} catch (Exception ex) {
s_logger.warn("Failed to disable static nat and release elastic ip " + ip + " as a part of vm " + profile.getVirtualMachine() + " stop due to exception ", ex);
s_logger.warn("Failed to disable static nat and release system ip " + ip + " as a part of vm " + profile.getVirtualMachine() + " stop due to exception ", ex);
}
}
}

View File

@ -770,7 +770,7 @@ public class MockNetworkManagerImpl implements NetworkManager, Manager, NetworkS
@Override
public IpAddress allocateIP(long networkId, Account ipOwner,
boolean isElastic) throws ResourceAllocationException,
boolean isSystem) throws ResourceAllocationException,
InsufficientAddressCapacityException, ConcurrentOperationException {
// TODO Auto-generated method stub
return null;
@ -778,7 +778,7 @@ public class MockNetworkManagerImpl implements NetworkManager, Manager, NetworkS
@Override
public PublicIp assignPublicIpAddress(long dcId, Long podId, Account owner,
VlanType type, Long networkId, String requestedIp, boolean isElastic)
VlanType type, Long networkId, String requestedIp, boolean isSystem)
throws InsufficientAddressCapacityException {
// TODO Auto-generated method stub
return null;
@ -798,7 +798,7 @@ public class MockNetworkManagerImpl implements NetworkManager, Manager, NetworkS
}
@Override
public IpAddress assignElasticIp(long networkId, Account owner,
public IpAddress assignSystemIp(long networkId, Account owner,
boolean forElasticLb, boolean forElasticIp)
throws InsufficientAddressCapacityException {
// TODO Auto-generated method stub
@ -806,7 +806,7 @@ public class MockNetworkManagerImpl implements NetworkManager, Manager, NetworkS
}
@Override
public boolean handleElasticIpRelease(IpAddress ip) {
public boolean handleSystemIpRelease(IpAddress ip) {
// TODO Auto-generated method stub
return false;
}

View File

@ -96,7 +96,7 @@ CREATE TABLE `cloud_usage`.`usage_ip_address` (
`zone_id` bigint unsigned NOT NULL,
`public_ip_address` varchar(15) NOT NULL,
`is_source_nat` smallint(1) NOT NULL,
`is_elastic` smallint(1) NOT NULL,
`is_system` smallint(1) NOT NULL,
`assigned` DATETIME NOT NULL,
`released` DATETIME NULL,
UNIQUE KEY (`id`, `assigned`)

View File

@ -921,7 +921,7 @@ CREATE TABLE `cloud`.`user_ip_address` (
`source_network_id` bigint unsigned NOT NULL COMMENT 'network id ip belongs to',
`network_id` bigint unsigned COMMENT 'network this public ip address is associated with',
`physical_network_id` bigint unsigned NOT NULL COMMENT 'physical network id that this configuration is based on',
`is_elastic` int(1) unsigned NOT NULL default '0',
`is_system` int(1) unsigned NOT NULL default '0',
PRIMARY KEY (`id`),
UNIQUE (`public_ip_address`, `source_network_id`),
CONSTRAINT `fk_user_ip_address__source_network_id` FOREIGN KEY (`source_network_id`) REFERENCES `networks`(`id`),

View File

@ -14,12 +14,12 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
INSERT INTO `cloud`.`vm_template` (id, unique_name, name, public, created, type, hvm, bits, account_id, url, checksum, enable_password, display_text, format, guest_os_id, featured, cross_zones, hypervisor_type)
VALUES (1, 'routing-1', 'SystemVM Template (XenServer)', 0, now(), 'SYSTEM', 0, 64, 1, 'http://download.cloud.com/templates/acton/acton-systemvm-01062012.vhd.bz2', '59bb270c3a028abd86cc580274020a14', 0, 'SystemVM Template (XenServer)', 'VHD', 15, 0, 1, 'XenServer');
VALUES (1, 'routing-1', 'SystemVM Template (XenServer)', 0, now(), 'SYSTEM', 0, 64, 1, 'http://download.cloud.com/templates/acton/acton-systemvm-02062012.vhd.bz2', 'f613f38c96bf039f2e5cbf92fa8ad4f8', 0, 'SystemVM Template (XenServer)', 'VHD', 15, 0, 1, 'XenServer');
INSERT INTO `cloud`.`vm_template` (id, unique_name, name, public, created, removed, type, hvm, bits, account_id, url, checksum, enable_password, display_text, format, guest_os_id, featured, cross_zones, hypervisor_type, extractable)
VALUES (2, 'centos53-x86_64', 'CentOS 5.3(64-bit) no GUI (XenServer)', 1, now(), now(), 'BUILTIN', 0, 64, 1, 'http://download.cloud.com/templates/builtin/f59f18fb-ae94-4f97-afd2-f84755767aca.vhd.bz2', 'b63d854a9560c013142567bbae8d98cf', 0, 'CentOS 5.3(64-bit) no GUI (XenServer)', 'VHD', 12, 1, 1, 'XenServer', 1);
INSERT INTO `cloud`.`vm_template` (id, unique_name, name, public, created, type, hvm, bits, account_id, url, checksum, enable_password, display_text, format, guest_os_id, featured, cross_zones, hypervisor_type)
VALUES (3, 'routing-3', 'SystemVM Template (KVM)', 0, now(), 'SYSTEM', 0, 64, 1, 'http://download.cloud.com/templates/acton/acton-systemvm-01062012.qcow2.bz2', 'abccb541342fb058d06f70f372fc30b5', 0, 'SystemVM Template (KVM)', 'QCOW2', 15, 0, 1, 'KVM');
VALUES (3, 'routing-3', 'SystemVM Template (KVM)', 0, now(), 'SYSTEM', 0, 64, 1, 'http://download.cloud.com/templates/acton/acton-systemvm-02062012.qcow2.bz2', '2755de1f9ef2ce4d6f2bee2efbb4da92', 0, 'SystemVM Template (KVM)', 'QCOW2', 15, 0, 1, 'KVM');
INSERT INTO `cloud`.`vm_template` (id, unique_name, name, public, created, type, hvm, bits, account_id, url, checksum, display_text, enable_password, format, guest_os_id, featured, cross_zones, hypervisor_type, extractable)
VALUES (4, 'centos55-x86_64', 'CentOS 5.5(64-bit) no GUI (KVM)', 1, now(), 'BUILTIN', 0, 64, 1, 'http://download.cloud.com/releases/2.2.0/eec2209b-9875-3c8d-92be-c001bd8a0faf.qcow2.bz2', 'ed0e788280ff2912ea40f7f91ca7a249', 'CentOS 5.5(64-bit) no GUI (KVM)', 0, 'QCOW2', 112, 1, 1, 'KVM', 1);
@ -31,10 +31,10 @@ INSERT INTO `cloud`.`vm_template` (id, unique_name, name, public, created, type,
VALUES (7, 'centos53-x64', 'CentOS 5.3(64-bit) no GUI (vSphere)', 1, now(), 'BUILTIN', 0, 64, 1, 'http://download.cloud.com/releases/2.2.0/CentOS5.3-x86_64.ova', 'f6f881b7f2292948d8494db837fe0f47', 0, 'CentOS 5.3(64-bit) no GUI (vSphere)', 'OVA', 12, 1, 1, 'VMware', 1);
INSERT INTO `cloud`.`vm_template` (id, unique_name, name, public, created, type, hvm, bits, account_id, url, checksum, enable_password, display_text, format, guest_os_id, featured, cross_zones, hypervisor_type)
VALUES (8, 'routing-8', 'SystemVM Template (vSphere)', 0, now(), 'SYSTEM', 0, 32, 1, 'http://download.cloud.com/templates/acton/acton-systemvm-01062012.ova', 'ae7900950ff2e9820f6cde2fd58691e5', 0, 'SystemVM Template (vSphere)', 'OVA', 15, 0, 1, 'VMware');
VALUES (8, 'routing-8', 'SystemVM Template (vSphere)', 0, now(), 'SYSTEM', 0, 32, 1, 'http://download.cloud.com/templates/acton/acton-systemvm-02062012.ova', 'e72b21c9541d005600297cb92d241434', 0, 'SystemVM Template (vSphere)', 'OVA', 15, 0, 1, 'VMware');
INSERT INTO `cloud`.`vm_template` (id, unique_name, name, public, created, type, hvm, bits, account_id, url, checksum, enable_password, display_text, format, guest_os_id, featured, cross_zones, hypervisor_type)
VALUES (9, 'routing-9', 'SystemVM Template (HyperV)', 0, now(), 'SYSTEM', 0, 32, 1, 'http://download.cloud.com/templates/acton/acton-systemvm-01062012.vhd.bz2', '59bb270c3a028abd86cc580274020a14', 0, 'SystemVM Template (HyperV)', 'VHD', 15, 0, 1, 'Hyperv');
VALUES (9, 'routing-9', 'SystemVM Template (HyperV)', 0, now(), 'SYSTEM', 0, 32, 1, 'http://download.cloud.com/templates/acton/acton-systemvm-02062012.vhd.bz2', 'f613f38c96bf039f2e5cbf92fa8ad4f8', 0, 'SystemVM Template (HyperV)', 'VHD', 15, 0, 1, 'Hyperv');
INSERT INTO `cloud`.`guest_os_category` (id, name) VALUES (1, 'CentOS');
INSERT INTO `cloud`.`guest_os_category` (id, name) VALUES (2, 'Debian');

View File

@ -213,7 +213,7 @@ class deployDataCenters():
def enableZone(self, zoneid, allocation_state="Enabled"):
zoneCmd = updateZone.updateZoneCmd()
zoneCmd.zoneid = zoneid
zoneCmd.id = zoneid
zoneCmd.allocationstate = allocation_state
return self.apiClient.updateZone(zoneCmd)
@ -227,22 +227,19 @@ class deployDataCenters():
createzone.name = zone.name
createzone.securitygroupenabled = zone.securitygroupenabled
createzone.networktype = zone.networktype
createzone.guestcidraddress = zone.guestcidraddress
zoneresponse = self.apiClient.createZone(createzone)
zoneId = zoneresponse.id
phynetwrk = self.createPhysicalNetwork(zone.name + "-pnet", \
zoneId, zone.vlan)
zoneId)
if zone.networktype == "Advanced":
self.addTrafficTypes(phynetwrk.id, ["Guest", "Public", \
self.addTrafficTypes(phynetwrk.id, ["Guest", "Public", \
"Management"])
elif zone.networktype == "Basic":
self.addTrafficTypes(phynetwrk.id, ["Guest", "Public", \
"Management", "Storage"])
self.configureProviders(phynetwrk, zone)
self.updatePhysicalNetwork(phynetwrk.id, "Enabled")
self.updatePhysicalNetwork(phynetwrk.id, "Enabled", vlan=zone.vlan)
if zone.networktype == "Basic":
listnetworkoffering = \

View File

@ -1,273 +1,65 @@
{
"zones": [
{
"name": "Sandbox-Simulator",
"name": "Sandbox-simulator",
"guestcidraddress": "10.1.1.0/24",
"dns2": "10.223.110.254",
"dns1": "4.2.2.2",
"vlan": "100-300",
"providers": [
{
"broadcastdomainrange": "ZONE",
"name": "VirtualRouter"
}
],
"dns1": "10.147.28.6",
"vlan": "100-500",
"ipranges": [
{
"startip": "172.1.2.2",
"endip": "172.1.2.200",
"startip": "172.2.1.2",
"endip": "172.2.1.252",
"netmask": "255.255.255.0",
"vlan": "30",
"gateway": "172.1.2.1"
"gateway": "172.2.1.1"
}
],
"networktype": "Advanced",
"pods": [
{
"endip": "172.1.1.200",
"endip": "172.1.2.252",
"name": "POD0",
"startip": "172.1.1.2",
"startip": "172.1.2.2",
"netmask": "255.255.255.0",
"clusters": [
{
"clustername": "POD1-CLUSTER1",
"hypervisor": "Simulator",
"clustername": "C0",
"hypervisor": "simulator",
"hosts": [
{
"username": "root",
"url": "http://sim/test-1",
"password": "password"
},
{
"username": "root",
"url": "http://sim/test-2",
"url": "http://sim",
"password": "password"
}
],
"clustertype": "CloudManaged",
"primaryStorages": [
{
"url": "nfs://172.16.24.32/export/path/1",
"name": "spool1"
}
]
},
{
"clustername": "POD1-CLUSTER2",
"hypervisor": "Simulator",
"hosts": [
{
"username": "root",
"url": "http://sim/test-3",
"password": "password"
},
{
"username": "root",
"url": "http://sim/test-4",
"password": "password"
}
],
"clustertype": "CloudManaged",
"primaryStorages": [
{
"url": "nfs://172.16.24.32/export/path/2",
"name": "spool2"
}
]
},
{
"clustername": "POD1-CLUSTER3",
"hypervisor": "Simulator",
"hosts": [
{
"username": "root",
"url": "http://sim/test-5",
"password": "password"
},
{
"username": "root",
"url": "http://sim/test-6",
"password": "password"
}
],
"clustertype": "CloudManaged",
"primaryStorages": [
{
"url": "nfs://172.16.24.32/export/path/3",
"name": "spool3"
}
]
},
{
"clustername": "POD1-CLUSTER4",
"hypervisor": "Simulator",
"hosts": [
{
"username": "root",
"url": "http://sim/test-7",
"password": "password"
},
{
"username": "root",
"url": "http://sim/test-8",
"password": "password"
}
],
"clustertype": "CloudManaged",
"primaryStorages": [
{
"url": "nfs://172.16.24.32/export/path/4",
"name": "spool4"
}
]
},
{
"clustername": "POD1-CLUSTER5",
"hypervisor": "Simulator",
"hosts": [
{
"username": "root",
"url": "http://sim/test-9",
"password": "password"
},
{
"username": "root",
"url": "http://sim/test-10",
"password": "password"
}
],
"clustertype": "CloudManaged",
"primaryStorages": [
{
"url": "nfs://172.16.24.32/export/path/5",
"name": "spool5"
}
]
},
{
"clustername": "POD1-CLUSTER6",
"hypervisor": "Simulator",
"hosts": [
{
"username": "root",
"url": "http://sim/test-11",
"password": "password"
},
{
"username": "root",
"url": "http://sim/test-12",
"password": "password"
}
],
"clustertype": "CloudManaged",
"primaryStorages": [
{
"url": "nfs://172.16.24.32/export/path/6",
"name": "spool6"
}
]
},
{
"clustername": "POD1-CLUSTER7",
"hypervisor": "Simulator",
"hosts": [
{
"username": "root",
"url": "http://sim/test-13",
"password": "password"
},
{
"username": "root",
"url": "http://sim/test-14",
"password": "password"
}
],
"clustertype": "CloudManaged",
"primaryStorages": [
{
"url": "nfs://172.16.24.32/export/path/7",
"name": "spool7"
}
]
},
{
"clustername": "POD1-CLUSTER8",
"hypervisor": "Simulator",
"hosts": [
{
"username": "root",
"url": "http://sim/test-15",
"password": "password"
},
{
"username": "root",
"url": "http://sim/test-16",
"password": "password"
}
],
"clustertype": "CloudManaged",
"primaryStorages": [
{
"url": "nfs://172.16.24.32/export/path/8",
"name": "spool8"
}
]
},
{
"clustername": "POD1-CLUSTER9",
"hypervisor": "Simulator",
"hosts": [
{
"username": "root",
"url": "http://sim/test-17",
"password": "password"
},
{
"username": "root",
"url": "http://sim/test-18",
"password": "password"
}
],
"clustertype": "CloudManaged",
"primaryStorages": [
{
"url": "nfs://172.16.24.32/export/path/9",
"name": "spool9"
}
]
},
{
"clustername": "POD1-CLUSTER10",
"hypervisor": "Simulator",
"hosts": [
{
"username": "root",
"url": "http://sim/test-19",
"password": "password"
},
{
"username": "root",
"url": "http://sim/test-20",
"password": "password"
}
],
"clustertype": "CloudManaged",
"primaryStorages": [
{
"url": "nfs://172.16.24.32/export/path/10",
"name": "spool10"
"url": "nfs://172.2.2.6:/export/home/primary",
"name": "PS0"
}
]
}
],
"gateway": "172.1.1.1"
"gateway": "172.1.2.1"
}
],
"internaldns1": "10.147.28.6",
"internaldns2": "10.223.110.254",
"secondaryStorages": [
{
"url": "nfs://172.16.25.32/secondary/path"
"url": "nfs://172.2.2.6:/export/home/secondary"
}
]
}
],
"dbSvr": {
"dbSvr": "10.147.28.40",
"dbSvr": "localhost",
"passwd": "cloud",
"db": "cloud",
"port": 3306,
@ -285,61 +77,61 @@
],
"globalConfig": [
{
"name": "use.user.concentrated.pod.allocation",
"value": "false"
"name": "storage.cleanup.interval",
"value": "300"
},
{
"name": "vm.op.wait.interval",
"value": "5"
},
{
"name": "default.page.size",
"value": "10000"
},
{
"name": "instance.name",
"value": "QA"
},
{
"name": "workers",
"value": "10"
},
{
"name": "direct.agent.load.size",
"value": "1000"
},
{
"name": "account.cleanup.interval",
"value": "600"
},
{
"name": "guest.domain.suffix",
"value": "sandbox.simulator"
},
{
"name": "expunge.delay",
"value": "60"
},
{
"name": "vm.allocation.algorithm",
"value": "random"
},
{
"name": "check.pod.cidrs",
"value": "false"
},
{
"name": "instance.name",
"value": "SIMQA"
},
{
"name": "workers",
"value": "10"
},
{
"name": "vm.op.wait.interval",
"value": "5"
},
{
"name": "guest.domain.suffix",
"value": "sandbox.simulator"
"value": "userdispersing"
},
{
"name": "expunge.interval",
"value": "60"
},
{
"name": "linkLocalIp.nums",
"value": "10"
},
{
"name": "expunge.workers",
"value": "3"
},
{
"name": "check.pod.cidrs",
"value": "true"
}
],
"mgtSvr": [
{
"mgtSvrIp": "10.147.28.40",
"mgtSvrIp": "localhost",
"port": 8096
}
]

View File

@ -31,10 +31,7 @@ def describeResources(config):
z.name = 'Sandbox-%s'%(config.get('environment', 'hypervisor'))
z.networktype = 'Advanced'
z.guestcidraddress = '10.1.1.0/24'
prov = provider()
prov.vlan = config.get('cloudstack','guest.vlan')
z.providers.append(prov)
z.vlan = config.get('cloudstack','guest.vlan')
p = pod()
p.name = 'POD0'

View File

@ -13,20 +13,36 @@ div.panel div.list-view div.fixed-header {
top: expression(this.offsetParent.scrollTop + 30);
}
.detail-view div.list-view div.fixed-header {
top: 29px !important;
left: 12px !important;
}
div.panel div.list-view div.data-table table.body {
top: 78px;
}
.detail-view .main-groups {
width: 554px;
width: 96%;
height: 416px;
position: relative;
overflow-x: hidden;
margin-top: -18px;
}
.detail-view .ui-widget-content {
overflow-x: hidden !important;
}
.tree-view {
position: relative;
top: expression(this.offsetParent.scrollTop);
}
.tree-view li .name {
margin: 0px !important;
}
.detail-view .button.done {
/*+placement:shift 0px 459px;*/
position: relative;
@ -92,3 +108,28 @@ table th {
vertical-align: middle;
}
.detail-view > .toolbar {
position: relative;
float: left;
left: -14px;
}
.detail-view .list-view > .toolbar {
width: 100% !important;
}
.system-chart ul.resources li .label {
/*+placement:shift 3px 9px;*/
position: relative;
left: 3px;
top: 9px;
position: absolute;
}
.system-chart ul.resources li .button.view-all .view-all-label {
/*+placement:shift 6px 5px;*/
position: relative;
left: 6px;
top: 5px;
}

View File

@ -1205,7 +1205,7 @@ div.list-view td.state.off span {
.ui-tabs li a {
float: left;
padding: 15px;
width: 91px;
min-width: 91px;
text-align: center;
font-size: 11px;
margin-right: 1px;
@ -2040,6 +2040,9 @@ div.detail-group.actions td {
.detail-view .ui-tabs-panel div.toolbar {
width: 768px;
background: none;
border: none;
margin-top: 8px;
}
.project-view div.toolbar {
@ -6099,7 +6102,8 @@ label.error {
/*Tree view*/
.tree-view {
height: 100%;
width: 24%;
height: 98%;
overflow: auto;
}

View File

@ -68,7 +68,7 @@
<ul>
<li class="first"><span class="number">1</span><span><fmt:message key="label.setup"/></span><span class="arrow"></span></li>
<li><span class="number">2</span><span class="multiline"><fmt:message key="label.select.a.template"/></span><span class="arrow"></span></li>
<li><span class="number">3</span><span class="multiline"><fmt:message key="label.service.offering"/></span><span class="arrow"></span></li>
<li><span class="number">3</span><span class="multiline"><fmt:message key="label.compute.offering"/></span><span class="arrow"></span></li>
<li><span class="number">4</span><span class="multiline"><fmt:message key="label.data.disk.offering"/></span><span class="arrow"></span></li>
<li><span class="number">5</span><span><fmt:message key="label.menu.network"/></span><span class="arrow"></span></li>
<li class="last"><span class="number">6</span><span><fmt:message key="label.review"/></span></li>
@ -260,7 +260,7 @@
<!-- Service offering -->
<div class="select-desc field service-offering hide-if-unselected">
<div class="name"><fmt:message key="label.service.offering"/></div>
<div class="name"><fmt:message key="label.compute.offering"/></div>
<div class="desc">
<select name="new-network-networkofferingid">
</select>
@ -362,7 +362,7 @@
<!-- Service offering -->
<div class="select odd">
<div class="name">
<span><fmt:message key="label.service.offering"/></span>
<span><fmt:message key="label.compute.offering"/></span>
</div>
<div class="value">
<span wizard-field="service-offering"></span>
@ -1614,6 +1614,26 @@
<script language="javascript">
dictionary = {
'label.compute.offering': '<fmt:message key="label.compute.offering"/>',
'label.add.compute.offering': '<fmt:message key="label.add.compute.offering"/>',
'label.compute.offerings': '<fmt:message key="label.compute.offerings"/>',
'label.select.offering': '<fmt:message key="label.select.offering"/>',
'label.menu.infrastructure': '<fmt:message key="label.menu.infrastructure"/>',
'label.sticky.domain': '<fmt:message key="label.sticky.domain"/>',
'label.sticky.postonly': '<fmt:message key="label.sticky.postonly"/>',
'label.sticky.indirect': '<fmt:message key="label.sticky.indirect"/>',
'label.sticky.nocache': '<fmt:message key="label.sticky.nocache"/>',
'label.sticky.prefix': '<fmt:message key="label.sticky.prefix"/>',
'label.sticky.request-learn': '<fmt:message key="label.sticky.request-learn"/>',
'label.sticky.holdtime': '<fmt:message key="label.sticky.holdtime"/>',
'label.sticky.length': '<fmt:message key="label.sticky.length"/>',
'label.sticky.mode': '<fmt:message key="label.sticky.mode"/>',
'label.sticky.cookie-name': '<fmt:message key="label.sticky.cookie-name"/>',
'label.sticky.expire': '<fmt:message key="label.sticky.expire"/>',
'label.sticky.tablesize': '<fmt:message key="label.sticky.tablesize"/>',
'state.Migrating': '<fmt:message key="state.Migrating"/>',
'state.Allocating': '<fmt:message key="state.Allocating"/>',
'label.total.of.ip': '<fmt:message key="label.total.of.ip"/>',
'state.Stopping': '<fmt:message key="state.Stopping"/>',
'message.add.load.balancer.under.ip': '<fmt:message key="message.add.load.balancer.under.ip"/>',
'message.select.instance': '<fmt:message key="message.select.instance"/>',
@ -2836,6 +2856,8 @@ dictionary = {
'message.zone.creation.complete.would.you.like.to.enable.this.zone': '<fmt:message key="message.zone.creation.complete.would.you.like.to.enable.this.zone" />',
'message.please.add.at.lease.one.traffic.range': '<fmt:message key="message.please.add.at.lease.one.traffic.range" />',
'message.you.must.have.at.least.one.physical.network': '<fmt:message key="message.you.must.have.at.least.one.physical.network" />',
'message.please.select.a.different.public.and.management.network.before.removing': '<fmt:message key="message.please.select.a.different.public.and.management.network.before.removing" />'
'message.please.select.a.different.public.and.management.network.before.removing': '<fmt:message key="message.please.select.a.different.public.and.management.network.before.removing" />',
'label.purpose': '<fmt:message key="label.purpose" />',
'error.please.specify.physical.network.tags': '<fmt:message key="error.please.specify.physical.network.tags" />'
};
</script>

View File

@ -522,7 +522,7 @@
},
vmtotal: { label: 'label.total.of.vm' },
iptotal: { label: 'label.totoal.of.ip' },
iptotal: { label: 'label.total.of.ip' },
receivedbytes: {
label: 'label.bytes.received',
converter: function(args) {

View File

@ -4,15 +4,15 @@
var networkServiceObjs = [], serviceCheckboxNames = [];
cloudStack.sections.configuration = {
title: 'label.configuration',
title: 'label.menu.service.offerings',
id: 'configuration',
sectionSelect: {
label: 'label.select-view'
label: 'label.select.offering'
},
sections: {
serviceOfferings: {
type: 'select',
title: 'label.menu.service.offerings',
title: 'label.compute.offerings',
listView: {
id: 'serviceOfferings',
label: 'label.menu.service.offerings',
@ -25,19 +25,19 @@
actions: {
add: {
label: 'label.add.service.offering',
label: 'label.add.compute.offering',
messages: {
confirm: function(args) {
return 'message.add.service.offering';
},
notification: function(args) {
return 'label.add.service.offering';
return 'label.add.compute.offering';
}
},
createForm: {
title: 'label.add.service.offering',
title: 'label.add.compute.offering',
fields: {
name: {
label: 'label.name',
@ -892,95 +892,7 @@
}
}
}
},
hypervisorCapabilities: {
type: 'select',
title: 'label.hypervisor.capabilities',
listView: {
id: 'hypervisorCapabilities',
label: 'label.hypervisor.capabilities',
fields: {
hypervisor: { label: 'label.hypervisor' },
hypervisorversion: { label: 'label.hypervisor.version' },
maxguestslimit: { label: 'label.max.guest.limit' }
},
dataProvider: function(args) {
var array1 = [];
if(args.filterBy != null) {
if(args.filterBy.search != null && args.filterBy.search.by != null && args.filterBy.search.value != null) {
switch(args.filterBy.search.by) {
case "name":
if(args.filterBy.search.value.length > 0)
array1.push("&keyword=" + args.filterBy.search.value);
break;
}
}
}
$.ajax({
url: createURL("listHypervisorCapabilities&page=" + args.page + "&pagesize=" + pageSize + array1.join("")),
dataType: "json",
async: true,
success: function(json) {
var items = json.listhypervisorcapabilitiesresponse.hypervisorCapabilities;
args.response.success({data:items});
},
error: function(data) {
args.response.error(parseXMLHttpResponse(data));
}
});
},
detailView: {
name: 'label.details',
actions: {
edit: {
label: 'label.edit',
action: function(args) {
var array1 = [];
array1.push("&maxguestslimit=" + todb(args.data.maxguestslimit));
$.ajax({
url: createURL("updateHypervisorCapabilities&id=" + args.context.hypervisorCapabilities[0].id + array1.join("")),
dataType: "json",
success: function(json) {
var item = json.updatehypervisorcapabilitiesresponse['null'];
args.response.success({data: item});
},
error: function(data) {
args.response.error(parseXMLHttpResponse(data));
}
});
}
}
},
tabs: {
details: {
title: 'label.details',
fields: [
{
id: { label: 'label.id' },
hypervisor: { label: 'label.hypervisor' },
hypervisorversion: { label: 'label.hypervisor.version' },
maxguestslimit: {
label: 'label.max.guest.limit',
isEditable: true
}
}
],
dataProvider: function(args) {
args.response.success(
{
data:args.context.hypervisorCapabilities[0]
}
);
}
}
}
}
}
},
},
networkOfferings: {
type: 'select',
@ -1245,7 +1157,7 @@
//show or hide upon checked services and selected providers above (begin)
serviceOfferingId: {
label: 'label.service.offering',
label: 'label.compute.offering',
select: function(args) {
$.ajax({
url: createURL('listServiceOfferings&issystem=true'),

View File

@ -2,58 +2,154 @@
cloudStack.sections['global-settings'] = {
title: 'label.menu.global.settings',
id: 'global-settings',
listView: {
label: 'label.menu.global.settings',
actions: {
edit: {
label: 'label.change.value',
action: function(args) {
var name = args.data.jsonObj.name;
var value = args.data.value;
sectionSelect: {
label: 'label.select-view'
},
sections: {
globalSettings: {
type: 'select',
title: 'label.menu.global.settings',
listView: {
label: 'label.menu.global.settings',
actions: {
edit: {
label: 'label.change.value',
action: function(args) {
var name = args.data.jsonObj.name;
var value = args.data.value;
$.ajax({
url: createURL(
'updateConfiguration&name=' + name + '&value=' + value
),
dataType: 'json',
async: true,
success: function(json) {
var item = json.updateconfigurationresponse.configuration;
cloudStack.dialog.notice({ message: _l('message.restart.mgmt.server') });
args.response.success({data: item});
},
error: function(json) {
args.response.error(parseXMLHttpResponse(json));
}
});
}
}
},
fields: {
name: { label: 'label.name', id: true },
description: { label: 'label.description' },
value: { label: 'label.value', editable: true }
},
dataProvider: function(args) {
var data = {
page: args.page,
pagesize: pageSize
};
if (args.filterBy.search.value) {
data.name = args.filterBy.search.value;
}
$.ajax({
url: createURL(
'updateConfiguration&name=' + name + '&value=' + value
),
dataType: 'json',
url: createURL('listConfigurations'),
data: data,
dataType: "json",
async: true,
success: function(json) {
var item = json.updateconfigurationresponse.configuration;
cloudStack.dialog.notice({ message: _l('message.restart.mgmt.server') });
args.response.success({data: item});
},
error: function(json) {
args.response.error(parseXMLHttpResponse(json));
success: function(json) {
var items = json.listconfigurationsresponse.configuration;
args.response.success({ data: items });
}
});
}
}
},
fields: {
name: { label: 'label.name', id: true },
description: { label: 'label.description' },
value: { label: 'label.value', editable: true }
},
dataProvider: function(args) {
var data = {
page: args.page,
pagesize: pageSize
};
hypervisorCapabilities: {
type: 'select',
title: 'label.hypervisor.capabilities',
listView: {
id: 'hypervisorCapabilities',
label: 'label.hypervisor.capabilities',
fields: {
hypervisor: { label: 'label.hypervisor' },
hypervisorversion: { label: 'label.hypervisor.version' },
maxguestslimit: { label: 'label.max.guest.limit' }
},
dataProvider: function(args) {
var array1 = [];
if(args.filterBy != null) {
if(args.filterBy.search != null && args.filterBy.search.by != null && args.filterBy.search.value != null) {
switch(args.filterBy.search.by) {
case "name":
if(args.filterBy.search.value.length > 0)
array1.push("&keyword=" + args.filterBy.search.value);
break;
}
}
}
$.ajax({
url: createURL("listHypervisorCapabilities&page=" + args.page + "&pagesize=" + pageSize + array1.join("")),
dataType: "json",
async: true,
success: function(json) {
var items = json.listhypervisorcapabilitiesresponse.hypervisorCapabilities;
args.response.success({data:items});
},
error: function(data) {
args.response.error(parseXMLHttpResponse(data));
}
});
},
if (args.filterBy.search.value) {
data.name = args.filterBy.search.value;
}
detailView: {
name: 'label.details',
actions: {
edit: {
label: 'label.edit',
action: function(args) {
var array1 = [];
array1.push("&maxguestslimit=" + todb(args.data.maxguestslimit));
$.ajax({
url: createURL("updateHypervisorCapabilities&id=" + args.context.hypervisorCapabilities[0].id + array1.join("")),
dataType: "json",
success: function(json) {
var item = json.updatehypervisorcapabilitiesresponse['null'];
args.response.success({data: item});
},
error: function(data) {
args.response.error(parseXMLHttpResponse(data));
}
});
}
}
},
$.ajax({
url: createURL('listConfigurations'),
data: data,
dataType: "json",
async: true,
success: function(json) {
var items = json.listconfigurationsresponse.configuration;
args.response.success({ data: items });
tabs: {
details: {
title: 'label.details',
fields: [
{
id: { label: 'label.id' },
hypervisor: { label: 'label.hypervisor' },
hypervisorversion: { label: 'label.hypervisor.version' },
maxguestslimit: {
label: 'label.max.guest.limit',
isEditable: true
}
}
],
dataProvider: function(args) {
args.response.success(
{
data:args.context.hypervisorCapabilities[0]
}
);
}
}
}
}
});
}
}
}
};

View File

@ -252,13 +252,14 @@
var services = $.map(networkOffering.service, function(service) {
return service.name;
});
return $.inArray('SecurityGroup', services) == -1;
//pick the network offering including SecurityGroup, but excluding Lb and StaticNat. (bug 13665)
return (($.inArray('SecurityGroup', services) != -1) && ($.inArray('Lb', services) == -1) && ($.inArray('StaticNat', services) == -1)) ;
}
)[0];
)[0];
}
});
cloudStack.zoneWizard.action($.extend(true, {}, args, {
// Plug in hard-coded values specific to quick install
data: {
@ -266,7 +267,11 @@
networkType: 'Basic',
domain: 1,
networkOfferingId: selectedNetworkOffering.id
}
},
pluginFrom: {
name: 'installWizard',
selectedNetworkOfferingHavingSG: true
}
},
response: {
success: function(args) {

View File

@ -997,8 +997,10 @@
edit: {
label: 'Edit',
action: function(args) {
var array1 = [];
array1.push("&displayName=" + args.data.displayname);
var array1 = [];
if(args.data.displayname != args.context.instances[0].name)
array1.push("&displayName=" + args.data.displayname);
array1.push("&group=" + args.data.group);
array1.push("&ostypeid=" + args.data.guestosid);
//array1.push("&haenable=" + haenable);
@ -1181,7 +1183,7 @@
desc: '',
fields: {
serviceOffering: {
label: 'label.service.offering',
label: 'label.compute.offering',
select: function(args) {
$.ajax({
url: createURL("listServiceOfferings&VirtualMachineId=" + args.context.instances[0].id),
@ -1483,6 +1485,11 @@
else {
hiddenFields = ["hypervisor"];
}
if (!args.context.instances[0].publicip) {
hiddenFields.push('publicip');
}
return hiddenFields;
},
@ -1491,6 +1498,7 @@
id: { label: 'label.id', isEditable: false },
displayname: { label: 'label.display.name', isEditable: true },
state: { label: 'label.state', isEditable: false },
publicip: { label: 'label.public.ip', isEditable: false },
zonename: { label: 'label.zone.name', isEditable: false },
hypervisor: { label: 'label.hypervisor', isEditable: false },
templatename: { label: 'label.template', isEditable: false },
@ -1514,7 +1522,7 @@
}
},
serviceofferingname: { label: 'label.service.offering', isEditable: false },
serviceofferingname: { label: 'label.compute.offering', isEditable: false },
group: { label: 'label.group', isEditable: true },
hostname: { label: 'label.host', isEditable: false},
haenable: { label: 'label.ha.enabled', isEditable: false, converter:cloudStack.converters.toBooleanText },

View File

@ -19,21 +19,24 @@
)[0].value);
var baseFields = {
stickyName: { label: 'Sticky Name', validation: { required: true } },
name: { label: 'Name', validation: { required: true }, isHidden: true },
mode: { label: 'Mode', isHidden: true },
length: { label: 'Length', validation: { required: true }, isHidden: true },
holdtime: { label: 'Hold Time', validation: { required: true }, isHidden: true },
tablesize: { label: 'Table size', isHidden: true },
expire: { label: 'Expire', isHidden: true },
requestlearn: { label: 'Request-Learn', isBoolean: true, isHidden: true },
prefix: { label: 'Prefix', isBoolean: true, isHidden: true },
nocache: { label: 'No cache', isBoolean: true, isHidden: true },
indirect: { label: 'Indirect', isBoolean: true, isHidden: true },
postonly: { label: 'Is post-only', isBoolean: true, isHidden: true },
domain: { label: 'Domain', isBoolean: true, isHidden: true }
stickyName: { label: 'Sticky Name', validation: { required: true } }
};
$.map(
$.map(
stickinessCapabilities,
function(c) { return c.paramlist; }
),
function(p) {
baseFields[p.paramname] = {
label: _l('label.sticky.' + p.paramname),
isHidden: true,
isBoolean: p.isflag,
validation: { required: p.required }
};
}
);
var conditionalFields = {
methodname: {
label: 'Stickiness method',
@ -123,7 +126,7 @@
},
after: function(args) {
// Remove fields not applicable to sticky method
args.$form.find('.form-item:hidden').remove()
args.$form.find('.form-item:hidden').remove();
var data = cloudStack.serializeForm(args.$form);

View File

@ -1,3 +1,4 @@
(function(cloudStack, $) {
var ipChangeNotice = function() {
cloudStack.dialog.confirm({
@ -32,7 +33,7 @@
status == 'Creating' ||
status == 'Allocating' ||
item.account == 'system' ||
item.iselastic == true ) {
item.issystem == true ) {
disallowedActions = allowedActions;
}
@ -42,10 +43,16 @@
disallowedActions.push('disableStaticNAT');
}
if (item.vpnenabled) {
disallowedActions.push('enableVPN');
if ($.inArray('Vpn', $.map(args.context.networks[0].service,
function(service) { return service.name; })) > -1) {
if (item.vpnenabled) {
disallowedActions.push('enableVPN');
} else {
disallowedActions.push('disableVPN');
}
} else {
disallowedActions.push('disableVPN');
disallowedActions.push('enableVPN');
}
if (item.issourcenat){
@ -896,9 +903,8 @@
}
},
zonename: { label: 'label.zone' },
//vlanname: { label: 'VLAN' },
iselastic: { label: 'label.elastic', converter: cloudStack.converters.toBooleanText },
account: { label: 'label.account' },
//vlanname: { label: 'VLAN' },
virtualmachinedisplayname: { label: 'label.vm.name' },
state: {
converter: function(str) {
// For localization
@ -1051,7 +1057,7 @@
if (!ipAddress.vpnenabled) {
disabledTabs.push('vpn');
}
if(ipAddress.iselastic == true) {
if(ipAddress.issystem == true) {
disabledTabs.push('vpn');
if(ipAddress.isstaticnat == true || ipAddress.virtualmachineid != null)
@ -1320,6 +1326,25 @@
tabs: {
details: {
title: 'label.details',
preFilter: function(args) {
var hiddenFields = [];
var zoneObj;
$.ajax({
url: createURL("listZones&id=" + args.context.ipAddresses[0].zoneid),
dataType: "json",
async: false,
success: function(json) {
zoneObj = json.listzonesresponse.zone[0];
}
});
if(zoneObj.networktype == "Advanced") {
hiddenFields.push("issystem");
hiddenFields.push("purpose");
}
return hiddenFields;
},
fields: [
{
ipaddress: { label: 'IP' }
@ -1333,7 +1358,8 @@
state: { label: 'label.state' },
issourcenat: { label: 'label.source.nat', converter: cloudStack.converters.toBooleanText },
isstaticnat: { label: 'label.static.nat', converter: cloudStack.converters.toBooleanText },
iselastic: { label: 'label.elastic', converter: cloudStack.converters.toBooleanText },
issystem: { label: 'label.is.system', converter: cloudStack.converters.toBooleanText }, //(basic zone only)
purpose: { label: 'label.purpose' }, //(basic zone only) When an IP is system-generated, the purpose it serves can be Lb or static nat.
virtualmachinedisplayname: { label: 'label.vm.name' },
domain: { label: 'label.domain' },
account: { label: 'label.account' },
@ -1454,11 +1480,18 @@
});
if ($(this).val() == 'icmp') {
$icmpFields.show();
$icmpFields.attr('disabled', false);
$otherFields.attr('disabled', 'disabled');
$otherFields.hide();
$otherFields.parent().find('label.error').hide();
} else {
$otherFields.show();
$otherFields.parent().find('label.error').hide();
$otherFields.attr('disabled', false);
$icmpFields.attr('disabled', 'disabled');
$icmpFields.hide();
$icmpFields.parent().find('label.error').hide();
}
});
@ -1684,6 +1717,7 @@
$.ajax({
url: createURL('listIpForwardingRules'),
data: {
listAll: true,
ipaddressid: args.context.ipAddresses[0].id
},
dataType: 'json',

View File

@ -932,7 +932,7 @@
},
accept: {
label: 'message.accept.project.invitation',
label: 'label.accept.project.invitation',
action: function(args) {
$.ajax({
url: createURL('updateProjectInvitation'),
@ -954,7 +954,7 @@
},
messages: {
confirm: function() { return 'message.confirm.join.project'; },
notification: function() { return 'message.accept.project.invitation'; }
notification: function() { return 'label.accept.project.invitation'; }
},
notification: { poll: pollAsyncJobResult }
},

View File

@ -1,6 +1,6 @@
(function($, cloudStack) {
var zoneObjs, podObjs, clusterObjs, domainObjs, networkOfferingObjs;
var zoneObjs, podObjs, clusterObjs, domainObjs, networkOfferingObjs, physicalNetworkObjs;
var selectedClusterObj, selectedZoneObj, selectedPublicNetworkObj, selectedManagementNetworkObj, selectedPhysicalNetworkObj, selectedGuestNetworkObj;
var naasStatusMap = {};
var nspMap = {};
@ -79,7 +79,7 @@
};
cloudStack.sections.system = {
title: 'label.menu.system',
title: 'label.menu.infrastructure',
id: 'system',
// System dashboard
@ -1046,24 +1046,60 @@
label: 'label.network.offering',
dependsOn: 'scope',
select: function(args) {
var array1 = [];
var apiCmd = "listNetworkOfferings&state=Enabled&zoneid=" + selectedZoneObj.id;
var array1 = [];
if(physicalNetworkObjs.length > 1) { //multiple physical networks
var guestTrafficTypeTotal = 0;
for(var i = 0; i < physicalNetworkObjs.length; i++) {
if(guestTrafficTypeTotal > 1)
break;
$.ajax({
url: createURL("listTrafficTypes&physicalnetworkid=" + physicalNetworkObjs[i].id),
dataType: "json",
async: false,
success: function(json) {
var items = json.listtraffictypesresponse.traffictype;
for(var k = 0; k < items.length; k++) {
if(items[k].traffictype == "Guest") {
guestTrafficTypeTotal++;
break;
}
}
}
});
}
if(guestTrafficTypeTotal > 1) {
if(args.context.physicalNetworks[0].tags != null && args.context.physicalNetworks[0].tags.length > 0) {
array1.push("&tags=" + args.context.physicalNetworks[0].tags);
}
else {
alert(dictionary['error.please.specify.physical.network.tags']);
return;
}
}
}
//this tab (Network tab in guest network) only shows when it's under an Advanced zone
if(args.scope == "zone-wide" || args.scope == "domain-specific") {
apiCmd += "&guestiptype=Shared";
array1.push("&guestiptype=Shared");
}
var networkOfferingArray = [];
$.ajax({
url: createURL(apiCmd),
url: createURL(apiCmd + array1.join("")),
dataType: "json",
async: false,
success: function(json) {
networkOfferingObjs = json.listnetworkofferingsresponse.networkoffering;
networkOfferingObjs = json.listnetworkofferingsresponse.networkoffering;
if (networkOfferingObjs != null && networkOfferingObjs.length > 0) {
for (var i = 0; i < networkOfferingObjs.length; i++) {
//if security groups provider is disabled, exclude network offerings that has "SecurityGroupProvider" in service
if(nspMap["securityGroups"].state == "Disabled"){
//comment the following section becaues nspMap is empty unless network providers has been clicked.
/*
if(nspMap["securityGroups"].state == "Disabled"){
var includingSGP = false;
var serviceObjArray = networkOfferingObjs[i].service;
for(var k = 0; k < serviceObjArray.length; k++) {
@ -1075,6 +1111,7 @@
if(includingSGP == true)
continue; //skip to next network offering
}
*/
//if args.scope == "account-specific" or "project-specific", exclude Isolated network offerings with SourceNat service (bug 12869)
if(args.scope == "account-specific" || args.scope == "project-specific") {
@ -1090,13 +1127,13 @@
continue; //skip to next network offering
}
array1.push({id: networkOfferingObjs[i].id, description: networkOfferingObjs[i].displaytext});
networkOfferingArray.push({id: networkOfferingObjs[i].id, description: networkOfferingObjs[i].displaytext});
}
}
}
});
args.response.success({data: array1});
args.response.success({data: networkOfferingArray});
args.$select.change(function(){
@ -1603,6 +1640,7 @@
zoneid: args.context.zones[0].id
},
success: function(json) {
physicalNetworkObjs = json.listphysicalnetworksresponse.physicalnetwork;
args.response.success({
data: json.listphysicalnetworksresponse.physicalnetwork
});
@ -1857,6 +1895,20 @@
});
}
});
// Get project routers
$.ajax({
url: createURL("listRouters&zoneid=" + selectedZoneObj.id + "&listAll=true&page=" + args.page + "&pagesize=" + pageSize + array1.join("") + "&projectid=-1"),
dataType: 'json',
async: true,
success: function(json) {
var items = json.listroutersresponse.router;
args.response.success({
actionFilter: routerActionfilter,
data: items
});
}
});
},
detailView: {
name: 'Virtual applicance details',
@ -1980,7 +2032,7 @@
desc: '',
fields: {
serviceOfferingId: {
label: 'label.service.offering',
label: 'label.compute.offering',
select: function(args) {
$.ajax({
url: createURL("listServiceOfferings&issystem=true&systemvmtype=domainrouter"),
@ -2121,18 +2173,26 @@
tabs: {
details: {
title: 'label.details',
preFilter: function(args) {
if (!args.context.routers[0].project)
return ['project', 'projectid'];
return [];
},
fields: [
{
name: { label: 'label.name' }
name: { label: 'label.name' },
project: { label: 'label.project' }
},
{
id: { label: 'label.id' },
projectid: { label: 'label.project.id' },
state: { label: 'label.state' },
publicip: { label: 'label.public.ip' },
guestipaddress: { label: 'label.guest.ip' },
linklocalip: { label: 'label.linklocal.ip' },
hostname: { label: 'label.host' },
serviceofferingname: { label: 'label.service.offering' },
serviceofferingname: { label: 'label.compute.offering' },
networkdomain: { label: 'label.network.domain' },
domain: { label: 'label.domain' },
account: { label: 'label.account' },
@ -2169,16 +2229,17 @@
url: createURL("updateNetworkServiceProvider&id=" + nspMap["virtualRouter"].id + "&state=Enabled"),
dataType: "json",
success: function(json) {
var jid = json.updatenetworkserviceproviderresponse.jobid;
args.response.success(
var jid = json.updatenetworkserviceproviderresponse.jobid;
args.response.success(
{_custom:
{
jobId: jid
jobId: jid,
getUpdatedItem: function(json) {
$(window).trigger('cloudStack.fullRefresh');
}
}
}
);
$(window).trigger('cloudStack.fullRefresh');
);
}
});
},
@ -2199,16 +2260,17 @@
url: createURL("updateNetworkServiceProvider&id=" + nspMap["virtualRouter"].id + "&state=Disabled"),
dataType: "json",
success: function(json) {
var jid = json.updatenetworkserviceproviderresponse.jobid;
args.response.success(
var jid = json.updatenetworkserviceproviderresponse.jobid;
args.response.success(
{_custom:
{
jobId: jid
jobId: jid,
getUpdatedItem: function(json) {
$(window).trigger('cloudStack.fullRefresh');
}
}
}
);
$(window).trigger('cloudStack.fullRefresh');
);
}
});
},
@ -2368,12 +2430,13 @@
args.response.success(
{_custom:
{
jobId: jid
jobId: jid,
getUpdatedItem: function(json) {
$(window).trigger('cloudStack.fullRefresh');
}
}
}
);
$(window).trigger('cloudStack.fullRefresh');
);
}
});
},
@ -2398,12 +2461,13 @@
args.response.success(
{_custom:
{
jobId: jid
jobId: jid,
getUpdatedItem: function(json) {
$(window).trigger('cloudStack.fullRefresh');
}
}
}
);
$(window).trigger('cloudStack.fullRefresh');
);
}
});
},
@ -2520,12 +2584,12 @@
capacity: {
label: 'label.capacity',
validation: { required: false, number: true }
},
dedicated: {
label: 'label.dedicated',
isBoolean: true,
isChecked: false
}
// dedicated: {
// label: 'label.dedicated',
// isBoolean: true,
// isChecked: false
// }
}
},
action: function(args) {
@ -2589,13 +2653,14 @@
var jid = json.updatenetworkserviceproviderresponse.jobid;
args.response.success(
{_custom:
{
jobId: jid
}
{
jobId: jid,
getUpdatedItem: function(json) {
$(window).trigger('cloudStack.fullRefresh');
}
}
}
);
$(window).trigger('cloudStack.fullRefresh');
);
}
});
},
@ -2619,13 +2684,14 @@
var jid = json.updatenetworkserviceproviderresponse.jobid;
args.response.success(
{_custom:
{
jobId: jid
}
{
jobId: jid,
getUpdatedItem: function(json) {
$(window).trigger('cloudStack.fullRefresh');
}
}
}
);
$(window).trigger('cloudStack.fullRefresh');
);
}
});
},
@ -2828,12 +2894,13 @@
args.response.success(
{_custom:
{
jobId: jid
jobId: jid,
getUpdatedItem: function(json) {
$(window).trigger('cloudStack.fullRefresh');
}
}
}
);
$(window).trigger('cloudStack.fullRefresh');
);
}
});
},
@ -2858,12 +2925,13 @@
args.response.success(
{_custom:
{
jobId: jid
jobId: jid,
getUpdatedItem: function(json) {
$(window).trigger('cloudStack.fullRefresh');
}
}
}
);
$(window).trigger('cloudStack.fullRefresh');
);
}
});
},
@ -2957,12 +3025,13 @@
args.response.success(
{_custom:
{
jobId: jid
jobId: jid,
getUpdatedItem: function(json) {
$(window).trigger('cloudStack.fullRefresh');
}
}
}
);
$(window).trigger('cloudStack.fullRefresh');
);
}
});
},
@ -2987,12 +3056,13 @@
args.response.success(
{_custom:
{
jobId: jid
jobId: jid,
getUpdatedItem: function(json) {
$(window).trigger('cloudStack.fullRefresh');
}
}
}
);
$(window).trigger('cloudStack.fullRefresh');
);
}
});
},
@ -3325,7 +3395,7 @@
},
compute: {
title: 'label.compute',
title: 'label.compute.and.storage',
custom: cloudStack.uiCustom.systemChart('compute')
},
network: {
@ -3941,12 +4011,12 @@
capacity: {
label: 'label.capacity',
validation: { required: false, number: true }
},
dedicated: {
label: 'label.dedicated',
isBoolean: true,
isChecked: false
}
// dedicated: {
// label: 'label.dedicated',
// isBoolean: true,
// isChecked: false
// }
}
},
action: function(args) {

View File

@ -53,7 +53,6 @@
* @param args CloudStack3 configuration
*/
var showSection = function(sectionID, args) {
var $panel;
var $browser = $('#browser div.container');
var $navItem = $('#navigation').find('li').filter(function() {
return $(this).hasClass(sectionID);
@ -66,25 +65,25 @@
// Reset browser panels
$browser.cloudBrowser('removeAllPanels');
$panel = $browser.cloudBrowser('addPanel', {
$browser.cloudBrowser('addPanel', {
title: _l(data.title),
data: ''
data: '',
complete: function($panel) {
// Hide breadcrumb if this is the home section
if (args.home === sectionID) {
$('#breadcrumbs').find('li:first, div.end:last').hide();
}
// Append specified widget to view
if (data.show)
$panel.append(data.show(data));
else if (data.treeView)
$panel.treeView(data, { context: args.context });
else
$panel.listView(data, { context: args.context });
}
});
// Hide breadcrumb if this is the home section
if (args.home === sectionID) {
$('#breadcrumbs').find('li:first, div.end:last').hide();
}
// Append specified widget to view
if (data.show)
$panel.append(data.show(data));
else if (data.treeView)
$panel.treeView(data, { context: args.context });
else
$panel.listView(data, { context: args.context });
return $navItem;
};

View File

@ -357,6 +357,7 @@
* Clear all panels
*/
removeAllPanels: function(args) {
$('div.panel').stop(); // Prevent destroyed panels from animating
this.element.find('div.panel').remove();
$('#breadcrumbs').find('ul li').remove();
$('#breadcrumbs').find('ul div.end').remove();

View File

@ -8,18 +8,20 @@
var $newRow;
var jsonObj = $row.data('json-obj');
$listView.listView('replaceItem', {
$row: $row,
data: $.extend(jsonObj, newData),
after: function($newRow) {
$detailView.data('list-view-row', $newRow);
setTimeout(function() {
$('.data-table').dataTable('selectRow', $newRow.index());
}, 100);
}
});
if($listView.length > 0 ) { //$listView.length is 0 after calling $(window).trigger('cloudStack.fullRefresh')
$listView.listView('replaceItem', {
$row: $row,
data: $.extend(jsonObj, newData),
after: function($newRow) {
$detailView.data('list-view-row', $newRow);
setTimeout(function() {
$('.data-table').dataTable('selectRow', $newRow.index());
}, 100);
}
});
}
// Refresh detail view context
$.extend(
$detailView.data('view-args').context[

View File

@ -112,7 +112,7 @@
}).find('option').filter(function() {
return $(this).val() == data[fieldName];
}).html()));
} else if (field.addButton && $.isArray(itemData) && !options.noSelect) {
} else if (field.addButton && !options.noSelect) {
if (options.multipleAdd) {
$addButton.click(function() {
_medit.vmList($multi,
@ -670,7 +670,7 @@
var $range = $('<div>').addClass('range').appendTo($td);
$(field.range).each(function() {
$('<input>')
var $input = $('<input>')
.attr({
name: this,
type: 'text'
@ -680,9 +680,11 @@
.appendTo(
$('<div>').addClass('range-item').appendTo($range)
);
if (field.isDisabled) $input.hide();
});
} else {
$('<input>')
var $input = $('<input>')
.attr({
name: fieldName,
type: field.isPassword ? 'password' : 'text'
@ -690,6 +692,8 @@
.addClass(!field.isOptional ? 'required' : null)
.attr('disabled', field.isDisabled ? 'disabled' : false)
.appendTo($td);
if (field.isDisabled) $input.hide();
}
} else if (field.custom) {
$('<div>').addClass('button add-vm custom-action')

View File

@ -1423,7 +1423,10 @@
$("body").stopTime(updateNetworkServiceProviderTimer);
if (result.jobstatus == 1) {
//alert("Virtual Router Provider is enabled");
if(args.data.pluginFrom != null && args.data.pluginFrom.name == "installWizard") {
selectedNetworkOfferingHavingSG = args.data.pluginFrom.selectedNetworkOfferingHavingSG;
}
if(selectedNetworkOfferingHavingSG == true) { //need to Enable security group provider first
// get network service provider ID of Security Group
var securityGroupProviderId;

View File

@ -1028,8 +1028,8 @@ public class UsageManagerImpl implements UsageManager, Runnable {
long id = event.getResourceId();
long sourceNat = event.getSize();
boolean isSourceNat = (sourceNat == 1) ? true : false ;
boolean isElastic = (event.getTemplateId() == null || event.getTemplateId() == 0) ? false : true ;
UsageIPAddressVO ipAddressVO = new UsageIPAddressVO(id, event.getAccountId(), acct.getDomainId(), zoneId, ipAddress, isSourceNat, isElastic, event.getCreateDate(), null);
boolean isSystem = (event.getTemplateId() == null || event.getTemplateId() == 0) ? false : true ;
UsageIPAddressVO ipAddressVO = new UsageIPAddressVO(id, event.getAccountId(), acct.getDomainId(), zoneId, ipAddress, isSourceNat, isSystem, event.getCreateDate(), null);
m_usageIPAddressDao.persist(ipAddressVO);
} else if (EventTypes.EVENT_NET_IP_RELEASE.equals(event.getType())) {
SearchCriteria<UsageIPAddressVO> sc = m_usageIPAddressDao.createSearchCriteria();

View File

@ -78,7 +78,7 @@ public class IPAddressUsageParser {
String key = ""+IpId;
// store the info in the IP map
IPMap.put(key, new IpInfo(usageIp.getZoneId(), IpId, usageIp.getAddress(), usageIp.isSourceNat(), usageIp.isElastic()));
IPMap.put(key, new IpInfo(usageIp.getZoneId(), IpId, usageIp.getAddress(), usageIp.isSourceNat(), usageIp.isSystem()));
Date IpAssignDate = usageIp.getAssigned();
Date IpReleaseDeleteDate = usageIp.getReleased();
@ -104,7 +104,7 @@ public class IPAddressUsageParser {
// Only create a usage record if we have a runningTime of bigger than zero.
if (useTime > 0L) {
IpInfo info = IPMap.get(ipIdKey);
createUsageRecord(info.getZoneId(), useTime, startDate, endDate, account, info.getIpId(), info.getIPAddress(), info.isSourceNat(), info.isElastic);
createUsageRecord(info.getZoneId(), useTime, startDate, endDate, account, info.getIpId(), info.getIPAddress(), info.isSourceNat(), info.isSystem);
}
}
@ -123,7 +123,7 @@ public class IPAddressUsageParser {
usageDataMap.put(key, ipUsageInfo);
}
private static void createUsageRecord(long zoneId, long runningTime, Date startDate, Date endDate, AccountVO account, long IpId, String IPAddress, boolean isSourceNat, boolean isElastic) {
private static void createUsageRecord(long zoneId, long runningTime, Date startDate, Date endDate, AccountVO account, long IpId, String IPAddress, boolean isSourceNat, boolean isSystem) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Total usage time " + runningTime + "ms");
}
@ -142,7 +142,7 @@ public class IPAddressUsageParser {
// Create the usage record
UsageVO usageRecord = new UsageVO(zoneId, account.getAccountId(), account.getDomainId(), usageDesc, usageDisplay + " Hrs", UsageTypes.IP_ADDRESS, new Double(usage), IpId,
(isElastic?1:0), (isSourceNat?"SourceNat":""), startDate, endDate);
(isSystem?1:0), (isSourceNat?"SourceNat":""), startDate, endDate);
m_usageDao.persist(usageRecord);
}
@ -151,14 +151,14 @@ public class IPAddressUsageParser {
private long IpId;
private String IPAddress;
private boolean isSourceNat;
private boolean isElastic;
private boolean isSystem;
public IpInfo(long zoneId,long IpId, String IPAddress, boolean isSourceNat, boolean isElastic) {
public IpInfo(long zoneId,long IpId, String IPAddress, boolean isSourceNat, boolean isSystem) {
this.zoneId = zoneId;
this.IpId = IpId;
this.IPAddress = IPAddress;
this.isSourceNat = isSourceNat;
this.isElastic = isElastic;
this.isSystem = isSystem;
}
public long getZoneId() {
@ -176,10 +176,5 @@ public class IPAddressUsageParser {
public boolean isSourceNat() {
return isSourceNat;
}
public boolean isElastic() {
return isElastic;
}
}
}