diff --git a/api/src/com/cloud/agent/api/to/LoadBalancerTO.java b/api/src/com/cloud/agent/api/to/LoadBalancerTO.java index 24ea702b4bb..2e19af05569 100644 --- a/api/src/com/cloud/agent/api/to/LoadBalancerTO.java +++ b/api/src/com/cloud/agent/api/to/LoadBalancerTO.java @@ -282,8 +282,7 @@ public class LoadBalancerTO { private final String serviceOfferingId; private final String templateId; private final String otherDeployParams; - private final String snmpCommunity; - private final Integer snmpPort; + private final List> counterParamList; private final Integer destroyVmGraceperiod; private final String cloudStackApiUrl; private final String autoScaleUserApiKey; @@ -292,14 +291,13 @@ public class LoadBalancerTO { private final String networkId; public AutoScaleVmProfileTO(String zoneId, String domainId, String cloudStackApiUrl, String autoScaleUserApiKey, String autoScaleUserSecretKey, String serviceOfferingId, - String templateId, String vmName, String networkId, String otherDeployParams, String snmpCommunity, Integer snmpPort, Integer destroyVmGraceperiod) { + String templateId, String vmName, String networkId, String otherDeployParams, List> counterParamList, Integer destroyVmGraceperiod) { this.zoneId = zoneId; this.domainId = domainId; this.serviceOfferingId = serviceOfferingId; this.templateId = templateId; this.otherDeployParams = otherDeployParams; - this.snmpCommunity = snmpCommunity; - this.snmpPort = snmpPort; + this.counterParamList = counterParamList; this.destroyVmGraceperiod = destroyVmGraceperiod; this.cloudStackApiUrl = cloudStackApiUrl; this.autoScaleUserApiKey = autoScaleUserApiKey; @@ -328,12 +326,8 @@ public class LoadBalancerTO { return otherDeployParams; } - public String getSnmpCommunity() { - return snmpCommunity; - } - - public Integer getSnmpPort() { - return snmpPort; + public List> getCounterParamList() { + return counterParamList; } public Integer getDestroyVmGraceperiod() { @@ -447,8 +441,8 @@ public class LoadBalancerTO { AutoScaleVmProfileTO autoScaleVmProfileTO = new AutoScaleVmProfileTO(lbAutoScaleVmProfile.getZoneId(), lbAutoScaleVmProfile.getDomainId(), lbAutoScaleVmProfile.getCsUrl(), lbAutoScaleVmProfile.getAutoScaleUserApiKey(), lbAutoScaleVmProfile.getAutoScaleUserSecretKey(), lbAutoScaleVmProfile.getServiceOfferingId(), lbAutoScaleVmProfile.getTemplateId(), lbAutoScaleVmProfile.getVmName(), - lbAutoScaleVmProfile.getNetworkId(),autoScaleVmProfile.getOtherDeployParams(), autoScaleVmProfile.getSnmpCommunity(), - autoScaleVmProfile.getSnmpPort(), autoScaleVmProfile.getDestroyVmGraceperiod()); + lbAutoScaleVmProfile.getNetworkId(),autoScaleVmProfile.getOtherDeployParams(), autoScaleVmProfile.getCounterParams(), + autoScaleVmProfile.getDestroyVmGraceperiod()); AutoScaleVmGroup autoScaleVmGroup = lbAutoScaleVmGroup.getVmGroup(); autoScaleVmGroupTO = new AutoScaleVmGroupTO(autoScaleVmGroup.getUuid(), autoScaleVmGroup.getMinMembers(), autoScaleVmGroup.getMaxMembers(), autoScaleVmGroup.getMemberPort(), diff --git a/api/src/com/cloud/api/ApiConstants.java b/api/src/com/cloud/api/ApiConstants.java index c69d816dc9c..78a3deda578 100755 --- a/api/src/com/cloud/api/ApiConstants.java +++ b/api/src/com/cloud/api/ApiConstants.java @@ -243,13 +243,13 @@ public class ApiConstants { public static final String PRIVATE_NETWORK_ID = "privatenetworkid"; public static final String ALLOCATION_STATE = "allocationstate"; public static final String MANAGED_STATE = "managedstate"; - public static final String STORAGE_ID="storageid"; + public static final String STORAGE_ID = "storageid"; public static final String PING_STORAGE_SERVER_IP = "pingstorageserverip"; public static final String PING_DIR = "pingdir"; public static final String TFTP_DIR = "tftpdir"; public static final String PING_CIFS_USERNAME = "pingcifsusername"; public static final String PING_CIFS_PASSWORD = "pingcifspassword"; - public static final String CHECKSUM="checksum"; + public static final String CHECKSUM = "checksum"; public static final String NETWORK_DEVICE_TYPE = "networkdevicetype"; public static final String NETWORK_DEVICE_PARAMETER_LIST = "networkdeviceparameterlist"; public static final String ZONE_TOKEN = "zonetoken"; @@ -265,8 +265,8 @@ public class ApiConstants { public static final String IP_NETWORK_LIST = "iptonetworklist"; public static final String PARAM_LIST = "param"; public static final String FOR_LOAD_BALANCING = "forloadbalancing"; - public static final String KEYBOARD="keyboard"; - public static final String OPEN_FIREWALL="openfirewall"; + public static final String KEYBOARD = "keyboard"; + public static final String OPEN_FIREWALL = "openfirewall"; public static final String TEMPLATE_TAG = "templatetag"; public static final String HYPERVISOR_VERSION = "hypervisorversion"; public static final String MAX_GUESTS_LIMIT = "maxguestslimit"; @@ -303,8 +303,8 @@ public class ApiConstants { public static final String SERVICE_LIST = "servicelist"; public static final String CAN_ENABLE_INDIVIDUAL_SERVICE = "canenableindividualservice"; public static final String SUPPORTED_SERVICES = "supportedservices"; - public static final String NSP_ID= "nspid"; - public static final String ACL_TYPE= "acltype"; + public static final String NSP_ID = "nspid"; + public static final String ACL_TYPE = "acltype"; public static final String SUBDOMAIN_ACCESS = "subdomainaccess"; public static final String LOAD_BALANCER_DEVICE_ID = "lbdeviceid"; public static final String LOAD_BALANCER_DEVICE_NAME = "lbdevicename"; @@ -391,8 +391,6 @@ public class ApiConstants { public static final String AGGR_VALUE = "aggrvalue"; public static final String THRESHOLD = "threshold"; public static final String RELATIONAL_OPERATOR = "relationaloperator"; - public static final String SNMP_COMMUNITY = "snmpcommunity"; - public static final String SNMP_PORT = "snmpport"; public static final String OTHER_DEPLOY_PARAMS = "otherdeployparams"; public static final String MIN_MEMBERS = "minmembers"; public static final String MAX_MEMBERS = "maxmembers"; @@ -409,6 +407,7 @@ public class ApiConstants { public static final String ACTION = "action"; public static final String CONDITION_ID = "conditionid"; public static final String CONDITION_IDS = "conditionids"; + public static final String COUNTERPARAM_LIST = "counterparam"; public static final String AUTOSCALE_USER_ID = "autoscaleuserid"; public enum HostDetails { @@ -418,12 +417,12 @@ public class ApiConstants { public enum VMDetails { all, group, nics, stats, secgrp, tmpl, servoff, iso, volume, min; } - + public enum LDAPParams { hostname, port, usessl, queryfilter, searchbase, dn, passwd, truststore, truststorepass; @Override - public String toString(){ + public String toString() { return "ldap." + name(); } } diff --git a/api/src/com/cloud/api/commands/CreateAutoScaleVmProfileCmd.java b/api/src/com/cloud/api/commands/CreateAutoScaleVmProfileCmd.java index f5b21a8f868..68c85d09199 100644 --- a/api/src/com/cloud/api/commands/CreateAutoScaleVmProfileCmd.java +++ b/api/src/com/cloud/api/commands/CreateAutoScaleVmProfileCmd.java @@ -39,6 +39,7 @@ import com.cloud.user.User; import com.cloud.user.UserContext; @Implementation(description = "Creates a profile that contains information about the virtual machine which will be provisioned automatically by autoscale feature.", responseObject = AutoScaleVmProfileResponse.class) +@SuppressWarnings("rawtypes") public class CreateAutoScaleVmProfileCmd extends BaseAsyncCreateCmd { public static final Logger s_logger = Logger.getLogger(CreateAutoScaleVmProfileCmd.class.getName()); @@ -66,11 +67,8 @@ public class CreateAutoScaleVmProfileCmd extends BaseAsyncCreateCmd { @Parameter(name = ApiConstants.AUTOSCALE_VM_DESTROY_TIME, type = CommandType.INTEGER, description = "the time allowed for existing connections to get closed before a vm is destroyed") private Integer destroyVmGraceperiod; - @Parameter(name = ApiConstants.SNMP_COMMUNITY, type = CommandType.STRING, description = "snmp community string to be used to contact a virtual machine deployed by this profile") - private String snmpCommunity; - - @Parameter(name = ApiConstants.SNMP_PORT, type = CommandType.INTEGER, description = "port at which snmp agent is listening in a virtual machine deployed by this profile") - private Integer snmpPort; + @Parameter(name = ApiConstants.COUNTERPARAM_LIST, type = CommandType.MAP, description = "counterparam list. Example: counterparam[0].name=snmpcommunity&counterparam[0].value=public&counterparam[1].name=snmpport&counterparam[1].value=161") + private Map counterParamList; @IdentityMapper(entityTableName = "user") @Parameter(name = ApiConstants.AUTOSCALE_USER_ID, type = CommandType.LONG, description = "the ID of the user used to launch and destroy the VMs") @@ -109,12 +107,8 @@ public class CreateAutoScaleVmProfileCmd extends BaseAsyncCreateCmd { return templateId; } - public Integer getSnmpPort() { - return snmpPort; - } - - public String getSnmpCommunity() { - return snmpCommunity; + public Map getCounterParamList() { + return counterParamList; } public String getOtherDeployParams() { diff --git a/api/src/com/cloud/api/commands/UpdateAutoScaleVmProfileCmd.java b/api/src/com/cloud/api/commands/UpdateAutoScaleVmProfileCmd.java index c613a34cc35..c94dad4dd3e 100644 --- a/api/src/com/cloud/api/commands/UpdateAutoScaleVmProfileCmd.java +++ b/api/src/com/cloud/api/commands/UpdateAutoScaleVmProfileCmd.java @@ -17,6 +17,8 @@ package com.cloud.api.commands; +import java.util.Map; + import org.apache.log4j.Logger; import com.cloud.api.ApiConstants; @@ -54,11 +56,8 @@ public class UpdateAutoScaleVmProfileCmd extends BaseAsyncCmd { @Parameter(name = ApiConstants.AUTOSCALE_VM_DESTROY_TIME, type = CommandType.INTEGER, description = "the time allowed for existing connections to get closed before a vm is destroyed") private Integer destroyVmGraceperiod; - @Parameter(name = ApiConstants.SNMP_COMMUNITY, type = CommandType.STRING, description = "snmp community string to be used to contact a virtual machine deployed by this profile") - private String snmpCommunity; - - @Parameter(name = ApiConstants.SNMP_PORT, type = CommandType.INTEGER, description = "port at which snmp agent is listening in a virtual machine deployed by this profile") - private Integer snmpPort; + @Parameter(name = ApiConstants.COUNTERPARAM_LIST, type = CommandType.MAP, description = "counterparam list. Example: counterparam[0].name=snmpcommunity&counterparam[0].value=public&counterparam[1].name=snmpport&counterparam[1].value=161") + private Map counterParamList; @IdentityMapper(entityTableName = "user") @Parameter(name = ApiConstants.AUTOSCALE_USER_ID, type = CommandType.LONG, description = "the ID of the user used to launch and destroy the VMs") @@ -93,12 +92,8 @@ public class UpdateAutoScaleVmProfileCmd extends BaseAsyncCmd { return templateId; } - public Integer getSnmpPort() { - return snmpPort; - } - - public String getSnmpCommunity() { - return snmpCommunity; + public Map getCounterParamList() { + return counterParamList; } public Long getAutoscaleUserId() { diff --git a/api/src/com/cloud/api/response/AutoScaleVmProfileResponse.java b/api/src/com/cloud/api/response/AutoScaleVmProfileResponse.java index 842fa3ad2ee..08d95261715 100644 --- a/api/src/com/cloud/api/response/AutoScaleVmProfileResponse.java +++ b/api/src/com/cloud/api/response/AutoScaleVmProfileResponse.java @@ -16,11 +16,16 @@ // under the License. package com.cloud.api.response; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + import com.cloud.api.ApiConstants; -import com.cloud.api.Parameter; import com.cloud.api.BaseCmd.CommandType; +import com.cloud.api.Parameter; import com.cloud.serializer.Param; import com.cloud.utils.IdentityProxy; +import com.cloud.utils.Pair; import com.google.gson.annotations.SerializedName; public class AutoScaleVmProfileResponse extends BaseResponse implements ControlledEntityResponse { @@ -52,13 +57,9 @@ public class AutoScaleVmProfileResponse extends BaseResponse implements Controll private Integer destroyVmGraceperiod; /* Parameters related to a running virtual machine - monitoring aspects */ - @SerializedName(ApiConstants.SNMP_COMMUNITY) - @Param(description = "snmp community string to be used to contact a virtual machine deployed by this profile") - private String snmpCommunity; - - @SerializedName(ApiConstants.SNMP_PORT) - @Param(description = "port at which the snmp agent is listening in a virtual machine deployed by this profile") - private Integer snmpPort; + @SerializedName(ApiConstants.COUNTERPARAM_LIST) + @Parameter(name = ApiConstants.COUNTERPARAM_LIST, type = CommandType.MAP, description = "counterparam list. Example: counterparam[0].name=snmpcommunity&counterparam[0].value=public&counterparam[1].name=snmpport&counterparam[1].value=161") + private Map counterParams; @SerializedName(ApiConstants.AUTOSCALE_USER_ID) @Param(description = "the ID of the user used to launch and destroy the VMs") @@ -111,12 +112,13 @@ public class AutoScaleVmProfileResponse extends BaseResponse implements Controll this.otherDeployParams = otherDeployParams; } - public void setSnmpCommunity(String snmpCommunity) { - this.snmpCommunity = snmpCommunity; - } - - public void setSnmpPort(Integer snmpPort) { - this.snmpPort = snmpPort; + public void setCounterParams(List> counterParams) { + this.counterParams = new HashMap(); + for (Pair paramKV : counterParams) { + String key = paramKV.first(); + String value = paramKV.second(); + this.counterParams.put(key, value); + } } @Override diff --git a/api/src/com/cloud/network/as/AutoScaleCounter.java b/api/src/com/cloud/network/as/AutoScaleCounter.java new file mode 100644 index 00000000000..ca7b65a39d4 --- /dev/null +++ b/api/src/com/cloud/network/as/AutoScaleCounter.java @@ -0,0 +1,122 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package com.cloud.network.as; + +import java.util.ArrayList; +import java.util.List; + +import com.google.gson.annotations.SerializedName; + +public class AutoScaleCounter { + public static class AutoScaleCounterType { + private String _name; + + public static final AutoScaleCounterType Snmp = new AutoScaleCounterType("snmp"); + public static final AutoScaleCounterType Netscaler = new AutoScaleCounterType("netscaler"); + + public AutoScaleCounterType(String name) { + _name = name; + } + + public String getName() { + return _name; + } + } + + public class AutoScaleCounterParam { + @SerializedName("paramname") + private String _paramName; + + @SerializedName("required") + private Boolean _required; + + @SerializedName("isflag") + private Boolean _isFlag; + + @SerializedName("description") + private String _description; + + public AutoScaleCounterParam(String name, Boolean required, + String description, Boolean flag) { + this._paramName = name; + this._required = required; + this._description = description; + this._isFlag = flag; + } + + public String getParamName() { + return _paramName; + } + + public void setParamName(String paramName) { + this._paramName = paramName; + } + + public Boolean getIsflag() { + return _isFlag; + } + + public void setIsflag(Boolean isFlag) { + this._isFlag = isFlag; + } + + public Boolean getRequired() { + return _required; + } + + public void setRequired(Boolean required) { + this._required = required; + } + + public String getDescription() { + return _description; + } + + public void setDescription(String description) { + this._description = description; + } + } + + @SerializedName("methodname") + private String _counterName; + + @SerializedName("paramlist") + private List _paramList; + + public AutoScaleCounter(AutoScaleCounterType methodType) { + this._counterName = methodType.getName(); + this._paramList = new ArrayList(1); + } + + public void addParam(String name, Boolean required, String description, Boolean isFlag) { + AutoScaleCounterParam param = new AutoScaleCounterParam(name, required, description, isFlag); + _paramList.add(param); + return; + } + + public String getName() { + return _counterName; + } + + public List getParamList() { + return _paramList; + } + + public void setParamList(List paramList) { + this._paramList = paramList; + } +} diff --git a/api/src/com/cloud/network/as/AutoScaleVmProfile.java b/api/src/com/cloud/network/as/AutoScaleVmProfile.java index 7fc61916485..77f5ce45f98 100644 --- a/api/src/com/cloud/network/as/AutoScaleVmProfile.java +++ b/api/src/com/cloud/network/as/AutoScaleVmProfile.java @@ -17,7 +17,10 @@ package com.cloud.network.as; +import java.util.List; + import com.cloud.acl.ControlledEntity; +import com.cloud.utils.Pair; /** * AutoScaleVmProfile @@ -34,11 +37,10 @@ public interface AutoScaleVmProfile extends ControlledEntity { public String getOtherDeployParams(); - public String getSnmpCommunity(); - - public Integer getSnmpPort(); + List> getCounterParams(); public Integer getDestroyVmGraceperiod(); public long getAutoScaleUserId(); + } diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerElement.java b/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerElement.java index 4ac0d806021..1d8bcad5f35 100644 --- a/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerElement.java +++ b/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerElement.java @@ -79,6 +79,8 @@ import com.cloud.network.Networks.TrafficType; import com.cloud.network.PhysicalNetworkServiceProvider; import com.cloud.network.PhysicalNetworkVO; import com.cloud.network.PublicIpAddress; +import com.cloud.network.as.AutoScaleCounter; +import com.cloud.network.as.AutoScaleCounter.AutoScaleCounterType; import com.cloud.network.dao.ExternalLoadBalancerDeviceDao; import com.cloud.network.dao.NetScalerPodDao; import com.cloud.network.dao.NetworkDao; @@ -94,7 +96,6 @@ import com.cloud.network.rules.LbStickinessMethod; import com.cloud.network.rules.LbStickinessMethod.StickinessMethodType; import com.cloud.network.rules.StaticNat; import com.cloud.offering.NetworkOffering; -import com.cloud.resource.ServerResource; import com.cloud.utils.NumbersUtil; import com.cloud.utils.component.Inject; import com.cloud.utils.db.DB; @@ -112,6 +113,8 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl StaticNatServiceProvider { private static final Logger s_logger = Logger.getLogger(NetscalerElement.class); + public static final AutoScaleCounterType AutoScaleCounterSnmp = new AutoScaleCounterType("snmp"); + public static final AutoScaleCounterType AutoScaleCounterNetscaler = new AutoScaleCounterType("netscaler"); @Inject NetworkManager _networkManager; @@ -253,8 +256,20 @@ StaticNatServiceProvider { // Specifies that load balancing rules can only be made with public IPs that aren't source NAT IPs lbCapabilities.put(Capability.LoadBalancingSupportedIps, "additional"); - // Specifies that load balancing rules can support autoscaling - lbCapabilities.put(Capability.AutoScaleCounters, "snmp,netscaler"); + // Specifies that load balancing rules can support autoscaling and the list of counters it supports + AutoScaleCounter counter; + List counterList = new ArrayList(); + counter = new AutoScaleCounter(AutoScaleCounterSnmp); + counterList.add(counter); + counter.addParam("snmpcommunity", true, "the community string that has to be used to do a SNMP GET on the AutoScaled Vm", false); + counter.addParam("snmpport", false, "the port at which SNMP agent is running on the AutoScaled Vm", false); + + counter = new AutoScaleCounter(AutoScaleCounterNetscaler); + counterList.add(counter); + + Gson gson = new Gson(); + String autoScaleCounterList = gson.toJson(counterList); + lbCapabilities.put(Capability.AutoScaleCounters, autoScaleCounterList); LbStickinessMethod method; List methodList = new ArrayList(); @@ -270,7 +285,6 @@ StaticNatServiceProvider { methodList.add(method); method.addParam("holdtime", false, "time period for which persistence is in effect.", false); - Gson gson = new Gson(); String stickyMethodList = gson.toJson(methodList); lbCapabilities.put(Capability.SupportedStickinessMethods, stickyMethodList); @@ -371,7 +385,7 @@ StaticNatServiceProvider { HostPodVO pod = _podDao.findById(podId); if (pod == null) { throw new InvalidParameterValueException("Can't find pod by id " + podId); - } + } } for (Long podId: newPodsConfig) { @@ -676,7 +690,7 @@ StaticNatServiceProvider { if ((destinations != null && !destinations.isEmpty()) || rule.isAutoScaleConfig()) { LoadBalancerTO loadBalancer = new LoadBalancerTO(lbUuid, srcIp, srcPort, protocol, algorithm, revoked, false, destinations, rule.getStickinessPolicies()); - if(rule.isAutoScaleConfig()) { + if (rule.isAutoScaleConfig()) { loadBalancer.setAutoScaleVmGroup(rule.getAutoScaleVmGroup()); } loadBalancersToApply.add(loadBalancer); @@ -712,41 +726,41 @@ StaticNatServiceProvider { try { if (!multiNetScalerDeployment) { - String errMsg; - ExternalLoadBalancerDeviceVO lbDevice = getExternalLoadBalancerForNetwork(config); - if (lbDevice == null) { - try { - lbDevice = allocateLoadBalancerForNetwork(config); - } catch (Exception e) { - errMsg = "Could not allocate a NetSclaer load balancer for configuring static NAT rules due to" + e.getMessage(); - s_logger.error(errMsg); - throw new ResourceUnavailableException(errMsg, this.getClass(), 0); - } - } - - if (!isNetscalerDevice(lbDevice.getDeviceName())) { - errMsg = "There are no NetScaler load balancer assigned for this network. So NetScaler element will not be handling the static nat rules."; - s_logger.error(errMsg); - throw new ResourceUnavailableException(errMsg, this.getClass(), 0); - } - SetStaticNatRulesAnswer answer = null; - List rulesTO = null; - if (rules != null) { - rulesTO = new ArrayList(); - for (StaticNat rule : rules) { - IpAddress sourceIp = _networkMgr.getIp(rule.getSourceIpAddressId()); - StaticNatRuleTO ruleTO = new StaticNatRuleTO(0, sourceIp.getAddress().addr(), null, null, rule.getDestIpAddress(), null, null, null, rule.isForRevoke(), false); - rulesTO.add(ruleTO); + String errMsg; + ExternalLoadBalancerDeviceVO lbDevice = getExternalLoadBalancerForNetwork(config); + if (lbDevice == null) { + try { + lbDevice = allocateLoadBalancerForNetwork(config); + } catch (Exception e) { + errMsg = "Could not allocate a NetSclaer load balancer for configuring static NAT rules due to" + e.getMessage(); + s_logger.error(errMsg); + throw new ResourceUnavailableException(errMsg, this.getClass(), 0); + } } - } - SetStaticNatRulesCommand cmd = new SetStaticNatRulesCommand(rulesTO, null); - answer = (SetStaticNatRulesAnswer) _agentMgr.send(lbDevice.getHostId(), cmd); - if (answer == null) { - return false; - } else { - return answer.getResult(); - } + if (!isNetscalerDevice(lbDevice.getDeviceName())) { + errMsg = "There are no NetScaler load balancer assigned for this network. So NetScaler element will not be handling the static nat rules."; + s_logger.error(errMsg); + throw new ResourceUnavailableException(errMsg, this.getClass(), 0); + } + SetStaticNatRulesAnswer answer = null; + List rulesTO = null; + if (rules != null) { + rulesTO = new ArrayList(); + for (StaticNat rule : rules) { + IpAddress sourceIp = _networkMgr.getIp(rule.getSourceIpAddressId()); + StaticNatRuleTO ruleTO = new StaticNatRuleTO(0, sourceIp.getAddress().addr(), null, null, rule.getDestIpAddress(), null, null, null, rule.isForRevoke(), false); + rulesTO.add(ruleTO); + } + } + + SetStaticNatRulesCommand cmd = new SetStaticNatRulesCommand(rulesTO); + answer = (SetStaticNatRulesAnswer) _agentMgr.send(lbDevice.getHostId(), cmd); + if (answer == null) { + return false; + } else { + return answer.getResult(); + } } else { if (rules != null) { for (StaticNat rule : rules) { diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/resource/NetscalerResource.java b/plugins/network-elements/netscaler/src/com/cloud/network/resource/NetscalerResource.java index cc18fe99e9e..d11d16a5c9f 100644 --- a/plugins/network-elements/netscaler/src/com/cloud/network/resource/NetscalerResource.java +++ b/plugins/network-elements/netscaler/src/com/cloud/network/resource/NetscalerResource.java @@ -108,6 +108,7 @@ class NitroError { public class NetscalerResource implements ServerResource { + public final static int DEFAULT_SNMP_PORT = 161; // deployment configuration private String _name; private String _zoneId; @@ -1620,10 +1621,21 @@ public class NetscalerResource implements ServerResource { AutoScaleVmProfileTO profileTO = vmGroupTO.getProfile(); List policies = vmGroupTO.getPolicies(); int interval = vmGroupTO.getInterval(); - int snmpPort = profileTO.getSnmpPort(); - String snmpCommunity = profileTO.getSnmpCommunity(); + List> counterParams = profileTO.getCounterParamList(); + String snmpCommunity = null; + int snmpPort = DEFAULT_SNMP_PORT; long cur_prirotiy = 1; + // get the session persistence parameters + List> paramsList = profileTO.getCounterParamList(); + for(Pair param : paramsList) { + if ("snmpcommunity".equalsIgnoreCase(param.first())) { + snmpCommunity = param.second(); + } else if ("snmpport".equalsIgnoreCase(param.first())) { + snmpPort = Integer.parseInt(param.second()); + } + } + try { // Set min and max autoscale members; @@ -1650,7 +1662,7 @@ public class NetscalerResource implements ServerResource { String secretKey = profileTO.getAutoScaleUserSecretKey(); String url = profileTO.getCloudStackApiUrl(); - com.citrix.netscaler.nitro.resource.config.autoscale.autoscaleprofile autoscaleProfile = new com.citrix.netscaler.nitro.resource.config.autoscale.autoscaleprofile(); + autoscaleprofile autoscaleProfile = new autoscaleprofile(); try { autoscaleProfile.set_name(profileName); autoscaleProfile.set_type("CLOUDSTACK"); @@ -1991,7 +2003,7 @@ public class NetscalerResource implements ServerResource { } // Delete AutoScale Profile - com.citrix.netscaler.nitro.resource.config.autoscale.autoscaleprofile autoscaleProfile = new com.citrix.netscaler.nitro.resource.config.autoscale.autoscaleprofile(); + autoscaleprofile autoscaleProfile = new autoscaleprofile(); try { autoscaleProfile.set_name(profileName); autoscaleProfile.delete(_netscalerService, autoscaleProfile); diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index 67947b35631..9c55a3f90ab 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -3859,8 +3859,7 @@ public class ApiResponseHelper implements ResponseGenerator { response.setServiceOfferingId(profile.getServiceOfferingId()); response.setTemplateId(profile.getTemplateId()); response.setOtherDeployParams(profile.getOtherDeployParams()); - response.setSnmpCommunity(profile.getSnmpCommunity()); - response.setSnmpPort(profile.getSnmpPort()); + response.setCounterParams(profile.getCounterParams()); response.setDestroyVmGraceperiod(profile.getDestroyVmGraceperiod()); response.setAutoscaleUserId(profile.getAutoScaleUserId()); response.setObjectName("autoscalevmprofile"); diff --git a/server/src/com/cloud/network/as/AutoScaleManagerImpl.java b/server/src/com/cloud/network/as/AutoScaleManagerImpl.java index b536b0baca3..c59ff5b7b19 100644 --- a/server/src/com/cloud/network/as/AutoScaleManagerImpl.java +++ b/server/src/com/cloud/network/as/AutoScaleManagerImpl.java @@ -18,7 +18,6 @@ package com.cloud.network.as; import java.security.InvalidParameterException; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -59,6 +58,7 @@ import com.cloud.exception.ResourceInUseException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.LoadBalancerVO; import com.cloud.network.Network.Capability; +import com.cloud.network.as.AutoScaleCounter.AutoScaleCounterParam; import com.cloud.network.as.dao.AutoScalePolicyConditionMapDao; import com.cloud.network.as.dao.AutoScalePolicyDao; import com.cloud.network.as.dao.AutoScaleVmGroupDao; @@ -82,6 +82,7 @@ import com.cloud.user.UserContext; import com.cloud.user.dao.AccountDao; import com.cloud.user.dao.UserDao; import com.cloud.utils.IdentityProxy; +import com.cloud.utils.Pair; import com.cloud.utils.Ternary; import com.cloud.utils.component.Inject; import com.cloud.utils.component.Manager; @@ -94,6 +95,8 @@ import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.Transaction; import com.cloud.utils.net.NetUtils; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; @Local(value = { AutoScaleService.class, AutoScaleManager.class }) public class AutoScaleManagerImpl implements AutoScaleManager, AutoScaleService, Manager { @@ -160,25 +163,52 @@ public class AutoScaleManagerImpl implements AutoScaleManager, AutoScaleSe return _name; } - public List getSupportedAutoScaleCounters(long networkid) + public List getSupportedAutoScaleCounters(long networkid) { - String autoScaleCapability = _lbRulesMgr.getLBCapability(networkid, Capability.AutoScaleCounters.getName()); - if (autoScaleCapability == null || autoScaleCapability.length() == 0) { + String capability = _lbRulesMgr.getLBCapability(networkid, Capability.AutoScaleCounters.getName()); + if (capability == null) { return null; } - return Arrays.asList(autoScaleCapability.split(",")); + Gson gson = new Gson(); + java.lang.reflect.Type listType = new TypeToken>() { + }.getType(); + List result = gson.fromJson(capability, listType); + return result; } - public void validateAutoScaleCounters(long networkid, List counters) - { - List supportedCounters = getSupportedAutoScaleCounters(networkid); + public void validateAutoScaleCounters(long networkid, List counters, List> counterParamPassed) { + List supportedCounters = getSupportedAutoScaleCounters(networkid); if (supportedCounters == null) { throw new InvalidParameterException("AutoScale is not supported in the network"); } for (Counter counter : counters) { - if (!supportedCounters.contains(counter.getSource().name().toString())) { - throw new InvalidParameterException("AutoScale counter with source='" + counter.getSource() + "' is not supported " + - "in the network where lb is configured"); + String counterName = counter.getSource().name().toString(); + boolean isCounterSupported = false; + for (AutoScaleCounter autoScaleCounter : supportedCounters) { + if (autoScaleCounter.getName().equals(counterName)) { + isCounterSupported = true; + List counterParams = autoScaleCounter.getParamList(); + for (AutoScaleCounterParam autoScaleCounterParam : counterParams) { + boolean isRequiredParameter = autoScaleCounterParam.getRequired(); + if (isRequiredParameter) { + boolean isRequiredParamPresent = false; + for (Pair pair : counterParamPassed) { + if (pair.first().equals(autoScaleCounterParam.getParamName())) + isRequiredParamPresent = true; + + } + if (!isRequiredParamPresent) { + throw new InvalidParameterException("Parameter " + autoScaleCounterParam.getParamName() + " has to be set in AutoScaleVmProfile's " + + ApiConstants.COUNTERPARAM_LIST); + } + } + } + break; + } + } + if (!isCounterSupported) { + throw new InvalidParameterException("AutoScale counter with source='" + counter.getSource().name() + "' is not supported " + + "in the network"); } } } @@ -249,6 +279,7 @@ public class AutoScaleManagerImpl implements AutoScaleManager, AutoScaleSe return policies; } + @DB protected AutoScaleVmProfileVO checkValidityAndPersist(AutoScaleVmProfileVO vmProfile) { long templateId = vmProfile.getTemplateId(); long autoscaleUserId = vmProfile.getAutoScaleUserId(); @@ -315,7 +346,7 @@ public class AutoScaleManagerImpl implements AutoScaleManager, AutoScaleSe // validations HashMap deployParams = cmd.getDeployParamMap(); - if(deployParams.containsKey("networks") && deployParams.get("networks").length() > 0) { + if (deployParams.containsKey("networks") && deployParams.get("networks").length() > 0) { throw new InvalidParameterValueException("'networks' is not a valid parameter, network for an AutoScaled VM is chosen automatically. An autoscaled VM is deployed in the loadbalancer's network"); } /* @@ -330,7 +361,7 @@ public class AutoScaleManagerImpl implements AutoScaleManager, AutoScaleSe } AutoScaleVmProfileVO profileVO = new AutoScaleVmProfileVO(cmd.getZoneId(), cmd.getDomainId(), cmd.getAccountId(), cmd.getServiceOfferingId(), cmd.getTemplateId(), cmd.getOtherDeployParams(), - cmd.getSnmpCommunity(), cmd.getSnmpPort(), cmd.getDestroyVmGraceperiod(), autoscaleUserId); + cmd.getCounterParamList(), cmd.getDestroyVmGraceperiod(), autoscaleUserId); profileVO = checkValidityAndPersist(profileVO); s_logger.info("Successfully create AutoScale Vm Profile with Id: " + profileVO.getId()); @@ -343,8 +374,8 @@ public class AutoScaleManagerImpl implements AutoScaleManager, AutoScaleSe Long profileId = cmd.getId(); Long templateId = cmd.getTemplateId(); Long autoscaleUserId = cmd.getAutoscaleUserId(); - Integer snmpPort = cmd.getSnmpPort(); - String snmpCommunity = cmd.getSnmpCommunity(); + Map counterParamList = cmd.getCounterParamList(); + Integer destroyVmGraceperiod = cmd.getDestroyVmGraceperiod(); AutoScaleVmProfileVO vmProfile = getEntityInDatabase(UserContext.current().getCaller(), "Auto Scale Vm Profile", profileId, _autoScaleVmProfileDao); @@ -357,12 +388,8 @@ public class AutoScaleManagerImpl implements AutoScaleManager, AutoScaleSe vmProfile.setAutoscaleUserId(autoscaleUserId); } - if (snmpCommunity != null) { - vmProfile.setSnmpCommunity(snmpCommunity); - } - - if (snmpPort != null) { - vmProfile.setSnmpPort(snmpPort); + if (counterParamList != null) { + vmProfile.setCounterParamsForUpdate(counterParamList); } if (destroyVmGraceperiod != null) { @@ -569,7 +596,7 @@ public class AutoScaleManagerImpl implements AutoScaleManager, AutoScaleSe Account caller = UserContext.current().getCaller(); Ternary domainIdRecursiveListProject = new Ternary(domainId, isRecursive, null); + ListProjectResourcesCriteria>(domainId, isRecursive, null); _accountMgr.buildACLSearchParameters(caller, id, accountName, null, permittedAccounts, domainIdRecursiveListProject, listAll, false); domainId = domainIdRecursiveListProject.first(); @@ -720,7 +747,7 @@ public class AutoScaleManagerImpl implements AutoScaleManager, AutoScaleSe return vmGroup.getLoadBalancerId() != null; } - private boolean configureAutoScaleVmGroup(long vmGroupid, String currentState) throws ResourceUnavailableException{ + private boolean configureAutoScaleVmGroup(long vmGroupid, String currentState) throws ResourceUnavailableException { AutoScaleVmGroup vmGroup = _autoScaleVmGroupDao.findById(vmGroupid); if (isLoadBalancerBasedAutoScaleVmGroup(vmGroup)) { @@ -757,8 +784,7 @@ public class AutoScaleManagerImpl implements AutoScaleManager, AutoScaleSe } catch (ResourceUnavailableException e) { autoScaleVmGroupVO.setState(bakupState); _autoScaleVmGroupDao.persist(autoScaleVmGroupVO); - } - finally { + } finally { if (!success) { s_logger.warn("Could not delete AutoScale Vm Group id : " + id); return false; @@ -873,11 +899,10 @@ public class AutoScaleManagerImpl implements AutoScaleManager, AutoScaleSe getAutoScalePolicies("scaledownpolicyid", currentScaleDownPolicyIds, counters, interval, false); policyIds.addAll(currentScaleDownPolicyIds); } + AutoScaleVmProfileVO profileVO = getEntityInDatabase(UserContext.current().getCaller(), ApiConstants.VMPROFILE_ID, vmGroup.getProfileId(), _autoScaleVmProfileDao); LoadBalancerVO loadBalancer = getEntityInDatabase(UserContext.current().getCaller(), ApiConstants.LBID, vmGroup.getLoadBalancerId(), _lbDao); - validateAutoScaleCounters(loadBalancer.getNetworkId(), counters); - - AutoScaleVmProfileVO profileVO = getEntityInDatabase(UserContext.current().getCaller(), ApiConstants.VMPROFILE_ID, vmGroup.getProfileId(), _autoScaleVmProfileDao); + validateAutoScaleCounters(loadBalancer.getNetworkId(), counters, profileVO.getCounterParams()); ControlledEntity[] sameOwnerEntities = policies.toArray(new ControlledEntity[policies.size() + 2]); sameOwnerEntities[sameOwnerEntities.length - 2] = loadBalancer; diff --git a/server/src/com/cloud/network/as/AutoScaleVmProfileVO.java b/server/src/com/cloud/network/as/AutoScaleVmProfileVO.java index d963eef2940..ea2fc767850 100644 --- a/server/src/com/cloud/network/as/AutoScaleVmProfileVO.java +++ b/server/src/com/cloud/network/as/AutoScaleVmProfileVO.java @@ -16,7 +16,12 @@ // under the License. package com.cloud.network.as; +import java.util.ArrayList; import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; import java.util.UUID; import javax.persistence.Column; @@ -29,6 +34,7 @@ import javax.persistence.InheritanceType; import javax.persistence.Table; import com.cloud.api.Identity; +import com.cloud.utils.Pair; import com.cloud.utils.db.GenericDao; import com.cloud.utils.net.NetUtils; @@ -69,11 +75,8 @@ public class AutoScaleVmProfileVO implements AutoScaleVmProfile, Identity { @Column(name = "destroy_vm_grace_period", updatable = true) private Integer destroyVmGraceperiod = NetUtils.DEFAULT_AUTOSCALE_VM_DESTROY_TIME; - @Column(name = "snmp_community", updatable = true) - private String snmpCommunity = NetUtils.DEFAULT_SNMP_COMMUNITY; - - @Column(name = "snmp_port", updatable = true) - private Integer snmpPort = NetUtils.DEFAULT_SNMP_PORT; + @Column(name = "counter_params", updatable = true) + private String counterParams; @Column(name = GenericDao.REMOVED_COLUMN) protected Date removed; @@ -84,7 +87,7 @@ public class AutoScaleVmProfileVO implements AutoScaleVmProfile, Identity { public AutoScaleVmProfileVO() { } - public AutoScaleVmProfileVO(long zoneId, long domainId, long accountId, long serviceOfferingId, long templateId, String otherDeployParams, String snmpCommunity, Integer snmpPort, Integer destroyVmGraceperiod, + public AutoScaleVmProfileVO(long zoneId, long domainId, long accountId, long serviceOfferingId, long templateId, String otherDeployParams, Map counterParamList, Integer destroyVmGraceperiod, long autoscaleUserId) { this.uuid = UUID.randomUUID().toString(); this.zoneId = zoneId; @@ -97,12 +100,7 @@ public class AutoScaleVmProfileVO implements AutoScaleVmProfile, Identity { if (destroyVmGraceperiod != null) { this.destroyVmGraceperiod = destroyVmGraceperiod; } - if (snmpCommunity != null) { - this.snmpCommunity = snmpCommunity; - } - if (snmpPort != null) { - this.snmpPort = snmpPort; - } + setCounterParamsForUpdate(counterParamList); } @Override @@ -134,21 +132,44 @@ public class AutoScaleVmProfileVO implements AutoScaleVmProfile, Identity { } @Override - public String getSnmpCommunity() { - return snmpCommunity; + public List> getCounterParams() { + List> paramsList = new ArrayList>(); + if (counterParams != null) { + String[] params = counterParams.split("[=&]"); + for (int i = 0; i < (params.length - 1); i = i + 2) { + paramsList.add(new Pair(params[i], params[i + 1])); + } + } + return paramsList; } - public void setSnmpCommunity(String snmpCommunity) { - this.snmpCommunity = snmpCommunity; + public void setCounterParams(String counterParam) { + this.counterParams = counterParam; } - @Override - public Integer getSnmpPort() { - return snmpPort; - } - - public void setSnmpPort(Integer snmpPort) { - this.snmpPort = snmpPort; + public void setCounterParamsForUpdate(Map counterParamList) { + StringBuilder sb = new StringBuilder(""); + boolean isFirstParam = true; + if (counterParamList != null) { + Iterator> iter = counterParamList.values().iterator(); + while (iter.hasNext()) { + HashMap paramKVpair = iter.next(); + if (!isFirstParam) { + sb.append("&"); + } + String paramName = paramKVpair.get("name"); + String paramValue = paramKVpair.get("value"); + sb.append(paramName + "=" + paramValue); + isFirstParam = false; + } + } + /* + * setCounterParams(String counterParam)'s String param is caught by UpdateBuilder and stored in an internal + * list. + * Which is used later to update the db. The variables in a VO object is not used to update the db. + * Hence calling the function which is intercepted. + */ + setCounterParams(sb.toString()); } @Override diff --git a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java index 49b3949cda7..99cfe61f7fe 100755 --- a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java +++ b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java @@ -237,7 +237,7 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa serviceResponse.setName(service.getName()); if ("Lb".equalsIgnoreCase(service.getName())) { Map serviceCapabilities = serviceCapabilitiesMap - .get(service); + .get(service); if (serviceCapabilities != null) { for (Capability capability : serviceCapabilities .keySet()) { @@ -862,10 +862,10 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa if (apply) { try { - if (!applyLoadBalancerConfig(loadBalancerId)) { - s_logger.warn("Unable to apply the load balancer config"); - return false; - } + if (!applyLoadBalancerConfig(loadBalancerId)) { + s_logger.warn("Unable to apply the load balancer config"); + return false; + } } catch (ResourceUnavailableException e) { if (rollBack && isRollBackAllowedForProvider(lb)) { if (backupMaps != null) { @@ -989,8 +989,8 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa ipVO = _ipAddressDao.findById(ipVO.getId()); _vpcMgr.unassignIPFromVpcNetwork(ipVO.getId(), lb.getNetworkId()); } + } } - } if (result == null) { throw new CloudRuntimeException("Failed to create load balancer rule: " + lb.getName()); @@ -1411,14 +1411,6 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa return loadBalancerInstances; } - public List getSupportedAutoScaleCounters(long networkid) - { - String capability = getLBCapability(networkid, Capability.AutoScaleCounters.getName()); - if (capability == null || capability.length() == 0) { - return null; - } - return Arrays.asList(capability.split(",")); - } @Override public List getStickinessMethods(long networkid) diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql index 6997c3cfb2c..fff084e6336 100755 --- a/setup/db/create-schema.sql +++ b/setup/db/create-schema.sql @@ -2430,8 +2430,7 @@ CREATE TABLE `cloud`.`autoscale_vmprofiles` ( `template_id` bigint unsigned NOT NULL, `other_deploy_params` varchar(1024) COMMENT 'other deployment parameters that is in addition to zoneid,serviceofferingid,domainid', `destroy_vm_grace_period` int unsigned COMMENT 'the time allowed for existing connections to get closed before a vm is destroyed', - `snmp_community` varchar(255) COMMENT 'the community string to be used to reach out to the VM deployed by this profile', - `snmp_port` int unsigned COMMENT 'the snmp port to be used to reach out to the VM deployed by this profile', + `counter_params` varchar(1024) COMMENT 'the parameters for the counter to be used to get metric information from VMs', `created` datetime NOT NULL COMMENT 'date created', `removed` datetime COMMENT 'date removed if not null', PRIMARY KEY (`id`), diff --git a/utils/src/com/cloud/utils/net/NetUtils.java b/utils/src/com/cloud/utils/net/NetUtils.java index 69de0dca871..c456cdcca8e 100755 --- a/utils/src/com/cloud/utils/net/NetUtils.java +++ b/utils/src/com/cloud/utils/net/NetUtils.java @@ -60,9 +60,6 @@ public class NetUtils { public final static String ALL_CIDRS = "0.0.0.0/0"; - public final static String DEFAULT_SNMP_COMMUNITY = "public"; - public final static int DEFAULT_SNMP_PORT = 161; - public final static int DEFAULT_AUTOSCALE_VM_DESTROY_TIME = 2 * 60; // Grace period before Vm is destroyed public final static int DEFAULT_AUTOSCALE_POLICY_INTERVAL_TIME = 30; public final static int DEFAULT_AUTOSCALE_POLICY_QUIET_TIME = 5 * 60; @@ -163,7 +160,7 @@ public class NetUtils { try { Process result = Runtime.getRuntime().exec("route print -4"); BufferedReader output = new BufferedReader - (new InputStreamReader(result.getInputStream())); + (new InputStreamReader(result.getInputStream())); String line = output.readLine(); while(line != null){ @@ -173,8 +170,8 @@ public class NetUtils { } line = output.readLine(); } - } catch( Exception e ) { - } + } catch( Exception e ) { + } return null; } else { NetworkInterface nic = null; @@ -799,7 +796,7 @@ public class NetUtils { long shift = 32 - cidrBLong[1]; return ((cidrALong[0] >> shift) == (cidrBLong[0] >> shift)); } - + public static Long[] cidrToLong(String cidr) { if (cidr == null || cidr.isEmpty()) { return null; @@ -1067,7 +1064,7 @@ public class NetUtils { if (instanceName.contains("-") || instanceName.contains(" ") || instanceName.contains("+")) { s_logger.warn("Instance name can not contain hyphen, spaces and \"+\" char"); return false; - } + } return true; }