diff --git a/api/src/com/cloud/agent/api/to/LoadBalancerTO.java b/api/src/com/cloud/agent/api/to/LoadBalancerTO.java index d0eeb66b77e..884c7c542b6 100644 --- a/api/src/com/cloud/agent/api/to/LoadBalancerTO.java +++ b/api/src/com/cloud/agent/api/to/LoadBalancerTO.java @@ -17,28 +17,46 @@ package com.cloud.agent.api.to; +import java.io.Serializable; +import java.util.ArrayList; import java.util.List; -import com.cloud.utils.Pair; + +import com.cloud.network.as.AutoScalePolicy; +import com.cloud.network.as.AutoScaleVmGroup; +import com.cloud.network.as.AutoScaleVmProfile; +import com.cloud.network.as.Condition; +import com.cloud.network.as.Counter; +import com.cloud.network.lb.LoadBalancingRule.LbAutoScalePolicy; +import com.cloud.network.lb.LoadBalancingRule.LbAutoScaleVmGroup; +import com.cloud.network.lb.LoadBalancingRule.LbAutoScaleVmProfile; +import com.cloud.network.lb.LoadBalancingRule.LbCondition; import com.cloud.network.lb.LoadBalancingRule.LbDestination; import com.cloud.network.lb.LoadBalancingRule.LbStickinessPolicy; +import com.cloud.utils.Pair; public class LoadBalancerTO { + Long id; String srcIp; int srcPort; String protocol; - String algorithm; + String algorithm; boolean revoked; boolean alreadyAdded; DestinationTO[] destinations; private StickinessPolicyTO[] stickinessPolicies; - final static int MAX_STICKINESS_POLICIES = 1; - - public LoadBalancerTO (String srcIp, int srcPort, String protocol, String algorithm, boolean revoked, boolean alreadyAdded, List destinations) { + private AutoScaleVmGroupTO autoScaleVmGroupTO; + final static int MAX_STICKINESS_POLICIES = 1; + + public LoadBalancerTO (Long id, String srcIp, int srcPort, String protocol, String algorithm, boolean revoked, boolean alreadyAdded, List destinations) { + if(destinations == null) { // for autoscaleconfig destinations will be null; + destinations = new ArrayList(); + } + this.id = id; this.srcIp = srcIp; this.srcPort = srcPort; this.protocol = protocol; - this.algorithm = algorithm; + this.algorithm = algorithm; this.revoked = revoked; this.alreadyAdded = alreadyAdded; this.destinations = new DestinationTO[destinations.size()]; @@ -48,9 +66,9 @@ public class LoadBalancerTO { this.destinations[i++] = new DestinationTO(destination.getIpAddress(), destination.getDestinationPortStart(), destination.isRevoked(), false); } } - - public LoadBalancerTO (String srcIp, int srcPort, String protocol, String algorithm, boolean revoked, boolean alreadyAdded, List arg_destinations, List stickinessPolicies) { - this(srcIp, srcPort, protocol, algorithm, revoked, alreadyAdded, arg_destinations); + + public LoadBalancerTO (Long id, String srcIp, int srcPort, String protocol, String algorithm, boolean revoked, boolean alreadyAdded, List arg_destinations, List stickinessPolicies) { + this(id, srcIp, srcPort, protocol, algorithm, revoked, alreadyAdded, arg_destinations); this.stickinessPolicies = null; if (stickinessPolicies != null && stickinessPolicies.size()>0) { this.stickinessPolicies = new StickinessPolicyTO[MAX_STICKINESS_POLICIES]; @@ -65,11 +83,16 @@ public class LoadBalancerTO { if (index == 0) this.stickinessPolicies = null; } } - - + + protected LoadBalancerTO() { } - + + + public Long getId() { + return id; + } + public String getSrcIp() { return srcIp; } @@ -93,15 +116,27 @@ public class LoadBalancerTO { public boolean isAlreadyAdded() { return alreadyAdded; } - + public StickinessPolicyTO[] getStickinessPolicies() { return stickinessPolicies; } - + public DestinationTO[] getDestinations() { return destinations; } - + + public AutoScaleVmGroupTO getAutoScaleVmGroupTO() { + return autoScaleVmGroupTO; + } + + public void setAutoScaleVmGroupTO(AutoScaleVmGroupTO autoScaleVmGroupTO) { + this.autoScaleVmGroupTO = autoScaleVmGroupTO; + } + + public boolean isAutoScaleVmGroupTO() { + return this.autoScaleVmGroupTO != null; + } + public static class StickinessPolicyTO { private String _methodName; private List> _paramsList; @@ -119,7 +154,7 @@ public class LoadBalancerTO { this._paramsList = paramsList; } } - + public static class DestinationTO { String destIp; int destPort; @@ -131,18 +166,18 @@ public class LoadBalancerTO { this.revoked = revoked; this.alreadyAdded = alreadyAdded; } - + protected DestinationTO() { } - + public String getDestIp() { return destIp; } - + public int getDestPort() { return destPort; } - + public boolean isRevoked() { return revoked; } @@ -151,5 +186,249 @@ public class LoadBalancerTO { return alreadyAdded; } } + public static class CounterTO implements Serializable{ + private final String name; + private final String source; + private final String value; + + public CounterTO(String name, String source, String value) { + this.name = name; + this.source = source; + this.value = value; + } + + public String getName() { + return name; + } + + public String getSource() { + return source; + } + + public String getValue() { + return value; + } + } + + public static class ConditionTO implements Serializable{ + private final long threshold; + private final String relationalOperator; + private final CounterTO counter; + + public ConditionTO(long threshold, String relationalOperator, CounterTO counter) + { + this.threshold = threshold; + this.relationalOperator = relationalOperator; + this.counter = counter; + } + + public long getThreshold() { + return threshold; + } + + public String getRelationalOperator() { + return relationalOperator; + } + + public CounterTO getCounter() { + return counter; + } + } + + public static class AutoScalePolicyTO implements Serializable{ + private final long id; + private final int duration; + private final int quietTime; + private String action; + boolean revoked; + private final List conditions; + + public AutoScalePolicyTO(long id, int duration, int quietTime, String action, List conditions, boolean revoked) { + this.id = id; + this.duration = duration; + this.quietTime = quietTime; + this.conditions = conditions; + this.action = action; + this.revoked = revoked; + } + + public long getId() { + return id; + } + + public int getDuration() { + return duration; + } + + public int getQuietTime() { + return quietTime; + } + + public String getAction() { + return action; + } + + public boolean isRevoked() { + return revoked; + } + + public List getConditions() { + return conditions; + } + } + + public static class AutoScaleVmProfileTO implements Serializable{ + private final Long zoneId; + private final Long domainId; + private final Long serviceOfferingId; + private final Long templateId; + private final String otherDeployParams; + private final String snmpCommunity; + private final Integer snmpPort; + private final Integer destroyVmGraceperiod; + private final String cloudStackApiUrl; + private final String autoScaleUserApiKey; + private final String autoScaleUserSecretKey; + + public AutoScaleVmProfileTO(Long zoneId, Long domainId, String cloudStackApiUrl, String autoScaleUserApiKey, String autoScaleUserSecretKey, Long serviceOfferingId, Long templateId, + String otherDeployParams, String snmpCommunity, Integer snmpPort, Integer destroyVmGraceperiod) { + this.zoneId = zoneId; + this.domainId = domainId; + this.serviceOfferingId = serviceOfferingId; + this.templateId = templateId; + this.otherDeployParams = otherDeployParams; + this.snmpCommunity = snmpCommunity; + this.snmpPort = snmpPort; + this.destroyVmGraceperiod = destroyVmGraceperiod; + this.cloudStackApiUrl = cloudStackApiUrl; + this.autoScaleUserApiKey = autoScaleUserApiKey; + this.autoScaleUserSecretKey = autoScaleUserSecretKey; + } + + public Long getZoneId() { + return zoneId; + } + + public Long getDomainId() { + return domainId; + } + + public Long getServiceOfferingId() { + return serviceOfferingId; + } + + public Long getTemplateId() { + return templateId; + } + + public String getOtherDeployParams() { + return otherDeployParams; + } + + public String getSnmpCommunity() { + return snmpCommunity; + } + + public Integer getSnmpPort() { + return snmpPort; + } + + public Integer getDestroyVmGraceperiod() { + return destroyVmGraceperiod; + } + + public String getCloudStackApiUrl() { + return cloudStackApiUrl; + } + + public String getAutoScaleUserApiKey() { + return autoScaleUserApiKey; + } + + public String getAutoScaleUserSecretKey() { + return autoScaleUserSecretKey; + } + } + + public static class AutoScaleVmGroupTO implements Serializable{ + private final int minMembers; + private final int maxMembers; + private final int memberPort; + private final int interval; + private final List policies; + private final AutoScaleVmProfileTO profile; + private final String state; + + AutoScaleVmGroupTO(int minMembers, int maxMembers, int memberPort, int interval, List policies, AutoScaleVmProfileTO profile, String state) + { + this.minMembers = minMembers; + this.maxMembers = maxMembers; + this.memberPort = memberPort; + this.interval = interval; + this.policies = policies; + this.profile = profile; + this.state = state; + } + + public int getMinMembers() { + return minMembers; + } + + public int getMaxMembers() { + return maxMembers; + } + + public int getMemberPort() { + return memberPort; + } + + public int getInterval() { + return interval; + } + + public List getPolicies() { + return policies; + } + + public AutoScaleVmProfileTO getProfile() { + return profile; + } + + public String getState() { + return state; + } + } + + public void setAutoScaleVmGroup(LbAutoScaleVmGroup lbAutoScaleVmGroup) + { + List lbAutoScalePolicies = lbAutoScaleVmGroup.getPolicies(); + List autoScalePolicyTOs = new ArrayList(lbAutoScalePolicies.size()); + for (LbAutoScalePolicy lbAutoScalePolicy : lbAutoScalePolicies) { + List lbConditions = lbAutoScalePolicy.getConditions(); + List conditionTOs = new ArrayList(lbConditions.size()); + for (LbCondition lbCondition : lbConditions) { + Counter counter = lbCondition.getCounter(); + CounterTO counterTO = new CounterTO(counter.getName(), counter.getSource().toString(), "" + counter.getValue()); + Condition condition = lbCondition.getCondition(); + ConditionTO conditionTO = new ConditionTO(condition.getThreshold(), condition.getRelationalOperator().toString(), counterTO); + conditionTOs.add(conditionTO); + } + AutoScalePolicy autoScalePolicy = lbAutoScalePolicy.getPolicy(); + autoScalePolicyTOs.add(new AutoScalePolicyTO(autoScalePolicy.getId(), autoScalePolicy.getDuration(), + autoScalePolicy.getQuietTime(), autoScalePolicy.getAction(), + conditionTOs, lbAutoScalePolicy.isRevoked())); + } + LbAutoScaleVmProfile lbAutoScaleVmProfile = lbAutoScaleVmGroup.getProfile(); + AutoScaleVmProfile autoScaleVmProfile = lbAutoScaleVmProfile.getProfile(); + + AutoScaleVmProfileTO autoScaleVmProfileTO = new AutoScaleVmProfileTO(autoScaleVmProfile.getZoneId(), autoScaleVmProfile.getDomainId(), + lbAutoScaleVmProfile.getCsUrl(), lbAutoScaleVmProfile.getAutoScaleUserApiKey(), lbAutoScaleVmProfile.getAutoScaleUserSecretKey(), + autoScaleVmProfile.getServiceOfferingId(), autoScaleVmProfile.getTemplateId(), autoScaleVmProfile.getOtherDeployParams(), + autoScaleVmProfile.getSnmpCommunity(), autoScaleVmProfile.getSnmpPort(), autoScaleVmProfile.getDestroyVmGraceperiod()); + + AutoScaleVmGroup autoScaleVmGroup = lbAutoScaleVmGroup.getVmGroup(); + autoScaleVmGroupTO = new AutoScaleVmGroupTO(autoScaleVmGroup.getMinMembers(), autoScaleVmGroup.getMaxMembers(), autoScaleVmGroup.getMemberPort(), + autoScaleVmGroup.getInterval(), autoScalePolicyTOs, autoScaleVmProfileTO, autoScaleVmGroup.getState()); + } } diff --git a/api/src/com/cloud/api/ApiConstants.java b/api/src/com/cloud/api/ApiConstants.java index 32b852fb4a3..c69d816dc9c 100755 --- a/api/src/com/cloud/api/ApiConstants.java +++ b/api/src/com/cloud/api/ApiConstants.java @@ -31,10 +31,10 @@ public class ApiConstants { public static final String BIND_DN = "binddn"; public static final String BIND_PASSWORD = "bindpass"; public static final String CATEGORY = "category"; - public static final String CERTIFICATE = "certificate"; - public static final String PRIVATE_KEY = "privatekey"; - public static final String DOMAIN_SUFFIX = "domainsuffix"; - public static final String DNS_SEARCH_ORDER = "dnssearchorder"; + public static final String CERTIFICATE = "certificate"; + public static final String PRIVATE_KEY = "privatekey"; + public static final String DOMAIN_SUFFIX = "domainsuffix"; + public static final String DNS_SEARCH_ORDER = "dnssearchorder"; public static final String CIDR = "cidr"; public static final String CIDR_LIST = "cidrlist"; public static final String CLEANUP = "cleanup"; @@ -104,7 +104,7 @@ public class ApiConstants { public static final String JOB_STATUS = "jobstatus"; public static final String LASTNAME = "lastname"; public static final String LEVEL = "level"; - public static final String LIMIT_CPU_USE = "limitcpuuse"; + public static final String LIMIT_CPU_USE = "limitcpuuse"; public static final String LOCK = "lock"; public static final String LUN = "lun"; public static final String LBID = "lbruleid"; @@ -137,9 +137,9 @@ public class ApiConstants { public static final String PORTAL = "portal"; public static final String PORT_FORWARDING_SERVICE_ID = "portforwardingserviceid"; public static final String PRIVATE_INTERFACE = "privateinterface"; - public static final String PRIVATE_IP = "privateip"; + public static final String PRIVATE_IP = "privateip"; public static final String PRIVATE_PORT = "privateport"; - public static final String PRIVATE_START_PORT = "privateport"; + public static final String PRIVATE_START_PORT = "privateport"; public static final String PRIVATE_END_PORT = "privateendport"; public static final String PRIVATE_ZONE = "privatezone"; public static final String PROTOCOL = "protocol"; @@ -147,7 +147,7 @@ public class ApiConstants { public static final String PUBLIC_IP_ID = "publicipid"; public static final String PUBLIC_IP = "publicip"; public static final String PUBLIC_PORT = "publicport"; - public static final String PUBLIC_START_PORT = "publicport"; + public static final String PUBLIC_START_PORT = "publicport"; public static final String PUBLIC_END_PORT = "publicendport"; public static final String PUBLIC_ZONE = "publiczone"; public static final String RECEIVED_BYTES = "receivedbytes"; @@ -171,7 +171,7 @@ public class ApiConstants { public static final String SNAPSHOT_ID = "snapshotid"; public static final String SNAPSHOT_POLICY_ID = "snapshotpolicyid"; public static final String SNAPSHOT_TYPE = "snapshottype"; - public static final String SOURCE_ZONE_ID = "sourcezoneid"; + public static final String SOURCE_ZONE_ID = "sourcezoneid"; public static final String START_DATE = "startdate"; public static final String START_IP = "startip"; public static final String START_PORT = "startport"; @@ -384,18 +384,44 @@ public class ApiConstants { public static final String NICIRA_NVP_DEVICE_NAME = "niciradevicename"; public static final String NICIRA_NVP_GATEWAYSERVICE_UUID = "l3gatewayserviceuuid"; + public static final String SOURCE = "source"; + public static final String COUNTER_ID = "counterid"; + public static final String AGGR_OPERATOR = "aggroperator"; + public static final String AGGR_FUNCTION = "aggrfunction"; + 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"; + public static final String AUTOSCALE_VM_DESTROY_TIME = "destroyvmgraceperiod"; + public static final String VMPROFILE_ID = "vmprofileid"; + public static final String VMGROUP_ID = "vmgroupid"; + public static final String CS_URL = "csurl"; + public static final String SCALEUP_POLICY_IDS = "scaleuppolicyids"; + public static final String SCALEDOWN_POLICY_IDS = "scaledownpolicyids"; + public static final String SCALEUP_POLICIES = "scaleuppolicies"; + public static final String SCALEDOWN_POLICIES = "scaledownpolicies"; + public static final String INTERVAL = "interval"; + public static final String QUIETTIME = "quiettime"; + public static final String ACTION = "action"; + public static final String CONDITION_ID = "conditionid"; + public static final String CONDITION_IDS = "conditionids"; + public static final String AUTOSCALE_USER_ID = "autoscaleuserid"; public enum HostDetails { all, capacity, events, stats, min; } - + 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(){ return "ldap." + name(); diff --git a/api/src/com/cloud/api/BaseCmd.java b/api/src/com/cloud/api/BaseCmd.java index 91c2035665d..12a2176fb2e 100755 --- a/api/src/com/cloud/api/BaseCmd.java +++ b/api/src/com/cloud/api/BaseCmd.java @@ -42,6 +42,7 @@ import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.NetworkService; import com.cloud.network.StorageNetworkService; import com.cloud.network.VpcVirtualNetworkApplianceService; +import com.cloud.network.as.AutoScaleService; import com.cloud.network.firewall.FirewallService; import com.cloud.network.firewall.NetworkACLService; import com.cloud.network.lb.LoadBalancingRulesService; @@ -125,6 +126,7 @@ public abstract class BaseCmd { public static ResponseGenerator _responseGenerator; public static EntityManager _entityMgr; public static RulesService _rulesService; + public static AutoScaleService _autoScaleService; public static LoadBalancingRulesService _lbService; public static RemoteAccessVpnService _ravService; public static BareMetalVmService _bareMetalVmService; @@ -156,6 +158,7 @@ public abstract class BaseCmd { _entityMgr = locator.getManager(EntityManager.class); _rulesService = locator.getManager(RulesService.class); _lbService = locator.getManager(LoadBalancingRulesService.class); + _autoScaleService = locator.getManager(AutoScaleService.class); _ravService = locator.getManager(RemoteAccessVpnService.class); _responseGenerator = generator; _bareMetalVmService = locator.getManager(BareMetalVmService.class); @@ -203,9 +206,9 @@ public abstract class BaseCmd { } public ManagementService getMgmtServiceRef() { - return _mgr; + return _mgr; } - + public static String getDateString(Date date) { if (date == null) { return ""; @@ -342,7 +345,7 @@ public abstract class BaseCmd { if (suffixSb.length() > 0) { if (RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) { // append comma only if we have some suffix else -// not as per strict Json syntax. + // not as per strict Json syntax. prefixSb.append(","); } prefixSb.append(suffixSb); @@ -502,7 +505,7 @@ public abstract class BaseCmd { if (!enabledOnly || account.getState() == Account.State.enabled) { return account.getId(); } else { - throw new PermissionDeniedException("Can't add resources to the account id=" + account.getId() + " in state=" + account.getState() + " as it's no longer active"); + throw new PermissionDeniedException("Can't add resources to the account id=" + account.getId() + " in state=" + account.getState() + " as it's no longer active"); } } else { List idList = new ArrayList(); @@ -517,8 +520,8 @@ public abstract class BaseCmd { if (!enabledOnly || project.getState() == Project.State.Active) { return project.getProjectAccountId(); } else { - PermissionDeniedException ex = new PermissionDeniedException("Can't add resources to the project with specified projectId in state=" + project.getState() + " as it's no longer active"); - ex.addProxyObject(project, projectId, "projectId"); + PermissionDeniedException ex = new PermissionDeniedException("Can't add resources to the project with specified projectId in state=" + project.getState() + " as it's no longer active"); + ex.addProxyObject(project, projectId, "projectId"); throw ex; } } else { diff --git a/api/src/com/cloud/api/ResponseGenerator.java b/api/src/com/cloud/api/ResponseGenerator.java index 996a5fcfd4b..4e8fbd824a9 100755 --- a/api/src/com/cloud/api/ResponseGenerator.java +++ b/api/src/com/cloud/api/ResponseGenerator.java @@ -25,9 +25,14 @@ import com.cloud.api.ApiConstants.VMDetails; import com.cloud.api.commands.QueryAsyncJobResultCmd; import com.cloud.api.response.AccountResponse; import com.cloud.api.response.AsyncJobResponse; +import com.cloud.api.response.AutoScalePolicyResponse; +import com.cloud.api.response.AutoScaleVmGroupResponse; +import com.cloud.api.response.AutoScaleVmProfileResponse; import com.cloud.api.response.CapacityResponse; import com.cloud.api.response.ClusterResponse; +import com.cloud.api.response.ConditionResponse; import com.cloud.api.response.ConfigurationResponse; +import com.cloud.api.response.CounterResponse; import com.cloud.api.response.CreateCmdResponse; import com.cloud.api.response.DiskOfferingResponse; import com.cloud.api.response.DomainResponse; @@ -110,6 +115,11 @@ import com.cloud.network.Site2SiteVpnConnection; import com.cloud.network.Site2SiteVpnGateway; import com.cloud.network.VirtualRouterProvider; import com.cloud.network.VpnUser; +import com.cloud.network.as.AutoScalePolicy; +import com.cloud.network.as.AutoScaleVmGroup; +import com.cloud.network.as.AutoScaleVmProfile; +import com.cloud.network.as.Condition; +import com.cloud.network.as.Counter; import com.cloud.network.router.VirtualRouter; import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.LoadBalancer; @@ -306,6 +316,7 @@ public interface ResponseGenerator { ResourceTagResponse createResourceTagResponse(ResourceTag resourceTag, boolean keyValueOnly); Site2SiteVpnGatewayResponse createSite2SiteVpnGatewayResponse(Site2SiteVpnGateway result); + /** * @param offering @@ -340,4 +351,14 @@ public interface ResponseGenerator { Site2SiteCustomerGatewayResponse createSite2SiteCustomerGatewayResponse(Site2SiteCustomerGateway result); Site2SiteVpnConnectionResponse createSite2SiteVpnConnectionResponse(Site2SiteVpnConnection result); + + CounterResponse createCounterResponse(Counter ctr); + + ConditionResponse createConditionResponse(Condition cndn); + + AutoScalePolicyResponse createAutoScalePolicyResponse(AutoScalePolicy policy); + + AutoScaleVmProfileResponse createAutoScaleVmProfileResponse(AutoScaleVmProfile profile); + + AutoScaleVmGroupResponse createAutoScaleVmGroupResponse(AutoScaleVmGroup vmGroup); } diff --git a/api/src/com/cloud/api/commands/CreateAutoScalePolicyCmd.java b/api/src/com/cloud/api/commands/CreateAutoScalePolicyCmd.java new file mode 100644 index 00000000000..4d9374791ed --- /dev/null +++ b/api/src/com/cloud/api/commands/CreateAutoScalePolicyCmd.java @@ -0,0 +1,170 @@ +// 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.api.commands; + +import java.util.List; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +import com.cloud.api.BaseAsyncCreateCmd; +import com.cloud.api.BaseCmd; +import com.cloud.api.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.AutoScalePolicyResponse; +import com.cloud.async.AsyncJob; +import com.cloud.domain.Domain; +import com.cloud.event.EventTypes; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.network.as.AutoScalePolicy; +import com.cloud.network.as.Condition; +import com.cloud.user.Account; + +@Implementation(description = "Creates an autoscale policy for a provision or deprovision action, the action is taken when the all the conditions evaluates to true for the specified duration. The policy is in effect once it is attached to a autscale vm group.", responseObject = AutoScalePolicyResponse.class) +public class CreateAutoScalePolicyCmd extends BaseAsyncCreateCmd { + public static final Logger s_logger = Logger.getLogger(CreateAutoScalePolicyCmd.class.getName()); + + private static final String s_name = "autoscalepolicyresponse"; + + // /////////////////////////////////////////////////// + // ////////////// API parameters ///////////////////// + // /////////////////////////////////////////////////// + + @Parameter(name = ApiConstants.ACTION, type = CommandType.STRING, required = true, description = "the action to be executed if all the conditions evaluate to true for the specified duration.") + private String action; + + @Parameter(name = ApiConstants.DURATION, type = CommandType.INTEGER, required = true, description = "the duration for which the conditions have to be true before action is taken") + private int duration; + + @Parameter(name = ApiConstants.QUIETTIME, type = CommandType.INTEGER, description = "the cool down period for which the policy should not be evaluated after the action has been taken") + private Integer quietTime; + + @IdentityMapper(entityTableName = "conditions") + @Parameter(name = ApiConstants.CONDITION_IDS, type = CommandType.LIST, collectionType = CommandType.LONG, required = true, description = "the list of IDs of the conditions that are being evaluated on every interval") + private List conditionIds; + + // /////////////////////////////////////////////////// + // ///////////////// Accessors /////////////////////// + // /////////////////////////////////////////////////// + + private Long conditionDomainId; + private Long conditionAccountId; + + @Override + public String getEntityTable() { + return "autoscale_policies"; + } + + public int getDuration() { + return duration; + } + + public Integer getQuietTime() { + return quietTime; + } + + public String getAction() { + return action; + } + + public List getConditionIds() { + return conditionIds; + } + + // /////////////////////////////////////////////////// + // ///////////// API Implementation/////////////////// + // /////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + public static String getResultObjectName() { + return "autoscalepolicy"; + } + + public long getAccountId() + { + if (conditionAccountId == null) + getEntityOwnerId(); + return conditionAccountId; + } + + public long getDomainId() + { + if (conditionDomainId == null) { + getEntityOwnerId(); + } + + return conditionDomainId; + } + + @Override + public long getEntityOwnerId() { + if (conditionAccountId != null) { + return conditionAccountId; + } + long conditionId = getConditionIds().get(0); + Condition condition = _entityMgr.findById(Condition.class, conditionId); + if(condition == null) { + // it is an invalid condition, return system acccount, error will be thrown later. + conditionDomainId = Domain.ROOT_DOMAIN; + conditionAccountId = Account.ACCOUNT_ID_SYSTEM; + } else { + conditionDomainId = condition.getDomainId(); + conditionAccountId = condition.getAccountId(); + } + + return conditionAccountId; + } + + @Override + public String getEventType() { + return EventTypes.EVENT_AUTOSCALEPOLICY_CREATE; + } + + @Override + public String getEventDescription() { + return "creating AutoScale Policy"; + } + + @Override + public AsyncJob.Type getInstanceType() { + return AsyncJob.Type.AutoScalePolicy; + } + + @Override + public void execute() { + AutoScalePolicy result = _entityMgr.findById(AutoScalePolicy.class, getEntityId()); + AutoScalePolicyResponse response = _responseGenerator.createAutoScalePolicyResponse(result); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } + + @Override + public void create() throws ResourceAllocationException { + AutoScalePolicy result = _autoScaleService.createAutoScalePolicy(this); + if (result != null) { + this.setEntityId(result.getId()); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to create AutoScale Policy"); + } + } +} diff --git a/api/src/com/cloud/api/commands/CreateAutoScaleVmGroupCmd.java b/api/src/com/cloud/api/commands/CreateAutoScaleVmGroupCmd.java new file mode 100644 index 00000000000..83d76072d83 --- /dev/null +++ b/api/src/com/cloud/api/commands/CreateAutoScaleVmGroupCmd.java @@ -0,0 +1,194 @@ +// 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.api.commands; + +import java.util.List; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +import com.cloud.api.BaseAsyncCreateCmd; +import com.cloud.api.BaseCmd; +import com.cloud.api.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.AutoScaleVmGroupResponse; +import com.cloud.async.AsyncJob; +import com.cloud.event.EventTypes; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.network.as.AutoScaleVmGroup; +import com.cloud.network.rules.LoadBalancer; + +@Implementation(description = "Creates and automatically starts a virtual machine based on a service offering, disk offering, and template.", responseObject = AutoScaleVmGroupResponse.class) +public class CreateAutoScaleVmGroupCmd extends BaseAsyncCreateCmd { + public static final Logger s_logger = Logger.getLogger(CreateAutoScaleVmGroupCmd.class.getName()); + + private static final String s_name = "autoscalevmgroupresponse"; + + // /////////////////////////////////////////////////// + // ////////////// API parameters ///////////////////// + // /////////////////////////////////////////////////// + + @IdentityMapper(entityTableName = "firewall_rules") + @Parameter(name = ApiConstants.LBID, type = CommandType.LONG, required = true, description = "the ID of the load balancer rule") + private long lbRuleId; + + @Parameter(name = ApiConstants.MIN_MEMBERS, type = CommandType.INTEGER, required = true, description = "the minimum number of members in the vmgroup, the number of instances in the vm group will be equal to or more than this number.") + private int minMembers; + + @Parameter(name = ApiConstants.MAX_MEMBERS, type = CommandType.INTEGER, required = true, description = "the maximum number of members in the vmgroup, The number of instances in the vm group will be equal to or less than this number.") + private int maxMembers; + + @Parameter(name = ApiConstants.INTERVAL, type = CommandType.INTEGER, description = "the frequency at which the conditions have to be evaluated") + private Integer interval; + + @IdentityMapper(entityTableName = "autoscale_policies") + @Parameter(name = ApiConstants.SCALEUP_POLICY_IDS, type = CommandType.LIST, collectionType = CommandType.LONG, required = true, description = "list of scaleup autoscale policies") + private List scaleUpPolicyIds; + + @IdentityMapper(entityTableName = "autoscale_policies") + @Parameter(name = ApiConstants.SCALEDOWN_POLICY_IDS, type = CommandType.LIST, collectionType = CommandType.LONG, required = true, description = "list of scaledown autoscale policies") + private List scaleDownPolicyIds; + + @IdentityMapper(entityTableName = "autoscale_vmprofiles") + @Parameter(name = ApiConstants.VMPROFILE_ID, type = CommandType.LONG, required = true, description = "the autoscale profile that contains information about the vms in the vm group.") + private long profileId; + + // /////////////////////////////////////////////////// + // ///////////////// Accessors /////////////////////// + // /////////////////////////////////////////////////// + + @Override + public String getEntityTable() { + return "autoscale_vmgroups"; + } + + public int getMinMembers() { + return minMembers; + } + + public int getMaxMembers() { + return maxMembers; + } + + public Integer getInterval() { + return interval; + } + + public long getProfileId() { + return profileId; + } + + public List getScaleUpPolicyIds() { + return scaleUpPolicyIds; + } + + public List getScaleDownPolicyIds() { + return scaleDownPolicyIds; + } + + public long getLbRuleId() { + return lbRuleId; + } + + // /////////////////////////////////////////////////// + // ///////////// API Implementation/////////////////// + // /////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + public static String getResultObjectName() { + return "autoscalevmgroup"; + } + + @Override + public long getEntityOwnerId() { + LoadBalancer lb = _entityMgr.findById(LoadBalancer.class, getLbRuleId()); + if (lb == null) { + throw new InvalidParameterValueException("Unable to find loadbalancer by lbRuleId"); + } + return lb.getAccountId(); + } + + public void setLbRuleId(Long lbRuleId) { + this.lbRuleId = lbRuleId; + } + + @Override + public String getEventType() { + return EventTypes.EVENT_AUTOSCALEVMGROUP_CREATE; + } + + @Override + public String getCreateEventType() { + return EventTypes.EVENT_AUTOSCALEVMGROUP_CREATE; + } + + @Override + public String getCreateEventDescription() { + return "creating AutoScale Vm Group"; + } + + @Override + public String getEventDescription() { + return "configuring AutoScale Vm Group. Vm Group Id: " + getEntityId(); + } + + @Override + public AsyncJob.Type getInstanceType() { + return AsyncJob.Type.AutoScaleVmGroup; + } + + @Override + public void create() throws ResourceAllocationException { + AutoScaleVmGroup result = _autoScaleService.createAutoScaleVmGroup(this); + if (result != null) { + this.setEntityId(result.getId()); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to create Autoscale Vm Group"); + } + } + + @Override + public void execute() { + boolean success = false; + AutoScaleVmGroup vmGroup = null; + try + { + success = _autoScaleService.configureAutoScaleVmGroup(this); + if (success) { + vmGroup = _entityMgr.findById(AutoScaleVmGroup.class, getEntityId()); + AutoScaleVmGroupResponse responseObject = _responseGenerator.createAutoScaleVmGroupResponse(vmGroup); + setResponseObject(responseObject); + responseObject.setResponseName(getCommandName()); + } + } catch (Exception ex) { + // TODO what will happen if Resource Layer fails in a step inbetween + s_logger.warn("Failed to create autoscale vm group", ex); + } finally { + if (!success || vmGroup == null) { + _autoScaleService.deleteAutoScaleVmGroup(getEntityId()); + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to create Autoscale Vm Group"); + } + } + } +} diff --git a/api/src/com/cloud/api/commands/CreateAutoScaleVmProfileCmd.java b/api/src/com/cloud/api/commands/CreateAutoScaleVmProfileCmd.java new file mode 100644 index 00000000000..f5b21a8f868 --- /dev/null +++ b/api/src/com/cloud/api/commands/CreateAutoScaleVmProfileCmd.java @@ -0,0 +1,242 @@ +// 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.api.commands; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +import com.cloud.api.BaseAsyncCreateCmd; +import com.cloud.api.BaseCmd; +import com.cloud.api.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.AutoScaleVmProfileResponse; +import com.cloud.async.AsyncJob; +import com.cloud.event.EventTypes; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.network.as.AutoScaleVmProfile; +import com.cloud.user.Account; +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) +public class CreateAutoScaleVmProfileCmd extends BaseAsyncCreateCmd { + public static final Logger s_logger = Logger.getLogger(CreateAutoScaleVmProfileCmd.class.getName()); + + private static final String s_name = "autoscalevmprofileresponse"; + + // /////////////////////////////////////////////////// + // ////////////// API parameters ///////////////////// + // /////////////////////////////////////////////////// + + @IdentityMapper(entityTableName = "data_center") + @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.LONG, required = true, description = "availability zone for the auto deployed virtual machine") + private Long zoneId; + + @IdentityMapper(entityTableName = "disk_offering") + @Parameter(name = ApiConstants.SERVICE_OFFERING_ID, type = CommandType.LONG, required = true, description = "the service offering of the auto deployed virtual machine") + private Long serviceOfferingId; + + @IdentityMapper(entityTableName = "vm_template") + @Parameter(name = ApiConstants.TEMPLATE_ID, type = CommandType.LONG, required = true, description = "the template of the auto deployed virtual machine") + private Long templateId; + + @Parameter(name = ApiConstants.OTHER_DEPLOY_PARAMS, type = CommandType.STRING, description = "parameters other than zoneId/serviceOfferringId/templateId of the auto deployed virtual machine") + private String otherDeployParams; + + @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; + + @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") + private Long autoscaleUserId; + + private Map otherDeployParamMap; + + // /////////////////////////////////////////////////// + // ///////////////// Accessors /////////////////////// + // /////////////////////////////////////////////////// + + private Long domainId; + private Long accountId; + + @Override + public String getEntityTable() { + return "autoscale_vmprofiles"; + } + + public Long getDomainId() { + if (domainId == null) { + getAccountId(); + } + return domainId; + } + + public Long getZoneId() { + return zoneId; + } + + public Long getServiceOfferingId() { + return serviceOfferingId; + } + + public Long getTemplateId() { + return templateId; + } + + public Integer getSnmpPort() { + return snmpPort; + } + + public String getSnmpCommunity() { + return snmpCommunity; + } + + public String getOtherDeployParams() { + return otherDeployParams; + } + + public Long getAutoscaleUserId() { + if (autoscaleUserId != null) { + return autoscaleUserId; + } else { + return UserContext.current().getCaller().getId(); + } + } + + public Integer getDestroyVmGraceperiod() { + return destroyVmGraceperiod; + } + + public long getAccountId() { + if (accountId != null) { + return accountId; + } + Account account = null; + if (autoscaleUserId != null) { + User user = _entityMgr.findById(User.class, autoscaleUserId); + account = _entityMgr.findById(Account.class, user.getAccountId()); + } else { + account = UserContext.current().getCaller(); + } + accountId = account.getAccountId(); + domainId = account.getDomainId(); + return accountId; + } + + private void createOtherDeployParamMap() + { + if (otherDeployParamMap == null) { + otherDeployParamMap = new HashMap(); + } + if (otherDeployParams == null) + return; + String[] keyValues = otherDeployParams.split("&"); // hostid=123, hypervisor=xenserver + for (String keyValue : keyValues) { // keyValue == "hostid=123" + String[] keyAndValue = keyValue.split("="); // keyValue = hostid, 123 + if (keyAndValue.length != 2) { + throw new InvalidParameterValueException("Invalid parameter in otherDeployParam : " + keyValue); + } + String paramName = keyAndValue[0]; // hostid + String paramValue = keyAndValue[1]; // 123 + otherDeployParamMap.put(paramName, paramValue); + } + } + + public HashMap getDeployParamMap() + { + createOtherDeployParamMap(); + HashMap deployParams = new HashMap(otherDeployParamMap); + deployParams.put("command", "deployVirtualMachine"); + deployParams.put("zoneId", zoneId.toString()); + deployParams.put("serviceOfferingId", serviceOfferingId.toString()); + deployParams.put("templateId", templateId.toString()); + return deployParams; + } + + public String getOtherDeployParam(String param) + { + if (param == null) { + return null; + } + createOtherDeployParamMap(); + return otherDeployParamMap.get(param); + } + + // /////////////////////////////////////////////////// + // ///////////// API Implementation/////////////////// + // /////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + public static String getResultObjectName() { + return "autoscalevmprofile"; + } + + @Override + public long getEntityOwnerId() { + return getAccountId(); + } + + @Override + public String getEventType() { + return EventTypes.EVENT_AUTOSCALEVMPROFILE_CREATE; + } + + @Override + public String getEventDescription() { + return "creating AutoScale Vm Profile"; + } + + @Override + public AsyncJob.Type getInstanceType() { + return AsyncJob.Type.AutoScaleVmProfile; + } + + @Override + public void execute() { + AutoScaleVmProfile result = _entityMgr.findById(AutoScaleVmProfile.class, getEntityId()); + AutoScaleVmProfileResponse response = _responseGenerator.createAutoScaleVmProfileResponse(result); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } + + @Override + public void create() throws ResourceAllocationException { + + AutoScaleVmProfile result = _autoScaleService.createAutoScaleVmProfile(this); + if (result != null) { + this.setEntityId(result.getId()); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to create Autoscale Vm Profile"); + } + } +} diff --git a/api/src/com/cloud/api/commands/CreateConditionCmd.java b/api/src/com/cloud/api/commands/CreateConditionCmd.java new file mode 100644 index 00000000000..2c2a3cd54a5 --- /dev/null +++ b/api/src/com/cloud/api/commands/CreateConditionCmd.java @@ -0,0 +1,152 @@ +// 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.api.commands; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +import com.cloud.api.BaseAsyncCreateCmd; +import com.cloud.api.BaseCmd; +import com.cloud.api.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.ConditionResponse; +import com.cloud.async.AsyncJob; +import com.cloud.event.EventTypes; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.network.as.Condition; +import com.cloud.user.UserContext; + +@Implementation(description = "Creates a condition", responseObject = ConditionResponse.class) +public class CreateConditionCmd extends BaseAsyncCreateCmd { + public static final Logger s_logger = Logger.getLogger(CreateConditionCmd.class.getName()); + private static final String s_name = "conditionresponse"; + + // /////////////////////////////////////////////////// + // ////////////// API parameters ///////////////////// + // /////////////////////////////////////////////////// + + @IdentityMapper(entityTableName = "counter") + @Parameter(name = ApiConstants.COUNTER_ID, type = CommandType.LONG, required = true, description = "ID of the Counter.") + private long counterId; + + @Parameter(name = ApiConstants.RELATIONAL_OPERATOR, type = CommandType.STRING, required = true, description = "Relational Operator to be used with threshold.") + private String relationalOperator; + + @Parameter(name = ApiConstants.THRESHOLD, type = CommandType.LONG, required = true, description = "Threshold value.") + private Long threshold; + + @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "the account of the condition. " + + "Must be used with the domainId parameter.") + private String accountName; + + @IdentityMapper(entityTableName = "domain") + @Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.LONG, description = "the domain ID of the account.") + private Long domainId; + + // /////////////////////////////////////////////////// + // ///////////// API Implementation/////////////////// + // /////////////////////////////////////////////////// + + @Override + public void create() throws ResourceAllocationException { + Condition condition = null; + condition = _autoScaleService.createCondition(this); + + if (condition != null) { + this.setEntityId(condition.getId()); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to create condition."); + } + } + + @Override + public void execute() { + Condition condition = _entityMgr.findById(Condition.class, getEntityId()); + ConditionResponse response = _responseGenerator.createConditionResponse(condition); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } + + // ///////////////////////////////////////////////// + // ///////////////// Accessors /////////////////////// + // /////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + public Long getCounterId() { + return counterId; + } + + public String getRelationalOperator() { + return relationalOperator; + } + + public String getAccountName() { + if (accountName == null) { + return UserContext.current().getCaller().getAccountName(); + } + + return accountName; + } + + public Long getDomainId() { + if (domainId == null) { + return UserContext.current().getCaller().getDomainId(); + } + return domainId; + } + + public Long getThreshold() { + return threshold; + } + + @Override + public AsyncJob.Type getInstanceType() { + return AsyncJob.Type.Condition; + } + + @Override + public String getEventDescription() { + return "creating a condition"; + } + + @Override + public String getEventType() { + return EventTypes.EVENT_CONDITION_CREATE; + } + + @Override + public long getEntityOwnerId() { + Long accountId = finalyzeAccountId(accountName, domainId, null, true); + if (accountId == null) { + return UserContext.current().getCaller().getId(); + } + + return accountId; + } + + @Override + public String getEntityTable() { + return "conditions"; + } +} \ No newline at end of file diff --git a/api/src/com/cloud/api/commands/CreateCounterCmd.java b/api/src/com/cloud/api/commands/CreateCounterCmd.java new file mode 100644 index 00000000000..e5ba91f9ff4 --- /dev/null +++ b/api/src/com/cloud/api/commands/CreateCounterCmd.java @@ -0,0 +1,120 @@ +// 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.api.commands; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +import com.cloud.api.BaseAsyncCreateCmd; +import com.cloud.api.BaseCmd; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.CounterResponse; +import com.cloud.async.AsyncJob; +import com.cloud.event.EventTypes; +import com.cloud.network.as.Counter; +import com.cloud.user.Account; + +@Implementation(description = "Adds metric counter", responseObject = CounterResponse.class) +public class CreateCounterCmd extends BaseAsyncCreateCmd { + public static final Logger s_logger = Logger.getLogger(CreateCounterCmd.class.getName()); + private static final String s_name = "counterresponse"; + + // /////////////////////////////////////////////////// + // ////////////// API parameters ///////////////////// + // /////////////////////////////////////////////////// + + @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "Name of the counter.") + private String name; + + @Parameter(name = ApiConstants.SOURCE, type = CommandType.STRING, required = true, description = "Source of the counter.") + private String source; + + @Parameter(name = ApiConstants.VALUE, type = CommandType.STRING, required = true, description = "Value of the counter e.g. oid in case of snmp.") + private String value; + + // ///////////////////////////////////////////////// + // ///////////////// Accessors /////////////////////// + // /////////////////////////////////////////////////// + + public String getName() { + return name; + } + + public String getSource() { + return source; + } + + public String getValue() { + return value; + } + + // /////////////////////////////////////////////////// + // ///////////// API Implementation/////////////////// + // /////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public void create() { + Counter ctr = null; + ctr = _autoScaleService.createCounter(this); + + if (ctr != null) { + this.setEntityId(ctr.getId()); + CounterResponse response = _responseGenerator.createCounterResponse(ctr); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to create Counter with name " + getName()); + } + } + + @Override + public void execute() { + } + + @Override + public AsyncJob.Type getInstanceType() { + return AsyncJob.Type.Counter; + } + + @Override + public String getEventType() { + return EventTypes.EVENT_COUNTER_CREATE; + } + + @Override + public String getEventDescription() { + return "creating a new Counter"; + } + + @Override + public long getEntityOwnerId() { + return Account.ACCOUNT_ID_SYSTEM; + } + + @Override + public String getEntityTable() { + return "counter"; + } +} diff --git a/api/src/com/cloud/api/commands/DeleteAutoScalePolicyCmd.java b/api/src/com/cloud/api/commands/DeleteAutoScalePolicyCmd.java new file mode 100644 index 00000000000..6d7ce5e8861 --- /dev/null +++ b/api/src/com/cloud/api/commands/DeleteAutoScalePolicyCmd.java @@ -0,0 +1,103 @@ +// 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.api.commands; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +import com.cloud.api.BaseAsyncCmd; +import com.cloud.api.BaseCmd; +import com.cloud.api.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.SuccessResponse; +import com.cloud.async.AsyncJob; +import com.cloud.event.EventTypes; +import com.cloud.network.as.AutoScalePolicy; +import com.cloud.user.Account; +import com.cloud.user.UserContext; + +@Implementation(description = "Deletes a autoscale policy.", responseObject = SuccessResponse.class) +public class DeleteAutoScalePolicyCmd extends BaseAsyncCmd { + public static final Logger s_logger = Logger.getLogger(DeleteAutoScalePolicyCmd.class.getName()); + private static final String s_name = "deleteautoscalepolicyresponse"; + // /////////////////////////////////////////////////// + // ////////////// API parameters ///////////////////// + // /////////////////////////////////////////////////// + + @IdentityMapper(entityTableName = "autoscale_policies") + @Parameter(name = ApiConstants.ID, type = CommandType.LONG, required = true, description = "the ID of the autoscale policy") + private Long id; + + // /////////////////////////////////////////////////// + // ///////////////// Accessors /////////////////////// + // /////////////////////////////////////////////////// + + public Long getId() { + return id; + } + + // /////////////////////////////////////////////////// + // ///////////// API Implementation/////////////////// + // /////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + AutoScalePolicy autoScalePolicy = _entityMgr.findById(AutoScalePolicy.class, getId()); + if (autoScalePolicy != null) { + return autoScalePolicy.getAccountId(); + } + + return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are +// tracked + } + + @Override + public String getEventType() { + return EventTypes.EVENT_AUTOSCALEPOLICY_DELETE; + } + + @Override + public String getEventDescription() { + return "deleting AutoScale Policy: " + getId(); + } + + @Override + public void execute() { + UserContext.current().setEventDetails("AutoScale Policy Id: " + getId()); + boolean result = _autoScaleService.deleteAutoScalePolicy(id); + + if (result) { + SuccessResponse response = new SuccessResponse(getCommandName()); + this.setResponseObject(response); + } else { + s_logger.warn("Failed to delete autoscale policy " + getId()); + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to delete AutoScale Policy"); + } + } + + @Override + public AsyncJob.Type getInstanceType() { + return AsyncJob.Type.AutoScalePolicy; + } +} diff --git a/api/src/com/cloud/api/commands/DeleteAutoScaleVmGroupCmd.java b/api/src/com/cloud/api/commands/DeleteAutoScaleVmGroupCmd.java new file mode 100644 index 00000000000..b97d734020b --- /dev/null +++ b/api/src/com/cloud/api/commands/DeleteAutoScaleVmGroupCmd.java @@ -0,0 +1,103 @@ +// 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.api.commands; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +import com.cloud.api.BaseAsyncCmd; +import com.cloud.api.BaseCmd; +import com.cloud.api.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.SuccessResponse; +import com.cloud.async.AsyncJob; +import com.cloud.event.EventTypes; +import com.cloud.network.as.AutoScaleVmGroup; +import com.cloud.user.Account; +import com.cloud.user.UserContext; + +@Implementation(description = "Deletes a autoscale vm group.", responseObject = SuccessResponse.class) +public class DeleteAutoScaleVmGroupCmd extends BaseAsyncCmd { + public static final Logger s_logger = Logger.getLogger(DeleteAutoScaleVmGroupCmd.class.getName()); + private static final String s_name = "deleteautoscalevmgroupresponse"; + // /////////////////////////////////////////////////// + // ////////////// API parameters ///////////////////// + // /////////////////////////////////////////////////// + + @IdentityMapper(entityTableName = "autoscale_vmgroups") + @Parameter(name = ApiConstants.ID, type = CommandType.LONG, required = true, description = "the ID of the autoscale group") + private Long id; + + // /////////////////////////////////////////////////// + // ///////////////// Accessors /////////////////////// + // /////////////////////////////////////////////////// + + public Long getId() { + return id; + } + + // /////////////////////////////////////////////////// + // ///////////// API Implementation/////////////////// + // /////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + AutoScaleVmGroup autoScaleVmGroup = _entityMgr.findById(AutoScaleVmGroup.class, getId()); + if (autoScaleVmGroup != null) { + return autoScaleVmGroup.getAccountId(); + } + + return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are +// tracked + } + + @Override + public String getEventType() { + return EventTypes.EVENT_AUTOSCALEVMGROUP_DELETE; + } + + @Override + public String getEventDescription() { + return "deleting autoscale vm group: " + getId(); + } + + @Override + public void execute() { + UserContext.current().setEventDetails("AutoScale Vm Group Id: " + getId()); + boolean result = _autoScaleService.deleteAutoScaleVmGroup(id); + + if (result) { + SuccessResponse response = new SuccessResponse(getCommandName()); + this.setResponseObject(response); + } else { + s_logger.warn("Failed to delete autoscale vm group " + getId()); + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to delete autoscale vm group"); + } + } + + @Override + public AsyncJob.Type getInstanceType() { + return AsyncJob.Type.AutoScalePolicy; + } +} diff --git a/api/src/com/cloud/api/commands/DeleteAutoScaleVmProfileCmd.java b/api/src/com/cloud/api/commands/DeleteAutoScaleVmProfileCmd.java new file mode 100644 index 00000000000..e248c8e2050 --- /dev/null +++ b/api/src/com/cloud/api/commands/DeleteAutoScaleVmProfileCmd.java @@ -0,0 +1,102 @@ +// 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.api.commands; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +import com.cloud.api.BaseAsyncCmd; +import com.cloud.api.BaseCmd; +import com.cloud.api.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.SuccessResponse; +import com.cloud.async.AsyncJob; +import com.cloud.event.EventTypes; +import com.cloud.network.as.AutoScaleVmProfile; +import com.cloud.user.Account; +import com.cloud.user.UserContext; + +@Implementation(description = "Deletes a autoscale vm profile.", responseObject = SuccessResponse.class) +public class DeleteAutoScaleVmProfileCmd extends BaseAsyncCmd { + public static final Logger s_logger = Logger.getLogger(DeleteAutoScaleVmProfileCmd.class.getName()); + private static final String s_name = "deleteautoscalevmprofileresponse"; + // /////////////////////////////////////////////////// + // ////////////// API parameters ///////////////////// + // /////////////////////////////////////////////////// + + @IdentityMapper(entityTableName = "autoscale_vmprofiles") + @Parameter(name = ApiConstants.ID, type = CommandType.LONG, required = true, description = "the ID of the autoscale profile") + private Long id; + + // /////////////////////////////////////////////////// + // ///////////////// Accessors /////////////////////// + // /////////////////////////////////////////////////// + + public Long getId() { + return id; + } + + // /////////////////////////////////////////////////// + // ///////////// API Implementation/////////////////// + // /////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + AutoScaleVmProfile autoScaleVmProfile = _entityMgr.findById(AutoScaleVmProfile.class, getId()); + if (autoScaleVmProfile != null) { + return autoScaleVmProfile.getAccountId(); + } + + return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are +// tracked + } + + @Override + public String getEventType() { + return EventTypes.EVENT_AUTOSCALEVMPROFILE_DELETE; + } + + @Override + public String getEventDescription() { + return "deleting autoscale vm profile: " + getId(); + } + + @Override + public void execute() { + UserContext.current().setEventDetails("AutoScale VM Profile Id: " + getId()); + boolean result = _autoScaleService.deleteAutoScaleVmProfile(id); + if (result) { + SuccessResponse response = new SuccessResponse(getCommandName()); + this.setResponseObject(response); + } else { + s_logger.warn("Failed to delete autoscale vm profile " + getId()); + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to delete autoscale vm profile"); + } + } + + @Override + public AsyncJob.Type getInstanceType() { + return AsyncJob.Type.AutoScaleVmProfile; + } +} diff --git a/api/src/com/cloud/api/commands/DeleteConditionCmd.java b/api/src/com/cloud/api/commands/DeleteConditionCmd.java new file mode 100644 index 00000000000..8d52ed89741 --- /dev/null +++ b/api/src/com/cloud/api/commands/DeleteConditionCmd.java @@ -0,0 +1,109 @@ +// 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.api.commands; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +import com.cloud.api.BaseAsyncCmd; +import com.cloud.api.BaseCmd; +import com.cloud.api.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.SuccessResponse; +import com.cloud.async.AsyncJob; +import com.cloud.event.EventTypes; +import com.cloud.exception.ResourceInUseException; +import com.cloud.network.as.Condition; +import com.cloud.user.Account; + +@Implementation(description = "Removes a condition", responseObject = SuccessResponse.class) +public class DeleteConditionCmd extends BaseAsyncCmd { + public static final Logger s_logger = Logger.getLogger(DeleteConditionCmd.class.getName()); + private static final String s_name = "deleteconditionresponse"; + + // /////////////////////////////////////////////////// + // ////////////// API parameters ///////////////////// + // /////////////////////////////////////////////////// + + @IdentityMapper(entityTableName = "conditions") + @Parameter(name = ApiConstants.ID, type = CommandType.LONG, required = true, description = "the ID of the condition.") + private Long id; + + // /////////////////////////////////////////////////// + // ///////////// API Implementation/////////////////// + // /////////////////////////////////////////////////// + + @Override + public void execute() { + boolean result = false; + try { + result = _autoScaleService.deleteCondition(getId()); + } catch (ResourceInUseException ex) { + s_logger.warn("Exception: ", ex); + throw new ServerApiException(BaseCmd.RESOURCE_IN_USE_ERROR, ex.getMessage()); + } + if (result) { + SuccessResponse response = new SuccessResponse(getCommandName()); + this.setResponseObject(response); + } else { + s_logger.warn("Failed to delete condition " + getId()); + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to delete condition."); + } + } + + // /////////////////////////////////////////////////// + // ///////////////// Accessors /////////////////////// + // /////////////////////////////////////////////////// + + public Long getId() { + return id; + } + + @Override + public AsyncJob.Type getInstanceType() { + return AsyncJob.Type.Condition; + } + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + Condition condition = _entityMgr.findById(Condition.class, getId()); + if (condition != null) { + return condition.getAccountId(); + } + + return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are + // tracked + } + + @Override + public String getEventType() { + return EventTypes.EVENT_CONDITION_DELETE; + } + + @Override + public String getEventDescription() { + return "Deleting a condition."; + } +} \ No newline at end of file diff --git a/api/src/com/cloud/api/commands/DeleteCounterCmd.java b/api/src/com/cloud/api/commands/DeleteCounterCmd.java new file mode 100644 index 00000000000..72d98bd72c2 --- /dev/null +++ b/api/src/com/cloud/api/commands/DeleteCounterCmd.java @@ -0,0 +1,103 @@ +// 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.api.commands; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +import com.cloud.api.BaseAsyncCmd; +import com.cloud.api.BaseCmd; +import com.cloud.api.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.SuccessResponse; +import com.cloud.async.AsyncJob; +import com.cloud.event.EventTypes; +import com.cloud.exception.ResourceInUseException; +import com.cloud.user.Account; + +@Implementation(description = "Deletes a counter", responseObject = SuccessResponse.class) +public class DeleteCounterCmd extends BaseAsyncCmd { + public static final Logger s_logger = Logger.getLogger(DeleteCounterCmd.class.getName()); + private static final String s_name = "deletecounterresponse"; + + // /////////////////////////////////////////////////// + // ////////////// API parameters ///////////////////// + // /////////////////////////////////////////////////// + + @IdentityMapper(entityTableName = "counter") + @Parameter(name = ApiConstants.ID, type = CommandType.LONG, required = true, description = "the ID of the counter") + private Long id; + + // /////////////////////////////////////////////////// + // ///////////// API Implementation/////////////////// + // /////////////////////////////////////////////////// + + @Override + public void execute() { + boolean result = false; + try { + result = _autoScaleService.deleteCounter(getId()); + } catch (ResourceInUseException ex) { + s_logger.warn("Exception: ", ex); + throw new ServerApiException(BaseCmd.RESOURCE_IN_USE_ERROR, ex.getMessage()); + } + + if (result) { + SuccessResponse response = new SuccessResponse(getCommandName()); + this.setResponseObject(response); + } else { + s_logger.warn("Failed to delete counter with Id: " + getId()); + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to delete counter."); + } + } + + // /////////////////////////////////////////////////// + // ///////////////// Accessors /////////////////////// + // /////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + public Long getId() { + return id; + } + + @Override + public AsyncJob.Type getInstanceType() { + return AsyncJob.Type.Counter; + } + + @Override + public long getEntityOwnerId() { + return Account.ACCOUNT_ID_SYSTEM; + } + + @Override + public String getEventType() { + return EventTypes.EVENT_COUNTER_DELETE; + } + + @Override + public String getEventDescription() { + return "Deleting a counter."; + } +} \ No newline at end of file diff --git a/api/src/com/cloud/api/commands/DisableAutoScaleVmGroupCmd.java b/api/src/com/cloud/api/commands/DisableAutoScaleVmGroupCmd.java new file mode 100644 index 00000000000..086cfd29044 --- /dev/null +++ b/api/src/com/cloud/api/commands/DisableAutoScaleVmGroupCmd.java @@ -0,0 +1,95 @@ +// 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.api.commands; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +import com.cloud.api.BaseAsyncCmd; +import com.cloud.api.BaseCmd; +import com.cloud.api.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.AutoScaleVmGroupResponse; +import com.cloud.event.EventTypes; +import com.cloud.network.as.AutoScaleVmGroup; +import com.cloud.user.Account; + +@Implementation(description = "Disables an AutoScale Vm Group", responseObject = AutoScaleVmGroupResponse.class) +public class DisableAutoScaleVmGroupCmd extends BaseAsyncCmd { + public static final Logger s_logger = Logger.getLogger(DisableAutoScaleVmGroupCmd.class.getName()); + private static final String s_name = "disableautoscalevmGroupresponse"; + + // /////////////////////////////////////////////////// + // ////////////// API parameters ///////////////////// + // /////////////////////////////////////////////////// + + @IdentityMapper(entityTableName="autoscale_vmgroups") + @Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="the ID of the autoscale group") + private Long id; + + // /////////////////////////////////////////////////// + // ///////////// API Implementation/////////////////// + // /////////////////////////////////////////////////// + + @Override + public void execute() { + AutoScaleVmGroup result = _autoScaleService.disableAutoScaleVmGroup(getId()); + if (result != null) { + AutoScaleVmGroupResponse response = _responseGenerator.createAutoScaleVmGroupResponse(result); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to disable AutoScale Vm Group"); + } + } + + // /////////////////////////////////////////////////// + // ///////////////// Accessors /////////////////////// + // /////////////////////////////////////////////////// + + public Long getId() { + return id; + } + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + AutoScaleVmGroup autoScaleVmGroup = _entityMgr.findById(AutoScaleVmGroup.class, getId()); + if (autoScaleVmGroup != null) { + return autoScaleVmGroup.getAccountId(); + } + return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are + // tracked + } + + @Override + public String getEventType() { + return EventTypes.EVENT_AUTOSCALEVMGROUP_DISABLE; + } + + @Override + public String getEventDescription() { + return "Disabling AutoScale Vm Group. Vm Group Id: " + getId(); + } +} diff --git a/api/src/com/cloud/api/commands/EnableAutoScaleVmGroupCmd.java b/api/src/com/cloud/api/commands/EnableAutoScaleVmGroupCmd.java new file mode 100644 index 00000000000..a7de00a859c --- /dev/null +++ b/api/src/com/cloud/api/commands/EnableAutoScaleVmGroupCmd.java @@ -0,0 +1,96 @@ +// 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.api.commands; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +import com.cloud.api.BaseAsyncCmd; +import com.cloud.api.BaseCmd; +import com.cloud.api.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.AutoScaleVmGroupResponse; +import com.cloud.event.EventTypes; +import com.cloud.network.as.AutoScaleVmGroup; +import com.cloud.user.Account; + +@Implementation(description = "Enables an AutoScale Vm Group", responseObject = AutoScaleVmGroupResponse.class) +public class EnableAutoScaleVmGroupCmd extends BaseAsyncCmd { + public static final Logger s_logger = Logger.getLogger(EnableAutoScaleVmGroupCmd.class.getName()); + private static final String s_name = "enableautoscalevmGroupresponse"; + + // /////////////////////////////////////////////////// + // ////////////// API parameters ///////////////////// + // /////////////////////////////////////////////////// + + @IdentityMapper(entityTableName="autoscale_vmgroups") + @Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="the ID of the autoscale group") + private Long id; + + // /////////////////////////////////////////////////// + // ///////////// API Implementation/////////////////// + // /////////////////////////////////////////////////// + + @Override + public void execute() { + AutoScaleVmGroup result = _autoScaleService.enableAutoScaleVmGroup(getId()); + if (result != null) { + AutoScaleVmGroupResponse response = _responseGenerator.createAutoScaleVmGroupResponse(result); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to enable AutoScale Vm Group"); + } + } + + // /////////////////////////////////////////////////// + // ///////////////// Accessors /////////////////////// + // /////////////////////////////////////////////////// + + public Long getId() { + return id; + } + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + AutoScaleVmGroup autoScaleVmGroup = _entityMgr.findById(AutoScaleVmGroup.class, getId()); + if (autoScaleVmGroup != null) { + return autoScaleVmGroup.getAccountId(); + } + return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are + // tracked + } + + @Override + public String getEventType() { + return EventTypes.EVENT_AUTOSCALEVMGROUP_ENABLE; + } + + @Override + public String getEventDescription() { + return "Enabling AutoScale Vm Group. Vm Group Id: "+getId(); + } + +} diff --git a/api/src/com/cloud/api/commands/ListAutoScalePoliciesCmd.java b/api/src/com/cloud/api/commands/ListAutoScalePoliciesCmd.java new file mode 100644 index 00000000000..1d61641530b --- /dev/null +++ b/api/src/com/cloud/api/commands/ListAutoScalePoliciesCmd.java @@ -0,0 +1,103 @@ +// 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.api.commands; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +import com.cloud.api.BaseListAccountResourcesCmd; +import com.cloud.api.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.response.AutoScalePolicyResponse; +import com.cloud.api.response.ListResponse; +import com.cloud.network.as.AutoScalePolicy; + +@Implementation(description = "Lists autoscale policies.", responseObject = AutoScalePolicyResponse.class) +public class ListAutoScalePoliciesCmd extends BaseListAccountResourcesCmd { + public static final Logger s_logger = Logger.getLogger(ListAutoScalePoliciesCmd.class.getName()); + + private static final String s_name = "listautoscalepoliciesresponse"; + + // /////////////////////////////////////////////////// + // ////////////// API parameters ///////////////////// + // /////////////////////////////////////////////////// + + @IdentityMapper(entityTableName = "autoscale_policies") + @Parameter(name = ApiConstants.ID, type = CommandType.LONG, description = "the ID of the autoscale policy") + private Long id; + + @IdentityMapper(entityTableName = "conditions") + @Parameter(name = ApiConstants.CONDITION_ID, type = CommandType.LONG, description = "the ID of the condition of the policy") + private Long conditionId; + + @Parameter(name = ApiConstants.ACTION, type = CommandType.STRING, required = true, description = "the action to be executed if all the conditions evaluate to true for the specified duration.") + private String action; + + @IdentityMapper(entityTableName="autoscale_vmgroups") + @Parameter(name = ApiConstants.VMGROUP_ID, type = CommandType.LONG, description = "the ID of the autoscale vm group") + private Long vmGroupId; + + // /////////////////////////////////////////////////// + // ///////////////// Accessors /////////////////////// + // /////////////////////////////////////////////////// + + public Long getId() { + return id; + } + + public Long getConditionId() { + return conditionId; + } + + public String getAction() { + return action; + } + + public Long getVmGroupId() { + return vmGroupId; + } + // /////////////////////////////////////////////////// + // ///////////// API Implementation/////////////////// + // /////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public void execute() { + List autoScalePolicies = _autoScaleService.listAutoScalePolicies(this); + ListResponse response = new ListResponse(); + List responses = new ArrayList(); + if (autoScalePolicies != null) { + for (AutoScalePolicy autoScalePolicy : autoScalePolicies) { + AutoScalePolicyResponse autoScalePolicyResponse = _responseGenerator.createAutoScalePolicyResponse(autoScalePolicy); + autoScalePolicyResponse.setObjectName("autoscalepolicy"); + responses.add(autoScalePolicyResponse); + } + } + response.setResponses(responses); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } + +} diff --git a/api/src/com/cloud/api/commands/ListAutoScaleVmGroupsCmd.java b/api/src/com/cloud/api/commands/ListAutoScaleVmGroupsCmd.java new file mode 100644 index 00000000000..0d1b2e00b11 --- /dev/null +++ b/api/src/com/cloud/api/commands/ListAutoScaleVmGroupsCmd.java @@ -0,0 +1,115 @@ +// 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.api.commands; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +import com.cloud.api.BaseListProjectAndAccountResourcesCmd; +import com.cloud.api.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.response.AutoScaleVmGroupResponse; +import com.cloud.api.response.ListResponse; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.network.as.AutoScaleVmGroup; + +@Implementation(description = "Lists autoscale vm groups.", responseObject = AutoScaleVmGroupResponse.class) +public class ListAutoScaleVmGroupsCmd extends BaseListProjectAndAccountResourcesCmd { + public static final Logger s_logger = Logger.getLogger(ListAutoScaleVmGroupsCmd.class.getName()); + + private static final String s_name = "listautoscalevmgroupsresponse"; + + // /////////////////////////////////////////////////// + // ////////////// API parameters ///////////////////// + // /////////////////////////////////////////////////// + + @IdentityMapper(entityTableName="autoscale_vmgroups") + @Parameter(name = ApiConstants.ID, type = CommandType.LONG, description = "the ID of the autoscale vm group") + private Long id; + + @IdentityMapper(entityTableName="firewall_rules") + @Parameter(name = ApiConstants.LBID, type = CommandType.LONG, description = "the ID of the loadbalancer") + private Long loadBalancerId; + + @IdentityMapper(entityTableName="autoscale_vmprofiles") + @Parameter(name = ApiConstants.VMPROFILE_ID, type = CommandType.LONG, description = "the ID of the profile") + private Long profileId; + + @IdentityMapper(entityTableName="autoscale_policies") + @Parameter(name = ApiConstants.POLICY_ID, type = CommandType.LONG, description = "the ID of the policy") + private Long policyId; + + @IdentityMapper(entityTableName="data_center") + @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.LONG, description = "the availability zone ID") + private Long zoneId; + // /////////////////////////////////////////////////// + // ///////////////// Accessors /////////////////////// + // /////////////////////////////////////////////////// + + public Long getId() { + return id; + } + + public Long getLoadBalancerId() { + return loadBalancerId; + } + + + public Long getProfileId() { + return profileId; + } + + public Long getPolicyId() { + return policyId; + } + + public Long getZoneId() { + return zoneId; + } + // /////////////////////////////////////////////////// + // ///////////// API Implementation/////////////////// + // /////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public void execute() { + if(id != null && (loadBalancerId != null || profileId != null || policyId != null)) + throw new InvalidParameterValueException("When id is specified other parameters need not be specified"); + + List autoScaleGroups = _autoScaleService.listAutoScaleVmGroups(this); + ListResponse response = new ListResponse(); + List responses = new ArrayList(); + if (autoScaleGroups != null) { + for (AutoScaleVmGroup autoScaleVmGroup : autoScaleGroups) { + AutoScaleVmGroupResponse autoScaleVmGroupResponse = _responseGenerator.createAutoScaleVmGroupResponse(autoScaleVmGroup); + autoScaleVmGroupResponse.setObjectName("autoscalevmgroup"); + responses.add(autoScaleVmGroupResponse); + } + } + response.setResponses(responses); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } +} diff --git a/api/src/com/cloud/api/commands/ListAutoScaleVmProfilesCmd.java b/api/src/com/cloud/api/commands/ListAutoScaleVmProfilesCmd.java new file mode 100644 index 00000000000..80348006b85 --- /dev/null +++ b/api/src/com/cloud/api/commands/ListAutoScaleVmProfilesCmd.java @@ -0,0 +1,95 @@ +// 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.api.commands; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +import com.cloud.api.BaseListProjectAndAccountResourcesCmd; +import com.cloud.api.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.response.AutoScaleVmProfileResponse; +import com.cloud.api.response.ListResponse; +import com.cloud.network.as.AutoScaleVmProfile; + +@Implementation(description = "Lists autoscale vm profiles.", responseObject = AutoScaleVmProfileResponse.class) +public class ListAutoScaleVmProfilesCmd extends BaseListProjectAndAccountResourcesCmd { + public static final Logger s_logger = Logger.getLogger(ListAutoScaleVmProfilesCmd.class.getName()); + + private static final String s_name = "listautoscalevmprofilesresponse"; + + // /////////////////////////////////////////////////// + // ////////////// API parameters ///////////////////// + // /////////////////////////////////////////////////// + + @IdentityMapper(entityTableName="autoscale_vmprofiles") + @Parameter(name = ApiConstants.ID, type = CommandType.LONG, description = "the ID of the autoscale vm profile") + private Long id; + + @IdentityMapper(entityTableName="vm_template") + @Parameter(name=ApiConstants.TEMPLATE_ID, type=CommandType.LONG, description="the templateid of the autoscale vm profile") + private Long templateId; + + @Parameter(name=ApiConstants.OTHER_DEPLOY_PARAMS, type=CommandType.STRING, description="the otherdeployparameters of the autoscale vm profile") + private String otherDeployParams; + // /////////////////////////////////////////////////// + // ///////////////// Accessors /////////////////////// + // /////////////////////////////////////////////////// + + public Long getId() { + return id; + } + + public Long getTemplateId() { + return templateId; + } + + public String getOtherDeployParams() { + return otherDeployParams; + } + + // /////////////////////////////////////////////////// + // ///////////// API Implementation/////////////////// + // /////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public void execute() { + List autoScaleProfiles = _autoScaleService.listAutoScaleVmProfiles(this); + ListResponse response = new ListResponse(); + List responses = new ArrayList(); + if (autoScaleProfiles != null) { + for (AutoScaleVmProfile autoScaleVmProfile : autoScaleProfiles) { + AutoScaleVmProfileResponse autoScaleVmProfileResponse = _responseGenerator.createAutoScaleVmProfileResponse(autoScaleVmProfile); + autoScaleVmProfileResponse.setObjectName("autoscalevmprofile"); + responses.add(autoScaleVmProfileResponse); + } + } + response.setResponses(responses); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } + +} diff --git a/api/src/com/cloud/api/commands/ListConditionsCmd.java b/api/src/com/cloud/api/commands/ListConditionsCmd.java new file mode 100644 index 00000000000..4140370392f --- /dev/null +++ b/api/src/com/cloud/api/commands/ListConditionsCmd.java @@ -0,0 +1,96 @@ +// 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.api.commands; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +import com.cloud.api.BaseListAccountResourcesCmd; +import com.cloud.api.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.response.ConditionResponse; +import com.cloud.api.response.CounterResponse; +import com.cloud.api.response.ListResponse; +import com.cloud.network.as.Condition; + +@Implementation(description = "List Conditions for the specific user", responseObject = CounterResponse.class) +public class ListConditionsCmd extends BaseListAccountResourcesCmd { + public static final Logger s_logger = Logger.getLogger(ListConditionsCmd.class.getName()); + private static final String s_name = "listconditionsresponse"; + + // /////////////////////////////////////////////////// + // ////////////// API parameters ///////////////////// + // /////////////////////////////////////////////////// + + @IdentityMapper(entityTableName = "conditions") + @Parameter(name = ApiConstants.ID, type = CommandType.LONG, required = false, description = "ID of the Condition.") + private Long id; + + @IdentityMapper(entityTableName = "counter") + @Parameter(name = ApiConstants.COUNTER_ID, type = CommandType.LONG, required = false, description = "Counter-id of the condition.") + private Long counterId; + + @IdentityMapper(entityTableName="autoscale_policies") + @Parameter(name = ApiConstants.POLICY_ID, type = CommandType.LONG, description = "the ID of the policy") + private Long policyId; + // /////////////////////////////////////////////////// + // ///////////// API Implementation/////////////////// + // /////////////////////////////////////////////////// + + @Override + public void execute() { + List conditions = null; + conditions = _autoScaleService.listConditions(this); + ListResponse response = new ListResponse(); + List cndnResponses = new ArrayList(); + for (Condition cndn : conditions) { + ConditionResponse cndnResponse = _responseGenerator.createConditionResponse(cndn); + cndnResponses.add(cndnResponse); + } + + response.setResponses(cndnResponses); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } + + // ///////////////////////////////////////////////// + // ///////////////// Accessors /////////////////////// + // /////////////////////////////////////////////////// + + public Long getId() { + return id; + } + + public Long getCounterId() { + return counterId; + } + + public Long getPolicyId() { + return policyId; + } + + @Override + public String getCommandName() { + return s_name; + } + +} \ No newline at end of file diff --git a/api/src/com/cloud/api/commands/ListCountersCmd.java b/api/src/com/cloud/api/commands/ListCountersCmd.java new file mode 100644 index 00000000000..f5c9d99e963 --- /dev/null +++ b/api/src/com/cloud/api/commands/ListCountersCmd.java @@ -0,0 +1,99 @@ +// 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.api.commands; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +import com.cloud.api.BaseListCmd; +import com.cloud.api.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.response.CounterResponse; +import com.cloud.api.response.ListResponse; +import com.cloud.network.as.Counter; +import com.cloud.user.Account; + +@Implementation(description = "List the counters", responseObject = CounterResponse.class) +public class ListCountersCmd extends BaseListCmd { + public static final Logger s_logger = Logger.getLogger(ListCountersCmd.class.getName()); + private static final String s_name = "counterresponse"; + + // /////////////////////////////////////////////////// + // ////////////// API parameters ///////////////////// + // /////////////////////////////////////////////////// + + @IdentityMapper(entityTableName = "counter") + @Parameter(name = ApiConstants.ID, type = CommandType.LONG, description = "ID of the Counter.") + private Long id; + + @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "Name of the counter.") + private String name; + + @Parameter(name = ApiConstants.SOURCE, type = CommandType.STRING, description = "Source of the counter.") + private String source; + + // /////////////////////////////////////////////////// + // ///////////// API Implementation/////////////////// + // /////////////////////////////////////////////////// + + @Override + public void execute() { + List counters = null; + counters = _autoScaleService.listCounters(this); + ListResponse response = new ListResponse(); + List ctrResponses = new ArrayList(); + for (Counter ctr : counters) { + CounterResponse ctrResponse = _responseGenerator.createCounterResponse(ctr); + ctrResponses.add(ctrResponse); + } + + response.setResponses(ctrResponses); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } + + // ///////////////////////////////////////////////// + // ///////////////// Accessors /////////////////////// + // /////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + public Long getId() { + return id; + } + + public String getName() { + return name; + } + + public String getSource() { + return source; + } + + @Override + public long getEntityOwnerId() { + return Account.ACCOUNT_ID_SYSTEM; + } +} \ No newline at end of file diff --git a/api/src/com/cloud/api/commands/UpdateAutoScalePolicyCmd.java b/api/src/com/cloud/api/commands/UpdateAutoScalePolicyCmd.java new file mode 100644 index 00000000000..6c1ccbb83f4 --- /dev/null +++ b/api/src/com/cloud/api/commands/UpdateAutoScalePolicyCmd.java @@ -0,0 +1,109 @@ +package com.cloud.api.commands; + +import java.util.List; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +import com.cloud.api.BaseAsyncCmd; +import com.cloud.api.BaseCmd; +import com.cloud.api.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.AutoScalePolicyResponse; +import com.cloud.async.AsyncJob; +import com.cloud.event.EventTypes; +import com.cloud.network.as.AutoScalePolicy; +import com.cloud.user.Account; +import com.cloud.user.UserContext; + +@Implementation(description = "Updates an existing autoscale policy.", responseObject = AutoScalePolicyResponse.class) +public class UpdateAutoScalePolicyCmd extends BaseAsyncCmd { + public static final Logger s_logger = Logger.getLogger(UpdateAutoScalePolicyCmd.class.getName()); + + private static final String s_name = "updateautoscalepolicyresponse"; + + // /////////////////////////////////////////////////// + // ////////////// API parameters ///////////////////// + // /////////////////////////////////////////////////// + + @Parameter(name = ApiConstants.DURATION, type = CommandType.INTEGER, description = "the duration for which the conditions have to be true before action is taken") + private Integer duration; + + @Parameter(name = ApiConstants.QUIETTIME, type = CommandType.INTEGER, description = "the cool down period for which the policy should not be evaluated after the action has been taken") + private Integer quietTime; + + @IdentityMapper(entityTableName = "conditions") + @Parameter(name = ApiConstants.CONDITION_IDS, type = CommandType.LIST, collectionType = CommandType.LONG, description = "the list of IDs of the conditions that are being evaluated on every interval") + private List conditionIds; + + @IdentityMapper(entityTableName = "autoscale_policies") + @Parameter(name = ApiConstants.ID, type = CommandType.LONG, required = true, description = "the ID of the autoscale policy") + private Long id; + + @Override + public void execute() { + UserContext.current().setEventDetails("AutoScale Policy Id: " + getId()); + AutoScalePolicy result = _autoScaleService.updateAutoScalePolicy(this); + if (result != null) { + AutoScalePolicyResponse response = _responseGenerator.createAutoScalePolicyResponse(result); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to update autoscale policy"); + } + } + + // /////////////////////////////////////////////////// + // ///////////////// Accessors /////////////////////// + // /////////////////////////////////////////////////// + + public Long getId() { + return id; + } + + public Integer getDuration() { + return duration; + } + + public Integer getQuietTime() { + return quietTime; + } + + + public List getConditionIds() { + return conditionIds; + } + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + AutoScalePolicy autoScalePolicy = _entityMgr.findById(AutoScalePolicy.class, getId()); + if (autoScalePolicy != null) { + return autoScalePolicy.getAccountId(); + } + + return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are + // tracked + } + + @Override + public String getEventType() { + return EventTypes.EVENT_AUTOSCALEPOLICY_UPDATE; + } + + @Override + public String getEventDescription() { + return "Updating Auto Scale Policy. Policy Id: " + getId(); + } + + @Override + public AsyncJob.Type getInstanceType() { + return AsyncJob.Type.AutoScalePolicy; + } +} diff --git a/api/src/com/cloud/api/commands/UpdateAutoScaleVmGroupCmd.java b/api/src/com/cloud/api/commands/UpdateAutoScaleVmGroupCmd.java new file mode 100644 index 00000000000..a2a938fa0a6 --- /dev/null +++ b/api/src/com/cloud/api/commands/UpdateAutoScaleVmGroupCmd.java @@ -0,0 +1,143 @@ +// 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.api.commands; + +import java.util.List; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +import com.cloud.api.BaseAsyncCmd; +import com.cloud.api.BaseCmd; +import com.cloud.api.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.AutoScaleVmGroupResponse; +import com.cloud.async.AsyncJob; +import com.cloud.event.EventTypes; +import com.cloud.network.as.AutoScaleVmGroup; +import com.cloud.user.Account; +import com.cloud.user.UserContext; + +@Implementation(description = "Updates an existing autoscale vm group.", responseObject = AutoScaleVmGroupResponse.class) +public class UpdateAutoScaleVmGroupCmd extends BaseAsyncCmd { + public static final Logger s_logger = Logger.getLogger(UpdateAutoScaleVmGroupCmd.class.getName()); + + private static final String s_name = "updateautoscalevmgroupresponse"; + + // /////////////////////////////////////////////////// + // ////////////// API parameters ///////////////////// + // /////////////////////////////////////////////////// + + @Parameter(name = ApiConstants.MIN_MEMBERS, type = CommandType.INTEGER, description = "the minimum number of members in the vmgroup, the number of instances in the vm group will be equal to or more than this number.") + private Integer minMembers; + + @Parameter(name = ApiConstants.MAX_MEMBERS, type = CommandType.INTEGER, description = "the maximum number of members in the vmgroup, The number of instances in the vm group will be equal to or less than this number.") + private Integer maxMembers; + + @Parameter(name=ApiConstants.INTERVAL, type=CommandType.INTEGER, description="the frequency at which the conditions have to be evaluated") + private Integer interval; + + @IdentityMapper(entityTableName = "autoscale_policies") + @Parameter(name = ApiConstants.SCALEUP_POLICY_IDS, type = CommandType.LIST, collectionType = CommandType.LONG, description = "list of scaleup autoscale policies") + private List scaleUpPolicyIds; + + @IdentityMapper(entityTableName = "autoscale_policies") + @Parameter(name = ApiConstants.SCALEDOWN_POLICY_IDS, type = CommandType.LIST, collectionType = CommandType.LONG, description = "list of scaledown autoscale policies") + private List scaleDownPolicyIds; + + @IdentityMapper(entityTableName = "autoscale_vmgroups") + @Parameter(name = ApiConstants.ID, type = CommandType.LONG, required = true, description = "the ID of the autoscale group") + private Long id; + + // /////////////////////////////////////////////////// + // ///////////// API Implementation/////////////////// + // /////////////////////////////////////////////////// + + @Override + public void execute() { + UserContext.current().setEventDetails("AutoScale Vm Group Id: " + getId()); + AutoScaleVmGroup result = _autoScaleService.updateAutoScaleVmGroup(this); + if (result != null) { + AutoScaleVmGroupResponse response = _responseGenerator.createAutoScaleVmGroupResponse(result); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to update autoscale VmGroup"); + } + } + + // /////////////////////////////////////////////////// + // ///////////////// Accessors /////////////////////// + // /////////////////////////////////////////////////// + + public Long getId() { + return id; + } + + public Integer getMinMembers() { + return minMembers; + } + + public Integer getMaxMembers() { + return maxMembers; + } + + public Integer getInterval() { + return interval; + } + + public List getScaleUpPolicyIds() { + return scaleUpPolicyIds; + } + + public List getScaleDownPolicyIds() { + return scaleDownPolicyIds; + } + + @Override + public String getEventType() { + return EventTypes.EVENT_AUTOSCALEVMGROUP_UPDATE; + } + + @Override + public String getEventDescription() { + return "Updating AutoScale Vm Group. Vm Group Id: "+getId(); + } + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + AutoScaleVmGroup autoScaleVmGroup = _entityMgr.findById(AutoScaleVmGroup.class, getId()); + if (autoScaleVmGroup != null) { + return autoScaleVmGroup.getAccountId(); + } + return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are + // tracked + } + + @Override + public AsyncJob.Type getInstanceType() { + return AsyncJob.Type.AutoScaleVmGroup; + } +} diff --git a/api/src/com/cloud/api/commands/UpdateAutoScaleVmProfileCmd.java b/api/src/com/cloud/api/commands/UpdateAutoScaleVmProfileCmd.java new file mode 100644 index 00000000000..b6f32872544 --- /dev/null +++ b/api/src/com/cloud/api/commands/UpdateAutoScaleVmProfileCmd.java @@ -0,0 +1,141 @@ +// 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.api.commands; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +import com.cloud.api.BaseAsyncCmd; +import com.cloud.api.BaseCmd; +import com.cloud.api.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.AutoScaleVmProfileResponse; +import com.cloud.async.AsyncJob; +import com.cloud.event.EventTypes; +import com.cloud.network.as.AutoScaleVmProfile; +import com.cloud.user.Account; +import com.cloud.user.UserContext; + +@Implementation(description = "Updates an existing autoscale vm profile.", responseObject = AutoScaleVmProfileResponse.class) +public class UpdateAutoScaleVmProfileCmd extends BaseAsyncCmd { + public static final Logger s_logger = Logger.getLogger(UpdateAutoScaleVmProfileCmd.class.getName()); + + private static final String s_name = "updateautoscalevmprofileresponse"; + + // /////////////////////////////////////////////////// + // ////////////// API parameters ///////////////////// + // /////////////////////////////////////////////////// + + @IdentityMapper(entityTableName = "autoscale_vmprofiles") + @Parameter(name = ApiConstants.ID, type = CommandType.LONG, required = true, description = "the ID of the autoscale vm profile") + private Long id; + + @IdentityMapper(entityTableName = "vm_template") + @Parameter(name = ApiConstants.TEMPLATE_ID, type = CommandType.LONG, description = "the template of the auto deployed virtual machine") + private Long templateId; + + @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; + + @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") + private Long autoscaleUserId; + + // /////////////////////////////////////////////////// + // ///////////// API Implementation/////////////////// + // /////////////////////////////////////////////////// + + @Override + public void execute() { + UserContext.current().setEventDetails("AutoScale Policy Id: " + getId()); + AutoScaleVmProfile result = _autoScaleService.updateAutoScaleVmProfile(this); + if (result != null) { + AutoScaleVmProfileResponse response = _responseGenerator.createAutoScaleVmProfileResponse(result); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to update autoscale vm profile"); + } + } + + // /////////////////////////////////////////////////// + // ///////////////// Accessors /////////////////////// + // /////////////////////////////////////////////////// + + public Long getId() { + return id; + } + + public Long getTemplateId() { + return templateId; + } + + public Integer getSnmpPort() { + return snmpPort; + } + + public String getSnmpCommunity() { + return snmpCommunity; + } + + public Long getAutoscaleUserId() { + return autoscaleUserId; + } + + public Integer getDestroyVmGraceperiod() { + return destroyVmGraceperiod; + } + + @Override + public String getEventType() { + return EventTypes.EVENT_AUTOSCALEVMPROFILE_UPDATE; + } + + @Override + public String getEventDescription() { + return "Updating AutoScale Vm Profile. Vm Profile Id: " + getId(); + } + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + AutoScaleVmProfile vmProfile = _entityMgr.findById(AutoScaleVmProfile.class, getId()); + if (vmProfile != null) { + return vmProfile.getAccountId(); + } + return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are + // tracked + } + + @Override + public AsyncJob.Type getInstanceType() { + return AsyncJob.Type.AutoScaleVmProfile; + } +} diff --git a/api/src/com/cloud/api/response/AutoScalePolicyResponse.java b/api/src/com/cloud/api/response/AutoScalePolicyResponse.java new file mode 100644 index 00000000000..2fa3ad312fc --- /dev/null +++ b/api/src/com/cloud/api/response/AutoScalePolicyResponse.java @@ -0,0 +1,107 @@ +// 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.api.response; + +import com.cloud.api.ApiConstants; +import com.cloud.utils.IdentityProxy; +import com.cloud.serializer.Param; +import com.google.gson.annotations.SerializedName; + +import java.util.List; + +public class AutoScalePolicyResponse extends BaseResponse implements ControlledEntityResponse { + + @SerializedName(ApiConstants.ID) + @Param(description = "the autoscale policy ID") + private IdentityProxy id = new IdentityProxy("autoscale_policies"); + + @SerializedName(ApiConstants.ACTION) + @Param(description = "the action to be executed if all the conditions evaluate to true for the specified duration.") + private String action; + + @SerializedName(ApiConstants.DURATION) + @Param(description = "the duration for which the conditions have to be true before action is taken") + private Integer duration; + + @SerializedName(ApiConstants.QUIETTIME) + @Param(description = "the cool down period for which the policy should not be evaluated after the action has been taken") + private Integer quietTime; + + @SerializedName("conditions") + @Param(description = "the list of IDs of the conditions that are being evaluated on every interval") + private List conditions; + + @SerializedName(ApiConstants.ACCOUNT) @Param(description="the account owning the autoscale policy") + private String accountName; + + @SerializedName(ApiConstants.PROJECT_ID) @Param(description="the project id autoscale policy") + private IdentityProxy projectId = new IdentityProxy("projects"); + + @SerializedName(ApiConstants.PROJECT) @Param(description="the project name of the autoscale policy") + private String projectName; + + @SerializedName(ApiConstants.DOMAIN_ID) @Param(description="the domain ID of the autoscale policy") + private IdentityProxy domainId = new IdentityProxy("domain"); + + @SerializedName(ApiConstants.DOMAIN) @Param(description="the domain name of the autoscale policy") + private String domainName; + + public void setId(Long id) { + this.id.setValue(id); + } + + public void setDuration(Integer duration) { + this.duration = duration; + } + + public void setQuietTime(Integer quietTime) { + this.quietTime = quietTime; + } + + public void setAction(String action) { + this.action = action; + } + + public void setConditions(List conditions) { + this.conditions = conditions; + } + + @Override + public void setAccountName(String accountName) { + this.accountName = accountName; + } + + @Override + public void setDomainId(Long domainId) { + this.domainId.setValue(domainId); + } + + @Override + public void setDomainName(String domainName) { + this.domainName = domainName; + } + + @Override + public void setProjectId(Long projectId) { + this.projectId.setValue(projectId); + } + + @Override + public void setProjectName(String projectName) { + this.projectName = projectName; + } +} diff --git a/api/src/com/cloud/api/response/AutoScaleVmGroupResponse.java b/api/src/com/cloud/api/response/AutoScaleVmGroupResponse.java new file mode 100644 index 00000000000..d0d249d6f71 --- /dev/null +++ b/api/src/com/cloud/api/response/AutoScaleVmGroupResponse.java @@ -0,0 +1,143 @@ +// 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.api.response; + +import com.cloud.api.ApiConstants; +import com.cloud.utils.IdentityProxy; +import com.cloud.serializer.Param; +import com.google.gson.annotations.SerializedName; + +import java.util.List; + +public class AutoScaleVmGroupResponse extends BaseResponse implements ControlledEntityResponse { + + @SerializedName(ApiConstants.ID) + @Param(description = "the autoscale vm group ID") + private IdentityProxy id = new IdentityProxy("autoscale_vmgroups"); + + @SerializedName(ApiConstants.LBID) + @Param(description = "the load balancer rule ID") + private IdentityProxy loadBalancerId = new IdentityProxy("firewall_rules"); + + @SerializedName(ApiConstants.VMPROFILE_ID) + @Param(description = "the autoscale profile that contains information about the vms in the vm group.") + private IdentityProxy profileId = new IdentityProxy("autoscale_vmprofiles"); + + @SerializedName(ApiConstants.MIN_MEMBERS) + @Param(description = "the minimum number of members in the vmgroup, the number of instances in the vm group will be equal to or more than this number.") + private int minMembers; + + @SerializedName(ApiConstants.MAX_MEMBERS) + @Param(description = "the maximum number of members in the vmgroup, The number of instances in the vm group will be equal to or less than this number.") + private int maxMembers; + + @SerializedName(ApiConstants.INTERVAL) + @Param(description = "the frequency at which the conditions have to be evaluated") + private int interval; + + @SerializedName(ApiConstants.STATE) + @Param(description = "the current state of the AutoScale Vm Group") + private String state; + + @SerializedName(ApiConstants.SCALEUP_POLICIES) + @Param(description = "list of scaleup autoscale policies") + private List scaleUpPolicies; + + @SerializedName(ApiConstants.SCALEDOWN_POLICIES) + @Param(description = "list of scaledown autoscale policies") + private List scaleDownPolicies; + + @SerializedName(ApiConstants.ACCOUNT) @Param(description="the account owning the instance group") + private String accountName; + + @SerializedName(ApiConstants.PROJECT_ID) @Param(description="the project id vm profile") + private IdentityProxy projectId = new IdentityProxy("projects"); + + @SerializedName(ApiConstants.PROJECT) @Param(description="the project name of the vm profile") + private String projectName; + + @SerializedName(ApiConstants.DOMAIN_ID) @Param(description="the domain ID of the vm profile") + private IdentityProxy domainId = new IdentityProxy("domain"); + + @SerializedName(ApiConstants.DOMAIN) @Param(description="the domain name of the vm profile") + private String domainName; + + public AutoScaleVmGroupResponse() { + + } + + public void setId(Long id) { + this.id.setValue(id); + } + + public void setLoadBalancerId(Long loadBalancerId) { + this.loadBalancerId.setValue(loadBalancerId); + } + + public void setProfileId(Long profileId) { + this.profileId.setValue(profileId); + } + + public void setMinMembers(int minMembers) { + this.minMembers = minMembers; + } + + public void setMaxMembers(int maxMembers) { + this.maxMembers = maxMembers; + } + + public void setState(String state) { + this.state = state; + } + + public void setInterval(int interval) { + this.interval = interval; + } + + public void setScaleUpPolicies(List scaleUpPolicies) { + this.scaleUpPolicies = scaleUpPolicies; + } + + public void setScaleDownPolicies(List scaleDownPolicies) { + this.scaleDownPolicies = scaleDownPolicies; + } + + @Override + public void setAccountName(String accountName) { + this.accountName = accountName; + } + + @Override + public void setDomainId(Long domainId) { + this.domainId.setValue(domainId); + } + + @Override + public void setDomainName(String domainName) { + this.domainName = domainName; + } + + @Override + public void setProjectId(Long projectId) { + this.projectId.setValue(projectId); + } + + @Override + public void setProjectName(String projectName) { + this.projectName = projectName; + } +} diff --git a/api/src/com/cloud/api/response/AutoScaleVmProfileResponse.java b/api/src/com/cloud/api/response/AutoScaleVmProfileResponse.java new file mode 100644 index 00000000000..842fa3ad2ee --- /dev/null +++ b/api/src/com/cloud/api/response/AutoScaleVmProfileResponse.java @@ -0,0 +1,158 @@ +// 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.api.response; + +import com.cloud.api.ApiConstants; +import com.cloud.api.Parameter; +import com.cloud.api.BaseCmd.CommandType; +import com.cloud.serializer.Param; +import com.cloud.utils.IdentityProxy; +import com.google.gson.annotations.SerializedName; + +public class AutoScaleVmProfileResponse extends BaseResponse implements ControlledEntityResponse { + + @SerializedName(ApiConstants.ID) + @Param(description = "the autoscale vm profile ID") + private IdentityProxy id = new IdentityProxy("autoscale_vmprofiles"); + + /* Parameters related to deploy virtual machine */ + @SerializedName(ApiConstants.ZONE_ID) + @Param(description = "the availability zone to be used while deploying a virtual machine") + private IdentityProxy zoneId = new IdentityProxy("data_center"); + + @SerializedName(ApiConstants.SERVICE_OFFERING_ID) + @Param(description = "the service offering to be used while deploying a virtual machine") + private IdentityProxy serviceOfferingId = new IdentityProxy("disk_offering"); + + @SerializedName(ApiConstants.TEMPLATE_ID) + @Param(description = "the template to be used while deploying a virtual machine") + private IdentityProxy templateId = new IdentityProxy("vm_template"); + + @SerializedName(ApiConstants.OTHER_DEPLOY_PARAMS) + @Param(description = "parameters other than zoneId/serviceOfferringId/templateId to be used while deploying a virtual machine") + private String otherDeployParams; + + /* Parameters related to destroying a virtual machine */ + @SerializedName(ApiConstants.AUTOSCALE_VM_DESTROY_TIME) + @Param(description = "the time allowed for existing connections to get closed before a vm is destroyed") + 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.AUTOSCALE_USER_ID) + @Param(description = "the ID of the user used to launch and destroy the VMs") + private IdentityProxy autoscaleUserId = new IdentityProxy("user"); + + @Parameter(name = ApiConstants.CS_URL, type = CommandType.STRING, description = "the API URL including port of the CloudStack Management Server example: http://server.cloud.com:8080/client/api?") + private String csUrl; + + @SerializedName(ApiConstants.ACCOUNT) + @Param(description = "the account owning the instance group") + private String accountName; + + @SerializedName(ApiConstants.PROJECT_ID) + @Param(description = "the project id vm profile") + private IdentityProxy projectId = new IdentityProxy("projects"); + + @SerializedName(ApiConstants.PROJECT) + @Param(description = "the project name of the vm profile") + private String projectName; + + @SerializedName(ApiConstants.DOMAIN_ID) + @Param(description = "the domain ID of the vm profile") + private IdentityProxy domainId = new IdentityProxy("domain"); + + @SerializedName(ApiConstants.DOMAIN) + @Param(description = "the domain name of the vm profile") + private String domainName; + + public AutoScaleVmProfileResponse() { + + } + + public void setId(Long id) { + this.id.setValue(id); + } + + public void setZoneId(Long zoneId) { + this.zoneId.setValue(zoneId); + } + + public void setServiceOfferingId(Long serviceOfferingId) { + this.serviceOfferingId.setValue(serviceOfferingId); + } + + public void setTemplateId(Long templateId) { + this.templateId.setValue(templateId); + } + + public void setOtherDeployParams(String otherDeployParams) { + this.otherDeployParams = otherDeployParams; + } + + public void setSnmpCommunity(String snmpCommunity) { + this.snmpCommunity = snmpCommunity; + } + + public void setSnmpPort(Integer snmpPort) { + this.snmpPort = snmpPort; + } + + @Override + public void setAccountName(String accountName) { + this.accountName = accountName; + } + + @Override + public void setDomainId(Long domainId) { + this.domainId.setValue(domainId); + } + + @Override + public void setDomainName(String domainName) { + this.domainName = domainName; + } + + @Override + public void setProjectId(Long projectId) { + this.projectId.setValue(projectId); + } + + @Override + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + public void setAutoscaleUserId(Long autoscaleUserId) { + this.autoscaleUserId.setValue(autoscaleUserId); + } + + public void setDestroyVmGraceperiod(Integer destroyVmGraceperiod) { + this.destroyVmGraceperiod = destroyVmGraceperiod; + } + + public void setCsUrl(String csUrl) { + this.csUrl = csUrl; + } +} diff --git a/api/src/com/cloud/api/response/ConditionResponse.java b/api/src/com/cloud/api/response/ConditionResponse.java new file mode 100644 index 00000000000..d2922d6c648 --- /dev/null +++ b/api/src/com/cloud/api/response/ConditionResponse.java @@ -0,0 +1,115 @@ +// 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.api.response; + +import com.cloud.api.ApiConstants; +import com.cloud.serializer.Param; +import com.cloud.utils.IdentityProxy; +import com.google.gson.annotations.SerializedName; + +@SuppressWarnings("unused") +public class ConditionResponse extends BaseResponse implements ControlledEntityResponse { + @SerializedName("id") + @Param(description = "the id of the Condition") + private final IdentityProxy id = new IdentityProxy("conditions"); + + @SerializedName(value = ApiConstants.THRESHOLD) + @Param(description = "Threshold Value for the counter.") + private long threshold; + + @SerializedName(value = ApiConstants.RELATIONAL_OPERATOR) + @Param(description = "Relational Operator to be used with threshold.") + private String relationalOperator; + + @SerializedName("counter") + @Param(description = "Details of the Counter.") + private CounterResponse counter; + + @SerializedName(ApiConstants.DOMAIN_ID) + @Param(description = "the domain id of the Condition owner") + private final IdentityProxy domainId = new IdentityProxy("domain"); + + @SerializedName(ApiConstants.DOMAIN) + @Param(description = "the domain name of the owner.") + private String domain; + + @SerializedName(ApiConstants.ZONE_ID) + @Param(description = "zone id of counter") + private final IdentityProxy zoneId = new IdentityProxy("data_center"); + + @SerializedName(ApiConstants.PROJECT_ID) + @Param(description = "the project id of the Condition.") + private final IdentityProxy projectId = new IdentityProxy("projects"); + + @SerializedName(ApiConstants.PROJECT) + @Param(description = "the project name of the Condition") + private String projectName; + + @SerializedName(ApiConstants.ACCOUNT) + @Param(description = "the owner of the Condition.") + private String accountName; + + // ///////////////////////////////////////////////// + // ///////////////// Setters /////////////////////// + // /////////////////////////////////////////////////// + + public void setId(Long id) { + this.id.setValue(id); + } + + public void setThreshold(long threshold) { + this.threshold = threshold; + } + + public void setRelationalOperator(String relationalOperator) { + this.relationalOperator = relationalOperator; + } + + public void setCounter(CounterResponse counter) { + this.counter = counter; + } + + @Override + public void setAccountName(String accountName) { + this.accountName = accountName; + } + + @Override + public void setProjectId(Long projectId) { + this.projectId.setValue(projectId); + } + + public void setZoneId(Long zoneId) { + this.zoneId.setValue(zoneId); + } + + @Override + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + @Override + public void setDomainId(Long domainId) { + this.domainId.setValue(domainId); + } + + @Override + public void setDomainName(String domainName) { + this.domain = domainName; + } +} \ No newline at end of file diff --git a/api/src/com/cloud/api/response/CounterResponse.java b/api/src/com/cloud/api/response/CounterResponse.java new file mode 100644 index 00000000000..aaea8e6bb32 --- /dev/null +++ b/api/src/com/cloud/api/response/CounterResponse.java @@ -0,0 +1,62 @@ +// 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.api.response; + +import com.cloud.api.ApiConstants; +import com.cloud.serializer.Param; +import com.cloud.utils.IdentityProxy; +import com.google.gson.annotations.SerializedName; + +@SuppressWarnings("unused") +public class CounterResponse extends BaseResponse { + @SerializedName("id") + @Param(description = "the id of the Counter") + private final IdentityProxy id = new IdentityProxy("counter"); + + @SerializedName(value = ApiConstants.NAME) + @Param(description = "Name of the counter.") + private String name; + + @SerializedName(value = ApiConstants.SOURCE) + @Param(description = "Source of the counter.") + private String source; + + @SerializedName(value = ApiConstants.VALUE) + @Param(description = "Value in case of snmp or other specific counters.") + private String value; + + @SerializedName(ApiConstants.ZONE_ID) + @Param(description = "zone id of counter") + private final IdentityProxy zoneId = new IdentityProxy("data_center"); + + public void setId(Long id) { + this.id.setValue(id); + } + + public void setName(String name) { + this.name = name; + } + + public void setSource(String source) { + this.source = source; + } + + public void setValue(String value) { + this.value = value; + } +} \ No newline at end of file diff --git a/api/src/com/cloud/async/AsyncJob.java b/api/src/com/cloud/async/AsyncJob.java index 10279c5219e..b8551edc83e 100644 --- a/api/src/com/cloud/async/AsyncJob.java +++ b/api/src/com/cloud/async/AsyncJob.java @@ -42,7 +42,12 @@ public interface AsyncJob extends Identity { Account, User, PrivateGateway, - StaticRoute + StaticRoute, + Counter, + Condition, + AutoScalePolicy, + AutoScaleVmProfile, + AutoScaleVmGroup } Long getId(); diff --git a/api/src/com/cloud/event/EventTypes.java b/api/src/com/cloud/event/EventTypes.java index 9e6b36b780b..362ce11fac9 100755 --- a/api/src/com/cloud/event/EventTypes.java +++ b/api/src/com/cloud/event/EventTypes.java @@ -263,7 +263,7 @@ public class EventTypes { public static final String EVENT_EXTERNAL_SWITCH_MGMT_DEVICE_ENABLE = "SWITCH.MGMT.ENABLE"; public static final String EVENT_EXTERNAL_SWITCH_MGMT_DEVICE_DISABLE = "SWITCH.MGMT.DISABLE"; - + public static final String EVENT_EXTERNAL_FIREWALL_DEVICE_ADD = "PHYSICAL.FIREWALL.ADD"; public static final String EVENT_EXTERNAL_FIREWALL_DEVICE_DELETE = "PHYSICAL.FIREWALL.DELETE"; public static final String EVENT_EXTERNAL_FIREWALL_DEVICE_CONFIGURE = "PHYSICAL.FIREWALL.CONFIGURE"; @@ -296,4 +296,21 @@ public class EventTypes { public static final String EVENT_EXTERNAL_NVP_CONTROLLER_DELETE = "PHYSICAL.NVPCONTROLLER.DELETE"; public static final String EVENT_EXTERNAL_NVP_CONTROLLER_CONFIGURE = "PHYSICAL.NVPCONTROLLER.CONFIGURE"; + // AutoScale + public static final String EVENT_COUNTER_CREATE = "COUNTER.CREATE"; + public static final String EVENT_COUNTER_DELETE = "COUNTER.DELETE"; + public static final String EVENT_CONDITION_CREATE = "CONDITION.CREATE"; + public static final String EVENT_CONDITION_DELETE = "CONDITION.DELETE"; + public static final String EVENT_AUTOSCALEPOLICY_CREATE = "AUTOSCALEPOLICY.CREATE"; + public static final String EVENT_AUTOSCALEPOLICY_UPDATE = "AUTOSCALEPOLICY.UPDATE"; + public static final String EVENT_AUTOSCALEPOLICY_DELETE = "AUTOSCALEPOLICY.DELETE"; + public static final String EVENT_AUTOSCALEVMPROFILE_CREATE = "AUTOSCALEVMPROFILE.CREATE"; + public static final String EVENT_AUTOSCALEVMPROFILE_DELETE = "AUTOSCALEVMPROFILE.DELETE"; + public static final String EVENT_AUTOSCALEVMPROFILE_UPDATE = "AUTOSCALEVMPROFILE.UPDATE"; + public static final String EVENT_AUTOSCALEVMGROUP_CREATE = "AUTOSCALEVMGROUP.CREATE"; + public static final String EVENT_AUTOSCALEVMGROUP_DELETE = "AUTOSCALEVMGROUP.DELETE"; + public static final String EVENT_AUTOSCALEVMGROUP_UPDATE = "AUTOSCALEVMGROUP.UPDATE"; + public static final String EVENT_AUTOSCALEVMGROUP_ENABLE = "AUTOSCALEVMGROUP.ENABLE"; + public static final String EVENT_AUTOSCALEVMGROUP_DISABLE = "AUTOSCALEVMGROUP.DIABLE"; + } diff --git a/api/src/com/cloud/network/Network.java b/api/src/com/cloud/network/Network.java index 75d94ee163f..d38f7401682 100644 --- a/api/src/com/cloud/network/Network.java +++ b/api/src/com/cloud/network/Network.java @@ -29,10 +29,10 @@ import com.cloud.utils.fsm.FiniteState; import com.cloud.utils.fsm.StateMachine; /** - * owned by an account. + * owned by an account. */ public interface Network extends ControlledEntity { - + public enum GuestType { Shared, Isolated @@ -58,6 +58,7 @@ public interface Network extends ControlledEntity { public static final Service NetworkACL = new Service("NetworkACL", Capability.SupportedProtocols); public static final Service Connectivity = new Service("Connectivity"); + private String name; private Capability[] caps; @@ -65,7 +66,7 @@ public interface Network extends ControlledEntity { this.name = name; this.caps = caps; supportedServices.add(this); - } + } public String getName() { return name; @@ -85,11 +86,11 @@ public interface Network extends ControlledEntity { break; } } - } + } return success; } - + public static Service getService(String serviceName) { for (Service service : supportedServices) { if (service.getName().equalsIgnoreCase(serviceName)) { @@ -98,7 +99,7 @@ public interface Network extends ControlledEntity { } return null; } - + public static List listAllServices(){ return supportedServices; } @@ -109,7 +110,7 @@ public interface Network extends ControlledEntity { */ public static class Provider { private static List supportedProviders = new ArrayList(); - + public static final Provider VirtualRouter = new Provider("VirtualRouter", false); public static final Provider JuniperSRX = new Provider("JuniperSRX", true); public static final Provider F5BigIp = new Provider("F5BigIp", true); @@ -135,11 +136,11 @@ public interface Network extends ControlledEntity { public String getName() { return name; } - + public boolean isExternal() { return isExternal; } - + public static Provider getProvider(String providerName) { for (Provider provider : supportedProviders) { if (provider.getName().equalsIgnoreCase(providerName)) { @@ -153,7 +154,7 @@ public interface Network extends ControlledEntity { public static class Capability { private static List supportedCapabilities = new ArrayList(); - + public static final Capability SupportedProtocols = new Capability("SupportedProtocols"); public static final Capability SupportedLBAlgorithms = new Capability("SupportedLbAlgorithms"); public static final Capability SupportedLBIsolation = new Capability("SupportedLBIsolation"); @@ -168,6 +169,7 @@ public interface Network extends ControlledEntity { public static final Capability RedundantRouter = new Capability("RedundantRouter"); public static final Capability ElasticIp = new Capability("ElasticIp"); public static final Capability ElasticLb = new Capability("ElasticLb"); + public static final Capability AutoScaleCounters = new Capability("AutoScaleCounters"); private String name; @@ -287,14 +289,15 @@ public interface Network extends ControlledEntity { void setPhysicalNetworkId(Long physicalNetworkId); - ACLType getAclType(); - - boolean isRestartRequired(); + ACLType getAclType(); - boolean getSpecifyIpRanges(); + boolean isRestartRequired(); + + boolean getSpecifyIpRanges(); /** * @return */ Long getVpcId(); + } diff --git a/api/src/com/cloud/network/as/AutoScalePolicy.java b/api/src/com/cloud/network/as/AutoScalePolicy.java new file mode 100644 index 00000000000..43065741e46 --- /dev/null +++ b/api/src/com/cloud/network/as/AutoScalePolicy.java @@ -0,0 +1,32 @@ +// 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 com.cloud.acl.ControlledEntity; + +public interface AutoScalePolicy extends ControlledEntity { + + long getId(); + + public int getDuration(); + + public int getQuietTime(); + + public String getAction(); + +} \ No newline at end of file diff --git a/api/src/com/cloud/network/as/AutoScaleService.java b/api/src/com/cloud/network/as/AutoScaleService.java new file mode 100644 index 00000000000..ef99512aa54 --- /dev/null +++ b/api/src/com/cloud/network/as/AutoScaleService.java @@ -0,0 +1,84 @@ +// 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.List; + +import com.cloud.api.commands.CreateAutoScalePolicyCmd; +import com.cloud.api.commands.CreateAutoScaleVmGroupCmd; +import com.cloud.api.commands.CreateAutoScaleVmProfileCmd; +import com.cloud.api.commands.CreateConditionCmd; +import com.cloud.api.commands.CreateCounterCmd; +import com.cloud.api.commands.ListAutoScalePoliciesCmd; +import com.cloud.api.commands.ListAutoScaleVmGroupsCmd; +import com.cloud.api.commands.ListAutoScaleVmProfilesCmd; +import com.cloud.api.commands.ListConditionsCmd; +import com.cloud.api.commands.ListCountersCmd; +import com.cloud.api.commands.UpdateAutoScalePolicyCmd; +import com.cloud.api.commands.UpdateAutoScaleVmGroupCmd; +import com.cloud.api.commands.UpdateAutoScaleVmProfileCmd; +import com.cloud.exception.ResourceInUseException; +import com.cloud.network.as.AutoScalePolicy; +import com.cloud.network.as.AutoScaleVmGroup; +import com.cloud.network.as.AutoScaleVmProfile; +import com.cloud.network.as.Condition; +import com.cloud.network.as.Counter; + +public interface AutoScaleService { + + public AutoScalePolicy createAutoScalePolicy(CreateAutoScalePolicyCmd createAutoScalePolicyCmd); + + public boolean deleteAutoScalePolicy(long autoScalePolicyId); + + List listAutoScalePolicies(ListAutoScalePoliciesCmd cmd); + + AutoScalePolicy updateAutoScalePolicy(UpdateAutoScalePolicyCmd cmd); + + AutoScaleVmProfile createAutoScaleVmProfile(CreateAutoScaleVmProfileCmd cmd); + + boolean deleteAutoScaleVmProfile(long profileId); + + List listAutoScaleVmProfiles(ListAutoScaleVmProfilesCmd listAutoScaleVmProfilesCmd); + + AutoScaleVmProfile updateAutoScaleVmProfile(UpdateAutoScaleVmProfileCmd cmd); + + AutoScaleVmGroup createAutoScaleVmGroup(CreateAutoScaleVmGroupCmd cmd); + + boolean configureAutoScaleVmGroup(CreateAutoScaleVmGroupCmd cmd); + + boolean deleteAutoScaleVmGroup(long vmGroupId); + + AutoScaleVmGroup updateAutoScaleVmGroup(UpdateAutoScaleVmGroupCmd cmd); + + AutoScaleVmGroup enableAutoScaleVmGroup(Long id); + + AutoScaleVmGroup disableAutoScaleVmGroup(Long id); + + List listAutoScaleVmGroups(ListAutoScaleVmGroupsCmd listAutoScaleVmGroupsCmd); + + Counter createCounter(CreateCounterCmd cmd); + + boolean deleteCounter(long counterId) throws ResourceInUseException; + + List listCounters(ListCountersCmd cmd); + + Condition createCondition(CreateConditionCmd cmd); + + List listConditions(ListConditionsCmd cmd); + + boolean deleteCondition(long conditionId) throws ResourceInUseException; +} diff --git a/api/src/com/cloud/network/as/AutoScaleVmGroup.java b/api/src/com/cloud/network/as/AutoScaleVmGroup.java new file mode 100644 index 00000000000..02b8f503890 --- /dev/null +++ b/api/src/com/cloud/network/as/AutoScaleVmGroup.java @@ -0,0 +1,52 @@ +// 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 com.cloud.acl.ControlledEntity; + +/** + * @author Deepak Garg + */ + +public interface AutoScaleVmGroup extends ControlledEntity { + + String State_New = "new"; + String State_Revoke = "revoke"; + String State_Enabled = "enabled"; + String State_Disabled = "disabled"; + + long getId(); + + @Override + long getAccountId(); + + Long getLoadBalancerId(); + + long getProfileId(); + + int getMinMembers(); + + int getMaxMembers(); + + int getMemberPort(); + + int getInterval(); + + String getState(); + +} \ No newline at end of file diff --git a/api/src/com/cloud/network/as/AutoScaleVmProfile.java b/api/src/com/cloud/network/as/AutoScaleVmProfile.java new file mode 100644 index 00000000000..7fc61916485 --- /dev/null +++ b/api/src/com/cloud/network/as/AutoScaleVmProfile.java @@ -0,0 +1,44 @@ +// 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 com.cloud.acl.ControlledEntity; + +/** + * AutoScaleVmProfile + */ +public interface AutoScaleVmProfile extends ControlledEntity { + + public long getId(); + + public Long getZoneId(); + + public Long getServiceOfferingId(); + + public Long getTemplateId(); + + public String getOtherDeployParams(); + + public String getSnmpCommunity(); + + public Integer getSnmpPort(); + + public Integer getDestroyVmGraceperiod(); + + public long getAutoScaleUserId(); +} diff --git a/api/src/com/cloud/network/as/Condition.java b/api/src/com/cloud/network/as/Condition.java new file mode 100644 index 00000000000..117827d59de --- /dev/null +++ b/api/src/com/cloud/network/as/Condition.java @@ -0,0 +1,37 @@ +// 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 com.cloud.acl.ControlledEntity; + +public interface Condition extends ControlledEntity { + + static enum Operator { + EQ, GT, LT, GE, LE + }; + + long getCounterid(); + + long getThreshold(); + + Operator getRelationalOperator(); + + String getUuid(); + + long getId(); +} \ No newline at end of file diff --git a/api/src/com/cloud/network/as/Counter.java b/api/src/com/cloud/network/as/Counter.java new file mode 100644 index 00000000000..b4be1b8ec0e --- /dev/null +++ b/api/src/com/cloud/network/as/Counter.java @@ -0,0 +1,36 @@ +// 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; + +public interface Counter { + + public static enum Source { + netscaler, + snmp + } + + String getName(); + + String getValue(); + + Source getSource(); + + String getUuid(); + + long getId(); +} \ No newline at end of file diff --git a/api/src/com/cloud/network/lb/LoadBalancingRule.java b/api/src/com/cloud/network/lb/LoadBalancingRule.java index 9b4eddcc61c..7775f8916ac 100644 --- a/api/src/com/cloud/network/lb/LoadBalancingRule.java +++ b/api/src/com/cloud/network/lb/LoadBalancingRule.java @@ -18,6 +18,11 @@ package com.cloud.network.lb; import java.util.List; +import com.cloud.network.as.AutoScalePolicy; +import com.cloud.network.as.AutoScaleVmGroup; +import com.cloud.network.as.AutoScaleVmProfile; +import com.cloud.network.as.Condition; +import com.cloud.network.as.Counter; import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.LoadBalancer; import com.cloud.utils.Pair; @@ -26,42 +31,44 @@ public class LoadBalancingRule implements FirewallRule, LoadBalancer{ private LoadBalancer lb; private List destinations; private List stickinessPolicies; - - public LoadBalancingRule(LoadBalancer lb, List destinations, List stickinessPolicies) { + private LbAutoScaleVmGroup autoScaleVmGroup; + + public LoadBalancingRule(LoadBalancer lb, List destinations, List stickinessPolicies) { this.lb = lb; this.destinations = destinations; this.stickinessPolicies = stickinessPolicies; } - + @Override public long getId() { return lb.getId(); } - + @Override public long getAccountId() { return lb.getAccountId(); } - + @Override public long getDomainId() { return lb.getDomainId(); } - + @Override public String getName() { return lb.getName(); } - + @Override public String getDescription() { return lb.getDescription(); } + @Override public int getDefaultPortStart() { return lb.getDefaultPortStart(); } - + @Override public int getDefaultPortEnd() { return lb.getDefaultPortEnd(); @@ -71,22 +78,22 @@ public class LoadBalancingRule implements FirewallRule, LoadBalancer{ public String getAlgorithm() { return lb.getAlgorithm(); } - + @Override public String getXid() { return lb.getXid(); } - + @Override public Long getSourceIpAddressId() { return lb.getSourceIpAddressId(); } - + @Override public Integer getSourcePortStart() { return lb.getSourcePortStart(); } - + @Override public Integer getSourcePortEnd() { return lb.getSourcePortEnd(); @@ -96,22 +103,22 @@ public class LoadBalancingRule implements FirewallRule, LoadBalancer{ public String getProtocol() { return lb.getProtocol(); } - + @Override public Purpose getPurpose() { return Purpose.LoadBalancing; } - + @Override public State getState() { return lb.getState(); } - + @Override public long getNetworkId() { return lb.getNetworkId(); } - + public LoadBalancer getLb() { return lb; } @@ -119,12 +126,12 @@ public class LoadBalancingRule implements FirewallRule, LoadBalancer{ public List getDestinations() { return destinations; } - + public List getStickinessPolicies() { return stickinessPolicies; } - - + + public interface Destination { String getIpAddress(); int getDestinationPortStart(); @@ -148,7 +155,7 @@ public class LoadBalancingRule implements FirewallRule, LoadBalancer{ this._params = params; this._revoke = false; } - + public String getMethodName() { return _methodName; } @@ -161,66 +168,180 @@ public class LoadBalancingRule implements FirewallRule, LoadBalancer{ return _revoke; } } - + public static class LbDestination implements Destination { private int portStart; private int portEnd; private String ip; boolean revoked; - + public LbDestination(int portStart, int portEnd, String ip, boolean revoked) { this.portStart = portStart; this.portEnd = portEnd; this.ip = ip; this.revoked = revoked; } - + + @Override public String getIpAddress() { return ip; } + @Override public int getDestinationPortStart() { return portStart; } + @Override public int getDestinationPortEnd() { return portEnd; } - + + @Override public boolean isRevoked() { return revoked; } - + public void setRevoked(boolean revoked) { this.revoked = revoked; } } - + @Override public Integer getIcmpCode() { return null; } - + @Override public Integer getIcmpType() { return null; } - + @Override public List getSourceCidrList() { return null; } - + @Override public Long getRelated() { return null; } - @Override - public FirewallRuleType getType() { - return FirewallRuleType.User; - } @Override public TrafficType getTrafficType() { return null; } + @Override + public FirewallRuleType getType() { + return FirewallRuleType.User; + } + public LbAutoScaleVmGroup getAutoScaleVmGroup() { + return autoScaleVmGroup; + } + + public boolean isAutoScaleConfig() { + return this.autoScaleVmGroup != null; + } + + public void setAutoScaleVmGroup(LbAutoScaleVmGroup autoScaleVmGroup) { + this.autoScaleVmGroup = autoScaleVmGroup; + } + + public static class LbCondition { + private final Condition condition; + private final Counter counter; + + public LbCondition(Counter counter, Condition condition) { + this.condition = condition; + this.counter = counter; + } + + public Condition getCondition() { + return condition; + } + + public Counter getCounter() { + return counter; + } + } + + public static class LbAutoScalePolicy { + private final List conditions; + private final AutoScalePolicy policy; + private boolean revoked; + + public LbAutoScalePolicy(AutoScalePolicy policy, List conditions) + { + this.policy = policy; + this.conditions = conditions; + } + + public List getConditions() { + return conditions; + } + + public AutoScalePolicy getPolicy() { + return policy; + } + + public boolean isRevoked() { + return revoked; + } + + public void setRevoked(boolean revoked) { + this.revoked = revoked; + } + } + + public static class LbAutoScaleVmProfile { + AutoScaleVmProfile profile; + private final String autoScaleUserApiKey; + private final String autoScaleUserSecretKey; + private final String csUrl; + + public LbAutoScaleVmProfile(AutoScaleVmProfile profile, String autoScaleUserApiKey, String autoScaleUserSecretKey, String csUrl) { + this.profile = profile; + this.autoScaleUserApiKey = autoScaleUserApiKey; + this.autoScaleUserSecretKey = autoScaleUserSecretKey; + this.csUrl = csUrl; + } + + public AutoScaleVmProfile getProfile() { + return profile; + } + + public String getAutoScaleUserApiKey() { + return autoScaleUserApiKey; + } + + public String getAutoScaleUserSecretKey() { + return autoScaleUserSecretKey; + } + public String getCsUrl() { + return csUrl; + } + } + + public static class LbAutoScaleVmGroup { + AutoScaleVmGroup vmGroup; + private final List policies; + private final LbAutoScaleVmProfile profile; + + public LbAutoScaleVmGroup(AutoScaleVmGroup vmGroup, List policies, LbAutoScaleVmProfile profile) { + this.vmGroup = vmGroup; + this.policies = policies; + this.profile = profile; + } + + public AutoScaleVmGroup getVmGroup() { + return vmGroup; + } + + public List getPolicies() { + return policies; + } + + public LbAutoScaleVmProfile getProfile() { + return profile; + } + } } diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in index d9243d553fb..149547ee575 100755 --- a/client/tomcatconf/commands.properties.in +++ b/client/tomcatconf/commands.properties.in @@ -153,6 +153,28 @@ listLBStickinessPolicies=com.cloud.api.commands.ListLBStickinessPoliciesCmd;15 listLoadBalancerRuleInstances=com.cloud.api.commands.ListLoadBalancerRuleInstancesCmd;15 updateLoadBalancerRule=com.cloud.api.commands.UpdateLoadBalancerRuleCmd;15 +#### autoscale commands +createCounter = com.cloud.api.commands.CreateCounterCmd;1 +createCondition = com.cloud.api.commands.CreateConditionCmd;15 +createAutoScalePolicy=com.cloud.api.commands.CreateAutoScalePolicyCmd;15 +createAutoScaleVmProfile=com.cloud.api.commands.CreateAutoScaleVmProfileCmd;15 +createAutoScaleVmGroup=com.cloud.api.commands.CreateAutoScaleVmGroupCmd;15 +deleteCounter = com.cloud.api.commands.DeleteCounterCmd;1 +deleteCondition = com.cloud.api.commands.DeleteConditionCmd;15 +deleteAutoScalePolicy=com.cloud.api.commands.DeleteAutoScalePolicyCmd;15 +deleteAutoScaleVmProfile=com.cloud.api.commands.DeleteAutoScaleVmProfileCmd;15 +deleteAutoScaleVmGroup=com.cloud.api.commands.DeleteAutoScaleVmGroupCmd;15 +listCounters = com.cloud.api.commands.ListCountersCmd;15 +listConditions = com.cloud.api.commands.ListConditionsCmd;15 +listAutoScalePolicies=com.cloud.api.commands.ListAutoScalePoliciesCmd;15 +listAutoScaleVmProfiles=com.cloud.api.commands.ListAutoScaleVmProfilesCmd;15 +listAutoScaleVmGroups=com.cloud.api.commands.ListAutoScaleVmGroupsCmd;15 +enableAutoScaleVmGroup=com.cloud.api.commands.EnableAutoScaleVmGroupCmd;15 +disableAutoScaleVmGroup=com.cloud.api.commands.DisableAutoScaleVmGroupCmd;15 +updateAutoScalePolicy=com.cloud.api.commands.UpdateAutoScalePolicyCmd;15 +updateAutoScaleVmProfile=com.cloud.api.commands.UpdateAutoScaleVmProfileCmd;15 +updateAutoScaleVmGroup=com.cloud.api.commands.UpdateAutoScaleVmGroupCmd;15 + #### router commands startRouter=com.cloud.api.commands.StartRouterCmd;7 rebootRouter=com.cloud.api.commands.RebootRouterCmd;7 diff --git a/plugins/network-elements/elastic-loadbalancer/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java b/plugins/network-elements/elastic-loadbalancer/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java index 1cd830c9f4e..141e3ba013e 100644 --- a/plugins/network-elements/elastic-loadbalancer/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java +++ b/plugins/network-elements/elastic-loadbalancer/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java @@ -138,10 +138,10 @@ import com.cloud.vm.dao.NicDao; @Local(value = { ElasticLoadBalancerManager.class }) public class ElasticLoadBalancerManagerImpl implements - ElasticLoadBalancerManager, Manager, VirtualMachineGuru { +ElasticLoadBalancerManager, Manager, VirtualMachineGuru { private static final Logger s_logger = Logger - .getLogger(ElasticLoadBalancerManagerImpl.class); - + .getLogger(ElasticLoadBalancerManagerImpl.class); + @Inject IPAddressDao _ipAddressDao; @Inject @@ -184,9 +184,9 @@ public class ElasticLoadBalancerManagerImpl implements PodVlanMapDao _podVlanMapDao; @Inject ElasticLbVmMapDao _elbVmMapDao; - @Inject + @Inject NetworkDao _networksDao; - @Inject + @Inject AccountDao _accountDao; @Inject PhysicalNetworkServiceProviderDao _physicalProviderDao; @@ -200,7 +200,7 @@ public class ElasticLoadBalancerManagerImpl implements String _instance; static final private String _elbVmNamePrefix = "l"; static final private String _systemVmType = "elbvm"; - + boolean _enabled; TrafficType _frontendTrafficType = TrafficType.Guest; @@ -209,13 +209,13 @@ public class ElasticLoadBalancerManagerImpl implements ScheduledExecutorService _gcThreadPool; String _mgmtCidr; String _mgmtHost; - + Set _gcCandidateElbVmIds = Collections.newSetFromMap(new ConcurrentHashMap()); - + int _elasticLbVmRamSize; int _elasticLbvmCpuMHz; int _elasticLbvmNumCpu; - + private Long getPodIdForDirectIp(IPAddressVO ipAddr) { PodVlanMapVO podVlanMaps = _podVlanMapDao.listPodVlanMapsByVlan(ipAddr.getVlanId()); if (podVlanMaps == null) { @@ -226,7 +226,7 @@ public class ElasticLoadBalancerManagerImpl implements } - public DomainRouterVO deployLoadBalancerVM(Long networkId, IPAddressVO ipAddr, Long accountId) { + public DomainRouterVO deployLoadBalancerVM(Long networkId, IPAddressVO ipAddr, Long accountId) { NetworkVO network = _networkDao.findById(networkId); DataCenter dc = _dcDao.findById(network.getDataCenterId()); Long podId = getPodIdForDirectIp(ipAddr); @@ -246,14 +246,14 @@ public class ElasticLoadBalancerManagerImpl implements s_logger.debug("Deployed ELB vm = " + elbVm); return elbVm; - + } catch (Throwable t) { s_logger.warn("Error while deploying ELB VM: ", t); return null; } } - + private boolean sendCommandsToRouter(final DomainRouterVO elbVm, Commands cmds) throws AgentUnavailableException { Answer[] answers = null; @@ -295,11 +295,11 @@ public class ElasticLoadBalancerManagerImpl implements String algorithm = rule.getAlgorithm(); String elbIp = _networkMgr.getIp(rule.getSourceIpAddressId()).getAddress() - .addr(); + .addr(); int srcPort = rule.getSourcePortStart(); List destinations = rule.getDestinations(); - LoadBalancerTO lb = new LoadBalancerTO(elbIp, srcPort, protocol, algorithm, revoked, false, destinations); - lbs[i++] = lb; + LoadBalancerTO lb = new LoadBalancerTO(rule.getId(), elbIp, srcPort, protocol, algorithm, revoked, false, destinations); + lbs[i++] = lb; } LoadBalancerConfigCommand cmd = new LoadBalancerConfigCommand(lbs,elbVm.getPublicIpAddress(), @@ -314,7 +314,7 @@ public class ElasticLoadBalancerManagerImpl implements cmd.lbStatsUri = _configDao.getValue(Config.NetworkLBHaproxyStatsUri.key()); cmd.lbStatsAuth = _configDao.getValue(Config.NetworkLBHaproxyStatsAuth.key()); cmd.lbStatsPort = _configDao.getValue(Config.NetworkLBHaproxyStatsPort.key()); - + cmds.addCommand(cmd); } @@ -326,7 +326,7 @@ public class ElasticLoadBalancerManagerImpl implements // Send commands to elbVm return sendCommandsToRouter(elbVm, cmds); } - + protected DomainRouterVO findElbVmForLb(FirewallRule lb) {//TODO: use a table to lookup ElasticLbVmMapVO map = _elbVmMapDao.findOneByIp(lb.getSourceIpAddressId()); if (map == null) { @@ -336,9 +336,10 @@ public class ElasticLoadBalancerManagerImpl implements return elbVm; } + @Override public boolean applyLoadBalancerRules(Network network, List rules) - throws ResourceUnavailableException { + throws ResourceUnavailableException { if (rules == null || rules.isEmpty()) { return true; } @@ -346,9 +347,9 @@ public class ElasticLoadBalancerManagerImpl implements s_logger.warn("ELB: Not handling non-LB firewall rules"); return false; } - + DomainRouterVO elbVm = findElbVmForLb(rules.get(0)); - + if (elbVm == null) { s_logger.warn("Unable to apply lb rules, ELB vm doesn't exist in the network " + network.getId()); @@ -365,7 +366,7 @@ public class ElasticLoadBalancerManagerImpl implements List policyList = _lbMgr.getStickinessPolicies(lb.getId()); LoadBalancingRule loadBalancing = new LoadBalancingRule( lb, dstList, policyList); - lbRules.add(loadBalancing); + lbRules.add(loadBalancing); } return applyLBRules(elbVm, lbRules, network.getId()); } else if (elbVm.getState() == State.Stopped @@ -385,7 +386,7 @@ public class ElasticLoadBalancerManagerImpl implements @Override public boolean configure(String name, Map params) - throws ConfigurationException { + throws ConfigurationException { _name = name; final Map configs = _configDao.getConfiguration("AgentManager", params); _systemAcct = _accountService.getSystemAccount(); @@ -395,20 +396,20 @@ public class ElasticLoadBalancerManagerImpl implements } _mgmtCidr = _configDao.getValue(Config.ManagementNetwork.key()); _mgmtHost = _configDao.getValue(Config.ManagementHostIPAdr.key()); - + boolean useLocalStorage = Boolean.parseBoolean(configs.get(Config.SystemVMUseLocalStorage.key())); _elasticLbVmRamSize = NumbersUtil.parseInt(configs.get(Config.ElasticLoadBalancerVmMemory.key()), DEFAULT_ELB_VM_RAMSIZE); _elasticLbvmCpuMHz = NumbersUtil.parseInt(configs.get(Config.ElasticLoadBalancerVmCpuMhz.key()), DEFAULT_ELB_VM_CPU_MHZ); _elasticLbvmNumCpu = NumbersUtil.parseInt(configs.get(Config.ElasticLoadBalancerVmNumVcpu.key()), 1); - _elasticLbVmOffering = new ServiceOfferingVO("System Offering For Elastic LB VM", _elasticLbvmNumCpu, - _elasticLbVmRamSize, _elasticLbvmCpuMHz, 0, 0, true, null, useLocalStorage, + _elasticLbVmOffering = new ServiceOfferingVO("System Offering For Elastic LB VM", _elasticLbvmNumCpu, + _elasticLbVmRamSize, _elasticLbvmCpuMHz, 0, 0, true, null, useLocalStorage, true, null, true, VirtualMachine.Type.ElasticLoadBalancerVm, true); _elasticLbVmOffering.setUniqueName(ServiceOffering.elbVmDefaultOffUniqueName); _elasticLbVmOffering = _serviceOfferingDao.persistSystemServiceOffering(_elasticLbVmOffering); - - - + + + String enabled = _configDao.getValue(Config.ElasticLoadBalancerEnabled.key()); _enabled = (enabled == null) ? false: Boolean.parseBoolean(enabled); s_logger.info("Elastic Load balancer enabled: " + _enabled); @@ -422,14 +423,14 @@ public class ElasticLoadBalancerManagerImpl implements throw new ConfigurationException("ELB: Traffic type for front end of load balancer has to be guest or public; found : " + traffType); s_logger.info("ELB: Elastic Load Balancer: will balance on " + traffType ); int gcIntervalMinutes = NumbersUtil.parseInt(configs.get(Config.ElasticLoadBalancerVmGcInterval.key()), 5); - if (gcIntervalMinutes < 5) + if (gcIntervalMinutes < 5) gcIntervalMinutes = 5; s_logger.info("ELB: Elastic Load Balancer: scheduling GC to run every " + gcIntervalMinutes + " minutes" ); _gcThreadPool = Executors.newScheduledThreadPool(1, new NamedThreadFactory("ELBVM-GC")); _gcThreadPool.scheduleAtFixedRate(new CleanupThread(), gcIntervalMinutes, gcIntervalMinutes, TimeUnit.MINUTES); _itMgr.registerGuru(VirtualMachine.Type.ElasticLoadBalancerVm, this); } - + return true; } @@ -461,9 +462,9 @@ public class ElasticLoadBalancerManagerImpl implements } return null; } - + public DomainRouterVO deployELBVm(Network guestNetwork, DeployDestination dest, Account owner, Map params) throws - ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { + ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { long dcId = dest.getDataCenter().getId(); // lock guest network @@ -483,14 +484,14 @@ public class ElasticLoadBalancerManagerImpl implements if (s_logger.isDebugEnabled()) { s_logger.debug("Starting a ELB vm for network configurations: " + guestNetwork + " in " + dest); } - assert guestNetwork.getState() == Network.State.Implemented - || guestNetwork.getState() == Network.State.Setup - || guestNetwork.getState() == Network.State.Implementing - : "Network is not yet fully implemented: "+ guestNetwork; + assert guestNetwork.getState() == Network.State.Implemented + || guestNetwork.getState() == Network.State.Setup + || guestNetwork.getState() == Network.State.Implementing + : "Network is not yet fully implemented: "+ guestNetwork; DataCenterDeployment plan = null; DomainRouterVO elbVm = null; - + plan = new DataCenterDeployment(dcId, dest.getPod().getId(), null, null, null, null); if (elbVm == null) { @@ -498,7 +499,7 @@ public class ElasticLoadBalancerManagerImpl implements if (s_logger.isDebugEnabled()) { s_logger.debug("Creating the ELB vm " + id); } - + List offerings = _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemControlNetwork); NetworkOfferingVO controlOffering = offerings.get(0); NetworkVO controlConfig = _networkMgr.setupNetwork(_systemAcct, controlOffering, plan, null, null, false).get(0); @@ -509,7 +510,6 @@ public class ElasticLoadBalancerManagerImpl implements networks.add(new Pair(controlConfig, null)); networks.add(new Pair((NetworkVO) guestNetwork, guestNic)); - VMTemplateVO template = _templateDao.findSystemVMTemplate(dcId); String typeString = "ElasticLoadBalancerVm"; @@ -522,7 +522,7 @@ public class ElasticLoadBalancerManagerImpl implements if (vrProvider == null) { throw new CloudRuntimeException("Cannot find virtual router provider " + typeString + " as service provider " + provider.getId()); } - + elbVm = new DomainRouterVO(id, _elasticLbVmOffering.getId(), vrProvider.getId(), VirtualMachineName.getSystemVmName(id, _instance, _elbVmNamePrefix), template.getId(), template.getHypervisorType(), template.getGuestOSId(), owner.getDomainId(), owner.getId(), false, 0, false, RedundantState.UNKNOWN, @@ -543,7 +543,7 @@ public class ElasticLoadBalancerManagerImpl implements _networkDao.releaseFromLockTable(guestNetworkId); } } - + private DomainRouterVO start(DomainRouterVO elbVm, User user, Account caller, Map params) throws StorageUnavailableException, InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException { s_logger.debug("Starting ELB VM " + elbVm); @@ -553,8 +553,8 @@ public class ElasticLoadBalancerManagerImpl implements return null; } } - - + + private DomainRouterVO stop(DomainRouterVO elbVm, boolean forced, User user, Account caller) throws ConcurrentOperationException, ResourceUnavailableException { s_logger.debug("Stopping ELB vm " + elbVm); try { @@ -567,10 +567,10 @@ public class ElasticLoadBalancerManagerImpl implements throw new CloudRuntimeException("Unable to stop " + elbVm, e); } } - + protected List findExistingLoadBalancers(String lbName, Long ipId, Long accountId, Long domainId, Integer publicPort) { SearchBuilder sb = _lbDao.createSearchBuilder(); - sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ); + sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ); sb.and("accountId", sb.entity().getAccountId(), SearchCriteria.Op.EQ); sb.and("publicPort", sb.entity().getSourcePortStart(), SearchCriteria.Op.EQ); if (ipId != null) { @@ -587,7 +587,7 @@ public class ElasticLoadBalancerManagerImpl implements sc.setParameters("accountId", accountId); if (ipId != null) { sc.setParameters("sourceIpAddress", ipId); - } + } if (domainId != null) { sc.setParameters("domainId",domainId); } @@ -595,30 +595,30 @@ public class ElasticLoadBalancerManagerImpl implements sc.setParameters("publicPort", publicPort); } List lbs = _lbDao.search(sc, null); - + return lbs == null || lbs.size()==0 ? null: lbs; } - + @DB public PublicIp allocDirectIp(Account account, long guestNetworkId) throws InsufficientAddressCapacityException { Network frontEndNetwork = _networkMgr.getNetwork(guestNetworkId); Transaction txn = Transaction.currentTxn(); txn.start(); - + PublicIp ip = _networkMgr.assignPublicIpAddress(frontEndNetwork.getDataCenterId(), null, account, VlanType.DirectAttached, frontEndNetwork.getId(), null, true); IPAddressVO ipvo = _ipAddressDao.findById(ip.getId()); - ipvo.setAssociatedWithNetworkId(frontEndNetwork.getId()); + ipvo.setAssociatedWithNetworkId(frontEndNetwork.getId()); _ipAddressDao.update(ipvo.getId(), ipvo); txn.commit(); s_logger.info("Acquired frontend IP for ELB " + ip); return ip; } - + public void releaseIp(long ipId, long userId, Account caller) { s_logger.info("ELB: Release public IP for loadbalancing " + ipId); IPAddressVO ipvo = _ipAddressDao.findById(ipId); - ipvo.setAssociatedWithNetworkId(null); + ipvo.setAssociatedWithNetworkId(null); _ipAddressDao.update(ipvo.getId(), ipvo); _networkMgr.disassociatePublicIpAddress(ipId, userId, caller); _ipAddressDao.unassignIpAddress(ipId); @@ -628,11 +628,11 @@ public class ElasticLoadBalancerManagerImpl implements @DB public LoadBalancer handleCreateLoadBalancerRule(CreateLoadBalancerRuleCmd lb, Account account, long networkId) throws InsufficientAddressCapacityException, NetworkRuleConflictException { //this part of code is executed when the LB provider is Elastic Load Balancer vm - if (!_networkMgr.isProviderSupportServiceInNetwork(lb.getNetworkId(), Service.Lb, Provider.ElasticLoadBalancerVm)) { - return null; - } - - Long ipId = lb.getSourceIpAddressId(); + if (!_networkMgr.isProviderSupportServiceInNetwork(lb.getNetworkId(), Service.Lb, Provider.ElasticLoadBalancerVm)) { + return null; + } + + Long ipId = lb.getSourceIpAddressId(); if (ipId != null) { return null; } @@ -651,7 +651,7 @@ public class ElasticLoadBalancerManagerImpl implements existingLbs = findExistingLoadBalancers(lb.getName(), null, lb.getAccountId(), lb.getDomainId(), null); if (existingLbs != null) { throw new InvalidParameterValueException("Supplied LB name " + lb.getName() + " is not associated with IP " + lb.getSourceIpAddressId() ); - } + } } else { s_logger.debug("Could not find any existing frontend ips for this account for this LB rule, acquiring a new frontent IP for ELB"); PublicIp ip = allocDirectIp(account, networkId); @@ -669,7 +669,7 @@ public class ElasticLoadBalancerManagerImpl implements Network network = _networkMgr.getNetwork(networkId); IPAddressVO ipAddr = _ipAddressDao.findById(ipId); - + LoadBalancer result = null; try { lb.setSourceIpAddressId(ipId); @@ -702,26 +702,26 @@ public class ElasticLoadBalancerManagerImpl implements elbVm = _routerDao.findById(elbVmMap.getElbVmId()); } } - + if (elbVm == null) { s_logger.warn("No ELB VM can be found or deployed"); s_logger.warn("Deleting LB since we failed to deploy ELB VM"); _lbDao.remove(result.getId()); return null; } - + ElasticLbVmMapVO mapping = new ElasticLbVmMapVO(ipId, elbVm.getId(), result.getId()); _elbVmMapDao.persist(mapping); return result; - + } finally { if (account != null) { _accountDao.releaseFromLockTable(account.getId()); } } - + } - + void garbageCollectUnusedElbVms() { List unusedElbVms = _elbVmMapDao.listUnusedElbVms(); if (unusedElbVms != null && unusedElbVms.size() > 0) @@ -763,12 +763,12 @@ public class ElasticLoadBalancerManagerImpl implements } _gcCandidateElbVmIds = currentGcCandidates; } - + public class CleanupThread implements Runnable { @Override public void run() { garbageCollectUnusedElbVms(); - + } CleanupThread() { @@ -788,7 +788,7 @@ public class ElasticLoadBalancerManagerImpl implements } } - + @Override public DomainRouterVO findByName(String name) { if (!VirtualMachineName.isValidSystemVmName(name, _instance, _elbVmNamePrefix)) { @@ -874,13 +874,13 @@ public class ElasticLoadBalancerManagerImpl implements String domain = guestNetwork.getNetworkDomain(); if (domain != null) { buf.append(" domain=" + domain); - } + } buf.append(" dns1=").append(defaultDns1); if (defaultDns2 != null) { buf.append(" dns2=").append(defaultDns2); } - + if (s_logger.isDebugEnabled()) { s_logger.debug("Boot Args for " + profile + ": " + buf.toString()); } @@ -988,7 +988,7 @@ public class ElasticLoadBalancerManagerImpl implements processStopOrRebootAnswer(elbVm, answer); } } - + public void processStopOrRebootAnswer(final DomainRouterVO elbVm, Answer answer) { //TODO: process network usage stats } @@ -997,7 +997,7 @@ public class ElasticLoadBalancerManagerImpl implements @Override public void finalizeExpunge(DomainRouterVO vm) { // no-op - + } @Override 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 7c51ff79135..6aa7cf4e6e8 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 @@ -109,7 +109,7 @@ import com.google.gson.Gson; @Local(value = NetworkElement.class) public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl implements LoadBalancingServiceProvider, NetscalerLoadBalancerElementService, ExternalLoadBalancerDeviceManager, IpDeployer, - StaticNatServiceProvider { +StaticNatServiceProvider { private static final Logger s_logger = Logger.getLogger(NetscalerElement.class); @@ -143,7 +143,7 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl NetScalerPodDao _netscalerPodDao; @Inject DataCenterIpAddressDao _privateIpAddressDao; - + private boolean canHandle(Network config, Service service) { DataCenter zone = _dcDao.findById(config.getDataCenterId()); boolean handleInAdvanceZone = (zone.getNetworkType() == NetworkType.Advanced && config.getGuestType() == Network.GuestType.Isolated && config.getTrafficType() == TrafficType.Guest); @@ -164,14 +164,14 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl @Override public boolean implement(Network guestConfig, NetworkOffering offering, DeployDestination dest, ReservationContext context) throws ResourceUnavailableException, ConcurrentOperationException, - InsufficientNetworkCapacityException { + InsufficientNetworkCapacityException { if (!canHandle(guestConfig, Service.Lb)) { return false; } if (_ntwkSrvcDao.canProviderSupportServiceInNetwork(guestConfig.getId(), Service.StaticNat, Network.Provider.Netscaler) && !isBasicZoneNetwok(guestConfig)) { - s_logger.error("NetScaler provider can not be Static Nat service provider for the network " + guestConfig.getGuestType() + + s_logger.error("NetScaler provider can not be Static Nat service provider for the network " + guestConfig.getGuestType() + " and traffic type " + guestConfig.getTrafficType()); return false; } @@ -185,7 +185,7 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl @Override public boolean prepare(Network config, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, - InsufficientNetworkCapacityException, ResourceUnavailableException { + InsufficientNetworkCapacityException, ResourceUnavailableException { return true; } @@ -253,6 +253,9 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl // 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"); + LbStickinessMethod method; List methodList = new ArrayList(); method = new LbStickinessMethod(StickinessMethodType.LBCookieBased, "This is cookie based sticky method, can be used only for http"); @@ -315,7 +318,7 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl throw new InvalidParameterValueException(msg); } - ExternalLoadBalancerDeviceVO lbDeviceVO = addExternalLoadBalancer(cmd.getPhysicalNetworkId(), cmd.getUrl(), cmd.getUsername(), cmd.getPassword(), deviceName, (ServerResource) new NetscalerResource()); + ExternalLoadBalancerDeviceVO lbDeviceVO = addExternalLoadBalancer(cmd.getPhysicalNetworkId(), cmd.getUrl(), cmd.getUsername(), cmd.getPassword(), deviceName, new NetscalerResource()); return lbDeviceVO; } @@ -406,7 +409,7 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl } if (inline != null) { - boolean _setInline = Boolean.parseBoolean((String) lbDetails.get("inline")); + boolean _setInline = Boolean.parseBoolean(lbDetails.get("inline")); if (inline != _setInline) { throw new CloudRuntimeException("There are networks already using this netscaler device to change the device inline or side-by-side configuration"); } @@ -539,13 +542,13 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl response.setProvider(lbDeviceVO.getProviderName()); response.setDeviceState(lbDeviceVO.getState().name()); response.setObjectName("netscalerloadbalancer"); - + List associatedPods = new ArrayList(); List currentPodVOs = _netscalerPodDao.listByNetScalerDeviceId(lbDeviceVO.getId()); if (currentPodVOs != null && currentPodVOs.size() > 0) { - for (NetScalerPodVO nsPodVo: currentPodVOs) { - associatedPods.add(nsPodVo.getPodId()); - } + for (NetScalerPodVO nsPodVo: currentPodVOs) { + associatedPods.add(nsPodVo.getPodId()); + } } response.setAssociatedPods(associatedPods); return response; @@ -561,7 +564,7 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl List lbDevices = _lbDeviceDao.listByPhysicalNetworkAndProvider(provider.getPhysicalNetworkId(), Provider.Netscaler.getName()); // true if at-least one Netscaler device is added in to physical network and is in configured (in enabled state) -// state + // state if (lbDevices != null && !lbDevices.isEmpty()) { for (ExternalLoadBalancerDeviceVO lbDevice : lbDevices) { if (lbDevice.getState() == LBDeviceState.Enabled) { @@ -574,7 +577,7 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl @Override public boolean shutdownProviderInstances(PhysicalNetworkServiceProvider provider, ReservationContext context) throws ConcurrentOperationException, - ResourceUnavailableException { + ResourceUnavailableException { // TODO reset the configuration on all of the netscaler devices in this physical network return true; } @@ -602,12 +605,16 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl // NetScaler can only act as Lb and Static Nat service provider if (services != null && !services.isEmpty() && !netscalerServices.containsAll(services)) { + s_logger.warn("NetScaler network element can only support LB and Static NAT services and service combination " + + services + " is not supported."); String servicesList = ""; for (Service service : services) { servicesList += service.getName() + " "; } s_logger.warn("NetScaler network element can only support LB and Static NAT services and service combination " + servicesList + " is not supported."); + s_logger.warn("NetScaler network element can only support LB and Static NAT services and service combination " + + services + " is not supported."); return false; } @@ -666,8 +673,11 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl int srcPort = rule.getSourcePortStart(); List destinations = rule.getDestinations(); - if (destinations != null && !destinations.isEmpty()) { - LoadBalancerTO loadBalancer = new LoadBalancerTO(srcIp, srcPort, protocol, algorithm, revoked, false, destinations, rule.getStickinessPolicies()); + if ((destinations != null && !destinations.isEmpty()) || rule.isAutoScaleConfig()) { + LoadBalancerTO loadBalancer = new LoadBalancerTO(rule.getId(), srcIp, srcPort, protocol, algorithm, revoked, false, destinations, rule.getStickinessPolicies()); + if(rule.isAutoScaleConfig()) { + loadBalancer.setAutoScaleVmGroup(rule.getAutoScaleVmGroup()); + } loadBalancersToApply.add(loadBalancer); } } @@ -739,7 +749,7 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl } else { if (rules != null) { for (StaticNat rule : rules) { - // validate if EIP rule can be configured. + // validate if EIP rule can be configured. ExternalLoadBalancerDeviceVO lbDevice = getNetScalerForEIP(rule); if (lbDevice == null) { String errMsg = "There is no NetScaler device configured to perform EIP to guest IP address: " + rule.getDestIpAddress(); @@ -785,7 +795,7 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl return lbDeviceVO; } } - } + } } return null; } 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 a709cd4ec91..cadf391fa8f 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 @@ -16,14 +16,40 @@ // under the License. package com.cloud.network.resource; +import java.util.Formatter; +import java.util.HashMap; import java.util.List; +import java.util.Locale; import java.util.Map; + import javax.naming.ConfigurationException; + +import org.apache.log4j.Logger; + +import com.citrix.netscaler.nitro.exception.nitro_exception; +import com.citrix.netscaler.nitro.resource.base.base_response; +import com.citrix.netscaler.nitro.resource.config.autoscale.autoscaleprofile; +import com.citrix.netscaler.nitro.resource.config.basic.server_service_binding; +import com.citrix.netscaler.nitro.resource.config.lb.lbvserver; +import com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding; +import com.citrix.netscaler.nitro.resource.config.network.Interface; +import com.citrix.netscaler.nitro.resource.config.network.inat; +import com.citrix.netscaler.nitro.resource.config.network.vlan; +import com.citrix.netscaler.nitro.resource.config.network.vlan_interface_binding; +import com.citrix.netscaler.nitro.resource.config.network.vlan_nsip_binding; +import com.citrix.netscaler.nitro.resource.config.ns.nsconfig; +import com.citrix.netscaler.nitro.resource.config.ns.nshardware; +import com.citrix.netscaler.nitro.resource.config.ns.nsip; +import com.citrix.netscaler.nitro.resource.stat.lb.lbvserver_stats; +import com.citrix.netscaler.nitro.service.nitro_service; +import com.citrix.netscaler.nitro.util.filtervalue; +import com.citrix.sdx.nitro.resource.config.device_profile; +import com.citrix.sdx.nitro.resource.config.mps; +import com.citrix.sdx.nitro.resource.config.ns; +import com.citrix.sdx.nitro.resource.config.xen_vpx_image; import com.cloud.agent.IAgentControl; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; -import com.cloud.agent.api.routing.CreateLoadBalancerApplianceCommand; -import com.cloud.agent.api.routing.DestroyLoadBalancerApplianceCommand; import com.cloud.agent.api.ExternalNetworkResourceUsageAnswer; import com.cloud.agent.api.ExternalNetworkResourceUsageCommand; import com.cloud.agent.api.MaintainAnswer; @@ -33,6 +59,8 @@ import com.cloud.agent.api.ReadyAnswer; import com.cloud.agent.api.ReadyCommand; import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupExternalLoadBalancerCommand; +import com.cloud.agent.api.routing.CreateLoadBalancerApplianceCommand; +import com.cloud.agent.api.routing.DestroyLoadBalancerApplianceCommand; import com.cloud.agent.api.routing.IpAssocAnswer; import com.cloud.agent.api.routing.IpAssocCommand; import com.cloud.agent.api.routing.LoadBalancerConfigCommand; @@ -40,9 +68,15 @@ import com.cloud.agent.api.routing.SetStaticNatRulesAnswer; import com.cloud.agent.api.routing.SetStaticNatRulesCommand; import com.cloud.agent.api.to.IpAddressTO; import com.cloud.agent.api.to.LoadBalancerTO; -import com.cloud.agent.api.to.StaticNatRuleTO; +import com.cloud.agent.api.to.LoadBalancerTO.AutoScalePolicyTO; +import com.cloud.agent.api.to.LoadBalancerTO.AutoScaleVmGroupTO; +import com.cloud.agent.api.to.LoadBalancerTO.AutoScaleVmProfileTO; +import com.cloud.agent.api.to.LoadBalancerTO.ConditionTO; +import com.cloud.agent.api.to.LoadBalancerTO.CounterTO; import com.cloud.agent.api.to.LoadBalancerTO.DestinationTO; import com.cloud.agent.api.to.LoadBalancerTO.StickinessPolicyTO; +import com.cloud.agent.api.to.StaticNatRuleTO; +import com.cloud.api.ApiConstants; import com.cloud.host.Host; import com.cloud.host.Host.Type; import com.cloud.network.rules.LbStickinessMethod.StickinessMethodType; @@ -54,24 +88,6 @@ import com.cloud.utils.exception.ExecutionException; import com.cloud.utils.net.NetUtils; import com.google.gson.Gson; -import com.citrix.netscaler.nitro.service.nitro_service; -import com.citrix.netscaler.nitro.util.filtervalue; -import com.citrix.netscaler.nitro.resource.base.base_response; -import com.citrix.netscaler.nitro.exception.nitro_exception; -import com.citrix.netscaler.nitro.resource.config.ns.nsconfig; -import com.citrix.netscaler.nitro.resource.config.lb.lbvserver; -import com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding; -import com.citrix.netscaler.nitro.resource.config.network.*; -import com.citrix.netscaler.nitro.resource.config.ns.*; -import com.citrix.netscaler.nitro.resource.config.basic.server_service_binding; -import com.citrix.netscaler.nitro.resource.stat.lb.lbvserver_stats; -import com.citrix.sdx.nitro.resource.config.device_profile; -import com.citrix.sdx.nitro.resource.config.ns; -import com.citrix.sdx.nitro.resource.config.mps; -import com.citrix.sdx.nitro.resource.config.xen_vpx_image; - -import org.apache.log4j.Logger; - class NitroError { static final int NS_RESOURCE_EXISTS = 273; static final int NS_RESOURCE_NOT_EXISTS=258; @@ -91,7 +107,7 @@ public class NetscalerResource implements ServerResource { private String _password; private String _publicInterface; private String _privateInterface; - private Integer _numRetries; + private Integer _numRetries; private String _guid; private boolean _inline; private boolean _isSdx; @@ -186,8 +202,8 @@ public class NetscalerResource implements ServerResource { login(); validateDeviceType(_deviceName); validateInterfaces(_publicInterface, _privateInterface); - - //enable load balancing feature + + //enable load balancing feature enableLoadBalancingFeature(); //if the the device is cloud stack provisioned then make it part of the public network @@ -197,10 +213,10 @@ public class NetscalerResource implements ServerResource { _publicIPNetmask = (String) params.get("publicipnetmask"); _publicIPVlan = (String) params.get("publicipvlan"); if ("untagged".equalsIgnoreCase(_publicIPVlan)) { - // if public network is un-tagged just add subnet IP + // if public network is un-tagged just add subnet IP addSubnetIP(_publicIP, _publicIPNetmask); } else { - // if public network is tagged then add vlan and bind subnet IP to the vlan + // if public network is tagged then add vlan and bind subnet IP to the vlan addGuestVlanAndSubnet(Long.parseLong(_publicIPVlan), _publicIP, _publicIPNetmask, false); } } @@ -371,7 +387,7 @@ public class NetscalerResource implements ServerResource { String[] results = new String[cmd.getIpAddresses().length]; int i = 0; - try { + try { IpAddressTO[] ips = cmd.getIpAddresses(); for (IpAddressTO ip : ips) { long guestVlanTag = Long.valueOf(ip.getVlanId()); @@ -423,6 +439,11 @@ public class NetscalerResource implements ServerResource { String lbAlgorithm = loadBalancer.getAlgorithm(); String nsVirtualServerName = generateNSVirtualServerName(srcIp, srcPort); + if(loadBalancer.isAutoScaleVmGroupTO()) { + applyAutoScaleConfig(loadBalancer); + return new Answer(cmd); + } + boolean destinationsToAdd = false; for (DestinationTO destination : loadBalancer.getDestinations()) { if (!destination.isRevoked()) { @@ -434,16 +455,16 @@ public class NetscalerResource implements ServerResource { if (!loadBalancer.isRevoked() && destinationsToAdd) { // create a load balancing virtual server - addLBVirtualServer(nsVirtualServerName, srcIp, srcPort, lbAlgorithm, lbProtocol, loadBalancer.getStickinessPolicies()); + addLBVirtualServer(nsVirtualServerName, srcIp, srcPort, lbAlgorithm, lbProtocol, loadBalancer.getStickinessPolicies(), null); if (s_logger.isDebugEnabled()) { s_logger.debug("Created load balancing virtual server " + nsVirtualServerName + " on the Netscaler device"); } for (DestinationTO destination : loadBalancer.getDestinations()) { - + String nsServerName = generateNSServerName(destination.getDestIp()); String nsServiceName = generateNSServiceName(destination.getDestIp(), destination.getDestPort()); - + if (!destination.isRevoked()) { // add a new destination to deployed load balancing rule @@ -473,13 +494,13 @@ public class NetscalerResource implements ServerResource { } } - //bind service to load balancing virtual server + //bind service to load balancing virtual server if (!nsServiceBindingExists(nsVirtualServerName, nsServiceName)) { com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding svcBinding = new com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding(); svcBinding.set_name(nsVirtualServerName); svcBinding.set_servicename(nsServiceName); apiCallResult = com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding.add(_netscalerService, svcBinding); - + if (apiCallResult.errorcode != 0) { throw new ExecutionException("Failed to bind service: " + nsServiceName + " to the lb virtual server: " + nsVirtualServerName + " on Netscaler device"); } @@ -498,7 +519,7 @@ public class NetscalerResource implements ServerResource { if (apiCallResult.errorcode != 0) { throw new ExecutionException("Failed to delete the binding between the virtual server: " + nsVirtualServerName + " and service:" + nsServiceName + " due to" + apiCallResult.message); } - + // check if service is bound to any other virtual server if (!isServiceBoundToVirtualServer(nsServiceName)) { // no lb virtual servers are bound to this service so delete it @@ -507,7 +528,7 @@ public class NetscalerResource implements ServerResource { throw new ExecutionException("Failed to delete service: " + nsServiceName + " due to " + apiCallResult.message); } } - + // delete the server if there is no associated services server_service_binding[] services = server_service_binding.get(_netscalerService, nsServerName); if ((services == null) || (services.length == 0)) { @@ -519,15 +540,15 @@ public class NetscalerResource implements ServerResource { } } } - } + } } } else { - // delete the implemented load balancing rule and its destinations + // delete the implemented load balancing rule and its destinations lbvserver lbserver = getVirtualServerIfExisits(nsVirtualServerName); if (lbserver != null) { //unbind the all services associated with this virtual server com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding[] serviceBindings = com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding.get(_netscalerService, nsVirtualServerName); - + if (serviceBindings != null) { for (com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding binding : serviceBindings) { String serviceName = binding.get_servicename(); @@ -535,7 +556,7 @@ public class NetscalerResource implements ServerResource { if (apiCallResult.errorcode != 0) { throw new ExecutionException("Failed to unbind service from the lb virtual server: " + nsVirtualServerName + " due to " + apiCallResult.message); } - + com.citrix.netscaler.nitro.resource.config.basic.service svc = com.citrix.netscaler.nitro.resource.config.basic.service.get(_netscalerService, serviceName); String nsServerName = svc.get_servername(); @@ -583,7 +604,7 @@ public class NetscalerResource implements ServerResource { } else { return new Answer(cmd, e); } - } + } } private synchronized Answer execute(CreateLoadBalancerApplianceCommand cmd, int numRetries) { @@ -615,8 +636,8 @@ public class NetscalerResource implements ServerResource { // use the first device profile available on the SDX to create an instance of VPX device_profile[] profiles = device_profile.get(_netscalerSdxService); if (!(profiles != null && profiles.length >= 1)) { - new Answer(cmd, new ExecutionException("Failed to create VPX instance on the netscaler SDX device " + _ip + - " as there are no admin profile to use for creating VPX.")); + new Answer(cmd, new ExecutionException("Failed to create VPX instance on the netscaler SDX device " + _ip + + " as there are no admin profile to use for creating VPX.")); } String profileName = profiles[0].get_name(); ns_obj.set_nsroot_profile(profileName); @@ -625,8 +646,8 @@ public class NetscalerResource implements ServerResource { // TODO: should enable the option to choose the template while adding the SDX device in to CloudStack xen_vpx_image[] vpxImages = xen_vpx_image.get(_netscalerSdxService); if (!(vpxImages != null && vpxImages.length >= 1)) { - new Answer(cmd, new ExecutionException("Failed to create VPX instance on the netscaler SDX device " + _ip + - " as there are no VPX images on SDX to use for creating VPX.")); + new Answer(cmd, new ExecutionException("Failed to create VPX instance on the netscaler SDX device " + _ip + + " as there are no VPX images on SDX to use for creating VPX.")); } String imageName = vpxImages[0].get_file_name(); ns_obj.set_image_name(imageName); @@ -648,7 +669,7 @@ public class NetscalerResource implements ServerResource { long startTick = System.currentTimeMillis(); long startWaitMilliSeconds = 600000; while(!newVpx.get_ns_state().equalsIgnoreCase("up") && System.currentTimeMillis() - startTick < startWaitMilliSeconds) { - try { + try { Thread.sleep(10000); } catch(InterruptedException e) { } @@ -1044,7 +1065,7 @@ public class NetscalerResource implements ServerResource { } // unbind the vlan to subnet - try { + try { vlan_nsip_binding vlanSnipBinding = new vlan_nsip_binding(); vlanSnipBinding.set_netmask(vlanNetmask); vlanSnipBinding.set_ipaddress(vlanSelfIp); @@ -1081,7 +1102,7 @@ public class NetscalerResource implements ServerResource { if (apiCallResult.errorcode != 0) { throw new ExecutionException("Failed to remove vlan with tag:" + vlanTag + "due to" + apiCallResult.message); } - } + } } catch (nitro_exception e) { throw new ExecutionException("Failed to delete guest vlan network on the Netscaler device due to " + e.getMessage()); } catch (Exception e) { @@ -1179,7 +1200,7 @@ public class NetscalerResource implements ServerResource { for (lbvserver vserver : lbservers) { filtervalue[] filter = new filtervalue[1]; filter[0] = new filtervalue("servicename", serviceName); - lbvserver_service_binding[] result = (lbvserver_service_binding[]) lbvserver_service_binding.get_filtered(_netscalerService, vserver.get_name(), filter); + lbvserver_service_binding[] result = lbvserver_service_binding.get_filtered(_netscalerService, vserver.get_name(), filter); if (result != null && result.length > 0) { return true; } @@ -1189,7 +1210,7 @@ public class NetscalerResource implements ServerResource { throw new ExecutionException("Failed to verify service " + serviceName + " is bound to any virtual server due to " + e.getMessage()); } } - + private boolean nsServiceExists(String serviceName) throws ExecutionException { try { if (com.citrix.netscaler.nitro.resource.config.basic.service.get(_netscalerService, serviceName) != null) { @@ -1288,7 +1309,7 @@ public class NetscalerResource implements ServerResource { return nsProtocol; } - private void addLBVirtualServer(String virtualServerName, String publicIp, int publicPort, String lbAlgorithm, String protocol, StickinessPolicyTO[] stickyPolicies) throws ExecutionException { + private void addLBVirtualServer(String virtualServerName, String publicIp, int publicPort, String lbAlgorithm, String protocol, StickinessPolicyTO[] stickyPolicies, AutoScaleVmGroupTO vmGroupTO) throws ExecutionException { try { String lbMethod; if ("roundrobin".equalsIgnoreCase(lbAlgorithm)) { @@ -1333,7 +1354,7 @@ public class NetscalerResource implements ServerResource { List> paramsList = stickinessPolicy.getParams(); for(Pair param : paramsList) { if ("holdtime".equalsIgnoreCase(param.first())) { - timeout = Long.parseLong(param.second()); + timeout = Long.parseLong(param.second()); } else if ("name".equalsIgnoreCase(param.first())) { cookieName = param.second(); } @@ -1401,6 +1422,617 @@ public class NetscalerResource implements ServerResource { } } + private boolean isScaleUpPolicy(AutoScalePolicyTO autoScalePolicyTO) { + return autoScalePolicyTO.getAction().equals("scaleup"); + } + + private boolean isScaleDownPolicy(AutoScalePolicyTO autoScalePolicyTO) { + return autoScalePolicyTO.getAction().equals("scaledown"); + } + + private void removeAutoScalePolicy(String timerName, String policyName) throws Exception { + // unbind timer policy + // unbbind timer trigger lb_astimer -policyName lb_policy_scaleUp + com.citrix.netscaler.nitro.resource.config.timer.timertrigger_timerpolicy_binding timer_policy_binding = new com.citrix.netscaler.nitro.resource.config.timer.timertrigger_timerpolicy_binding(); + try { + timer_policy_binding.set_name(timerName); + timer_policy_binding.set_policyname(policyName); + timer_policy_binding.set_global("DEFAULT"); + timer_policy_binding.delete(_netscalerService, timer_policy_binding); + } catch (Exception e) { + // Ignore Exception + throw e; + } + + // Removing Timer policy + // rm timer policy lb_policy_scaleUp_cpu_mem + com.citrix.netscaler.nitro.resource.config.timer.timerpolicy timerPolicy = new com.citrix.netscaler.nitro.resource.config.timer.timerpolicy(); + try { + timerPolicy.set_name(policyName); + timerPolicy.delete(_netscalerService, timerPolicy); + } catch (Exception e) { + // Ignore Exception + throw e; + } + + } + + @SuppressWarnings("static-access") + private synchronized boolean removeAutoScaleConfig(LoadBalancerTO loadBalancerTO) throws Exception, ExecutionException { + String srcIp = loadBalancerTO.getSrcIp(); + int srcPort = loadBalancerTO.getSrcPort(); + + String nsVirtualServerName = generateNSVirtualServerName(srcIp, srcPort); + String serviceGroupName = generateAutoScaleServiceGroupName(srcIp, srcPort); + + disableAutoScaleConfig(loadBalancerTO); + + // UnBind autoscale service group + // unbind lb vserver lb lb_autoscaleGroup + com.citrix.netscaler.nitro.resource.config.lb.lbvserver_servicegroup_binding vserver_servicegroup_binding = new com.citrix.netscaler.nitro.resource.config.lb.lbvserver_servicegroup_binding(); + try { + vserver_servicegroup_binding.set_name(nsVirtualServerName); + vserver_servicegroup_binding.set_servicegroupname(serviceGroupName); + vserver_servicegroup_binding.delete(_netscalerService, vserver_servicegroup_binding); + } catch (Exception e) { + // Ignore Exception + throw e; + } + + // Remove autoscale service group + com.citrix.netscaler.nitro.resource.config.basic.servicegroup serviceGroup = new com.citrix.netscaler.nitro.resource.config.basic.servicegroup(); + try { + serviceGroup.set_servicegroupname(serviceGroupName); + serviceGroup.delete(_netscalerService, serviceGroup); + } catch (Exception e) { + // Ignore Exception + throw e; + } + + // // Set min and max autoscale members to zero + // com.citrix.netscaler.nitro.resource.config.lb.lbvserver lbvserver = new + // com.citrix.netscaler.nitro.resource.config.lb.lbvserver(); + // try { + // lbvserver.set_name(nsVirtualServerName); + // lbvserver.set_minautoscalemembers(0); + // lbvserver.set_maxautoscalemembers(0); + // lbvserver.update(_netscalerService, lbvserver); + // } catch (Exception e) { + // // Ignore Exception + // throw e; + // } + + removeLBVirtualServer(nsVirtualServerName); + + return true; + } + + @SuppressWarnings("static-access") + private synchronized boolean disableAutoScaleConfig(LoadBalancerTO loadBalancerTO) throws Exception { + String srcIp = loadBalancerTO.getSrcIp(); + int srcPort = loadBalancerTO.getSrcPort(); + + String nsVirtualServerName = generateNSVirtualServerName(srcIp, srcPort); + String profileName = generateAutoScaleProfileName(srcIp, srcPort); + String timerName = generateAutoScaleTimerName(srcIp, srcPort); + String scaleDownActionName = generateAutoScaleScaleDownActionName(srcIp, srcPort); + String scaleUpActionName = generateAutoScaleScaleUpActionName(srcIp, srcPort); + String mtName = generateSnmpMetricTableName(srcIp, srcPort); + String monitorName = generateSnmpMonitorName(srcIp, srcPort); + String serviceGroupName = generateAutoScaleServiceGroupName(srcIp, srcPort); + AutoScaleVmGroupTO vmGroupTO = loadBalancerTO.getAutoScaleVmGroupTO(); + List policies = vmGroupTO.getPolicies(); + + /* Delete min/max member policies */ + String minMemberPolicyName = generateAutoScaleMinPolicyName(srcIp, srcPort); + + removeAutoScalePolicy(timerName, minMemberPolicyName); + + String maxMemberPolicyName = generateAutoScaleMaxPolicyName(srcIp, srcPort); + removeAutoScalePolicy(timerName, maxMemberPolicyName); + + boolean isSnmp = false; + /* Create Counters */ + for (AutoScalePolicyTO autoScalePolicyTO : policies) { + List conditions = autoScalePolicyTO.getConditions(); + for (ConditionTO conditionTO : conditions) { + CounterTO counterTO = conditionTO.getCounter(); + if(counterTO.getSource().equals("snmp")) { + isSnmp = true; + break; + } + } + String policyId = Long.toString(autoScalePolicyTO.getId()); + String policyName = generateAutoScalePolicyName(srcIp, srcPort,policyId); + + // Removing Timer policy + removeAutoScalePolicy(timerName, policyName); + } + + /* Delete AutoScale Config */ + // Delete AutoScale ScaleDown action + com.citrix.netscaler.nitro.resource.config.autoscale.autoscaleaction scaleDownAction = new com.citrix.netscaler.nitro.resource.config.autoscale.autoscaleaction(); + try { + scaleDownAction.set_name(scaleDownActionName); + scaleDownAction.delete(_netscalerService, scaleDownAction); + } catch (Exception e) { + // Ignore Exception + throw e; + } + + // Delete AutoScale ScaleUp action + com.citrix.netscaler.nitro.resource.config.autoscale.autoscaleaction scaleUpAction = new com.citrix.netscaler.nitro.resource.config.autoscale.autoscaleaction(); + try { + scaleUpAction.set_name(scaleUpActionName); + scaleUpAction.delete(_netscalerService, scaleUpAction); + } catch (Exception e) { + // Ignore Exception + throw e; + } + + // Delete Timer + com.citrix.netscaler.nitro.resource.config.timer.timertrigger timer = new com.citrix.netscaler.nitro.resource.config.timer.timertrigger(); + try { + timer.set_name(timerName); + timer.delete(_netscalerService, timer); + } catch (Exception e) { + // Ignore Exception + throw e; + } + + // Delete AutoScale Profile + com.citrix.netscaler.nitro.resource.config.autoscale.autoscaleprofile autoscaleProfile = new com.citrix.netscaler.nitro.resource.config.autoscale.autoscaleprofile(); + try { + autoscaleProfile.set_name(profileName); + autoscaleProfile.delete(_netscalerService, autoscaleProfile); + } catch (Exception e) { + // Ignore Exception + throw e; + } + + if(isSnmp) { + com.citrix.netscaler.nitro.resource.config.lb.lbmonitor_servicegroup_binding monitor_servicegroup_binding = new com.citrix.netscaler.nitro.resource.config.lb.lbmonitor_servicegroup_binding(); + try { + monitor_servicegroup_binding.set_monitorname(monitorName); + monitor_servicegroup_binding.set_servicegroupname(serviceGroupName); + monitor_servicegroup_binding.delete(_netscalerService, monitor_servicegroup_binding); + } catch (Exception e) { + // Ignore Exception + throw e; + } + + // Delete Monitor + // rm lb monitor lb_metric_table_mon + com.citrix.netscaler.nitro.resource.config.lb.lbmonitor monitor = new com.citrix.netscaler.nitro.resource.config.lb.lbmonitor(); + try { + monitor.set_monitorname(monitorName); + monitor.set_type("LOAD"); + monitor.delete(_netscalerService, monitor); + } catch (Exception e) { + // Ignore Exception + throw e; + } + + // Delete Metric Table + com.citrix.netscaler.nitro.resource.config.lb.lbmetrictable metricTable = new com.citrix.netscaler.nitro.resource.config.lb.lbmetrictable(); + try { + metricTable.set_metrictable(mtName); + metricTable.delete(_netscalerService, metricTable); + } catch (Exception e) { + // Ignore Exception + throw e; + } + } + + + return true; + } + + @SuppressWarnings("static-access") + private synchronized boolean createAutoScaleConfig(LoadBalancerTO loadBalancerTO) throws ExecutionException, Exception { + + String srcIp = loadBalancerTO.getSrcIp(); + int srcPort = loadBalancerTO.getSrcPort(); + String lbProtocol = getNetScalerProtocol(loadBalancerTO); + String lbAlgorithm = loadBalancerTO.getAlgorithm(); + String nsVirtualServerName = generateNSVirtualServerName(srcIp, srcPort); + AutoScaleVmGroupTO vmGroupTO = loadBalancerTO.getAutoScaleVmGroupTO(); + addLBVirtualServer(nsVirtualServerName, srcIp, srcPort, lbAlgorithm, lbProtocol, loadBalancerTO.getStickinessPolicies(), vmGroupTO); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Created load balancing virtual server " + nsVirtualServerName + " on the Netscaler device"); + } + + String serviceGroupName = generateAutoScaleServiceGroupName(srcIp, srcPort); + // add servicegroup lb_autoscaleGroup -autoscale POLICY -memberPort 80 + com.citrix.netscaler.nitro.resource.config.basic.servicegroup serviceGroup = new com.citrix.netscaler.nitro.resource.config.basic.servicegroup(); + int memberPort = vmGroupTO.getMemberPort(); + try { + serviceGroup.set_servicegroupname(serviceGroupName); + serviceGroup.set_servicetype(lbProtocol); + serviceGroup.set_autoscale("POLICY"); // TODO: Values not displayed in API + serviceGroup.set_memberport(memberPort); + serviceGroup.add(_netscalerService, serviceGroup); + } catch (Exception e) { + // Ignore Exception + throw e; + } + + // Bind autoscale service group + // bind lb vserver lb lb_autoscaleGroup + com.citrix.netscaler.nitro.resource.config.lb.lbvserver_servicegroup_binding vserver_servicegroup_binding = new com.citrix.netscaler.nitro.resource.config.lb.lbvserver_servicegroup_binding(); + + try { + vserver_servicegroup_binding.set_name(nsVirtualServerName); + vserver_servicegroup_binding.set_servicegroupname(serviceGroupName); + vserver_servicegroup_binding.add(_netscalerService, vserver_servicegroup_binding); + } catch (Exception e) { + // Ignore Exception + throw e; + } + + // Create the autoscale config + enableAutoScaleConfig(loadBalancerTO); + return true; + } + + @SuppressWarnings("static-access") + private synchronized boolean enableAutoScaleConfig(LoadBalancerTO loadBalancerTO) throws Exception { + String srcIp = loadBalancerTO.getSrcIp(); + int srcPort = loadBalancerTO.getSrcPort(); + + String nsVirtualServerName = generateNSVirtualServerName(srcIp, srcPort); + String serviceGroupName = generateAutoScaleServiceGroupName(srcIp, srcPort); + String profileName = generateAutoScaleProfileName(srcIp, srcPort); + String timerName = generateAutoScaleTimerName(srcIp, srcPort); + String scaleDownActionName = generateAutoScaleScaleDownActionName(srcIp, srcPort); + String scaleUpActionName = generateAutoScaleScaleUpActionName(srcIp, srcPort); + String mtName = generateSnmpMetricTableName(srcIp, srcPort); + String monitorName = generateSnmpMonitorName(srcIp, srcPort); + AutoScaleVmGroupTO vmGroupTO = loadBalancerTO.getAutoScaleVmGroupTO(); + AutoScaleVmProfileTO profileTO = vmGroupTO.getProfile(); + List policies = vmGroupTO.getPolicies(); + int interval = vmGroupTO.getInterval(); + int snmpPort = profileTO.getSnmpPort(); + String snmpCommunity = profileTO.getSnmpCommunity(); + long cur_prirotiy = 1; + + + // Set min and max autoscale members; + // add lb vserver lb http 10.102.31.100 80 -minAutoscaleMinMembers 3 -maxAutoscaleMembers 10 + int minAutoScaleMembers = vmGroupTO.getMinMembers(); + int maxAutoScaleMembers = vmGroupTO.getMaxMembers(); + com.citrix.netscaler.nitro.resource.config.lb.lbvserver lbvserver = new com.citrix.netscaler.nitro.resource.config.lb.lbvserver(); + try { + lbvserver.set_name(nsVirtualServerName); + lbvserver.set_minautoscalemembers(minAutoScaleMembers); + lbvserver.set_maxautoscalemembers(maxAutoScaleMembers); + lbvserver.update(_netscalerService, lbvserver); + } catch (Exception e) { + // Ignore Exception + throw e; + } + + /* AutoScale Config */ + // Add AutoScale Profile + // add autoscale profile lb_asprofile CLOUDSTACK -url -http:// 10.102.31.34:8080/client/api- -apiKey abcdef + // -sharedSecret xyzabc + String apiKey = profileTO.getAutoScaleUserApiKey(); + 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(); + try { + autoscaleProfile.set_name(profileName); + autoscaleProfile.set_type("CLOUDSTACK"); + autoscaleProfile.set_apikey(apiKey); + autoscaleProfile.set_sharedsecret(secretKey); + autoscaleProfile.set_url(url); + autoscaleProfile.add(_netscalerService, autoscaleProfile); + } catch (Exception e) { + // Ignore Exception + + throw e; + } + + // Add Timer + com.citrix.netscaler.nitro.resource.config.timer.timertrigger timer = new com.citrix.netscaler.nitro.resource.config.timer.timertrigger(); + try { + timer.set_name(timerName); + timer.set_interval(interval); + timer.add(_netscalerService, timer); + } catch (Exception e) { + // Ignore Exception + throw e; + } + + // AutoScale Actions + Integer scaleUpQuietTime = null; + Integer scaleDownQuietTime = null; + for (AutoScalePolicyTO autoScalePolicyTO : policies) { + if(scaleUpQuietTime == null) { + if(isScaleUpPolicy(autoScalePolicyTO)) { + scaleUpQuietTime = autoScalePolicyTO.getQuietTime(); + if(scaleDownQuietTime != null) { + break; + } + } + } + if(scaleDownQuietTime == null) { + if(isScaleDownPolicy(autoScalePolicyTO)) { + scaleDownQuietTime = autoScalePolicyTO.getQuietTime(); + if(scaleUpQuietTime != null) { + break; + } + } + } + } + + // Add AutoScale ScaleUp action + // add autoscale action lb_scaleUpAction provision -vserver lb -profilename lb_asprofile -params + // -lbruleid=1234&command=deployvm&zoneid=10&templateid=5&serviceofferingid=3- -quiettime 300 + com.citrix.netscaler.nitro.resource.config.autoscale.autoscaleaction scaleUpAction = new com.citrix.netscaler.nitro.resource.config.autoscale.autoscaleaction(); + try { + scaleUpAction.set_name(scaleUpActionName); + scaleUpAction.set_type("SCALE_UP"); // TODO: will this be called provision? + scaleUpAction.set_vserver(nsVirtualServerName); // Actions Vserver, the one that is autoscaled, with CS + // now both are same. Not exposed in API. + scaleUpAction.set_profilename(profileName); + scaleUpAction.set_quiettime(scaleUpQuietTime); + String scaleUpParameters = "command=deployVirtualMachine" + "&" + + ApiConstants.ZONE_ID + "=" + profileTO.getZoneId()+ "&" + + ApiConstants.SERVICE_OFFERING_ID + "=" + profileTO.getServiceOfferingId()+ "&" + + ApiConstants.TEMPLATE_ID + "=" + profileTO.getTemplateId()+ "&" + + ((profileTO.getOtherDeployParams() == null)? "" : (profileTO.getOtherDeployParams() + "&")) + + "lbruleid=" + loadBalancerTO.getId(); + scaleUpAction.set_parameters(scaleUpParameters); + scaleUpAction.add(_netscalerService, scaleUpAction); + } catch (Exception e) { + // Ignore Exception + throw e; + } + + com.citrix.netscaler.nitro.resource.config.autoscale.autoscaleaction scaleDownAction = new com.citrix.netscaler.nitro.resource.config.autoscale.autoscaleaction(); + Integer destroyVmGracePeriod = profileTO.getDestroyVmGraceperiod(); + try { + scaleDownAction.set_name(scaleDownActionName); + scaleDownAction.set_type("SCALE_DOWN"); // TODO: will this be called de-provision? + scaleDownAction.set_vserver(nsVirtualServerName); // TODO: no global option as of now through Nitro. + // Testing cannot be done. + scaleDownAction.set_profilename(profileName); + scaleDownAction.set_quiettime(scaleDownQuietTime); + String scaleDownParameters = "command=destroyVirtualMachine" + "&" + + "lbruleid=" + loadBalancerTO.getId(); + scaleDownAction.set_parameters(scaleDownParameters); + scaleDownAction.set_vmdestroygraceperiod(destroyVmGracePeriod); + scaleDownAction.add(_netscalerService, scaleDownAction); + } catch (Exception e) { + // Ignore Exception + throw e; + } + + /* Create min member policy */ + String minMemberPolicyName = generateAutoScaleMinPolicyName(srcIp, srcPort); + String minMemberPolicyExp = "SYS.VSERVER(\"" + nsVirtualServerName + "\").ACTIVESERVICES.LT(SYS.VSERVER(\"" + nsVirtualServerName + "\").MINAUTOSCALEMEMBERS)"; + addAutoScalePolicy(timerName, minMemberPolicyName, cur_prirotiy++, minMemberPolicyExp, scaleUpActionName, + interval, interval); + + /* Create max member policy */ + String maxMemberPolicyName = generateAutoScaleMaxPolicyName(srcIp, srcPort); + String maxMemberPolicyExp = "SYS.VSERVER(\"" + nsVirtualServerName + "\").ACTIVESERVICES.GT(SYS.VSERVER(\"" + nsVirtualServerName + "\").MAXAUTOSCALEMEMBERS)"; + addAutoScalePolicy(timerName, maxMemberPolicyName, cur_prirotiy++, maxMemberPolicyExp, scaleDownActionName, + interval, interval); + + /* Create Counters */ + HashMap snmpMetrics = new HashMap(); + for (AutoScalePolicyTO autoScalePolicyTO : policies) { + List conditions = autoScalePolicyTO.getConditions(); + String policyExpression = ""; + int snmpCounterNumber = 0; + for (ConditionTO conditionTO : conditions) { + CounterTO counterTO = conditionTO.getCounter(); + String counterName = counterTO.getName(); + String operator = conditionTO.getRelationalOperator(); + long threshold = conditionTO.getThreshold(); + + StringBuilder conditionExpression = new StringBuilder(); + Formatter formatter = new Formatter(conditionExpression, Locale.US); + + if(counterTO.getSource().equals("snmp")) + { + counterName = generateSnmpMetricName(counterName); + if(snmpMetrics.size() == 0) { + // Create Metric Table + //add lb metricTable lb_metric_table + com.citrix.netscaler.nitro.resource.config.lb.lbmetrictable metricTable = new com.citrix.netscaler.nitro.resource.config.lb.lbmetrictable(); + try { + metricTable.set_metrictable(mtName); + metricTable.add(_netscalerService, metricTable); + } catch (Exception e) { + // Ignore Exception + throw e; + } + + // Create Monitor + // add lb monitor lb_metric_table_mon LOAD -destPort 161 -snmpCommunity public -metricTable + // lb_metric_table -interval + com.citrix.netscaler.nitro.resource.config.lb.lbmonitor monitor = new com.citrix.netscaler.nitro.resource.config.lb.lbmonitor(); + try { + monitor.set_monitorname(monitorName); + monitor.set_type("LOAD"); + monitor.set_destport(snmpPort); + monitor.set_snmpcommunity(snmpCommunity); + monitor.set_metrictable(mtName); + monitor.set_interval((int)(interval * 0.8)); + monitor.add(_netscalerService, monitor); + } catch (Exception e) { + // Ignore Exception + throw e; + } + + // Bind servicegroup to monitor. TODO: This will change later to bind Monitor to ServiceGroup. + // bind lb monitor lb_metric_table_mon lb_autoscaleGroup -passive + com.citrix.netscaler.nitro.resource.config.lb.lbmonitor_servicegroup_binding monitor_servicegroup_binding = new com.citrix.netscaler.nitro.resource.config.lb.lbmonitor_servicegroup_binding(); + try { + monitor_servicegroup_binding.set_monitorname(monitorName); + monitor_servicegroup_binding.set_servicegroupname(serviceGroupName); + monitor_servicegroup_binding.set_passive(true); // Mark the monitor to do only collect + // metrics, basically use it for autoscaling purpose only. + monitor_servicegroup_binding.add(_netscalerService, monitor_servicegroup_binding); + } catch (Exception e) { + // Ignore Exception + throw e; + } + } + + boolean newMetric = !snmpMetrics.containsKey(counterName); + if(newMetric) { + snmpMetrics.put(counterName, snmpCounterNumber++); + } + + if(newMetric) + { + // bind lb metricTable lb_metric_table mem 1.3.6.1.4.1.2021.11.9.0 + String counterOid = counterTO.getValue(); + com.citrix.netscaler.nitro.resource.config.lb.lbmetrictable_metric_binding metrictable_metric_binding = new com.citrix.netscaler.nitro.resource.config.lb.lbmetrictable_metric_binding(); + try { + metrictable_metric_binding.set_metrictable(mtName); + metrictable_metric_binding.set_metric(counterName); + metrictable_metric_binding.set_Snmpoid(counterOid); + metrictable_metric_binding.add(_netscalerService, metrictable_metric_binding); + } catch (Exception e) { + // Ignore Exception + throw e; + } + + // bind lb monitor lb_metric_table_mon -metric cpu -metricThreshold 1 + com.citrix.netscaler.nitro.resource.config.lb.lbmonitor_lbmetrictable_binding monitor_metrictable_binding = new com.citrix.netscaler.nitro.resource.config.lb.lbmonitor_lbmetrictable_binding(); + try { + monitor_metrictable_binding.set_monitorname(monitorName); + monitor_metrictable_binding.set_metric(counterName); + monitor_metrictable_binding.set_metricthreshold(1); // 1 is a dummy threshold + monitor_metrictable_binding.add(_netscalerService, monitor_metrictable_binding); + } catch (Exception e) { + // Ignore Exception + throw e; + } + } + // SYS.VSERVER("abcd").SNMP_TABLE(0).AVERAGE_VALUE.GT(80) + int counterIndex = snmpMetrics.get(counterName); // TODO: temporary fix. later on counter name will be added as a param to SNMP_TABLE. + formatter.format("SYS.VSERVER(\"%s\").SNMP_TABLE(%d).AVERAGE_VALUE.%s(%d)",nsVirtualServerName, counterIndex, operator, threshold); + } + else if (counterTO.getSource().equals("netscaler")) + { + //SYS.VSERVER("abcd").RESPTIME.GT(10) + formatter.format("SYS.VSERVER(\"%s\").%s.%s(%d)",nsVirtualServerName, counterTO.getValue(), operator, threshold); + } + if(policyExpression.length() != 0) { + policyExpression += " && "; + } + policyExpression += conditionExpression; + } + policyExpression = "(" + policyExpression + ")"; + + String policyId = Long.toString(autoScalePolicyTO.getId()); + String policyName = generateAutoScalePolicyName(srcIp, srcPort, policyId); + String action = null; + if(isScaleUpPolicy(autoScalePolicyTO)) { + action = scaleUpActionName; + String scaleUpCondition = "SYS.VSERVER(\"" + nsVirtualServerName + "\").ACTIVESERVICES.LT(SYS.VSERVER(\"" + nsVirtualServerName + "\").MAXAUTOSCALEMEMBERS)"; + policyExpression = scaleUpCondition + " && " + policyExpression; + } else { + action = scaleDownActionName; + String scaleDownCondition = "SYS.VSERVER(\"" + nsVirtualServerName + "\").ACTIVESERVICES.GT(SYS.VSERVER(\"" + nsVirtualServerName + "\").MINAUTOSCALEMEMBERS)"; + policyExpression = scaleDownCondition + " && " + policyExpression; + } + + addAutoScalePolicy(timerName, policyName, cur_prirotiy++, policyExpression, action, + autoScalePolicyTO.getDuration(), interval); + + } + + return true; + } + + + private synchronized void addAutoScalePolicy(String timerName,String policyName, long priority, String policyExpression, String action, + int duration, int interval) throws Exception { + // Adding a autoscale policy + // add timer policy lb_policy_scaleUp_cpu_mem -rule - (SYS.CUR_VSERVER.METRIC_TABLE(cpu).AVG_VAL.GT(80)- + // -action lb_scaleUpAction + com.citrix.netscaler.nitro.resource.config.timer.timerpolicy timerPolicy = new com.citrix.netscaler.nitro.resource.config.timer.timerpolicy(); + try { + timerPolicy.set_name(policyName); + timerPolicy.set_action(action); + timerPolicy.set_rule(policyExpression); + timerPolicy.add(_netscalerService, timerPolicy); + } catch (Exception e) { + // Ignore Exception + throw e; + } + + // bind timer policy + // For now it is bound globally. + // bind timer trigger lb_astimer -policyName lb_policy_scaleUp -vserver lb -priority 1 -samplesize 5 + // TODO: later bind to lbvserver. bind timer trigger lb_astimer -policyName lb_policy_scaleUp -vserver lb -priority 1 -samplesize 5 + // -thresholdsize 5 + com.citrix.netscaler.nitro.resource.config.timer.timertrigger_timerpolicy_binding timer_policy_binding = new com.citrix.netscaler.nitro.resource.config.timer.timertrigger_timerpolicy_binding(); + int sampleSize = duration/interval; + try { + timer_policy_binding.set_name(timerName); + timer_policy_binding.set_policyname(policyName); + // timer_policy_binding.set_vserver(nsVirtualServerName); + timer_policy_binding.set_global("DEFAULT"); // vserver name is present at the expression + timer_policy_binding.set_samplesize(sampleSize); + timer_policy_binding.set_thresholdsize(sampleSize); // We are not exposing this parameter as of now. + // i.e. n(m) is not exposed to CS user. So thresholdSize == sampleSize + timer_policy_binding.set_priority(priority); + timer_policy_binding.add(_netscalerService, timer_policy_binding); + } catch (Exception e) { + // Ignore Exception + throw e; + } + } + public synchronized void applyAutoScaleConfig(LoadBalancerTO loadBalancer) throws Exception, ExecutionException { + + AutoScaleVmGroupTO vmGroupTO = loadBalancer.getAutoScaleVmGroupTO(); + if(!isAutoScaleSupportedInNetScaler()) { + throw new ExecutionException("AutoScale not supported in this version of NetScaler"); + } + if(vmGroupTO.getState().equals("new")) { + assert !loadBalancer.isRevoked(); + createAutoScaleConfig(loadBalancer); + } + else if(loadBalancer.isRevoked() || vmGroupTO.getState().equals("revoke")) { + removeAutoScaleConfig(loadBalancer); + } + else if(vmGroupTO.getState().equals("enabled")) { + assert !loadBalancer.isRevoked(); + enableAutoScaleConfig(loadBalancer); + } + else if(vmGroupTO.getState().equals("disabled")) { + assert !loadBalancer.isRevoked(); + disableAutoScaleConfig(loadBalancer); + } else { + ///// This should never happen + throw new ExecutionException("Unknown vmGroup State :" + vmGroupTO.getState()); + } + } + + private boolean isAutoScaleSupportedInNetScaler() throws ExecutionException { + autoscaleprofile autoscaleProfile = new autoscaleprofile(); + try { + autoscaleProfile.get(_netscalerService); + } catch (Exception ex) { + // Looks like autoscale is not supported in this netscaler. + // TODO: Config team has introduce a new command to check + // the list of entities supported in a NetScaler. Can use that + // once it is present in AutoScale branch. + s_logger.warn("AutoScale is not supported in NetScaler"); + return false; + } + return true; + } + private void saveConfiguration() throws ExecutionException { try { apiCallResult = nsconfig.save(_netscalerService); @@ -1429,14 +2061,14 @@ public class NetscalerResource implements ServerResource { lbvserver vserver = lbvserver.get(_netscalerService, lbvserverName); if(vserver != null){ String lbVirtualServerIp = vserver.get_ipv46(); - + long[] bytesSentAndReceived = answer.ipBytes.get(lbVirtualServerIp); if (bytesSentAndReceived == null) { bytesSentAndReceived = new long[]{0, 0}; } bytesSentAndReceived[0] += stat_entry.get_totalrequestbytes(); bytesSentAndReceived[1] += stat_entry.get_totalresponsebytes(); - + if (bytesSentAndReceived[0] >= 0 && bytesSentAndReceived[1] >= 0) { answer.ipBytes.put(lbVirtualServerIp, bytesSentAndReceived); } @@ -1483,6 +2115,49 @@ public class NetscalerResource implements ServerResource { private String generateNSServiceName(String ip, long port) { return genObjectName("Cloud-Service", ip, port); } + private String generateAutoScaleServiceGroupName(String srcIp, long srcPort) { + return genObjectName("Cloud-AutoScaleServiceGroup", srcIp, srcPort); + } + + private String generateAutoScaleTimerName(String srcIp, long srcPort) { + return genObjectName("Cloud-AutoScale-Timer", srcIp, srcPort); + } + + private String generateAutoScaleProfileName(String srcIp, long srcPort) { + return genObjectName("Cloud-AutoScale-Profile", srcIp, srcPort); + } + + private String generateAutoScaleScaleUpActionName(String srcIp, long srcPort) { + return genObjectName("Cloud-AutoScale-ScaleUpAction", srcIp, srcPort); + } + + private String generateAutoScaleScaleDownActionName(String srcIp, long srcPort) { + return genObjectName("Cloud-AutoScale-ScaleDownAction", srcIp, srcPort); + } + + private String generateAutoScalePolicyName(String srcIp, long srcPort, String poilcyId) { + return genObjectName("Cloud-AutoScale-Policy", srcIp, srcPort, poilcyId); + } + + private String generateAutoScaleMinPolicyName(String srcIp, long srcPort) { + return genObjectName("Cloud-AutoScale-Policy-Min", srcIp, srcPort); + } + + private String generateAutoScaleMaxPolicyName(String srcIp, long srcPort) { + return genObjectName("Cloud-AutoScale-Policy-Max", srcIp, srcPort); + } + + private String generateSnmpMetricTableName(String srcIp, long srcPort) { + return genObjectName("Cloud-MTbl", srcIp, srcPort); + } + + private String generateSnmpMonitorName(String srcIp, long srcPort) { + return genObjectName("Cloud-Mon", srcIp, srcPort); + } + + private String generateSnmpMetricName(String counterName) { + return counterName.replace(' ', '_'); + } private String genObjectName(Object... args) { String objectName = ""; @@ -1514,7 +2189,7 @@ public class NetscalerResource implements ServerResource { public void setAgentControl(IAgentControl agentControl) { return; } - + @Override public String getName() { return _name; @@ -1528,7 +2203,7 @@ public class NetscalerResource implements ServerResource { @Override public boolean stop() { return true; - } + } @Override public void disconnected() { diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java index 418fe362fd4..3b5f634f216 100755 --- a/server/src/com/cloud/api/ApiDBUtils.java +++ b/server/src/com/cloud/api/ApiDBUtils.java @@ -16,6 +16,7 @@ // under the License. package com.cloud.api; +import java.util.ArrayList; import java.util.Hashtable; import java.util.List; import java.util.Map; @@ -65,6 +66,16 @@ import com.cloud.network.NetworkVO; import com.cloud.network.Site2SiteVpnGatewayVO; import com.cloud.network.Site2SiteCustomerGatewayVO; import com.cloud.network.Networks.TrafficType; +import com.cloud.network.as.AutoScalePolicy; +import com.cloud.network.as.AutoScalePolicyConditionMapVO; +import com.cloud.network.as.AutoScaleVmGroupPolicyMapVO; +import com.cloud.network.as.ConditionVO; +import com.cloud.network.as.CounterVO; +import com.cloud.network.as.dao.AutoScalePolicyConditionMapDao; +import com.cloud.network.as.dao.AutoScalePolicyDao; +import com.cloud.network.as.dao.AutoScaleVmGroupPolicyMapDao; +import com.cloud.network.as.dao.ConditionDao; +import com.cloud.network.as.dao.CounterDao; import com.cloud.network.dao.FirewallRulesCidrsDao; import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.LoadBalancerDao; @@ -213,9 +224,14 @@ public class ApiDBUtils { private static UserVmDetailsDao _userVmDetailsDao; private static SSHKeyPairDao _sshKeyPairDao; + private static ConditionDao _asConditionDao; + private static AutoScalePolicyConditionMapDao _asPolicyConditionMapDao; + private static AutoScaleVmGroupPolicyMapDao _asVmGroupPolicyMapDao; + private static AutoScalePolicyDao _asPolicyDao; + private static CounterDao _counterDao; static { _ms = (ManagementServer) ComponentLocator.getComponent(ManagementServer.Name); - ComponentLocator locator = ComponentLocator.getLocator(ManagementServer.Name); + ComponentLocator locator = ComponentLocator.getLocator(ManagementServer.Name); _asyncMgr = locator.getManager(AsyncJobManager.class); _securityGroupMgr = locator.getManager(SecurityGroupManager.class); _storageMgr = locator.getManager(StorageManager.class); @@ -271,6 +287,13 @@ public class ApiDBUtils { _taggedResourceService = locator.getManager(TaggedResourceService.class); _sshKeyPairDao = locator.getDao(SSHKeyPairDao.class); _userVmDetailsDao = locator.getDao(UserVmDetailsDao.class); + _asConditionDao = locator.getDao(ConditionDao.class); + _asPolicyDao = locator.getDao(AutoScalePolicyDao.class); + _asPolicyConditionMapDao = locator.getDao(AutoScalePolicyConditionMapDao.class); + _counterDao = locator.getDao(CounterDao.class); + _asVmGroupPolicyMapDao = locator.getDao(AutoScaleVmGroupPolicyMapDao.class); + _asVmGroupPolicyMapDao = locator.getDao(AutoScaleVmGroupPolicyMapDao.class); + _counterDao = locator.getDao(CounterDao.class); // Note: stats collector should already have been initialized by this time, otherwise a null instance is returned _statsCollector = StatsCollector.getInstance(); @@ -299,20 +322,20 @@ public class ApiDBUtils { // into this utils class. return _ms.getMemoryOrCpuCapacityByHost(poolId, capacityType); } - + public static List getCapacityByClusterPodZone(Long zoneId, Long podId, Long clusterId){ - return _capacityDao.findByClusterPodZone(zoneId,podId,clusterId); + return _capacityDao.findByClusterPodZone(zoneId,podId,clusterId); } - + public static List findNonSharedStorageForClusterPodZone(Long zoneId, Long podId, Long clusterId){ - return _capacityDao.findNonSharedStorageForClusterPodZone(zoneId,podId,clusterId); + return _capacityDao.findNonSharedStorageForClusterPodZone(zoneId,podId,clusterId); } - + public static List getCapacityByPod(){ - return null; - + return null; + } - + public static Long getPodIdForVlan(long vlanDbId) { return _networkMgr.getPodIdForVlan(vlanDbId); } @@ -402,15 +425,15 @@ public class ApiDBUtils { public static StorageStats getSecondaryStorageStatistics(long id) { return _statsCollector.getStorageStats(id); } - + public static CapacityVO getStoragePoolUsedStats(Long poolId, Long clusterId, Long podId, Long zoneId){ - return _storageMgr.getStoragePoolUsedStats(poolId, clusterId, podId, zoneId); + return _storageMgr.getStoragePoolUsedStats(poolId, clusterId, podId, zoneId); } public static CapacityVO getSecondaryStorageUsedStats(Long hostId, Long zoneId){ - return _storageMgr.getSecondaryStorageUsedStats(hostId, zoneId); + return _storageMgr.getSecondaryStorageUsedStats(hostId, zoneId); } - + // /////////////////////////////////////////////////////////// // Dao methods // // /////////////////////////////////////////////////////////// @@ -454,7 +477,7 @@ public class ApiDBUtils { public static GuestOS findGuestOSByDisplayName(String displayName) { return _guestOSDao.listByDisplayName(displayName); } - + public static HostVO findHostById(Long hostId) { return _hostDao.findByIdIncludingRemoved(hostId); } @@ -520,15 +543,15 @@ public class ApiDBUtils { } public static VMTemplateVO findTemplateById(Long templateId) { - VMTemplateVO template = _templateDao.findByIdIncludingRemoved(templateId); - if(template != null) { - Map details = _templateDetailsDao.findDetails(templateId); - if(details != null && !details.isEmpty()) - template.setDetails(details); - } - return template; + VMTemplateVO template = _templateDao.findByIdIncludingRemoved(templateId); + if(template != null) { + Map details = _templateDetailsDao.findDetails(templateId); + if(details != null && !details.isEmpty()) + template.setDetails(details); + } + return template; } - + public static VMTemplateHostVO findTemplateHostRef(long templateId, long zoneId) { return findTemplateHostRef(templateId, zoneId, false); } @@ -542,12 +565,12 @@ public class ApiDBUtils { return _storageMgr.getTemplateHostRef(zoneId, templateId, readyOnly); } } - - + + public static VolumeHostVO findVolumeHostRef(long volumeId, long zoneId) { return _volumeHostDao.findVolumeByZone(volumeId, zoneId); } - + public static VMTemplateSwiftVO findTemplateSwiftRef(long templateId) { return _templateSwiftDao.findOneByTemplateId(templateId); } @@ -600,9 +623,9 @@ public class ApiDBUtils { public static HypervisorType getVolumeHyperType(long volumeId) { return _volumeDao.getHypervisorType(volumeId); } - + public static HypervisorType getHypervisorTypeFromFormat(ImageFormat format){ - return _storageMgr.getHypervisorTypeFromFormat(format); + return _storageMgr.getHypervisorTypeFromFormat(format); } public static List listTemplateHostBy(long templateId, Long zoneId, boolean readyOnly) { @@ -703,13 +726,13 @@ public class ApiDBUtils { float cpuOverprovisioningFactor = NumbersUtil.parseFloat(opFactor, 1); return cpuOverprovisioningFactor; } - + public static boolean isExtractionDisabled(){ - String disableExtractionString = _configDao.getValue(Config.DisableExtraction.toString()); + String disableExtractionString = _configDao.getValue(Config.DisableExtraction.toString()); boolean disableExtraction = (disableExtractionString == null) ? false : Boolean.parseBoolean(disableExtractionString); return disableExtraction; } - + public static SecurityGroup getSecurityGroup(String groupName, long ownerId) { return _securityGroupMgr.getSecurityGroup(groupName, ownerId); } @@ -717,19 +740,19 @@ public class ApiDBUtils { public static ConsoleProxyVO findConsoleProxy(long id) { return _consoleProxyDao.findById(id); } - + public static List findFirewallSourceCidrs(long id){ - return _firewallCidrsDao.getSourceCidrs(id); + return _firewallCidrsDao.getSourceCidrs(id); } - + public static Hashtable listVmDetails(Hashtable vmData){ return _userVmDao.listVmDetails(vmData); } - + public static Account getProjectOwner(long projectId) { return _projectMgr.getProjectOwner(projectId); } - + public static Project findProjectByProjectAccountId(long projectAccountId) { return _projectMgr.findByProjectAccountId(projectAccountId); } @@ -741,53 +764,53 @@ public class ApiDBUtils { public static Project findProjectById(long projectId) { return _projectMgr.getProject(projectId); } - + public static long getProjectOwnwerId(long projectId) { return _projectMgr.getProjectOwner(projectId).getId(); } - + public static Map getAccountDetails(long accountId) { - Map details = _accountDetailsDao.findDetails(accountId); - return details.isEmpty() ? null : details; + Map details = _accountDetailsDao.findDetails(accountId); + return details.isEmpty() ? null : details; } public static Map> listNetworkOfferingServices(long networkOfferingId) { return _networkMgr.getNetworkOfferingServiceProvidersMap(networkOfferingId); } - + public static List getElementServices(Provider provider) { - return _networkMgr.getElementServices(provider); + return _networkMgr.getElementServices(provider); } - + public static List getProvidersForService(Service service) { return _networkMgr.listSupportedNetworkServiceProviders(service.getName()); - } + } public static boolean canElementEnableIndividualServices(Provider serviceProvider) { return _networkMgr.canElementEnableIndividualServices(serviceProvider); } - + public static Pair getDomainNetworkDetails(long networkId) { - NetworkDomainVO map = _networkDomainDao.getDomainNetworkMapByNetworkId(networkId); - - boolean subdomainAccess = (map.isSubdomainAccess() != null) ? map.isSubdomainAccess() : _networkMgr.getAllowSubdomainAccessGlobal(); - - return new Pair(map.getDomainId(), subdomainAccess); + NetworkDomainVO map = _networkDomainDao.getDomainNetworkMapByNetworkId(networkId); + + boolean subdomainAccess = (map.isSubdomainAccess() != null) ? map.isSubdomainAccess() : _networkMgr.getAllowSubdomainAccessGlobal(); + + return new Pair(map.getDomainId(), subdomainAccess); } - + public static long countFreePublicIps() { - return _ipAddressDao.countFreePublicIPs(); + return _ipAddressDao.countFreePublicIPs(); } - + public static long findDefaultRouterServiceOffering() { ServiceOfferingVO serviceOffering = _serviceOfferingDao.findByName(ServiceOffering.routerDefaultOffUniqueName); return serviceOffering.getId(); } - + public static IpAddress findIpByAssociatedVmId(long vmId) { return _ipAddressDao.findByAssociatedVmId(vmId); } - + public static String getHaTag() { return _haMgr.getHaTag(); } @@ -803,7 +826,7 @@ public class ApiDBUtils { public static boolean canUseForDeploy(Network network) { return _networkMgr.canUseForDeploy(network); } - + public static String getUuid(String resourceId, TaggedResourceType resourceType) { return _taggedResourceService.getUuid(resourceId, resourceType); } @@ -816,7 +839,28 @@ public class ApiDBUtils { public static List listByResourceTypeAndId(TaggedResourceType type, long resourceId) { return _taggedResourceService.listByResourceTypeAndId(type, resourceId); } + public static List getAutoScalePolicyConditions(long policyId) + { + List vos = _asPolicyConditionMapDao.listByAll(policyId, null); + ArrayList conditions = new ArrayList(vos.size()); + for (AutoScalePolicyConditionMapVO vo : vos) { + conditions.add(_asConditionDao.findById(vo.getConditionId())); + } + return conditions; + } + + public static void getAutoScaleVmGroupPolicyIds(long vmGroupId, List scaleUpPolicyIds, List scaleDownPolicyIds) + { + List vos = _asVmGroupPolicyMapDao.listByVmGroupId(vmGroupId); + for (AutoScaleVmGroupPolicyMapVO vo : vos) { + AutoScalePolicy autoScalePolicy = _asPolicyDao.findById(vo.getPolicyId()); + if(autoScalePolicy.getAction().equals("scaleup")) + scaleUpPolicyIds.add(autoScalePolicy.getId()); + else + scaleDownPolicyIds.add(autoScalePolicy.getId()); + } + } public static String getKeyPairName(String sshPublicKey) { SSHKeyPairVO sshKeyPair = _sshKeyPairDao.findByPublicKey(sshPublicKey); //key might be removed prior to this point @@ -829,4 +873,19 @@ public class ApiDBUtils { public static UserVmDetailVO findPublicKeyByVmId(long vmId) { return _userVmDetailsDao.findDetail(vmId, "SSH.PublicKey"); } -} + + public static void getAutoScaleVmGroupPolicies(long vmGroupId, List scaleUpPolicies, List scaleDownPolicies) + { + List vos = _asVmGroupPolicyMapDao.listByVmGroupId(vmGroupId); + for (AutoScaleVmGroupPolicyMapVO vo : vos) { + AutoScalePolicy autoScalePolicy = _asPolicyDao.findById(vo.getPolicyId()); + if(autoScalePolicy.getAction().equals("scaleup")) + scaleUpPolicies.add(autoScalePolicy); + else + scaleDownPolicies.add(autoScalePolicy); + } + } + + public static CounterVO getCounter(long counterId) { + return _counterDao.findById(counterId); + }} diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index caabd71cd10..67947b35631 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -39,11 +39,16 @@ import com.cloud.api.commands.QueryAsyncJobResultCmd; import com.cloud.api.response.AccountResponse; import com.cloud.api.response.ApiResponseSerializer; import com.cloud.api.response.AsyncJobResponse; +import com.cloud.api.response.AutoScalePolicyResponse; +import com.cloud.api.response.AutoScaleVmGroupResponse; +import com.cloud.api.response.AutoScaleVmProfileResponse; import com.cloud.api.response.CapabilityResponse; import com.cloud.api.response.CapacityResponse; import com.cloud.api.response.ClusterResponse; +import com.cloud.api.response.ConditionResponse; import com.cloud.api.response.ConfigurationResponse; import com.cloud.api.response.ControlledEntityResponse; +import com.cloud.api.response.CounterResponse; import com.cloud.api.response.CreateCmdResponse; import com.cloud.api.response.DiskOfferingResponse; import com.cloud.api.response.DomainResponse; @@ -150,6 +155,12 @@ import com.cloud.network.Site2SiteVpnGateway; import com.cloud.network.Site2SiteVpnGatewayVO; import com.cloud.network.VirtualRouterProvider; import com.cloud.network.VpnUser; +import com.cloud.network.as.AutoScalePolicy; +import com.cloud.network.as.AutoScaleVmGroup; +import com.cloud.network.as.AutoScaleVmProfile; +import com.cloud.network.as.Condition; +import com.cloud.network.as.ConditionVO; +import com.cloud.network.as.Counter; import com.cloud.network.router.VirtualRouter; import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.LoadBalancer; @@ -436,7 +447,7 @@ public class ApiResponseHelper implements ResponseGenerator { domainResponse.setLevel(domain.getLevel()); domainResponse.setNetworkDomain(domain.getNetworkDomain()); domainResponse.setParentDomainId(domain.getParent()); - StringBuilder domainPath = new StringBuilder("ROOT"); + StringBuilder domainPath = new StringBuilder("ROOT"); (domainPath.append(domain.getPath())).deleteCharAt(domainPath.length() - 1); domainResponse.setPath(domainPath.toString()); if (domain.getParent() != null) { @@ -564,7 +575,7 @@ public class ApiResponseHelper implements ResponseGenerator { snapshotResponse.setName(snapshot.getName()); snapshotResponse.setIntervalType(ApiDBUtils.getSnapshotIntervalTypes(snapshot.getId())); snapshotResponse.setState(snapshot.getStatus()); - + //set tag information List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.Snapshot, snapshot.getId()); List tagResponses = new ArrayList(); @@ -573,7 +584,7 @@ public class ApiResponseHelper implements ResponseGenerator { tagResponses.add(tagResponse); } snapshotResponse.setTags(tagResponses); - + snapshotResponse.setObjectName("snapshot"); return snapshotResponse; } @@ -654,7 +665,7 @@ public class ApiResponseHelper implements ResponseGenerator { hostResponse.setMemoryTotal(host.getTotalMemory()); String hostTags = ApiDBUtils.getHostTags(host.getId()); hostResponse.setHostTags(hostTags); - + String haTag = ApiDBUtils.getHaTag(); if (haTag != null && !haTag.isEmpty() && hostTags != null && !hostTags.isEmpty()) { if (haTag.equalsIgnoreCase(hostTags)) { @@ -665,7 +676,7 @@ public class ApiResponseHelper implements ResponseGenerator { } else { hostResponse.setHaHost(false); } - + hostResponse.setHypervisorVersion(host.getHypervisorVersion()); String cpuAlloc = decimalFormat.format(((float) cpu / (float) (host.getCpus() * host.getSpeed())) * 100f) + "%"; @@ -837,7 +848,7 @@ public class ApiResponseHelper implements ResponseGenerator { ipResponse.setVlanId(ipAddr.getVlanId()); ipResponse.setVlanName(ApiDBUtils.findVlanById(ipAddr.getVlanId()).getVlanTag()); } - + if (ipAddr.getSystem()) { if (ipAddr.isOneToOneNat()) { ipResponse.setPurpose(IpAddress.Purpose.StaticNat.toString()); @@ -845,7 +856,7 @@ public class ApiResponseHelper implements ResponseGenerator { ipResponse.setPurpose(IpAddress.Purpose.Lb.toString()); } } - + //set tag information List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.PublicIpAddress, ipAddr.getId()); List tagResponses = new ArrayList(); @@ -854,7 +865,7 @@ public class ApiResponseHelper implements ResponseGenerator { tagResponses.add(tagResponse); } ipResponse.setTags(tagResponses); - + ipResponse.setObjectName("ipaddress"); return ipResponse; } @@ -1094,7 +1105,7 @@ public class ApiResponseHelper implements ResponseGenerator { volResponse.setCreated(volumeHostRef.getCreated()); Account caller = UserContext.current().getCaller(); if (caller.getType() == Account.ACCOUNT_TYPE_ADMIN || caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) - volResponse.setHypervisor(ApiDBUtils.getHypervisorTypeFromFormat(volumeHostRef.getFormat()).toString()); + volResponse.setHypervisor(ApiDBUtils.getHypervisorTypeFromFormat(volumeHostRef.getFormat()).toString()); if (volumeHostRef.getDownloadState() != Status.DOWNLOADED) { String volumeStatus = "Processing"; if (volumeHostRef.getDownloadState() == VMTemplateHostVO.Status.DOWNLOAD_IN_PROGRESS) { @@ -1118,9 +1129,9 @@ public class ApiResponseHelper implements ResponseGenerator { volResponse.setState("Uploaded"); } else { volResponse.setStatus("Successfully Installed"); - } + } } - + populateOwner(volResponse, volume); if (volume.getVolumeType().equals(Volume.Type.ROOT)) { @@ -1154,15 +1165,15 @@ public class ApiResponseHelper implements ResponseGenerator { } volResponse.setAttached(volume.getAttached()); - volResponse.setDestroyed(volume.getState() == Volume.State.Destroy); + volResponse.setDestroyed(volume.getState() == Volume.State.Destroy); boolean isExtractable = true; if (volume.getVolumeType() != Volume.Type.DATADISK) { // Datadisk dont have any template dependence. VMTemplateVO template = ApiDBUtils.findTemplateById(volume.getTemplateId()); if (template != null) { // For ISO based volumes template = null and we allow extraction of all ISO based volumes - isExtractable = template.isExtractable() && template.getTemplateType() != Storage.TemplateType.SYSTEM; + isExtractable = template.isExtractable() && template.getTemplateType() != Storage.TemplateType.SYSTEM; } } - + //set tag information List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.Volume, volume.getId()); List tagResponses = new ArrayList(); @@ -1171,7 +1182,7 @@ public class ApiResponseHelper implements ResponseGenerator { tagResponses.add(tagResponse); } volResponse.setTags(tagResponses); - + volResponse.setExtractable(isExtractable); volResponse.setObjectName("volume"); return volResponse; @@ -1306,7 +1317,7 @@ public class ApiResponseHelper implements ResponseGenerator { if (vm != null) { response.setVirtualMachineId(vm.getId()); response.setVirtualMachineName(vm.getHostName()); - + if (vm.getDisplayName() != null) { response.setVirtualMachineDisplayName(vm.getDisplayName()); } else { @@ -1319,7 +1330,7 @@ public class ApiResponseHelper implements ResponseGenerator { if (state.equals(FirewallRule.State.Revoke)) { stateToSet = "Deleting"; } - + //set tag information List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.PortForwardingRule, fwRule.getId()); List tagResponses = new ArrayList(); @@ -1328,7 +1339,7 @@ public class ApiResponseHelper implements ResponseGenerator { tagResponses.add(tagResponse); } response.setTags(tagResponses); - + response.setState(stateToSet); response.setObjectName("portforwardingrule"); return response; @@ -1401,12 +1412,12 @@ public class ApiResponseHelper implements ResponseGenerator { } else { userVmResponse.setDisplayName(userVm.getHostName()); } - + if (caller.getType() == Account.ACCOUNT_TYPE_ADMIN) { userVmResponse.setInstanceName(userVm.getInstanceName()); } - - + + if (userVm.getPassword() != null) { userVmResponse.setPassword(userVm.getPassword()); } @@ -1464,7 +1475,7 @@ public class ApiResponseHelper implements ResponseGenerator { if (userVm.getHypervisorType() != null) { userVmResponse.setHypervisor(userVm.getHypervisorType().toString()); } - + if (details.contains(VMDetails.all) || details.contains(VMDetails.tmpl)) { // Template Info VMTemplateVO template = templates.get(userVm.getTemplateId()); @@ -1605,7 +1616,7 @@ public class ApiResponseHelper implements ResponseGenerator { } userVmResponse.setNics(nicResponses); } - + //set tag information List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.UserVm, userVm.getId()); List tagResponses = new ArrayList(); @@ -1614,7 +1625,7 @@ public class ApiResponseHelper implements ResponseGenerator { tagResponses.add(tagResponse); } userVmResponse.setTags(tagResponses); - + IpAddress ip = ApiDBUtils.findIpByAssociatedVmId(userVm.getId()); if (ip != null) { userVmResponse.setPublicIpId(ip.getId()); @@ -1926,7 +1937,7 @@ public class ApiResponseHelper implements ResponseGenerator { } else { tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.Template, result.getId()); } - + List tagResponses = new ArrayList(); for (ResourceTag tag : tags) { ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); @@ -2325,7 +2336,7 @@ public class ApiResponseHelper implements ResponseGenerator { //set tag information List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.ISO, iso.getId()); - + List tagResponses = new ArrayList(); for (ResourceTag tag : tags) { ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); @@ -2342,7 +2353,7 @@ public class ApiResponseHelper implements ResponseGenerator { public ListResponse createSecurityGroupResponses( List networkGroups) { List groupResultObjs = SecurityGroupResultObject - .transposeNetworkGroups(networkGroups); + .transposeNetworkGroups(networkGroups); ListResponse response = new ListResponse(); List netGrpResponses = new ArrayList(); @@ -2355,7 +2366,7 @@ public class ApiResponseHelper implements ResponseGenerator { populateOwner(netGrpResponse, networkGroup); List securityGroupRules = networkGroup - .getSecurityGroupRules(); + .getSecurityGroupRules(); if ((securityGroupRules != null) && !securityGroupRules.isEmpty()) { List ingressRulesResponse = new ArrayList(); List egressRulesResponse = new ArrayList(); @@ -2398,9 +2409,9 @@ public class ApiResponseHelper implements ResponseGenerator { tagResponses.add(tagResponse); } netGrpResponse.setTags(tagResponses); - + netGrpResponse - .setSecurityGroupIngressRules(ingressRulesResponse); + .setSecurityGroupIngressRules(ingressRulesResponse); netGrpResponse.setSecurityGroupEgressRules(egressRulesResponse); } netGrpResponse.setObjectName("securitygroup"); @@ -2474,7 +2485,7 @@ public class ApiResponseHelper implements ResponseGenerator { Object resultObject = ApiSerializerHelper.fromSerializedString(job.getResult()); jobResponse.setJobResult((ResponseObject) resultObject); SerializationContext.current().setUuidTranslation(savedValue); - + if (resultObject != null) { Class clz = resultObject.getClass(); if (clz.isPrimitive() || clz.getSuperclass() == Number.class || clz == String.class || clz == Date.class) { @@ -2595,17 +2606,17 @@ public class ApiResponseHelper implements ResponseGenerator { } if (capacityType == Capacity.CAPACITY_TYPE_CPU || capacityType == Capacity.CAPACITY_TYPE_MEMORY) { // Reserved - // Capacity - // accounts -// for + // Capacity + // accounts + // for // stopped -// vms + // vms // that -// have been + // have been // stopped -// within + // within // an -// interval + // interval usedCapacity += capacity.getReservedCapacity(); } @@ -2634,17 +2645,17 @@ public class ApiResponseHelper implements ResponseGenerator { } if (capacityType == Capacity.CAPACITY_TYPE_CPU || capacityType == Capacity.CAPACITY_TYPE_MEMORY) { // Reserved - // Capacity - // accounts - // for - // stopped - // vms -// that + // Capacity + // accounts + // for + // stopped + // vms + // that // have -// been + // been // stopped // within -// an + // an // interval usedCapacity += capacity.getReservedCapacity(); } @@ -2676,7 +2687,7 @@ public class ApiResponseHelper implements ResponseGenerator { @Override public List createCapacityResponse(List result, DecimalFormat format) { List capacityResponses = new ArrayList(); - + for (Capacity summedCapacity : result) { CapacityResponse capacityResponse = new CapacityResponse(); capacityResponse.setCapacityTotal(summedCapacity.getTotalCapacity()); @@ -3211,7 +3222,7 @@ public class ApiResponseHelper implements ResponseGenerator { userVmData.setDisplayName(userVm.getHostName()); } userVmData.setInstanceName(userVm.getInstanceName()); - + userVmData.setDomainId(userVm.getDomainId()); if (userVm.getHypervisorType() != null) { @@ -3651,18 +3662,18 @@ public class ApiResponseHelper implements ResponseGenerator { response.setObjectName("storagenetworkiprange"); return response; } - + @Override public Long getIdentiyId(String tableName, String token) { return ApiDispatcher.getIdentiyId(tableName, token); } - + @Override public ResourceTagResponse createResourceTagResponse(ResourceTag resourceTag, boolean keyValueOnly) { ResourceTagResponse response = new ResourceTagResponse(); response.setKey(resourceTag.getKey()); response.setValue(resourceTag.getValue()); - + if (!keyValueOnly) { response.setResourceType(resourceTag.getResourceType().toString()); response.setId(ApiDBUtils.getUuid(String.valueOf(resourceTag.getResourceId()),resourceTag.getResourceType())); @@ -3689,7 +3700,7 @@ public class ApiResponseHelper implements ResponseGenerator { response.setCustomer(resourceTag.getCustomer()); } - response.setObjectName("tag"); + response.setObjectName("ag"); return response; } @@ -3711,7 +3722,7 @@ public class ApiResponseHelper implements ResponseGenerator { if (service == Service.Gateway) { continue; } - svcRsp.setName(service.getName()); + svcRsp.setName(service.getName());response.setObjectName List providers = new ArrayList(); for (Provider provider : serviceProviderMap.get(service)) { if (provider != null) { @@ -3811,6 +3822,104 @@ public class ApiResponseHelper implements ResponseGenerator { response.setObjectName("privategateway"); + + return response; + } + + @Override + public CounterResponse createCounterResponse(Counter counter) { + CounterResponse response = new CounterResponse(); + response.setId(counter.getId()); + response.setSource(counter.getSource().toString()); + response.setName(counter.getName()); + response.setValue(counter.getValue()); + response.setObjectName("counter"); + return response; + } + + @Override + public ConditionResponse createConditionResponse(Condition condition) { + ConditionResponse response = new ConditionResponse(); + response.setId(condition.getId()); + CounterResponse counter; + counter = createCounterResponse(ApiDBUtils.getCounter(condition.getCounterid())); + response.setCounter(counter); + response.setRelationalOperator(condition.getRelationalOperator().toString()); + response.setThreshold(condition.getThreshold()); + response.setObjectName("condition"); + populateOwner(response, condition); + return response; + } + + @Override + public AutoScaleVmProfileResponse createAutoScaleVmProfileResponse(AutoScaleVmProfile profile) { + AutoScaleVmProfileResponse response = new AutoScaleVmProfileResponse(); + response.setId(profile.getId()); + response.setZoneId(profile.getZoneId()); + response.setServiceOfferingId(profile.getServiceOfferingId()); + response.setTemplateId(profile.getTemplateId()); + response.setOtherDeployParams(profile.getOtherDeployParams()); + response.setSnmpCommunity(profile.getSnmpCommunity()); + response.setSnmpPort(profile.getSnmpPort()); + response.setDestroyVmGraceperiod(profile.getDestroyVmGraceperiod()); + response.setAutoscaleUserId(profile.getAutoScaleUserId()); + response.setObjectName("autoscalevmprofile"); + + // Populates the account information in the response + populateOwner(response, profile); + return response; + } + + @Override + public AutoScalePolicyResponse createAutoScalePolicyResponse(AutoScalePolicy policy) { + AutoScalePolicyResponse response = new AutoScalePolicyResponse(); + response.setId(policy.getId()); + response.setDuration(policy.getDuration()); + response.setQuietTime(policy.getQuietTime()); + response.setAction(policy.getAction()); + List vos = ApiDBUtils.getAutoScalePolicyConditions(policy.getId()); + ArrayList conditions = new ArrayList(vos.size()); + for (ConditionVO vo : vos) { + conditions.add(createConditionResponse(vo)); + } + response.setConditions(conditions); + response.setObjectName("autoscalepolicy"); + + // Populates the account information in the response + populateOwner(response, policy); + + return response; + } + + @Override + public AutoScaleVmGroupResponse createAutoScaleVmGroupResponse(AutoScaleVmGroup vmGroup) { + AutoScaleVmGroupResponse response = new AutoScaleVmGroupResponse(); + response.setId(vmGroup.getId()); + response.setMinMembers(vmGroup.getMinMembers()); + response.setMaxMembers(vmGroup.getMaxMembers()); + response.setState(vmGroup.getState()); + response.setInterval(vmGroup.getInterval()); + response.setProfileId(vmGroup.getProfileId()); + response.setLoadBalancerId(vmGroup.getProfileId()); + + List scaleUpPoliciesResponse = new ArrayList(); + List scaleDownPoliciesResponse = new ArrayList(); + response.setScaleUpPolicies(scaleUpPoliciesResponse); + response.setScaleDownPolicies(scaleDownPoliciesResponse); + response.setObjectName("autoscalevmgroup"); + + // Fetch policies for vmgroup + List scaleUpPolicies = new ArrayList(); + List scaleDownPolicies = new ArrayList(); + ApiDBUtils.getAutoScaleVmGroupPolicies(vmGroup.getId(), scaleUpPolicies, scaleDownPolicies); + // populate policies + for (AutoScalePolicy autoScalePolicy : scaleUpPolicies) { + scaleUpPoliciesResponse.add(createAutoScalePolicyResponse(autoScalePolicy)); + } + for (AutoScalePolicy autoScalePolicy : scaleDownPolicies) { + scaleDownPoliciesResponse.add(createAutoScalePolicyResponse(autoScalePolicy)); + } + return response; } diff --git a/server/src/com/cloud/configuration/DefaultComponentLibrary.java b/server/src/com/cloud/configuration/DefaultComponentLibrary.java index 4edd4021900..ef61044d06b 100755 --- a/server/src/com/cloud/configuration/DefaultComponentLibrary.java +++ b/server/src/com/cloud/configuration/DefaultComponentLibrary.java @@ -75,6 +75,14 @@ import com.cloud.maint.dao.AgentUpgradeDaoImpl; import com.cloud.network.ExternalLoadBalancerUsageManagerImpl; import com.cloud.network.NetworkManagerImpl; import com.cloud.network.StorageNetworkManagerImpl; +import com.cloud.network.as.AutoScaleManagerImpl; +import com.cloud.network.as.dao.AutoScalePolicyConditionMapDaoImpl; +import com.cloud.network.as.dao.AutoScalePolicyDaoImpl; +import com.cloud.network.as.dao.AutoScaleVmGroupDaoImpl; +import com.cloud.network.as.dao.AutoScaleVmGroupPolicyMapDaoImpl; +import com.cloud.network.as.dao.AutoScaleVmProfileDaoImpl; +import com.cloud.network.as.dao.ConditionDaoImpl; +import com.cloud.network.as.dao.CounterDaoImpl; import com.cloud.network.dao.ExternalFirewallDeviceDaoImpl; import com.cloud.network.dao.ExternalLoadBalancerDeviceDaoImpl; import com.cloud.network.dao.FirewallRulesCidrsDaoImpl; @@ -238,6 +246,13 @@ public class DefaultComponentLibrary extends ComponentLibraryBase implements Com addDao("NetworkRuleConfigDao", NetworkRuleConfigDaoImpl.class); addDao("LoadBalancerVMMapDao", LoadBalancerVMMapDaoImpl.class); addDao("LBStickinessPolicyDao", LBStickinessPolicyDaoImpl.class); + addDao("CounterDao", CounterDaoImpl.class); + addDao("ConditionDao", ConditionDaoImpl.class); + addDao("AutoScalePolicyDao", AutoScalePolicyDaoImpl.class); + addDao("AutoScalePolicyConditionMapDao", AutoScalePolicyConditionMapDaoImpl.class); + addDao("AutoScaleVmProfileDao", AutoScaleVmProfileDaoImpl.class); + addDao("AutoScaleVmGroupDao", AutoScaleVmGroupDaoImpl.class); + addDao("AutoScaleVmGroupPolicyMapDao", AutoScaleVmGroupPolicyMapDaoImpl.class); addDao("DataCenterIpAddressDao", DataCenterIpAddressDaoImpl.class); addDao("SecurityGroupDao", SecurityGroupDaoImpl.class); addDao("SecurityGroupRuleDao", SecurityGroupRuleDaoImpl.class); @@ -374,6 +389,7 @@ public class DefaultComponentLibrary extends ComponentLibraryBase implements Com addManager("SecurityGroupManager", SecurityGroupManagerImpl2.class); addManager("EntityManager", EntityManagerImpl.class); addManager("LoadBalancingRulesManager", LoadBalancingRulesManagerImpl.class); + addManager("AutoScaleManager", AutoScaleManagerImpl.class); addManager("RulesManager", RulesManagerImpl.class); addManager("RemoteAccessVpnManager", RemoteAccessVpnManagerImpl.class); addManager("Capacity Manager", CapacityManagerImpl.class); diff --git a/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java b/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java index 38376776ac4..bc7f2c14b54 100644 --- a/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java +++ b/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java @@ -187,7 +187,7 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase if ((ntwkDevice == null) || (url == null) || (username == null) || (resource == null) || (password == null)) { throw new InvalidParameterValueException("Atleast one of the required parameters (url, username, password," + - " server resource, zone id/physical network id) is not specified or a valid parameter."); + " server resource, zone id/physical network id) is not specified or a valid parameter."); } pNetwork = _physicalNetworkDao.findById(physicalNetworkId); @@ -239,7 +239,7 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase boolean dedicatedUse = (configParams.get(ApiConstants.LOAD_BALANCER_DEVICE_DEDICATED) != null) ? Boolean.parseBoolean(configParams.get(ApiConstants.LOAD_BALANCER_DEVICE_DEDICATED)) : false; boolean inline = (configParams.get(ApiConstants.INLINE) != null) ? Boolean.parseBoolean(configParams.get(ApiConstants.INLINE)) : false; - long capacity = NumbersUtil.parseLong((String) configParams.get(ApiConstants.LOAD_BALANCER_DEVICE_CAPACITY), 0); + long capacity = NumbersUtil.parseLong(configParams.get(ApiConstants.LOAD_BALANCER_DEVICE_CAPACITY), 0); if (capacity == 0) { capacity = _defaultLbCapacity; } @@ -384,7 +384,7 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase if (deviceMapLock.lock(120)) { try { boolean dedicatedLB = offering.getDedicatedLB(); // does network offering supports a dedicated -// load balancer? + // load balancer? long lbDeviceId; txn.start(); @@ -398,7 +398,7 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase // persist the load balancer device id that will be used for this network. Once a network // is implemented on a LB device then later on all rules will be programmed on to same -// device + // device NetworkExternalLoadBalancerVO networkLB = new NetworkExternalLoadBalancerVO(guestConfig.getId(), lbDeviceId); _networkExternalLBDao.persist(networkLB); @@ -416,12 +416,12 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase if (tryLbProvisioning) { retry = false; // TODO: throwing warning instead of error for now as its possible another provider can -// service this network + // service this network s_logger.warn("There are no load balancer device with the capacity for implementing this network"); throw exception; } else { tryLbProvisioning = true; // if possible provision a LB appliance in to the physical -// network + // network } } } finally { @@ -436,7 +436,7 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase } // there are no LB devices or there is no free capacity on the devices in the physical network so provision -// a new LB appliance + // a new LB appliance if (tryLbProvisioning) { // check if LB appliance can be dynamically provisioned List providerLbDevices = _externalLoadBalancerDeviceDao.listByProviderAndDeviceAllocationState(physicalNetworkId, provider, LBDeviceAllocationState.Provider); @@ -444,7 +444,7 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase for (ExternalLoadBalancerDeviceVO lbProviderDevice : providerLbDevices) { if (lbProviderDevice.getState() == LBDeviceState.Enabled) { // acquire a private IP from the data center which will be used as management IP of -// provisioned LB appliance, + // provisioned LB appliance, DataCenterIpAddressVO dcPrivateIp = _dcDao.allocatePrivateIpAddress(guestConfig.getDataCenterId(), lbProviderDevice.getUuid()); if (dcPrivateIp == null) { throw new InsufficientNetworkCapacityException("failed to acquire a priavate IP in the zone " + guestConfig.getDataCenterId() + @@ -475,12 +475,12 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase String privateIf = createLbAnswer.getPrivateInterface(); // we have provisioned load balancer so add the appliance as cloudstack provisioned external -// load balancer + // load balancer String dedicatedLb = offering.getDedicatedLB() ? "true" : "false"; String capacity = Long.toString(lbProviderDevice.getCapacity()); // acquire a public IP to associate with lb appliance (used as subnet IP to make the -// appliance part of private network) + // appliance part of private network) PublicIp publicIp = _networkMgr.assignPublicIpAddress(guestConfig.getDataCenterId(), null, _accountMgr.getSystemAccount(), VlanType.VirtualNetwork, null, null, false); String publicIPNetmask = publicIp.getVlanNetmask(); String publicIPgateway = publicIp.getVlanGateway(); @@ -488,8 +488,8 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase String publicIP = publicIp.getAddress().toString(); String url = "https://" + lbIP + "?publicinterface=" + publicIf + "&privateinterface=" + privateIf + "&lbdevicededicated=" + dedicatedLb + - "&cloudmanaged=true" + "&publicip=" + publicIP + "&publicipnetmask=" + publicIPNetmask + "&lbdevicecapacity=" + capacity + - "&publicipvlan=" + publicIPVlanTag + "&publicipgateway=" + publicIPgateway; + "&cloudmanaged=true" + "&publicip=" + publicIP + "&publicipnetmask=" + publicIPNetmask + "&lbdevicecapacity=" + capacity + + "&publicipvlan=" + publicIPVlanTag + "&publicipgateway=" + publicIPgateway; ExternalLoadBalancerDeviceVO lbAppliance = null; try { lbAppliance = addExternalLoadBalancer(physicalNetworkId, url, username, password, createLbAnswer.getDeviceName(), createLbAnswer.getServerResource()); @@ -499,7 +499,7 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase if (lbAppliance != null) { // mark the load balancer as cloudstack managed and set parent host id on which lb -// appliance is provisioned + // appliance is provisioned ExternalLoadBalancerDeviceVO managedLb = _externalLoadBalancerDeviceDao.findById(lbAppliance.getId()); managedLb.setIsManagedDevice(true); managedLb.setParentHostId(lbProviderDevice.getHostId()); @@ -514,7 +514,7 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase s_logger.warn("Failed to destroy load balancer appliance created"); } else { // release the public & private IP back to dc pool, as the load balancer -// appliance is now destroyed + // appliance is now destroyed _dcDao.releasePrivateIpAddress(lbIP, guestConfig.getDataCenterId(), null); _networkMgr.disassociatePublicIpAddress(publicIp.getId(), _accountMgr.getSystemUser().getId(), _accountMgr.getSystemAccount()); } @@ -594,7 +594,7 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase } // if we are here then there are no existing LB devices in shared use or the devices in shared use has no -// free capacity left + // free capacity left // so allocate a new load balancer configured for shared use from the pool of free LB devices lbDevices = _externalLoadBalancerDeviceDao.listByProviderAndDeviceAllocationState(physicalNetworkId, provider, LBDeviceAllocationState.Free); if (lbDevices != null && !lbDevices.isEmpty()) { @@ -631,7 +631,7 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase if (!lbInUse && !lbCloudManaged) { // this is the last network mapped to the load balancer device so set device allocation state to be -// free + // free lbDevice.setAllocationState(LBDeviceAllocationState.Free); _externalLoadBalancerDeviceDao.update(lbDevice.getId(), lbDevice); } @@ -797,6 +797,7 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase LoadBalancingRule rule = loadBalancingRules.get(i); boolean revoked = (rule.getState().equals(FirewallRule.State.Revoke)); + Long lbId = rule.getId(); String protocol = rule.getProtocol(); String algorithm = rule.getAlgorithm(); String srcIp = _networkMgr.getIp(rule.getSourceIpAddressId()).getAddress().addr(); @@ -835,7 +836,7 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase _inlineLoadBalancerNicMapDao.persist(mapping); // On the firewall provider for the network, create a static NAT rule between the source IP -// address and the load balancing IP address + // address and the load balancing IP address applyStaticNatRuleForInlineLBRule(zone, network, firewallProviderHost, revoked, srcIp, loadBalancingIpNic.getIp4Address()); } else { loadBalancingIpNic = _nicDao.findById(mapping.getNicId()); @@ -846,7 +847,7 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase loadBalancingIpNic = _nicDao.findById(mapping.getNicId()); // On the firewall provider for the network, delete the static NAT rule between the source IP -// address and the load balancing IP address + // address and the load balancing IP address applyStaticNatRuleForInlineLBRule(zone, network, firewallProviderHost, revoked, srcIp, loadBalancingIpNic.getIp4Address()); // Delete the mapping between the source IP address and the load balancing IP address @@ -864,8 +865,11 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase srcIp = loadBalancingIpNic.getIp4Address(); } - if (destinations != null && !destinations.isEmpty()) { - LoadBalancerTO loadBalancer = new LoadBalancerTO(srcIp, srcPort, protocol, algorithm, revoked, false, destinations, rule.getStickinessPolicies()); + if ((destinations != null && !destinations.isEmpty()) || rule.isAutoScaleConfig()) { + LoadBalancerTO loadBalancer = new LoadBalancerTO(lbId, srcIp, srcPort, protocol, algorithm, revoked, false, destinations, rule.getStickinessPolicies()); + if(rule.isAutoScaleConfig()) { + loadBalancer.setAutoScaleVmGroup(rule.getAutoScaleVmGroup()); + } loadBalancersToApply.add(loadBalancer); } } @@ -913,7 +917,7 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase ExternalLoadBalancerDeviceVO lbDeviceVO = getExternalLoadBalancerForNetwork(guestConfig); if (lbDeviceVO == null) { s_logger.warn("Network shutdwon requested on external load balancer element, which did not implement the network." + - " Either network implement failed half way through or already network shutdown is completed. So just returning."); + " Either network implement failed half way through or already network shutdown is completed. So just returning."); return true; } @@ -940,7 +944,7 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase NicVO selfipNic = getPlaceholderNic(guestConfig); if (selfipNic == null) { s_logger.warn("Network shutdwon requested on external load balancer element, which did not implement the network." + - " Either network implement failed half way through or already network shutdown is completed. So just returning."); + " Either network implement failed half way through or already network shutdown is completed. So just returning."); return true; } selfIp = selfipNic.getIp4Address(); diff --git a/server/src/com/cloud/network/as/AutoScaleManager.java b/server/src/com/cloud/network/as/AutoScaleManager.java new file mode 100644 index 00000000000..7ea7807aa6f --- /dev/null +++ b/server/src/com/cloud/network/as/AutoScaleManager.java @@ -0,0 +1,20 @@ +// 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; + +public interface AutoScaleManager extends AutoScaleService { +} diff --git a/server/src/com/cloud/network/as/AutoScaleManagerImpl.java b/server/src/com/cloud/network/as/AutoScaleManagerImpl.java new file mode 100644 index 00000000000..758ef6556d2 --- /dev/null +++ b/server/src/com/cloud/network/as/AutoScaleManagerImpl.java @@ -0,0 +1,1140 @@ +// 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.security.InvalidParameterException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.ejb.Local; +import javax.naming.ConfigurationException; + +import org.apache.log4j.Logger; + +import com.cloud.acl.ControlledEntity; +import com.cloud.api.ApiConstants; +import com.cloud.api.ApiDBUtils; +import com.cloud.api.ApiDispatcher; +import com.cloud.api.BaseListAccountResourcesCmd; +import com.cloud.api.commands.CreateAutoScalePolicyCmd; +import com.cloud.api.commands.CreateAutoScaleVmGroupCmd; +import com.cloud.api.commands.CreateAutoScaleVmProfileCmd; +import com.cloud.api.commands.CreateConditionCmd; +import com.cloud.api.commands.CreateCounterCmd; +import com.cloud.api.commands.DeployVMCmd; +import com.cloud.api.commands.ListAutoScalePoliciesCmd; +import com.cloud.api.commands.ListAutoScaleVmGroupsCmd; +import com.cloud.api.commands.ListAutoScaleVmProfilesCmd; +import com.cloud.api.commands.ListConditionsCmd; +import com.cloud.api.commands.ListCountersCmd; +import com.cloud.api.commands.UpdateAutoScalePolicyCmd; +import com.cloud.api.commands.UpdateAutoScaleVmGroupCmd; +import com.cloud.api.commands.UpdateAutoScaleVmProfileCmd; +import com.cloud.configuration.Config; +import com.cloud.configuration.ConfigurationManager; +import com.cloud.configuration.dao.ConfigurationDao; +import com.cloud.dc.DataCenter; +import com.cloud.dc.dao.DataCenterDao; +import com.cloud.event.ActionEvent; +import com.cloud.event.EventTypes; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.ResourceInUseException; +import com.cloud.network.LoadBalancerVO; +import com.cloud.network.Network.Capability; +import com.cloud.network.as.dao.AutoScalePolicyConditionMapDao; +import com.cloud.network.as.dao.AutoScalePolicyDao; +import com.cloud.network.as.dao.AutoScaleVmGroupDao; +import com.cloud.network.as.dao.AutoScaleVmGroupPolicyMapDao; +import com.cloud.network.as.dao.AutoScaleVmProfileDao; +import com.cloud.network.as.dao.ConditionDao; +import com.cloud.network.as.dao.CounterDao; +import com.cloud.network.dao.IPAddressDao; +import com.cloud.network.dao.LoadBalancerDao; +import com.cloud.network.dao.LoadBalancerVMMapDao; +import com.cloud.network.dao.NetworkDao; +import com.cloud.network.lb.LoadBalancingRulesManager; +import com.cloud.offering.ServiceOffering; +import com.cloud.projects.Project.ListProjectResourcesCriteria; +import com.cloud.template.TemplateManager; +import com.cloud.template.VirtualMachineTemplate; +import com.cloud.user.Account; +import com.cloud.user.AccountManager; +import com.cloud.user.User; +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.Ternary; +import com.cloud.utils.component.Inject; +import com.cloud.utils.component.Manager; +import com.cloud.utils.db.DB; +import com.cloud.utils.db.Filter; +import com.cloud.utils.db.GenericDao; +import com.cloud.utils.db.JoinBuilder; +import com.cloud.utils.db.SearchBuilder; +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; + +@Local(value = { AutoScaleService.class }) +public class AutoScaleManagerImpl implements AutoScaleService, Manager { + private static final Logger s_logger = Logger.getLogger(AutoScaleManagerImpl.class); + + String _name; + @Inject + AccountDao _accountDao; + @Inject + AccountManager _accountMgr; + @Inject + ConfigurationManager _configMgr; + @Inject + TemplateManager _templateMgr; + @Inject + LoadBalancingRulesManager _lbRulesMgr; + @Inject + NetworkDao _networkDao; + @Inject + CounterDao _counterDao; + @Inject + ConditionDao _conditionDao; + @Inject + LoadBalancerVMMapDao _lb2VmMapDao; + @Inject + LoadBalancerDao _lbDao; + @Inject + AutoScaleVmProfileDao _autoScaleVmProfileDao; + @Inject + AutoScalePolicyDao _autoScalePolicyDao; + @Inject + AutoScalePolicyConditionMapDao _autoScalePolicyConditionMapDao; + @Inject + AutoScaleVmGroupDao _autoScaleVmGroupDao; + @Inject + AutoScaleVmGroupPolicyMapDao _autoScaleVmGroupPolicyMapDao; + @Inject + DataCenterDao _dcDao = null; + @Inject + UserDao _userDao; + @Inject + ConfigurationDao _configDao; + @Inject + IPAddressDao _ipAddressDao; + + @Override + public boolean configure(String name, Map params) throws ConfigurationException { + _name = name; + return true; + } + + @Override + public boolean start() { + return true; + } + + @Override + public boolean stop() { + return true; + } + + @Override + public String getName() { + return _name; + } + + public List getSupportedAutoScaleCounters(long networkid) + { + String autoScaleCapability = _lbRulesMgr.getLBCapability(networkid, Capability.AutoScaleCounters.getName()); + if (autoScaleCapability == null || autoScaleCapability.length() == 0) { + return null; + } + return Arrays.asList(autoScaleCapability.split(",")); + } + + public void validateAutoScaleCounters(long networkid, List counters) + { + 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"); + } + } + } + + private VO getEntityInDatabase(Account caller, String paramName, Long id, GenericDao dao) + { + + VO vo = dao.findById(id); + + if (vo == null) { + throw new InvalidParameterValueException("Unable to find " + paramName); + } + + _accountMgr.checkAccess(caller, null, false, (ControlledEntity) vo); + + return vo; + } + + private boolean isAutoScaleScaleUpPolicy(AutoScalePolicy policyVO) + { + return policyVO.getAction().equals("scaleup"); + } + + private List getAutoScalePolicies(String paramName, List policyIds, List counters, int interval, boolean scaleUpPolicies) + { + SearchBuilder policySearch = _autoScalePolicyDao.createSearchBuilder(); + policySearch.and("ids", policySearch.entity().getId(), Op.IN); + policySearch.done(); + SearchCriteria sc = policySearch.create(); + + sc.setParameters("ids", policyIds.toArray(new Object[0])); + List policies = _autoScalePolicyDao.search(sc, null); + + int prevQuietTime = 0; + + for (AutoScalePolicyVO policy : policies) { + int quietTime = policy.getQuietTime(); + if (prevQuietTime == 0) { + prevQuietTime = quietTime; + } + int duration = policy.getDuration(); + if (duration < interval) { + throw new InvalidParameterValueException("duration : " + duration + " specified in a policy cannot be less than vm group's interval : " + interval); + } + + if (quietTime < interval) { + throw new InvalidParameterValueException("quietTime : " + quietTime + " specified in a policy cannot be less than vm group's interval : " + interval); + } + + if (quietTime != prevQuietTime) { + throw new InvalidParameterValueException("quietTime should be same for all the policies specified in " + paramName); + } + + if (scaleUpPolicies) { + if (!isAutoScaleScaleUpPolicy(policy)) { + throw new InvalidParameterValueException("Only scaleup policies can be specified in scaleuppolicyids"); + } + } + else { + if (isAutoScaleScaleUpPolicy(policy)) { + throw new InvalidParameterValueException("Only scaledown policies can be specified in scaledownpolicyids"); + } + } + List policyConditionMapVOs = _autoScalePolicyConditionMapDao.listByAll(policy.getId(), null); + for (AutoScalePolicyConditionMapVO policyConditionMapVO : policyConditionMapVOs) { + long conditionid = policyConditionMapVO.getConditionId(); + Condition condition = _conditionDao.findById(conditionid); + Counter counter = _counterDao.findById(condition.getCounterid()); + counters.add(counter); + } + } + return policies; + } + + protected AutoScaleVmProfileVO checkValidityAndPersist(AutoScaleVmProfileVO vmProfile) { + long templateId = vmProfile.getTemplateId(); + long autoscaleUserId = vmProfile.getAutoScaleUserId(); + int destroyVmGraceperiod = vmProfile.getDestroyVmGraceperiod(); + + VirtualMachineTemplate template = _templateMgr.getTemplate(templateId); + // Make sure a valid template ID was specified + if (template == null) { + throw new InvalidParameterValueException("Unable to use the given template."); + } + + if (destroyVmGraceperiod < 0) { + throw new InvalidParameterValueException("Destroy Vm Grace Period cannot be less than 0."); + } + + User user = _userDao.findById(autoscaleUserId); + if (user.getAccountId() != vmProfile.getAccountId()) { + throw new InvalidParameterValueException("AutoScale User id does not belong to the same account"); + } + + String apiKey = user.getApiKey(); + String secretKey = user.getSecretKey(); + String csUrl = _configDao.getValue(Config.EndpointeUrl.key()); + + if(apiKey == null) { + throw new InvalidParameterValueException("apiKey for user: " + user.getUsername() + " is empty. Please generate it"); + } + + if(secretKey == null) { + throw new InvalidParameterValueException("secretKey for user: " + user.getUsername() + " is empty. Please generate it"); + } + + if(csUrl == null || csUrl.contains("localhost")) { + throw new InvalidParameterValueException("Global setting endpointe.url has to be set to the Management Server's API end point"); + } + + vmProfile = _autoScaleVmProfileDao.persist(vmProfile); + + return vmProfile; + } + + @Override + @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEVMPROFILE_CREATE, eventDescription = "creating autoscale vm profile", create = true) + public AutoScaleVmProfile createAutoScaleVmProfile(CreateAutoScaleVmProfileCmd cmd) { + + Account owner = _accountDao.findById(cmd.getAccountId()); + Account caller = UserContext.current().getCaller(); + _accountMgr.checkAccess(caller, null, true, owner); + + long zoneId = cmd.getZoneId(); + long serviceOfferingId = cmd.getServiceOfferingId(); + Long autoscaleUserId = cmd.getAutoscaleUserId(); + + DataCenter zone = _configMgr.getZone(zoneId); + + if (zone == null) { + throw new InvalidParameterValueException("Unable to find zone by id"); + } + + ServiceOffering serviceOffering = _configMgr.getServiceOffering(serviceOfferingId); + if (serviceOffering == null) { + throw new InvalidParameterValueException("Unable to find service offering by id"); + } + + // validations + HashMap deployParams = cmd.getDeployParamMap(); + /* + * Just for making sure the values are right in other deploy params. + * For ex. if projectId is given as a string instead of an long value, this + * will be throwing an error. + */ + ApiDispatcher.setupParameters(new DeployVMCmd(), deployParams); + + if (autoscaleUserId == null) { + autoscaleUserId = UserContext.current().getCallerUserId(); + } + + + AutoScaleVmProfileVO profileVO = new AutoScaleVmProfileVO(cmd.getZoneId(), cmd.getDomainId(), cmd.getAccountId(), cmd.getServiceOfferingId(), cmd.getTemplateId(), cmd.getOtherDeployParams(), + cmd.getSnmpCommunity(), cmd.getSnmpPort(), cmd.getDestroyVmGraceperiod(), autoscaleUserId); + profileVO = checkValidityAndPersist(profileVO); + s_logger.info("Successfully create AutoScale Vm Profile with Id: " + profileVO.getId()); + + return profileVO; + } + + @Override + @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEVMPROFILE_UPDATE, eventDescription = "updating autoscale vm profile") + public AutoScaleVmProfile updateAutoScaleVmProfile(UpdateAutoScaleVmProfileCmd cmd) { + Long profileId = cmd.getId(); + Long templateId = cmd.getTemplateId(); + Long autoscaleUserId = cmd.getAutoscaleUserId(); + Integer snmpPort = cmd.getSnmpPort(); + String snmpCommunity = cmd.getSnmpCommunity(); + Integer destroyVmGraceperiod = cmd.getDestroyVmGraceperiod(); + + AutoScaleVmProfileVO vmProfile = getEntityInDatabase(UserContext.current().getCaller(), "Auto Scale Vm Profile", profileId, _autoScaleVmProfileDao); + + if (templateId != null) { + vmProfile.setTemplateId(templateId); + } + + if (autoscaleUserId != null) { + vmProfile.setAutoscaleUserId(autoscaleUserId); + } + + if (snmpCommunity != null) { + vmProfile.setSnmpCommunity(snmpCommunity); + } + + if (snmpPort != null) { + vmProfile.setSnmpPort(snmpPort); + } + + if (destroyVmGraceperiod != null) { + vmProfile.setDestroyVmGraceperiod(destroyVmGraceperiod); + } + + List vmGroupList = _autoScaleVmGroupDao.listByAll(null, profileId); + for (AutoScaleVmGroupVO vmGroupVO : vmGroupList) { + if (vmGroupVO.getState().equals(AutoScaleVmGroup.State_Disabled)) { + throw new InvalidParameterValueException("The AutoScale Vm Profile can be updated only if the Vm Group it is associated with is disabled in state"); + } + } + + vmProfile = checkValidityAndPersist(vmProfile); + s_logger.info("Updated Auto Scale Vm Profile id:" + vmProfile.getId()); + + return vmProfile; + } + + @Override + @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEVMPROFILE_DELETE, eventDescription = "deleting autoscale vm profile") + public boolean deleteAutoScaleVmProfile(long id) { + /* Check if entity is in database */ + getEntityInDatabase(UserContext.current().getCaller(), "AutoScale Vm Profile", id, _autoScaleVmProfileDao); + if (_autoScaleVmGroupDao.isProfileInUse(id)) { + throw new InvalidParameterValueException("Cannot delete AutoScale Vm Profile when it is in use by one more vm groups"); + } + boolean success = _autoScaleVmProfileDao.remove(id); + if (success) { + s_logger.info("Successfully deleted AutoScale Vm Profile with Id: " + id); + } + return success; + } + + @Override + public List listAutoScaleVmProfiles(ListAutoScaleVmProfilesCmd cmd) { + Long id = cmd.getId(); + Long templateId = cmd.getTemplateId(); + String otherDeployParams = cmd.getOtherDeployParams(); + + SearchWrapper searchWrapper = new SearchWrapper(_autoScaleVmProfileDao, AutoScaleVmProfileVO.class, cmd, cmd.getId()); + SearchBuilder sb = searchWrapper.getSearchBuilder(); + + sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); + sb.and("templateId", sb.entity().getTemplateId(), SearchCriteria.Op.EQ); + sb.and("otherDeployParams", sb.entity().getOtherDeployParams(), SearchCriteria.Op.LIKE); + SearchCriteria sc = searchWrapper.buildSearchCriteria(); + + if (id != null) { + sc.setParameters("id", id); + } + if (templateId != null) { + sc.setParameters("templateId", templateId); + } + if (otherDeployParams != null) { + sc.addAnd("otherDeployParams", SearchCriteria.Op.LIKE, "%" + otherDeployParams + "%"); + } + return searchWrapper.search(); + } + + @DB + protected AutoScalePolicyVO checkValidityAndPersist(AutoScalePolicyVO autoScalePolicyVO, List conditionIds) { + int duration = autoScalePolicyVO.getDuration(); + int quietTime = autoScalePolicyVO.getQuietTime(); + + if (duration < 0) { + throw new InvalidParameterValueException("duration is an invalid value: " + duration); + } + + if (quietTime < 0) { + throw new InvalidParameterValueException("quiettime is an invalid value: " + quietTime); + } + + final Transaction txn = Transaction.currentTxn(); + txn.start(); + + autoScalePolicyVO = _autoScalePolicyDao.persist(autoScalePolicyVO); + + if (conditionIds != null) { + SearchBuilder conditionsSearch = _conditionDao.createSearchBuilder(); + conditionsSearch.and("ids", conditionsSearch.entity().getId(), Op.IN); + conditionsSearch.done(); + SearchCriteria sc = conditionsSearch.create(); + + sc.setParameters("ids", conditionIds.toArray(new Object[0])); + List conditions = _conditionDao.search(sc, null); + + ControlledEntity[] sameOwnerEntities = conditions.toArray(new ControlledEntity[conditions.size() + 1]); + sameOwnerEntities[sameOwnerEntities.length - 1] = autoScalePolicyVO; + _accountMgr.checkAccess(UserContext.current().getCaller(), null, true, sameOwnerEntities); + + if (conditionIds.size() != conditions.size()) { + // TODO report the condition id which could not be found + throw new InvalidParameterValueException("Unable to find the condition specified"); + } + + ArrayList counterIds = new ArrayList(); + for (ConditionVO condition : conditions) { + if (counterIds.contains(condition.getCounterid())) { + throw new InvalidParameterValueException("atleast two conditions in the conditionids have the same counter. It is not right to apply two different conditions for the same counter"); + } + counterIds.add(condition.getCounterid()); + } + + /* For update case remove the existing mappings and create fresh ones */ + _autoScalePolicyConditionMapDao.removeByAutoScalePolicyId(autoScalePolicyVO.getId()); + + for (Long conditionId : conditionIds) { + AutoScalePolicyConditionMapVO policyConditionMapVO = new AutoScalePolicyConditionMapVO(autoScalePolicyVO.getId(), conditionId); + _autoScalePolicyConditionMapDao.persist(policyConditionMapVO); + } + } + + txn.commit(); + return autoScalePolicyVO; + } + + @Override + @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEPOLICY_CREATE, eventDescription = "creating autoscale policy", create = true) + public AutoScalePolicy createAutoScalePolicy(CreateAutoScalePolicyCmd cmd) { + + int duration = cmd.getDuration(); + Integer quietTime = cmd.getQuietTime(); + String action = cmd.getAction(); + + if (quietTime == null) { + quietTime = NetUtils.DEFAULT_AUTOSCALE_POLICY_QUIET_TIME; + } + + action = action.toLowerCase(); + if (!NetUtils.isValidAutoScaleAction(action)) { + throw new InvalidParameterValueException("action is invalid, only 'scaleup' and 'scaledown' is supported"); + } + + AutoScalePolicyVO policyVO = new AutoScalePolicyVO(cmd.getDomainId(), cmd.getAccountId(), duration, quietTime, action); + + policyVO = checkValidityAndPersist(policyVO, cmd.getConditionIds()); + s_logger.info("Successfully created AutoScale Policy with Id: " + policyVO.getId()); + return policyVO; + } + + @Override + @DB + @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEPOLICY_DELETE, eventDescription = "deleting autoscale policy") + public boolean deleteAutoScalePolicy(long id) { + /* Check if entity is in database */ + getEntityInDatabase(UserContext.current().getCaller(), "AutoScale Policy", id, _autoScalePolicyDao); + + if (_autoScaleVmGroupPolicyMapDao.isAutoScalePolicyInUse(id)) { + throw new InvalidParameterValueException("Cannot delete AutoScale Policy when it is in use by one or more AutoScale Vm Groups"); + } + + Transaction txn = Transaction.currentTxn(); + txn.start(); + + boolean success = true; + success = _autoScalePolicyDao.remove(id); + if (!success) { + s_logger.warn("Failed to remove AutoScale Policy db object"); + return false; + } + success = _autoScalePolicyConditionMapDao.removeByAutoScalePolicyId(id); + if (!success) { + s_logger.warn("Failed to remove AutoScale Policy Condition mappings"); + return false; + } + txn.commit(); + s_logger.info("Successfully deleted autoscale policy id : " + id); + return true; // successful + } + + public void checkCallerAccess(String accountName, Long domainId) + { + Account caller = UserContext.current().getCaller(); + Account owner = _accountDao.findActiveAccount(accountName, domainId); + if (owner == null) { + List idList = new ArrayList(); + idList.add(new IdentityProxy("domain", domainId, "domainId")); + throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain with specifed domainId"); + } + _accountMgr.checkAccess(caller, null, false, owner); + } + + private class SearchWrapper { + GenericDao dao; + SearchBuilder searchBuilder; + SearchCriteria searchCriteria; + Long domainId; + boolean isRecursive; + List permittedAccounts = new ArrayList(); + ListProjectResourcesCriteria listProjectResourcesCriteria; + Filter searchFilter; + + public SearchWrapper(GenericDao dao, Class entityClass, BaseListAccountResourcesCmd cmd, Long id) + { + this.dao = dao; + this.searchBuilder = dao.createSearchBuilder(); + domainId = cmd.getDomainId(); + String accountName = cmd.getAccountName(); + isRecursive = cmd.isRecursive(); + boolean listAll = cmd.listAll(); + long startIndex = cmd.getStartIndex(); + long pageSizeVal = cmd.getPageSizeVal(); + Account caller = UserContext.current().getCaller(); + + Ternary domainIdRecursiveListProject = new Ternary(domainId, isRecursive, null); + _accountMgr.buildACLSearchParameters(caller, id, accountName, null, permittedAccounts, domainIdRecursiveListProject, + listAll, false); + domainId = domainIdRecursiveListProject.first(); + isRecursive = domainIdRecursiveListProject.second(); + ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); + _accountMgr.buildACLSearchBuilder(searchBuilder, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); + searchFilter = new Filter(entityClass, "id", false, startIndex, pageSizeVal); + } + + public SearchBuilder getSearchBuilder() { + return searchBuilder; + } + + public SearchCriteria buildSearchCriteria() + { + searchCriteria = searchBuilder.create(); + _accountMgr.buildACLSearchCriteria(searchCriteria, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); + return searchCriteria; + } + + public List search() { + return dao.search(searchCriteria, searchFilter); + } + } + + @Override + public List listAutoScalePolicies(ListAutoScalePoliciesCmd cmd) { + SearchWrapper searchWrapper = new SearchWrapper(_autoScalePolicyDao, AutoScalePolicyVO.class, cmd, cmd.getId()); + SearchBuilder sb = searchWrapper.getSearchBuilder(); + Long id = cmd.getId(); + Long conditionId = cmd.getConditionId(); + String action = cmd.getAction(); + Long vmGroupId = cmd.getVmGroupId(); + + sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); + sb.and("action", sb.entity().getAction(), SearchCriteria.Op.EQ); + + if (conditionId != null) { + SearchBuilder asPolicyConditionSearch = _autoScalePolicyConditionMapDao.createSearchBuilder(); + asPolicyConditionSearch.and("conditionId", asPolicyConditionSearch.entity().getConditionId(), SearchCriteria.Op.EQ); + sb.join("asPolicyConditionSearch", asPolicyConditionSearch, sb.entity().getId(), asPolicyConditionSearch.entity().getPolicyId(), JoinBuilder.JoinType.INNER); + } + + if (vmGroupId != null) { + SearchBuilder asVmGroupPolicySearch = _autoScaleVmGroupPolicyMapDao.createSearchBuilder(); + asVmGroupPolicySearch.and("vmGroupId", asVmGroupPolicySearch.entity().getVmGroupId(), SearchCriteria.Op.EQ); + sb.join("asVmGroupPolicySearch", asVmGroupPolicySearch, sb.entity().getId(), asVmGroupPolicySearch.entity().getPolicyId(), JoinBuilder.JoinType.INNER); + } + + SearchCriteria sc = searchWrapper.buildSearchCriteria(); + + if (id != null) { + sc.setParameters("id", id); + } + + if (action != null) { + sc.setParameters("action", action); + } + + if (conditionId != null) { + sc.setJoinParameters("asPolicyConditionSearch", "conditionId", conditionId); + } + + if (vmGroupId != null) { + sc.setJoinParameters("asVmGroupPolicySearch", "vmGroupId", vmGroupId); + } + + return searchWrapper.search(); + } + + @Override + @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEPOLICY_UPDATE, eventDescription = "updating autoscale policy") + public AutoScalePolicy updateAutoScalePolicy(UpdateAutoScalePolicyCmd cmd) { + Long policyId = cmd.getId(); + Integer duration = cmd.getDuration(); + Integer quietTime = cmd.getQuietTime(); + List conditionIds = cmd.getConditionIds(); + AutoScalePolicyVO policy = getEntityInDatabase(UserContext.current().getCaller(), "Auto Scale Policy", policyId, _autoScalePolicyDao); + + if (duration != null) { + policy.setDuration(duration); + } + + if (quietTime != null) { + policy.setQuietTime(quietTime); + } + + List vmGroupPolicyList = _autoScaleVmGroupPolicyMapDao.listByPolicyId(policyId); + for (AutoScaleVmGroupPolicyMapVO vmGroupPolicy : vmGroupPolicyList) { + AutoScaleVmGroupVO vmGroupVO = _autoScaleVmGroupDao.findById(vmGroupPolicy.getVmGroupId()); + if(vmGroupVO == null) { + s_logger.warn("Stale database entry! There is an entry in VmGroupPolicyMap but the vmGroup is missing:" + vmGroupPolicy.getVmGroupId()); + + continue; + + } + if (!vmGroupVO.getState().equals(AutoScaleVmGroup.State_Disabled)) { + throw new InvalidParameterValueException("The AutoScale Policy can be updated only if the Vm Group it is associated with is disabled in state"); + } + if (vmGroupVO.getInterval() < policy.getDuration()) { + throw new InvalidParameterValueException("duration is less than the associated AutoScaleVmGroup's interval"); + } + if (vmGroupVO.getInterval() < policy.getQuietTime()) { + throw new InvalidParameterValueException("quietTime is less than the associated AutoScaleVmGroup's interval"); + } + } + + policy = checkValidityAndPersist(policy, conditionIds); + s_logger.info("Successfully updated Auto Scale Policy id:" + policyId); + return policy; + } + + @Override + @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEVMGROUP_CREATE, eventDescription = "creating autoscale vm group", create = true) + public AutoScaleVmGroup createAutoScaleVmGroup(CreateAutoScaleVmGroupCmd cmd) { + int minMembers = cmd.getMinMembers(); + int maxMembers = cmd.getMaxMembers(); + Integer interval = cmd.getInterval(); + + if (interval == null) { + interval = NetUtils.DEFAULT_AUTOSCALE_POLICY_INTERVAL_TIME; + } + + LoadBalancerVO loadBalancer = getEntityInDatabase(UserContext.current().getCaller(), ApiConstants.LBID, cmd.getLbRuleId(), _lbDao); + + Long zoneId = _ipAddressDao.findById(loadBalancer.getSourceIpAddressId()).getDataCenterId(); + + if (_autoScaleVmGroupDao.isAutoScaleLoadBalancer(loadBalancer.getId())) { + throw new InvalidParameterValueException("an AutoScaleVmGroup is already attached to the lb rule, the existing vm group has to be first deleted"); + } + + if (_lb2VmMapDao.isVmAttachedToLoadBalancer(loadBalancer.getId())) { + throw new InvalidParameterValueException("there are Vms already bound to the specified LoadBalancing Rule. User bound Vms and AutoScaled Vm Group cannot co-exist on a Load Balancing Rule"); + } + + AutoScaleVmGroupVO vmGroupVO = new AutoScaleVmGroupVO(cmd.getLbRuleId(), zoneId, loadBalancer.getDomainId(), loadBalancer.getAccountId(), minMembers, maxMembers, + loadBalancer.getDefaultPortStart(), interval, cmd.getProfileId(), AutoScaleVmGroup.State_New); + + vmGroupVO = checkValidityAndPersist(vmGroupVO, cmd.getScaleUpPolicyIds(), cmd.getScaleDownPolicyIds()); + s_logger.info("Successfully created Autoscale Vm Group with Id: " + vmGroupVO.getId()); + + return vmGroupVO; + } + + @Override + public boolean configureAutoScaleVmGroup(CreateAutoScaleVmGroupCmd cmd) { + return configureAutoScaleVmGroup(cmd.getEntityId()); + } + + public boolean isLoadBalancerBasedAutoScaleVmGroup(AutoScaleVmGroup vmGroup) { + return vmGroup.getLoadBalancerId() != null; + } + + public boolean configureAutoScaleVmGroup(long vmGroupid) { + AutoScaleVmGroup vmGroup = _autoScaleVmGroupDao.findById(vmGroupid); + + if (isLoadBalancerBasedAutoScaleVmGroup(vmGroup)) { + try { + return _lbRulesMgr.configureLbAutoScaleVmGroup(vmGroupid); + } catch (RuntimeException re) { + s_logger.warn("Exception during configureLbAutoScaleVmGrouop in lb rules manager", re); + } + } + + // This should never happen, because today loadbalancerruleid is manadatory for AutoScaleVmGroup. + throw new InvalidParameterValueException("Only LoadBalancer based AutoScale is supported"); + } + + @Override + @DB + @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEVMGROUP_DELETE, eventDescription = "deleting autoscale vm group") + public boolean deleteAutoScaleVmGroup(long id) { + AutoScaleVmGroupVO autoScaleVmGroupVO = getEntityInDatabase(UserContext.current().getCaller(), "AutoScale Vm Group", id, _autoScaleVmGroupDao); + + if (autoScaleVmGroupVO.getState().equals(AutoScaleVmGroup.State_New)) { + /* This condition is for handling failures during creation command */ + return _autoScaleVmGroupDao.remove(id); + } + String bakupState = autoScaleVmGroupVO.getState(); + autoScaleVmGroupVO.setState(AutoScaleVmGroup.State_Revoke); + _autoScaleVmGroupDao.persist(autoScaleVmGroupVO); + boolean success = false; + + try { + success = configureAutoScaleVmGroup(id); + } finally { + if (!success) { + s_logger.warn("Could not delete AutoScale Vm Group id : " + id); + autoScaleVmGroupVO.setState(bakupState); + _autoScaleVmGroupDao.persist(autoScaleVmGroupVO); + return false; + } + } + + Transaction txn = Transaction.currentTxn(); + txn.start(); + success = _autoScaleVmGroupDao.remove(id); + + if (!success) { + s_logger.warn("Failed to remove AutoScale Group db object"); + return false; + } + + success = _autoScaleVmGroupPolicyMapDao.removeByGroupId(id); + if (!success) { + s_logger.warn("Failed to remove AutoScale Group Policy mappings"); + return false; + } + + txn.commit(); + s_logger.info("Successfully deleted autoscale vm group id : " + id); + return success; // Successfull + } + + @Override + public List listAutoScaleVmGroups(ListAutoScaleVmGroupsCmd cmd) { + Long id = cmd.getId(); + Long policyId = cmd.getPolicyId(); + Long loadBalancerId = cmd.getLoadBalancerId(); + Long profileId = cmd.getProfileId(); + Long zoneId = cmd.getZoneId(); + + SearchWrapper searchWrapper = new SearchWrapper(_autoScaleVmGroupDao, AutoScaleVmGroupVO.class, cmd, cmd.getId()); + SearchBuilder sb = searchWrapper.getSearchBuilder(); + + sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); + sb.and("loadBalancerId", sb.entity().getLoadBalancerId(), SearchCriteria.Op.EQ); + sb.and("profileId", sb.entity().getProfileId(), SearchCriteria.Op.EQ); + sb.and("zoneId", sb.entity().getZoneId(), SearchCriteria.Op.EQ); + + if (policyId != null) { + SearchBuilder asVmGroupPolicySearch = _autoScaleVmGroupPolicyMapDao.createSearchBuilder(); + asVmGroupPolicySearch.and("policyId", asVmGroupPolicySearch.entity().getPolicyId(), SearchCriteria.Op.EQ); + sb.join("asVmGroupPolicySearch", asVmGroupPolicySearch, sb.entity().getId(), asVmGroupPolicySearch.entity().getVmGroupId(), JoinBuilder.JoinType.INNER); + } + + SearchCriteria sc = searchWrapper.buildSearchCriteria(); + if (id != null) { + sc.setParameters("id", id); + } + if (loadBalancerId != null) { + sc.setParameters("loadBalancerId", loadBalancerId); + } + if (profileId != null) { + sc.setParameters("profileId", profileId); + } + if (zoneId != null) { + sc.setParameters("zoneId", zoneId); + } + if (policyId != null) { + sc.setJoinParameters("asVmGroupPolicySearch", "policyId", policyId); + } + return searchWrapper.search(); + } + + @DB + protected AutoScaleVmGroupVO checkValidityAndPersist(AutoScaleVmGroupVO vmGroup, List scaleUpPolicyIds, List scaleDownPolicyIds) { + int minMembers = vmGroup.getMinMembers(); + int maxMembers = vmGroup.getMaxMembers(); + int interval = vmGroup.getInterval(); + List counters = new ArrayList(); + List policies = new ArrayList(); + List policyIds = new ArrayList(); + + if (minMembers < 0) { + throw new InvalidParameterValueException(ApiConstants.MIN_MEMBERS + " is an invalid value: " + minMembers); + } + + if (maxMembers < 0) { + throw new InvalidParameterValueException(ApiConstants.MAX_MEMBERS + " is an invalid value: " + minMembers); + } + + if (minMembers > maxMembers) { + throw new InvalidParameterValueException(ApiConstants.MIN_MEMBERS + " (" + minMembers + ")cannot be greater than " + ApiConstants.MAX_MEMBERS + " (" + maxMembers + ")"); + } + + if (interval < 0) { + throw new InvalidParameterValueException("interval is an invalid value: " + interval); + } + + if (scaleUpPolicyIds != null) { + policies.addAll(getAutoScalePolicies("scaleuppolicyid", scaleUpPolicyIds, counters, interval, true)); + } + + if (scaleDownPolicyIds != null) { + policies.addAll(getAutoScalePolicies("scaledownpolicyid", scaleDownPolicyIds, counters, interval, false)); + } + + 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); + + ControlledEntity[] sameOwnerEntities = policies.toArray(new ControlledEntity[policies.size() + 2]); + sameOwnerEntities[sameOwnerEntities.length - 2] = loadBalancer; + sameOwnerEntities[sameOwnerEntities.length - 1] = profileVO; + _accountMgr.checkAccess(UserContext.current().getCaller(), null, true, sameOwnerEntities); + + final Transaction txn = Transaction.currentTxn(); + txn.start(); + vmGroup = _autoScaleVmGroupDao.persist(vmGroup); + + if (scaleUpPolicyIds != null || scaleDownPolicyIds != null) { + List bakupScaleUpPolicyIds = new ArrayList(); + List bakupScaleDownPolicyIds = new ArrayList(); + ApiDBUtils.getAutoScaleVmGroupPolicyIds(vmGroup.getId(), bakupScaleUpPolicyIds, bakupScaleDownPolicyIds); + if (scaleUpPolicyIds == null) { + policyIds.addAll(bakupScaleUpPolicyIds); + } else { + policyIds.addAll(scaleUpPolicyIds); + } + if (scaleDownPolicyIds == null) { + policyIds.addAll(bakupScaleDownPolicyIds); + } else { + policyIds.addAll(scaleDownPolicyIds); + } + + _autoScaleVmGroupPolicyMapDao.removeByGroupId(vmGroup.getId()); + + for (Long policyId : policyIds) { + _autoScaleVmGroupPolicyMapDao.persist(new AutoScaleVmGroupPolicyMapVO(vmGroup.getId(), policyId)); + } + } + txn.commit(); + + return vmGroup; + } + + @Override + @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEVMGROUP_UPDATE, eventDescription = "updating autoscale vm group") + public AutoScaleVmGroup updateAutoScaleVmGroup(UpdateAutoScaleVmGroupCmd cmd) { + Long vmGroupId = cmd.getId(); + Integer minMembers = cmd.getMinMembers(); + Integer maxMembers = cmd.getMaxMembers(); + Integer interval = cmd.getInterval(); + + List scaleUpPolicyIds = cmd.getScaleUpPolicyIds(); + List scaleDownPolicyIds = cmd.getScaleDownPolicyIds(); + + AutoScaleVmGroupVO vmGroupVO = getEntityInDatabase(UserContext.current().getCaller(), "AutoScale Vm Group", vmGroupId, _autoScaleVmGroupDao); + + if (!vmGroupVO.getState().equals(AutoScaleVmGroup.State_Disabled)) { + throw new InvalidParameterValueException("An AutoScale Vm Group can be updated only when it is in disabled state"); + } + + if (minMembers != null) { + vmGroupVO.setMinMembers(minMembers); + } + + if (maxMembers != null) { + vmGroupVO.setMaxMembers(maxMembers); + } + + if (interval != null) { + vmGroupVO.setInterval(interval); + } + + vmGroupVO = checkValidityAndPersist(vmGroupVO, scaleUpPolicyIds, scaleDownPolicyIds); + if (vmGroupVO != null) { + s_logger.debug("Updated Auto Scale VmGroup id:" + vmGroupId); + return vmGroupVO; + } else + return null; + } + + @Override + @DB + @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEVMGROUP_ENABLE, eventDescription = "enabling autoscale vm group") + public AutoScaleVmGroup enableAutoScaleVmGroup(Long id) { + AutoScaleVmGroupVO vmGroup = getEntityInDatabase(UserContext.current().getCaller(), "AutoScale Vm Group", id, _autoScaleVmGroupDao); + boolean success = false; + if (!vmGroup.getState().equals(AutoScaleVmGroup.State_Disabled)) { + throw new InvalidParameterValueException("Only a AutoScale Vm Group which is in Disabled state can be enabled."); + } + + try { + vmGroup.setState(AutoScaleVmGroup.State_Enabled); + vmGroup = _autoScaleVmGroupDao.persist(vmGroup); + success = configureAutoScaleVmGroup(id); + + } finally { + if (!success) { + vmGroup.setState(AutoScaleVmGroup.State_Disabled); + _autoScaleVmGroupDao.persist(vmGroup); + s_logger.warn("Failed to enable AutoScale Vm Group id : " + id); + return null; + } + s_logger.info("Successfully enabled AutoScale Vm Group with Id:" + id); + } + return vmGroup; + } + + @Override + @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEVMGROUP_DISABLE, eventDescription = "disabling autoscale vm group") + @DB + public AutoScaleVmGroup disableAutoScaleVmGroup(Long id) { + AutoScaleVmGroupVO vmGroup = getEntityInDatabase(UserContext.current().getCaller(), "AutoScale Vm Group", id, _autoScaleVmGroupDao); + boolean success = false; + if (!vmGroup.getState().equals(AutoScaleVmGroup.State_Enabled)) { + throw new InvalidParameterValueException("Only a AutoScale Vm Group which is in Disabled state can be disabled."); + } + + try { + vmGroup.setState(AutoScaleVmGroup.State_Disabled); + vmGroup = _autoScaleVmGroupDao.persist(vmGroup); + success = configureAutoScaleVmGroup(id); + } finally { + if (!success) { + vmGroup.setState(AutoScaleVmGroup.State_Enabled); + _autoScaleVmGroupDao.persist(vmGroup); + s_logger.warn("Failed to disable AutoScale Vm Group id : " + id); + return null; + } + s_logger.info("Successfully disabled AutoScale Vm Group with Id:" + id); + } + return vmGroup; + } + + @Override + @ActionEvent(eventType = EventTypes.EVENT_COUNTER_CREATE, eventDescription = "Counter", create = true) + @DB + public Counter createCounter(CreateCounterCmd cmd) { + String source = cmd.getSource().toLowerCase(); + String name = cmd.getName(); + Counter.Source src; + // Validate Source + try { + src = Counter.Source.valueOf(source); + } catch (Exception ex) { + throw new InvalidParameterValueException("The Source " + source + " does not exist; Unable to create Counter"); + } + + CounterVO counter = null; + + s_logger.debug("Adding Counter " + name); + counter = _counterDao.persist(new CounterVO(src, name, cmd.getValue())); + + UserContext.current().setEventDetails(" Id: " + counter.getId() + " Name: " + name); + return counter; + } + + @Override + @ActionEvent(eventType = EventTypes.EVENT_CONDITION_CREATE, eventDescription = "Condition", create = true) + public Condition createCondition(CreateConditionCmd cmd) { + checkCallerAccess(cmd.getAccountName(), cmd.getDomainId()); + String opr = cmd.getRelationalOperator().toUpperCase(); + long cid = cmd.getCounterId(); + long threshold = cmd.getThreshold(); + Condition.Operator op; + // Validate Relational Operator + try { + op = Condition.Operator.valueOf(opr); + } catch (IllegalArgumentException ex) { + throw new InvalidParameterValueException("The Operator " + opr + " does not exist; Unable to create Condition."); + } + // TODO - Validate threshold + + CounterVO counter = _counterDao.findById(cid); + + if (counter == null) { + throw new InvalidParameterValueException("Unable to find counter"); + } + ConditionVO condition = null; + + condition = _conditionDao.persist(new ConditionVO(cid, threshold, cmd.getEntityOwnerId(), cmd.getDomainId(), op)); + s_logger.info("Successfully created condition with Id: " + condition.getId()); + + UserContext.current().setEventDetails(" Id: " + condition.getId()); + return condition; + } + + @Override + public List listCounters(ListCountersCmd cmd) { + String name = cmd.getName(); + Long id = cmd.getId(); + String source = cmd.getSource(); + if (source != null) + source = source.toLowerCase(); + + Filter searchFilter = new Filter(CounterVO.class, "created", false, cmd.getStartIndex(), cmd.getPageSizeVal()); + + List counters = _counterDao.listCounters(id, name, source, cmd.getKeyword(), searchFilter); + + return counters; + } + + @Override + public List listConditions(ListConditionsCmd cmd) { + Long id = cmd.getId(); + Long counterId = cmd.getCounterId(); + Long policyId = cmd.getPolicyId(); + SearchWrapper searchWrapper = new SearchWrapper(_conditionDao, ConditionVO.class, cmd, cmd.getId()); + SearchBuilder sb = searchWrapper.getSearchBuilder(); + if (policyId != null) { + SearchBuilder asPolicyConditionSearch = _autoScalePolicyConditionMapDao.createSearchBuilder(); + asPolicyConditionSearch.and("policyId", asPolicyConditionSearch.entity().getPolicyId(), SearchCriteria.Op.EQ); + sb.join("asPolicyConditionSearch", asPolicyConditionSearch, sb.entity().getId(), asPolicyConditionSearch.entity().getConditionId(), JoinBuilder.JoinType.INNER); + } + + sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); + sb.and("counterId", sb.entity().getCounterid(), SearchCriteria.Op.EQ); + + // now set the SC criteria... + SearchCriteria sc = searchWrapper.buildSearchCriteria(); + + if (id != null) { + sc.setParameters("id", id); + } + + if (counterId != null) { + sc.setParameters("counterId", counterId); + } + + if (policyId != null) { + sc.setJoinParameters("asPolicyConditionSearch", "policyId", policyId); + } + + return searchWrapper.search(); + } + + @Override + @ActionEvent(eventType = EventTypes.EVENT_COUNTER_DELETE, eventDescription = "counter") + public boolean deleteCounter(long counterId) throws ResourceInUseException { + // Verify Counter id + CounterVO counter = _counterDao.findById(counterId); + if (counter == null) { + throw new InvalidParameterValueException("Unable to find Counter"); + } + + // Verify if it is used in any Condition + + ConditionVO condition = _conditionDao.findByCounterId(counterId); + if (condition != null) { + s_logger.info("Cannot delete counter " + counter.getName() + " as it is being used in a condition."); + throw new ResourceInUseException("Counter is in use."); + } + + boolean success = _counterDao.remove(counterId); + if (success) { + s_logger.info("Successfully deleted counter with Id: " + counterId); + } + + return success; + } + + @Override + @ActionEvent(eventType = EventTypes.EVENT_CONDITION_DELETE, eventDescription = "condition") + public boolean deleteCondition(long conditionId) throws ResourceInUseException { + /* Check if entity is in database */ + ConditionVO condition = getEntityInDatabase(UserContext.current().getCaller(), "Condition", conditionId, _conditionDao); + if (condition == null) { + throw new InvalidParameterValueException("Unable to find Condition"); + } + + // Verify if condition is used in any autoscale policy + if (_autoScalePolicyConditionMapDao.isConditionInUse(conditionId)) { + s_logger.info("Cannot delete condition " + conditionId + " as it is being used in a condition."); + throw new ResourceInUseException("Cannot delete Condition when it is in use by one or more AutoScale Policies."); + } + boolean success = _conditionDao.remove(conditionId); + if (success) { + s_logger.info("Successfully deleted condition " + condition.getId()); + } + return success; + } + +} diff --git a/server/src/com/cloud/network/as/AutoScalePolicyConditionMapVO.java b/server/src/com/cloud/network/as/AutoScalePolicyConditionMapVO.java new file mode 100644 index 00000000000..b387b9340f1 --- /dev/null +++ b/server/src/com/cloud/network/as/AutoScalePolicyConditionMapVO.java @@ -0,0 +1,59 @@ +// 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 javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name=("autoscale_policy_condition_map")) +public class AutoScalePolicyConditionMapVO { + + @Id + @GeneratedValue(strategy=GenerationType.IDENTITY) + @Column(name="id") + private long id; + + @Column(name="policy_id") + private long policyId; + + @Column(name="condition_id") + private long conditionId; + + public AutoScalePolicyConditionMapVO() { } + + public AutoScalePolicyConditionMapVO(long policyId, long conditionId) { + this.policyId = policyId; + this.conditionId = conditionId; + } + + public long getId() { + return id; + } + + public long getPolicyId() { + return policyId; + } + + public long getConditionId() { + return conditionId; + } +} diff --git a/server/src/com/cloud/network/as/AutoScalePolicyVO.java b/server/src/com/cloud/network/as/AutoScalePolicyVO.java new file mode 100644 index 00000000000..e23e34d1aa5 --- /dev/null +++ b/server/src/com/cloud/network/as/AutoScalePolicyVO.java @@ -0,0 +1,133 @@ +// 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.Date; +import java.util.UUID; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Inheritance; +import javax.persistence.InheritanceType; +import javax.persistence.Table; + +import com.cloud.utils.db.GenericDao; + +@Entity +@Table(name = "autoscale_policies") +@Inheritance(strategy = InheritanceType.JOINED) +public class AutoScalePolicyVO implements AutoScalePolicy { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + long id; + + @Column(name = "uuid") + String uuid; + + @Column(name = "domain_id") + private long domainId; + + @Column(name = "account_id") + private long accountId; + + @Column(name = "duration") + private int duration; + + @Column(name = "quiet_time", updatable = true, nullable = false) + private int quietTime; + + @Column(name = "action", updatable = false, nullable = false) + private String action; + + @Column(name = GenericDao.REMOVED_COLUMN) + protected Date removed; + + @Column(name = GenericDao.CREATED_COLUMN) + protected Date created; + + public AutoScalePolicyVO() { + } + + public AutoScalePolicyVO(long domainId, long accountId, int duration, int quietTime, String action) { + this.uuid = UUID.randomUUID().toString(); + this.domainId = domainId; + this.accountId = accountId; + this.duration = duration; + this.quietTime = quietTime; + this.action = action; + } + + @Override + public String toString() { + return new StringBuilder("AutoScalePolicy[").append("id-").append(id).append("]").toString(); + } + + @Override + public long getId() { + return id; + } + + public String getUuid() { + return uuid; + } + + @Override + public long getDomainId() { + return domainId; + } + + @Override + public long getAccountId() { + return accountId; + } + + @Override + public int getDuration() { + return duration; + } + + @Override + public int getQuietTime() { + return quietTime; + } + + @Override + public String getAction() { + return action; + } + + public Date getRemoved() { + return removed; + } + + public Date getCreated() { + return created; + } + + public void setDuration(Integer duration) { + this.duration = duration; + } + + public void setQuietTime(Integer quietTime) { + this.quietTime = quietTime; + } +} diff --git a/server/src/com/cloud/network/as/AutoScaleVmGroupPolicyMapVO.java b/server/src/com/cloud/network/as/AutoScaleVmGroupPolicyMapVO.java new file mode 100644 index 00000000000..9ea6cab30d7 --- /dev/null +++ b/server/src/com/cloud/network/as/AutoScaleVmGroupPolicyMapVO.java @@ -0,0 +1,62 @@ +// 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 javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name=("autoscale_vmgroup_policy_map")) +public class AutoScaleVmGroupPolicyMapVO { + @Id + @GeneratedValue(strategy=GenerationType.IDENTITY) + @Column(name="id") + private long id; + + @Column(name="vmgroup_id") + private long vmGroupId; + + @Column(name="policy_id") + private long policyId; + + public AutoScaleVmGroupPolicyMapVO() { } + + public AutoScaleVmGroupPolicyMapVO(long vmGroupId, long policyId) { + this.vmGroupId = vmGroupId; + this.policyId = policyId; + } + + public AutoScaleVmGroupPolicyMapVO(long vmgroupId, long policyId, boolean revoke) { + this(vmgroupId, policyId); + } + + public long getId() { + return id; + } + + public long getVmGroupId() { + return vmGroupId; + } + + public long getPolicyId() { + return policyId; + } +} diff --git a/server/src/com/cloud/network/as/AutoScaleVmGroupVO.java b/server/src/com/cloud/network/as/AutoScaleVmGroupVO.java new file mode 100644 index 00000000000..3de9f9b541e --- /dev/null +++ b/server/src/com/cloud/network/as/AutoScaleVmGroupVO.java @@ -0,0 +1,185 @@ +// 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.Date; +import java.util.UUID; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Inheritance; +import javax.persistence.InheritanceType; +import javax.persistence.Table; + +import com.cloud.utils.db.GenericDao; + +@Entity +@Table(name = "autoscale_vmgroups") +@Inheritance(strategy = InheritanceType.JOINED) +public class AutoScaleVmGroupVO implements AutoScaleVmGroup { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + long id; + + @Column(name = "uuid") + String uuid; + + @Column(name = "zone_id", updatable = false) + private long zoneId; + + @Column(name = "domain_id", updatable = false) + private long domainId; + + @Column(name = "account_id") + private long accountId; + + @Column(name = "load_balancer_id") + private Long loadBalancerId; + + @Column(name = "min_members", updatable = true) + private int minMembers; + + @Column(name = "max_members", updatable = true) + private int maxMembers; + + @Column(name = "member_port") + private int memberPort; + + @Column(name = "interval") + private int interval; + + @Column(name = "profile_id") + private long profileId; + + @Column(name = GenericDao.REMOVED_COLUMN) + protected Date removed; + + @Column(name = GenericDao.CREATED_COLUMN) + protected Date created; + + @Column(name = "state") + private String state; + + public AutoScaleVmGroupVO() { + } + + public AutoScaleVmGroupVO(long lbRuleId, long zoneId, long domainId, long accountId, int minMembers, int maxMembers, int memberPort, int interval, long profileId, String state) { + this.uuid = UUID.randomUUID().toString(); + this.loadBalancerId = lbRuleId; + this.minMembers = minMembers; + this.maxMembers = maxMembers; + this.memberPort = memberPort; + this.profileId = profileId; + this.accountId = accountId; + this.domainId = domainId; + this.zoneId = zoneId; + this.state = state; + this.interval = interval; + } + + @Override + public String toString() { + return new StringBuilder("AutoScaleVmGroupVO[").append("id").append("]").toString(); + } + + @Override + public long getId() { + return id; + } + + public long getZoneId() { + return zoneId; + } + + @Override + public long getDomainId() { + return domainId; + } + + @Override + public long getAccountId() { + return accountId; + } + + @Override + public Long getLoadBalancerId() { + return loadBalancerId; + } + + @Override + public int getMinMembers() { + return minMembers; + } + + @Override + public int getMaxMembers() { + return maxMembers; + } + + @Override + public int getMemberPort() { + return memberPort; + } + + @Override + public int getInterval() { + return interval; + } + + @Override + public long getProfileId() { + return profileId; + } + + public Date getRemoved() { + return removed; + } + + public Date getCreated() { + return created; + } + + @Override + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + public void setMinMembers(int minMembers) { + this.minMembers = minMembers; + } + + public void setMaxMembers(int maxMembers) { + this.maxMembers = maxMembers; + } + + public void setInterval(Integer interval) { + this.interval = interval; + } + + public void setLoadBalancerId(Long loadBalancerId) { + this.loadBalancerId = loadBalancerId; + } +} diff --git a/server/src/com/cloud/network/as/AutoScaleVmProfileVO.java b/server/src/com/cloud/network/as/AutoScaleVmProfileVO.java new file mode 100644 index 00000000000..d963eef2940 --- /dev/null +++ b/server/src/com/cloud/network/as/AutoScaleVmProfileVO.java @@ -0,0 +1,196 @@ +// 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.Date; +import java.util.UUID; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Inheritance; +import javax.persistence.InheritanceType; +import javax.persistence.Table; + +import com.cloud.api.Identity; +import com.cloud.utils.db.GenericDao; +import com.cloud.utils.net.NetUtils; + +@Entity +@Table(name = "autoscale_vmprofiles") +@Inheritance(strategy = InheritanceType.JOINED) +public class AutoScaleVmProfileVO implements AutoScaleVmProfile, Identity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + protected long id; + + @Column(name = "uuid") + protected String uuid; + + @Column(name = "zone_id", updatable = true, nullable = false) + protected Long zoneId; + + @Column(name = "domain_id", updatable = true) + private long domainId; + + @Column(name = "account_id") + private long accountId; + + @Column(name = "autoscale_user_id") + private long autoscaleUserId; + + @Column(name = "service_offering_id", updatable = true, nullable = false) + private Long serviceOfferingId; + + @Column(name = "template_id", updatable = true, nullable = false, length = 17) + private Long templateId; + + @Column(name = "other_deploy_params", updatable = true, length = 1024) + private String otherDeployParams; + + @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 = GenericDao.REMOVED_COLUMN) + protected Date removed; + + @Column(name = GenericDao.CREATED_COLUMN) + protected Date created; + + public AutoScaleVmProfileVO() { + } + + public AutoScaleVmProfileVO(long zoneId, long domainId, long accountId, long serviceOfferingId, long templateId, String otherDeployParams, String snmpCommunity, Integer snmpPort, Integer destroyVmGraceperiod, + long autoscaleUserId) { + this.uuid = UUID.randomUUID().toString(); + this.zoneId = zoneId; + this.domainId = domainId; + this.accountId = accountId; + this.serviceOfferingId = serviceOfferingId; + this.templateId = templateId; + this.otherDeployParams = otherDeployParams; + this.autoscaleUserId = autoscaleUserId; + if (destroyVmGraceperiod != null) { + this.destroyVmGraceperiod = destroyVmGraceperiod; + } + if (snmpCommunity != null) { + this.snmpCommunity = snmpCommunity; + } + if (snmpPort != null) { + this.snmpPort = snmpPort; + } + } + + @Override + public String toString() { + return new StringBuilder("AutoScaleVMProfileVO[").append("id").append(id).append("-").append("templateId").append("-").append(templateId).append("]").toString(); + } + + @Override + public Long getTemplateId() { + return templateId; + } + + public void setTemplateId(Long templateId) { + this.templateId = templateId; + } + + @Override + public Long getServiceOfferingId() { + return serviceOfferingId; + } + + @Override + public String getOtherDeployParams() { + return otherDeployParams; + } + + public void setOtherDeployParams(String otherDeployParams) { + this.otherDeployParams = otherDeployParams; + } + + @Override + public String getSnmpCommunity() { + return snmpCommunity; + } + + public void setSnmpCommunity(String snmpCommunity) { + this.snmpCommunity = snmpCommunity; + } + + @Override + public Integer getSnmpPort() { + return snmpPort; + } + + public void setSnmpPort(Integer snmpPort) { + this.snmpPort = snmpPort; + } + + @Override + public String getUuid() { + return uuid; + } + + public void setAutoscaleUserId(long autoscaleUserId) { + this.autoscaleUserId = autoscaleUserId; + } + + @Override + public Long getZoneId() { + return zoneId; + } + + @Override + public long getAccountId() { + return accountId; + } + + @Override + public long getDomainId() { + return domainId; + } + + @Override + public long getId() { + return id; + } + + @Override + public Integer getDestroyVmGraceperiod() { + return destroyVmGraceperiod; + } + + public void setDestroyVmGraceperiod(Integer destroyVmGraceperiod) { + this.destroyVmGraceperiod = destroyVmGraceperiod; + } + + @Override + public long getAutoScaleUserId() { + return autoscaleUserId; + } +} diff --git a/server/src/com/cloud/network/as/ConditionVO.java b/server/src/com/cloud/network/as/ConditionVO.java new file mode 100644 index 00000000000..f4d6c708f9c --- /dev/null +++ b/server/src/com/cloud/network/as/ConditionVO.java @@ -0,0 +1,128 @@ +// 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.Date; +import java.util.UUID; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.cloud.api.Identity; +import com.cloud.utils.db.GenericDao; + +@Entity +@Table(name = "conditions") +public class ConditionVO implements Condition, Identity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private long id; + + @Column(name = "counter_id") + private long counterid; + + @Column(name = "threshold") + private long threshold; + + @Column(name = "relational_operator") + @Enumerated(value = EnumType.STRING) + private Operator relationalOperator; + + @Column(name = "domain_id") + protected long domainId; + + @Column(name = "account_id") + protected long accountId; + + @Column(name = "uuid") + private String uuid; + + @Column(name = GenericDao.REMOVED_COLUMN) + Date removed; + + @Column(name = GenericDao.CREATED_COLUMN) + Date created; + + public ConditionVO() { + } + + public ConditionVO(long counterid, long threshold, long accountId, long domainId, Operator relationalOperator) { + this.counterid = counterid; + this.threshold = threshold; + this.relationalOperator = relationalOperator; + this.accountId = accountId; + this.domainId = domainId; + this.uuid = UUID.randomUUID().toString(); + } + + public Date getCreated() { + return created; + } + + @Override + public long getId() { + return id; + } + + @Override + public String toString() { + return new StringBuilder("Condition[").append("id-").append(id).append("]").toString(); + } + + @Override + public long getCounterid() { + return counterid; + } + + @Override + public long getThreshold() { + return threshold; + } + + @Override + public Operator getRelationalOperator() { + return relationalOperator; + } + + @Override + public long getAccountId() { + return accountId; + } + + @Override + public long getDomainId() { + return domainId; + } + + @Override + public String getUuid() { + return this.uuid; + } + + public Date getRemoved() { + return removed; + } +} \ No newline at end of file diff --git a/server/src/com/cloud/network/as/CounterVO.java b/server/src/com/cloud/network/as/CounterVO.java new file mode 100644 index 00000000000..894110bbcdf --- /dev/null +++ b/server/src/com/cloud/network/as/CounterVO.java @@ -0,0 +1,110 @@ +// 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.Date; +import java.util.UUID; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.cloud.api.Identity; +import com.cloud.utils.db.GenericDao; + +@Entity +@Table(name = "counter") +public class CounterVO implements Counter, Identity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private long id; + + @Column(name = "source") + @Enumerated(value = EnumType.STRING) + private Source source; + + @Column(name = "name") + private String name; + + @Column(name = "value") + private String value; + + @Column(name = "uuid") + private String uuid; + + @Column(name = GenericDao.REMOVED_COLUMN) + Date removed; + + @Column(name = GenericDao.CREATED_COLUMN) + Date created; + + public CounterVO() { + } + + public CounterVO(Source source, String name, String value) { + this.source = source; + this.name = name; + this.value = value; + this.uuid = UUID.randomUUID().toString(); + } + + @Override + public String toString() { + return new StringBuilder("Counter[").append("id-").append(id).append("]").toString(); + } + + @Override + public String getName() { + return name; + } + + @Override + public String getValue() { + return value; + } + + @Override + public Source getSource() { + return source; + } + + @Override + public long getId() { + return id; + } + + @Override + public String getUuid() { + return this.uuid; + } + + public Date getRemoved() { + return removed; + } + + public Date getCreated() { + return created; + } +} \ No newline at end of file diff --git a/server/src/com/cloud/network/as/dao/AutoScalePolicyConditionMapDao.java b/server/src/com/cloud/network/as/dao/AutoScalePolicyConditionMapDao.java new file mode 100644 index 00000000000..88755bb3378 --- /dev/null +++ b/server/src/com/cloud/network/as/dao/AutoScalePolicyConditionMapDao.java @@ -0,0 +1,28 @@ +// 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.dao; + +import java.util.List; + +import com.cloud.network.as.AutoScalePolicyConditionMapVO; +import com.cloud.utils.db.GenericDao; + +public interface AutoScalePolicyConditionMapDao extends GenericDao { + List listByAll(Long policyId, Long conditionId); + public boolean isConditionInUse(Long conditionId); + boolean removeByAutoScalePolicyId(long id); +} diff --git a/server/src/com/cloud/network/as/dao/AutoScalePolicyConditionMapDaoImpl.java b/server/src/com/cloud/network/as/dao/AutoScalePolicyConditionMapDaoImpl.java new file mode 100644 index 00000000000..84dd191b072 --- /dev/null +++ b/server/src/com/cloud/network/as/dao/AutoScalePolicyConditionMapDaoImpl.java @@ -0,0 +1,58 @@ +// 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.dao; + +import java.util.List; + +import javax.ejb.Local; + +import com.cloud.network.as.AutoScalePolicyConditionMapVO; +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.SearchCriteria; + +@Local(value={AutoScalePolicyConditionMapDao.class}) +public class AutoScalePolicyConditionMapDaoImpl extends GenericDaoBase implements AutoScalePolicyConditionMapDao { + + private SearchCriteria getSearchCriteria(Long policyId, Long conditionId) + { + SearchCriteria sc = createSearchCriteria(); + + if(policyId != null) + sc.addAnd("policyId", SearchCriteria.Op.EQ, policyId); + + if(conditionId != null) + sc.addAnd("conditionId", SearchCriteria.Op.EQ, conditionId); + + return sc; + } + + @Override + public List listByAll(Long policyId, Long conditionId) { + return listBy(getSearchCriteria(policyId, conditionId)); + } + + public boolean isConditionInUse(Long conditionId) { + return findOneBy(getSearchCriteria(null, conditionId)) != null; + } + + @Override + public boolean removeByAutoScalePolicyId(long policyId) { + SearchCriteria sc = createSearchCriteria(); + sc.addAnd("policyId", SearchCriteria.Op.EQ, policyId); + return expunge(sc) > 0; + } +} diff --git a/server/src/com/cloud/network/as/dao/AutoScalePolicyDao.java b/server/src/com/cloud/network/as/dao/AutoScalePolicyDao.java new file mode 100644 index 00000000000..8edfa946e0b --- /dev/null +++ b/server/src/com/cloud/network/as/dao/AutoScalePolicyDao.java @@ -0,0 +1,23 @@ +// 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.dao; + +import com.cloud.network.as.AutoScalePolicyVO; +import com.cloud.utils.db.GenericDao; + +public interface AutoScalePolicyDao extends GenericDao { +} diff --git a/server/src/com/cloud/network/as/dao/AutoScalePolicyDaoImpl.java b/server/src/com/cloud/network/as/dao/AutoScalePolicyDaoImpl.java new file mode 100644 index 00000000000..5dfe080e594 --- /dev/null +++ b/server/src/com/cloud/network/as/dao/AutoScalePolicyDaoImpl.java @@ -0,0 +1,26 @@ +// 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.dao; + +import javax.ejb.Local; + +import com.cloud.network.as.AutoScalePolicyVO; +import com.cloud.utils.db.GenericDaoBase; + +@Local(value = { AutoScalePolicyDao.class }) +public class AutoScalePolicyDaoImpl extends GenericDaoBase implements AutoScalePolicyDao { +} diff --git a/server/src/com/cloud/network/as/dao/AutoScaleVmGroupDao.java b/server/src/com/cloud/network/as/dao/AutoScaleVmGroupDao.java new file mode 100644 index 00000000000..a11bedda873 --- /dev/null +++ b/server/src/com/cloud/network/as/dao/AutoScaleVmGroupDao.java @@ -0,0 +1,28 @@ +// 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.dao; + +import java.util.List; + +import com.cloud.network.as.AutoScaleVmGroupVO; +import com.cloud.utils.db.GenericDao; + +public interface AutoScaleVmGroupDao extends GenericDao { + List listByAll(Long loadBalancerId, Long profileId); + boolean isProfileInUse(long profileId); + boolean isAutoScaleLoadBalancer(Long loadBalancerId); +} diff --git a/server/src/com/cloud/network/as/dao/AutoScaleVmGroupDaoImpl.java b/server/src/com/cloud/network/as/dao/AutoScaleVmGroupDaoImpl.java new file mode 100644 index 00000000000..80f2bee7cbb --- /dev/null +++ b/server/src/com/cloud/network/as/dao/AutoScaleVmGroupDaoImpl.java @@ -0,0 +1,62 @@ +// 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.dao; + +import java.util.List; + +import javax.ejb.Local; + +import com.cloud.network.as.AutoScaleVmGroupVO; +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.GenericSearchBuilder; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.SearchCriteria.Func; + +@Local(value = { AutoScaleVmGroupDao.class }) +public class AutoScaleVmGroupDaoImpl extends GenericDaoBase implements AutoScaleVmGroupDao { + + @Override + public List listByAll(Long loadBalancerId, Long profileId) { + SearchCriteria sc = createSearchCriteria(); + + if(loadBalancerId != null) + sc.addAnd("loadBalancerId", SearchCriteria.Op.EQ, loadBalancerId); + + if(profileId != null) + sc.addAnd("profileId", SearchCriteria.Op.EQ, profileId); + + return listBy(sc); + } + + @Override + public boolean isProfileInUse(long profileId) { + SearchCriteria sc = createSearchCriteria(); + sc.addAnd("profileId", SearchCriteria.Op.EQ, profileId); + return findOneBy(sc) != null; + } + + @Override + public boolean isAutoScaleLoadBalancer(Long loadBalancerId) { + GenericSearchBuilder CountByAccount = createSearchBuilder(Long.class); + CountByAccount.select(null, Func.COUNT, null); + CountByAccount.and("loadBalancerId", CountByAccount.entity().getLoadBalancerId(), SearchCriteria.Op.EQ); + + SearchCriteria sc = CountByAccount.create(); + sc.setParameters("loadBalancerId", loadBalancerId); + return customSearch(sc, null).get(0) > 0; + } +} diff --git a/server/src/com/cloud/network/as/dao/AutoScaleVmGroupPolicyMapDao.java b/server/src/com/cloud/network/as/dao/AutoScaleVmGroupPolicyMapDao.java new file mode 100644 index 00000000000..40a07763fde --- /dev/null +++ b/server/src/com/cloud/network/as/dao/AutoScaleVmGroupPolicyMapDao.java @@ -0,0 +1,26 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.as.dao; + +import java.util.List; + +import com.cloud.network.as.AutoScaleVmGroupPolicyMapVO; +import com.cloud.utils.db.GenericDao; + +public interface AutoScaleVmGroupPolicyMapDao extends GenericDao { + boolean removeByGroupId(long vmGroupId); + boolean removeByGroupAndPolicies(long vmGroupId, List bakupPolicyIds); + List listByVmGroupId(long vmGroupId); + List listByPolicyId(long policyId); + public boolean isAutoScalePolicyInUse(long policyId); +} diff --git a/server/src/com/cloud/network/as/dao/AutoScaleVmGroupPolicyMapDaoImpl.java b/server/src/com/cloud/network/as/dao/AutoScaleVmGroupPolicyMapDaoImpl.java new file mode 100644 index 00000000000..c33a55fe549 --- /dev/null +++ b/server/src/com/cloud/network/as/dao/AutoScaleVmGroupPolicyMapDaoImpl.java @@ -0,0 +1,74 @@ +// 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.dao; + +import java.util.List; + +import javax.ejb.Local; + +import com.cloud.network.as.AutoScaleVmGroupPolicyMapVO; +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.SearchCriteria.Op; + +@Local(value={AutoScaleVmGroupPolicyMapDao.class}) +public class AutoScaleVmGroupPolicyMapDaoImpl extends GenericDaoBase implements AutoScaleVmGroupPolicyMapDao { + + @Override + public boolean removeByGroupId(long vmGroupId) { + SearchCriteria sc = createSearchCriteria(); + sc.addAnd("vmGroupId", SearchCriteria.Op.EQ, vmGroupId); + + return expunge(sc) > 0; + } + + @Override + public boolean removeByGroupAndPolicies(long vmGroupId, List policyIds) { + SearchBuilder policySearch = createSearchBuilder(); + policySearch.and("vmGroupId", policySearch.entity().getVmGroupId(), Op.EQ); + policySearch.and("policyIds", policySearch.entity().getPolicyId(), Op.IN); + policySearch.done(); + SearchCriteria sc = policySearch.create(); + sc.setParameters("vmGroupId", vmGroupId); + sc.setParameters("policyIds", policyIds); + return expunge(sc) > 0; + } + + @Override + public List listByVmGroupId(long vmGroupId) { + SearchCriteria sc = createSearchCriteria(); + sc.addAnd("vmGroupId", SearchCriteria.Op.EQ, vmGroupId); + return listBy(sc); + } + + @Override + public List listByPolicyId(long policyId) { + SearchCriteria sc = createSearchCriteria(); + sc.addAnd("policyId", SearchCriteria.Op.EQ, policyId); + + return listBy(sc); + } + + @Override + public boolean isAutoScalePolicyInUse(long policyId) { + SearchCriteria sc = createSearchCriteria(); + sc.addAnd("policyId", SearchCriteria.Op.EQ, policyId); + return findOneBy(sc) != null; + } + +} diff --git a/server/src/com/cloud/network/as/dao/AutoScaleVmProfileDao.java b/server/src/com/cloud/network/as/dao/AutoScaleVmProfileDao.java new file mode 100644 index 00000000000..0803571a3af --- /dev/null +++ b/server/src/com/cloud/network/as/dao/AutoScaleVmProfileDao.java @@ -0,0 +1,23 @@ +// 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.dao; + +import com.cloud.network.as.AutoScaleVmProfileVO; +import com.cloud.utils.db.GenericDao; + +public interface AutoScaleVmProfileDao extends GenericDao { +} diff --git a/server/src/com/cloud/network/as/dao/AutoScaleVmProfileDaoImpl.java b/server/src/com/cloud/network/as/dao/AutoScaleVmProfileDaoImpl.java new file mode 100644 index 00000000000..12392c30dd2 --- /dev/null +++ b/server/src/com/cloud/network/as/dao/AutoScaleVmProfileDaoImpl.java @@ -0,0 +1,26 @@ +// 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.dao; + +import javax.ejb.Local; + +import com.cloud.network.as.AutoScaleVmProfileVO; +import com.cloud.utils.db.GenericDaoBase; + +@Local(value = { AutoScaleVmProfileDao.class }) +public class AutoScaleVmProfileDaoImpl extends GenericDaoBase implements AutoScaleVmProfileDao { +} diff --git a/server/src/com/cloud/network/as/dao/ConditionDao.java b/server/src/com/cloud/network/as/dao/ConditionDao.java new file mode 100644 index 00000000000..1ff4d208b89 --- /dev/null +++ b/server/src/com/cloud/network/as/dao/ConditionDao.java @@ -0,0 +1,27 @@ +// 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.dao; + +import com.cloud.network.as.ConditionVO; +import com.cloud.utils.db.GenericDao; + +public interface ConditionDao extends GenericDao { + + ConditionVO findByCounterId(long ctrId); + +} \ No newline at end of file diff --git a/server/src/com/cloud/network/as/dao/ConditionDaoImpl.java b/server/src/com/cloud/network/as/dao/ConditionDaoImpl.java new file mode 100644 index 00000000000..338fe19d767 --- /dev/null +++ b/server/src/com/cloud/network/as/dao/ConditionDaoImpl.java @@ -0,0 +1,46 @@ +// 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.dao; + +import javax.ejb.Local; + +import com.cloud.network.as.ConditionVO; +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.SearchCriteria.Op; + +@Local(value = ConditionDao.class) +public class ConditionDaoImpl extends GenericDaoBase implements ConditionDao { + final SearchBuilder AllFieldsSearch; + + protected ConditionDaoImpl() { + AllFieldsSearch = createSearchBuilder(); + AllFieldsSearch.and("id", AllFieldsSearch.entity().getId(), Op.EQ); + AllFieldsSearch.and("counterId", AllFieldsSearch.entity().getCounterid(), Op.EQ); + AllFieldsSearch.done(); + } + + @Override + public ConditionVO findByCounterId(long ctrId) { + // TODO - may consider indexing counterId field in db-schema + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("counterId", ctrId); + return findOneBy(sc); + } +} diff --git a/server/src/com/cloud/network/as/dao/CounterDao.java b/server/src/com/cloud/network/as/dao/CounterDao.java new file mode 100644 index 00000000000..dd9cf08e9d6 --- /dev/null +++ b/server/src/com/cloud/network/as/dao/CounterDao.java @@ -0,0 +1,29 @@ +// 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.dao; + +import java.util.List; + +import com.cloud.network.as.CounterVO; +import com.cloud.utils.db.Filter; +import com.cloud.utils.db.GenericDao; + +public interface CounterDao extends GenericDao { + public List listCounters(Long id, String name, String source, String keyword, Filter filter); + +} \ No newline at end of file diff --git a/server/src/com/cloud/network/as/dao/CounterDaoImpl.java b/server/src/com/cloud/network/as/dao/CounterDaoImpl.java new file mode 100644 index 00000000000..a8cbfbc1e26 --- /dev/null +++ b/server/src/com/cloud/network/as/dao/CounterDaoImpl.java @@ -0,0 +1,67 @@ +// 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.dao; + +import java.util.List; + +import javax.ejb.Local; + +import com.cloud.network.as.CounterVO; +import com.cloud.utils.db.Filter; +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.SearchCriteria.Op; + +@Local(value = CounterDao.class) +public class CounterDaoImpl extends GenericDaoBase implements CounterDao { + final SearchBuilder AllFieldsSearch; + + protected CounterDaoImpl() { + AllFieldsSearch = createSearchBuilder(); + AllFieldsSearch.and("id", AllFieldsSearch.entity().getId(), Op.EQ); + AllFieldsSearch.and("name", AllFieldsSearch.entity().getName(), Op.LIKE); + AllFieldsSearch.and("source", AllFieldsSearch.entity().getSource(), Op.EQ); + AllFieldsSearch.done(); + } + + @Override + public List listCounters(Long id, String name, String source, String keyword, Filter filter) { + SearchCriteria sc = AllFieldsSearch.create(); + + if (keyword != null) { + SearchCriteria ssc = createSearchCriteria(); + ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%"); + sc.addAnd("name", SearchCriteria.Op.SC, ssc); + } + + if (name != null) { + sc.addAnd("name", SearchCriteria.Op.LIKE, "%" + name + "%"); + } + + if (id != null) { + sc.addAnd("id", SearchCriteria.Op.EQ, id); + } + + if (source != null) { + sc.addAnd("source", SearchCriteria.Op.EQ, source); + } + return listBy(sc, filter); + } + +} diff --git a/server/src/com/cloud/network/dao/LoadBalancerVMMapDao.java b/server/src/com/cloud/network/dao/LoadBalancerVMMapDao.java index 24dcf45ef2b..f717344ac2e 100644 --- a/server/src/com/cloud/network/dao/LoadBalancerVMMapDao.java +++ b/server/src/com/cloud/network/dao/LoadBalancerVMMapDao.java @@ -28,5 +28,5 @@ public interface LoadBalancerVMMapDao extends GenericDao listByLoadBalancerId(long loadBalancerId); List listByLoadBalancerId(long loadBalancerId, boolean revoke); LoadBalancerVMMapVO findByLoadBalancerIdAndVmId(long loadBalancerId, long instanceId); - + boolean isVmAttachedToLoadBalancer(long loadBalancerId); } diff --git a/server/src/com/cloud/network/dao/LoadBalancerVMMapDaoImpl.java b/server/src/com/cloud/network/dao/LoadBalancerVMMapDaoImpl.java index ab0e3ab602e..b1a6dda205d 100644 --- a/server/src/com/cloud/network/dao/LoadBalancerVMMapDaoImpl.java +++ b/server/src/com/cloud/network/dao/LoadBalancerVMMapDaoImpl.java @@ -22,7 +22,9 @@ import javax.ejb.Local; import com.cloud.network.LoadBalancerVMMapVO; import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.GenericSearchBuilder; import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.SearchCriteria.Func; @Local(value={LoadBalancerVMMapDao.class}) public class LoadBalancerVMMapDaoImpl extends GenericDaoBase implements LoadBalancerVMMapDao { @@ -71,7 +73,7 @@ public class LoadBalancerVMMapDaoImpl extends GenericDaoBase sc = createSearchCriteria(); @@ -80,5 +82,14 @@ public class LoadBalancerVMMapDaoImpl extends GenericDaoBase CountByAccount = createSearchBuilder(Long.class); + CountByAccount.select(null, Func.COUNT, null); + CountByAccount.and("loadBalancerId", CountByAccount.entity().getLoadBalancerId(), SearchCriteria.Op.EQ); + + SearchCriteria sc = CountByAccount.create(); + sc.setParameters("loadBalancerId", loadBalancerId); + return customSearch(sc, null).get(0) > 0; + } } diff --git a/server/src/com/cloud/network/lb/LoadBalancingRulesManager.java b/server/src/com/cloud/network/lb/LoadBalancingRulesManager.java index d901663bd91..ebe4e2abb16 100644 --- a/server/src/com/cloud/network/lb/LoadBalancingRulesManager.java +++ b/server/src/com/cloud/network/lb/LoadBalancingRulesManager.java @@ -28,21 +28,23 @@ import com.cloud.network.rules.LoadBalancer; import com.cloud.user.Account; public interface LoadBalancingRulesManager extends LoadBalancingRulesService { - + LoadBalancer createLoadBalancer(CreateLoadBalancerRuleCmd lb, boolean openFirewall) throws NetworkRuleConflictException; - + boolean removeAllLoadBalanacersForIp(long ipId, Account caller, long callerUserId); boolean removeAllLoadBalanacersForNetwork(long networkId, Account caller, long callerUserId); List getExistingDestinations(long lbId); List getStickinessPolicies(long lbId); List getStickinessMethods(long networkid); - + /** * Remove vm from all load balancers * @param vmId * @return true if removal is successful */ boolean removeVmFromLoadBalancers(long vmId); - + boolean applyLoadBalancersForNetwork(long networkId) throws ResourceUnavailableException; + String getLBCapability(long networkid, String capabilityName); + boolean configureLbAutoScaleVmGroup(long vmGroupid); } diff --git a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java index ba4b0976181..c97818c2420 100755 --- a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java +++ b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java @@ -18,6 +18,7 @@ package com.cloud.network.lb; import java.security.InvalidParameterException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; @@ -38,7 +39,10 @@ import com.cloud.api.commands.ListLoadBalancerRuleInstancesCmd; import com.cloud.api.commands.ListLoadBalancerRulesCmd; import com.cloud.api.commands.UpdateLoadBalancerRuleCmd; import com.cloud.api.response.ServiceResponse; +import com.cloud.configuration.Config; import com.cloud.configuration.ConfigurationManager; +import com.cloud.configuration.dao.ConfigurationDao; +import com.cloud.dc.dao.DataCenterDao; import com.cloud.dc.dao.VlanDao; import com.cloud.domain.dao.DomainDao; import com.cloud.event.ActionEvent; @@ -63,6 +67,21 @@ import com.cloud.network.Network.Provider; import com.cloud.network.Network.Service; import com.cloud.network.NetworkManager; import com.cloud.network.NetworkVO; +import com.cloud.network.as.AutoScalePolicy; +import com.cloud.network.as.AutoScalePolicyConditionMapVO; +import com.cloud.network.as.AutoScaleVmGroup; +import com.cloud.network.as.AutoScaleVmGroupPolicyMapVO; +import com.cloud.network.as.AutoScaleVmGroupVO; +import com.cloud.network.as.AutoScaleVmProfile; +import com.cloud.network.as.Condition; +import com.cloud.network.as.Counter; +import com.cloud.network.as.dao.AutoScalePolicyConditionMapDao; +import com.cloud.network.as.dao.AutoScalePolicyDao; +import com.cloud.network.as.dao.AutoScaleVmGroupDao; +import com.cloud.network.as.dao.AutoScaleVmGroupPolicyMapDao; +import com.cloud.network.as.dao.AutoScaleVmProfileDao; +import com.cloud.network.as.dao.ConditionDao; +import com.cloud.network.as.dao.CounterDao; import com.cloud.network.dao.FirewallRulesCidrsDao; import com.cloud.network.dao.FirewallRulesDao; import com.cloud.network.dao.IPAddressDao; @@ -71,6 +90,10 @@ import com.cloud.network.dao.LoadBalancerDao; import com.cloud.network.dao.LoadBalancerVMMapDao; import com.cloud.network.dao.NetworkDao; import com.cloud.network.dao.NetworkServiceMapDao; +import com.cloud.network.lb.LoadBalancingRule.LbAutoScalePolicy; +import com.cloud.network.lb.LoadBalancingRule.LbAutoScaleVmGroup; +import com.cloud.network.lb.LoadBalancingRule.LbAutoScaleVmProfile; +import com.cloud.network.lb.LoadBalancingRule.LbCondition; import com.cloud.network.lb.LoadBalancingRule.LbDestination; import com.cloud.network.lb.LoadBalancingRule.LbStickinessPolicy; import com.cloud.network.rules.FirewallManager; @@ -89,11 +112,14 @@ import com.cloud.projects.Project.ListProjectResourcesCriteria; import com.cloud.server.ResourceTag.TaggedResourceType; import com.cloud.tags.ResourceTagVO; import com.cloud.tags.dao.ResourceTagDao; +import com.cloud.template.TemplateManager; import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.DomainService; +import com.cloud.user.User; import com.cloud.user.UserContext; import com.cloud.user.dao.AccountDao; +import com.cloud.user.dao.UserDao; import com.cloud.uservm.UserVm; import com.cloud.utils.IdentityProxy; import com.cloud.utils.Pair; @@ -163,15 +189,39 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa @Inject ConfigurationManager _configMgr; @Inject + TemplateManager _templateMgr; + @Inject ExternalLoadBalancerUsageManager _externalLBUsageMgr; - @Inject + @Inject NetworkServiceMapDao _ntwkSrvcDao; @Inject ResourceTagDao _resourceTagDao; @Inject VpcManager _vpcMgr; + @Inject + CounterDao _counterDao; + @Inject + ConditionDao _conditionDao; + @Inject + AutoScaleVmProfileDao _autoScaleVmProfileDao; + @Inject + AutoScalePolicyDao _autoScalePolicyDao; + @Inject + AutoScalePolicyConditionMapDao _autoScalePolicyConditionMapDao; + @Inject + AutoScaleVmGroupDao _autoScaleVmGroupDao; + @Inject + AutoScaleVmGroupPolicyMapDao _autoScaleVmGroupPolicyMapDao; + @Inject + ConfigurationDao _configDao; + @Inject + DataCenterDao _dcDao = null; + @Inject + UserDao _userDao; - private String getLBStickinessCapability(long networkid) { + // Will return a string. For LB Stickiness this will be a json, for autoscale this will be "," separated values + @Override + public String getLBCapability(long networkid, String capabilityName) { Map> serviceCapabilitiesMap = _networkMgr.getNetworkCapabilities(networkid); if (serviceCapabilitiesMap != null) { for (Service service : serviceCapabilitiesMap.keySet()) { @@ -179,12 +229,11 @@ 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()) { - if (Capability.SupportedStickinessMethods.getName() - .equals(capability.getName())) { + if (capabilityName.equals(capability.getName())) { return serviceCapabilities.get(capability); } } @@ -194,6 +243,113 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa } return null; } + private LbAutoScaleVmGroup getLbAutoScaleVmGroup(AutoScaleVmGroup vmGroup) { + List vmGroupPolicyMapList = _autoScaleVmGroupPolicyMapDao.listByVmGroupId(vmGroup.getId()); + List autoScalePolicies = new ArrayList(); + for (AutoScaleVmGroupPolicyMapVO vmGroupPolicyMap : vmGroupPolicyMapList) { + AutoScalePolicy autoScalePolicy = _autoScalePolicyDao.findById(vmGroupPolicyMap.getPolicyId()); + List autoScalePolicyConditionMapList = _autoScalePolicyConditionMapDao.listByAll(autoScalePolicy.getId(), null); + List lbConditions = new ArrayList(); + for (AutoScalePolicyConditionMapVO autoScalePolicyConditionMap : autoScalePolicyConditionMapList) { + Condition condition = _conditionDao.findById(autoScalePolicyConditionMap.getConditionId()); + Counter counter = _counterDao.findById(condition.getCounterid()); + lbConditions.add(new LbCondition(counter, condition)); + } + autoScalePolicies.add(new LbAutoScalePolicy(autoScalePolicy, lbConditions)); + } + AutoScaleVmProfile autoScaleVmProfile = _autoScaleVmProfileDao.findById(vmGroup.getProfileId()); + Long autoscaleUserId = autoScaleVmProfile.getAutoScaleUserId(); + User user = _userDao.findById(autoscaleUserId); + String apiKey = user.getApiKey(); + String secretKey = user.getSecretKey(); + String csUrl = _configDao.getValue(Config.EndpointeUrl.key()); + + if(apiKey == null) { + throw new InvalidParameterValueException("apiKey for user: " + user.getUsername() + " is empty. Please generate it"); + } + + if(secretKey == null) { + throw new InvalidParameterValueException("secretKey for user: " + user.getUsername() + " is empty. Please generate it"); + } + + if(csUrl == null || csUrl.contains("localhost")) { + throw new InvalidParameterValueException("Global setting endpointe.url has to be set to the Management Server's API end point"); + } + + LbAutoScaleVmProfile lbAutoScaleVmProfile = new LbAutoScaleVmProfile(autoScaleVmProfile, apiKey, secretKey, csUrl); + return new LbAutoScaleVmGroup(vmGroup, autoScalePolicies, lbAutoScaleVmProfile); + } + + private boolean applyAutoScaleConfig(LoadBalancerVO lb, LoadBalancingRule rule) throws ResourceUnavailableException { + if (!isRollBackAllowedForProvider(lb)) { + // this is for Netscalar type of devices. if their is failure the db entries will be rollbacked. + return false; + } + + List rules = Arrays.asList(rule); + + if (!_networkMgr.applyRules(rules, false)) { + s_logger.debug("LB rules' autoscale config are not completely applied"); + return false; + } + + return true; + } + + @Override + @DB + public boolean configureLbAutoScaleVmGroup(long vmGroupid) { + AutoScaleVmGroupVO vmGroup = _autoScaleVmGroupDao.findById(vmGroupid); + boolean success = false; + + LoadBalancerVO loadBalancer = _lbDao.findById(vmGroup.getLoadBalancerId()); + + FirewallRule.State backupState = loadBalancer.getState(); + + if (vmGroup.getState().equals(AutoScaleVmGroup.State_New)) { + loadBalancer.setState(FirewallRule.State.Add); + _lbDao.persist(loadBalancer); + } + else if (loadBalancer.getState() == FirewallRule.State.Active && + vmGroup.getState().equals(AutoScaleVmGroup.State_Revoke)) { + loadBalancer.setState(FirewallRule.State.Add); + _lbDao.persist(loadBalancer); + } + + // LBTODO + try { + LbAutoScaleVmGroup lbAutoScaleVmGroup = getLbAutoScaleVmGroup(vmGroup); + LoadBalancingRule rule = new LoadBalancingRule(loadBalancer, null, null); + rule.setAutoScaleVmGroup(lbAutoScaleVmGroup); + success = applyAutoScaleConfig(loadBalancer, rule); + } catch (ResourceUnavailableException e) { + s_logger.warn("Unable to configure AutoScaleVmGroup to the lb rule: " + loadBalancer.getId() + " because resource is unavaliable:", e); + } finally { + if (!success) { + s_logger.warn("Failed to configure LB Auto Scale Vm Group with Id:" + vmGroupid); + if (isRollBackAllowedForProvider(loadBalancer)) { + loadBalancer.setState(backupState); + _lbDao.persist(loadBalancer); + s_logger.debug("LB Rollback rule id: " + loadBalancer.getId() + " lb state rolback while creating AutoscaleVmGroup"); + } + } + } + + if (success) { + if (vmGroup.getState().equals(AutoScaleVmGroup.State_New)) { + Transaction.currentTxn().start(); + loadBalancer.setState(FirewallRule.State.Active); + s_logger.debug("LB rule " + loadBalancer.getId() + " state is set to Active"); + _lbDao.persist(loadBalancer); + vmGroup.setState(AutoScaleVmGroup.State_Enabled); + _autoScaleVmGroupDao.persist(vmGroup); + s_logger.debug("LB Auto Scale Vm Group with Id: " + vmGroupid + " is set to Enabled state."); + Transaction.currentTxn().commit(); + } + s_logger.info("Successfully configured LB Autoscale Vm Group with Id: " + vmGroupid); + } + return success; + } private boolean genericValidator(CreateLBStickinessPolicyCmd cmd) throws InvalidParameterValueException { LoadBalancerVO loadBalancer = _lbDao.findById(cmd.getLbRuleId()); @@ -310,7 +466,7 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa @ActionEvent(eventType = EventTypes.EVENT_LB_STICKINESSPOLICY_CREATE, eventDescription = "Apply Stickinesspolicy to load balancer ", async = true) public boolean applyLBStickinessPolicy(CreateLBStickinessPolicyCmd cmd) { boolean success = true; - + LoadBalancerVO loadBalancer = _lbDao.findById(cmd.getLbRuleId()); if (loadBalancer == null) { throw new InvalidParameterException("Invalid Load balancer Id:" + cmd.getLbRuleId()); @@ -338,7 +494,7 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa @ActionEvent(eventType = EventTypes.EVENT_LB_STICKINESSPOLICY_DELETE, eventDescription = "revoking LB Stickiness policy ", async = true) public boolean deleteLBStickinessPolicy(long stickinessPolicyId, boolean apply) { boolean success = true; - + UserContext caller = UserContext.current(); LBStickinessPolicyVO stickinessPolicy = _lb2stickinesspoliciesDao.findById(stickinessPolicyId); @@ -364,7 +520,7 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa stickinessPolicy.setRevoke(true); _lb2stickinesspoliciesDao.persist(stickinessPolicy); s_logger.debug("Set load balancer rule for revoke: rule id " + loadBalancerId + ", stickinesspolicyID " + stickinessPolicyId); - + try { if (!applyLoadBalancerConfig(loadBalancerId)) { s_logger.warn("Failed to remove load balancer rule id " + loadBalancerId + " for stickinesspolicyID " + stickinessPolicyId); @@ -386,7 +542,7 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa } return success; - } + } private boolean isRollBackAllowedForProvider(LoadBalancerVO loadBalancer) { Network network = _networkDao.findById(loadBalancer.getNetworkId()); @@ -420,8 +576,8 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa UserVm vm = _vmDao.findById(instanceId); if (vm == null || vm.getState() == State.Destroyed || vm.getState() == State.Expunging) { - InvalidParameterValueException ex = new InvalidParameterValueException("Invalid instance id specified"); - ex.addProxyObject(vm, instanceId, "instanceId"); + InvalidParameterValueException ex = new InvalidParameterValueException("Invalid instance id specified"); + ex.addProxyObject(vm, instanceId, "instanceId"); throw ex; } @@ -442,8 +598,8 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa } if (nicInSameNetwork == null) { - InvalidParameterValueException ex = new InvalidParameterValueException("VM " + instanceId + " cannot be added because it doesn't belong in the same network."); - ex.addProxyObject(vm, instanceId, "instanceId"); + InvalidParameterValueException ex = new InvalidParameterValueException("VM " + instanceId + " cannot be added because it doesn't belong in the same network."); + ex.addProxyObject(vm, instanceId, "instanceId"); throw ex; } @@ -460,7 +616,11 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa map = _lb2VmMapDao.persist(map); } txn.commit(); - + if (_autoScaleVmGroupDao.isAutoScaleLoadBalancer(loadBalancerId)) { + // Nothing needs to be done for an autoscaled loadbalancer, + // just persist and proceed. + return true; + } boolean success = false; FirewallRule.State backupState = loadBalancer.getState(); try { @@ -486,11 +646,11 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa } s_logger.warn("Unable to apply the load balancer config because resource is unavaliable.", e); } - + if(!success){ - CloudRuntimeException ex = new CloudRuntimeException("Failed to add specified loadbalancerruleid for vms " + instanceIds); - ex.addProxyObject(loadBalancer, loadBalancerId, "loadBalancerId"); - // TBD: Also pack in the instanceIds in the exception using the right VO object or table name. + CloudRuntimeException ex = new CloudRuntimeException("Failed to add specified loadbalancerruleid for vms " + instanceIds); + ex.addProxyObject(loadBalancer, loadBalancerId, "loadBalancerId"); + // TBD: Also pack in the instanceIds in the exception using the right VO object or table name. throw ex; } @@ -526,23 +686,29 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa s_logger.debug("Set load balancer rule for revoke: rule id " + loadBalancerId + ", vmId " + instanceId); } + if (_autoScaleVmGroupDao.isAutoScaleLoadBalancer(loadBalancerId)) { + // Nothing needs to be done for an autoscaled loadbalancer, + // just persist and proceed. + return true; + } + if (!applyLoadBalancerConfig(loadBalancerId)) { s_logger.warn("Failed to remove load balancer rule id " + loadBalancerId + " for vms " + instanceIds); CloudRuntimeException ex = new CloudRuntimeException("Failed to remove specified load balancer rule id for vms " + instanceIds); - ex.addProxyObject(loadBalancer, loadBalancerId, "loadBalancerId"); + ex.addProxyObject(loadBalancer, loadBalancerId, "loadBalancerId"); throw ex; } success = true; } catch (ResourceUnavailableException e) { if (rollBack && isRollBackAllowedForProvider(loadBalancer)) { - + for (long instanceId : instanceIds) { LoadBalancerVMMapVO map = _lb2VmMapDao.findByLoadBalancerIdAndVmId(loadBalancerId, instanceId); map.setRevoke(false); _lb2VmMapDao.persist(map); s_logger.debug("LB Rollback rule id: " + loadBalancerId + ",while removing vmId " + instanceId); } - + loadBalancer.setState(backupState); _lbDao.persist(loadBalancer); s_logger.debug("LB Rollback rule id: " + loadBalancerId + " while removing vm instances"); @@ -550,10 +716,10 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa s_logger.warn("Unable to apply the load balancer config because resource is unavaliable.", e); } if(!success){ - CloudRuntimeException ex = new CloudRuntimeException("Failed to remove specified load balancer rule id for vms " + instanceIds); - ex.addProxyObject(loadBalancer, loadBalancerId, "loadBalancerId"); + CloudRuntimeException ex = new CloudRuntimeException("Failed to remove specified load balancer rule id for vms " + instanceIds); + ex.addProxyObject(loadBalancer, loadBalancerId, "loadBalancerId"); throw ex; - } + } return success; } @@ -620,7 +786,7 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa boolean generateUsageEvent = false; boolean success = true; FirewallRule.State backupState = lb.getState(); - + txn.start(); if (lb.getState() == FirewallRule.State.Staged) { if (s_logger.isDebugEnabled()) { @@ -797,6 +963,7 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa return result; } + @Override @DB public LoadBalancer createLoadBalancer(CreateLoadBalancerRuleCmd lb, boolean openFirewall) throws NetworkRuleConflictException { UserContext caller = UserContext.current(); @@ -808,12 +975,12 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa IPAddressVO ipAddr = _ipAddressDao.findById(sourceIpId); // make sure ip address exists if (ipAddr == null || !ipAddr.readyToUse()) { - InvalidParameterValueException ex = new InvalidParameterValueException("Unable to create load balancer rule, invalid IP address id specified"); - ex.addProxyObject(ipAddr, sourceIpId, "sourceIpId"); + InvalidParameterValueException ex = new InvalidParameterValueException("Unable to create load balancer rule, invalid IP address id specified"); + ex.addProxyObject(ipAddr, sourceIpId, "sourceIpId"); throw ex; } else if (ipAddr.isOneToOneNat()) { - InvalidParameterValueException ex = new InvalidParameterValueException("Unable to create load balancer rule; specified sourceip id has static nat enabled"); - ex.addProxyObject(ipAddr, sourceIpId, "sourceIpId"); + InvalidParameterValueException ex = new InvalidParameterValueException("Unable to create load balancer rule; specified sourceip id has static nat enabled"); + ex.addProxyObject(ipAddr, sourceIpId, "sourceIpId"); throw ex; } @@ -822,8 +989,8 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa Long networkId = ipAddr.getAssociatedWithNetworkId(); if (networkId == null) { - InvalidParameterValueException ex = new InvalidParameterValueException("Unable to create load balancer rule ; specified sourceip id is not associated with any network"); - ex.addProxyObject(ipAddr, sourceIpId, "sourceIpId"); + InvalidParameterValueException ex = new InvalidParameterValueException("Unable to create load balancer rule ; specified sourceip id is not associated with any network"); + ex.addProxyObject(ipAddr, sourceIpId, "sourceIpId"); throw ex; } @@ -833,8 +1000,8 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa // verify that lb service is supported by the network if (!_networkMgr.areServicesSupportedInNetwork(network.getId(), Service.Lb)) { - InvalidParameterValueException ex = new InvalidParameterValueException("LB service is not supported in specified network id"); - ex.addProxyObject(network, networkId, "networkId"); + InvalidParameterValueException ex = new InvalidParameterValueException("LB service is not supported in specified network id"); + ex.addProxyObject(network, networkId, "networkId"); throw ex; } @@ -887,10 +1054,9 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa public boolean applyLoadBalancerConfig(long lbRuleId) throws ResourceUnavailableException { LoadBalancerVO lb = _lbDao.findById(lbRuleId); List lbs; - if (isRollBackAllowedForProvider(lb)) { + if (isRollBackAllowedForProvider(lb)) { // this is for Netscalar type of devices. if their is failure the db entries will be rollbacked. - lbs = new ArrayList(1); - lbs.add(_lbDao.findById(lbRuleId)); + lbs = Arrays.asList(lb); } else { // get all rules in transition state lbs = _lbDao.listInTransitionStateByNetworkId(lb.getNetworkId()); @@ -1099,7 +1265,7 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa String algorithm = cmd.getAlgorithm(); LoadBalancerVO lb = _lbDao.findById(lbRuleId); LoadBalancerVO lbBackup = _lbDao.findById(lbRuleId); - + if (lb == null) { throw new InvalidParameterValueException("Unable to find lb rule by id=" + lbRuleId); } @@ -1129,21 +1295,21 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa applyLoadBalancerConfig(lbRuleId); } catch (ResourceUnavailableException e) { if (isRollBackAllowedForProvider(lb)) { - /* NOTE : We use lb object to update db instead of lbBackup object since db layer will fail to update if there is no change in the object. + /* NOTE : We use lb object to update db instead of lbBackup object since db layer will fail to update if there is no change in the object. */ if (lbBackup.getName() != null) { - lb.setName(lbBackup.getName()); + lb.setName(lbBackup.getName()); } if (lbBackup.getDescription() != null) { lb.setDescription(lbBackup.getDescription()); } if (lbBackup.getAlgorithm() != null){ - lb.setAlgorithm(lbBackup.getAlgorithm()); + lb.setAlgorithm(lbBackup.getAlgorithm()); } lb.setState(lbBackup.getState()); _lbDao.update(lb.getId(), lb); _lbDao.persist(lb); - + s_logger.debug("LB Rollback rule id: " + lbRuleId + " while updating LB rule."); } s_logger.warn("Unable to apply the load balancer config because resource is unavaliable.", e); @@ -1154,7 +1320,7 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa if (!success) { throw new CloudRuntimeException("Failed to update load balancer rule: " + lbRuleId); } - + return lb; } @@ -1209,12 +1375,22 @@ 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) { - String capability = getLBStickinessCapability(networkid); - if (capability == null) + String capability = getLBCapability(networkid, Capability.SupportedStickinessMethods.getName()); + if (capability == null) { return null; + } Gson gson = new Gson(); java.lang.reflect.Type listType = new TypeToken>() { }.getType(); diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index f5ec28ce2c5..19ad591d130 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -2800,7 +2800,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian int srcPort = rule.getSourcePortStart(); List destinations = rule.getDestinations(); List stickinessPolicies = rule.getStickinessPolicies(); - LoadBalancerTO lb = new LoadBalancerTO(srcIp, srcPort, protocol, algorithm, revoked, false, destinations, stickinessPolicies); + LoadBalancerTO lb = new LoadBalancerTO(rule.getId(), srcIp, srcPort, protocol, algorithm, revoked, false, destinations, stickinessPolicies); lbs[i++] = lb; } String routerPublicIp = null; diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql index acbbc414813..8127a713ae0 100755 --- a/setup/db/create-schema.sql +++ b/setup/db/create-schema.sql @@ -147,6 +147,13 @@ DROP TABLE IF EXISTS `cloud`.`s2s_vpn_connection`; DROP TABLE IF EXISTS `cloud`,`external_nicira_nvp_devices`; DROP TABLE IF EXISTS `cloud`,`nicira_nvp_nic_map`; DROP TABLE IF EXISTS `cloud`,`nicira_nvp_router_map`; +DROP TABLE IF EXISTS `cloud`.`autoscale_vmgroup_policy_map`; +DROP TABLE IF EXISTS `cloud`.`autoscale_policy_condition_map`; +DROP TABLE IF EXISTS `cloud`.`autoscale_vmgroups`; +DROP TABLE IF EXISTS `cloud`.`autoscale_vmprofiles`; +DROP TABLE IF EXISTS `cloud`.`autoscale_policies`; +DROP TABLE IF EXISTS `cloud`.`counter`; +DROP TABLE IF EXISTS `cloud`.`conditions`; CREATE TABLE `cloud`.`version` ( `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT COMMENT 'id', @@ -2380,4 +2387,113 @@ CREATE TABLE `cloud`.`nicira_nvp_router_map` ( CONSTRAINT `fk_nicira_nvp_router_map__network_id` FOREIGN KEY (`network_id`) REFERENCES `networks`(`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; +CREATE TABLE `cloud`.`counter` ( + `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT COMMENT 'id', + `uuid` varchar(40), + `source` varchar(255) NOT NULL COMMENT 'source e.g. netscaler, snmp', + `name` varchar(255) NOT NULL COMMENT 'Counter name', + `value` varchar(255) NOT NULL COMMENT 'Value in case of source=snmp', + `removed` datetime COMMENT 'date removed if not null', + `created` datetime NOT NULL COMMENT 'date created', + PRIMARY KEY (`id`), + CONSTRAINT `uc_counter__uuid` UNIQUE (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`conditions` ( + `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT COMMENT 'id', + `uuid` varchar(40), + `counter_id` bigint unsigned NOT NULL COMMENT 'Counter Id', + `threshold` bigint unsigned NOT NULL COMMENT 'threshold value for the given counter', + `relational_operator` char(2) COMMENT 'relational operator to be used upon the counter and condition', + `domain_id` bigint unsigned NOT NULL COMMENT 'domain the Condition belongs to', + `account_id` bigint unsigned NOT NULL COMMENT 'owner of this Condition', + `removed` datetime COMMENT 'date removed if not null', + `created` datetime NOT NULL COMMENT 'date created', + PRIMARY KEY (`id`), + CONSTRAINT `fk_conditions__counter_id` FOREIGN KEY `fk_condition__counter_id`(`counter_id`) REFERENCES `counter`(`id`), + CONSTRAINT `fk_conditions__account_id` FOREIGN KEY `fk_condition__account_id` (`account_id`) REFERENCES `account`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_conditions__domain_id` FOREIGN KEY `fk_condition__domain_id` (`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE, + CONSTRAINT `uc_conditions__uuid` UNIQUE (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`autoscale_vmprofiles` ( + `id` bigint unsigned NOT NULL auto_increment, + `uuid` varchar(40), + `zone_id` bigint unsigned NOT NULL, + `domain_id` bigint unsigned NOT NULL, + `account_id` bigint unsigned NOT NULL, + `autoscale_user_id` bigint unsigned NOT NULL, + `service_offering_id` bigint unsigned NOT NULL, + `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', + `created` datetime NOT NULL COMMENT 'date created', + `removed` datetime COMMENT 'date removed if not null', + PRIMARY KEY (`id`), + CONSTRAINT `fk_autoscale_vmprofiles__domain_id` FOREIGN KEY `fk_autoscale_vmprofiles__domain_id` (`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_autoscale_vmprofiles__account_id` FOREIGN KEY `fk_autoscale_vmprofiles__account_id` (`account_id`) REFERENCES `account`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_autoscale_vmprofiles__autoscale_user_id` FOREIGN KEY `fk_autoscale_vmprofiles__autoscale_user_id` (`autoscale_user_id`) REFERENCES `user`(`id`) ON DELETE CASCADE, + CONSTRAINT `uc_autoscale_vmprofiles__uuid` UNIQUE (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`autoscale_policies` ( + `id` bigint unsigned NOT NULL auto_increment, + `uuid` varchar(40), + `domain_id` bigint unsigned NOT NULL, + `account_id` bigint unsigned NOT NULL, + `duration` int unsigned NOT NULL, + `quiet_time` int unsigned NOT NULL, + `action` varchar(15), + `created` datetime NOT NULL COMMENT 'date created', + `removed` datetime COMMENT 'date removed if not null', + PRIMARY KEY (`id`), + CONSTRAINT `fk_autoscale_policies__domain_id` FOREIGN KEY `fk_autoscale_policies__domain_id` (`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_autoscale_policies__account_id` FOREIGN KEY `fk_autoscale_policies__account_id` (`account_id`) REFERENCES `account`(`id`) ON DELETE CASCADE, + CONSTRAINT `uc_autoscale_policies__uuid` UNIQUE (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`autoscale_vmgroups` ( + `id` bigint unsigned NOT NULL auto_increment, + `uuid` varchar(40), + `zone_id` bigint unsigned NOT NULL, + `domain_id` bigint unsigned NOT NULL, + `account_id` bigint unsigned NOT NULL, + `load_balancer_id` bigint unsigned NOT NULL, + `min_members` int unsigned DEFAULT 1, + `max_members` int unsigned NOT NULL, + `member_port` int unsigned NOT NULL, + `interval` int unsigned NOT NULL, + `profile_id` bigint unsigned NOT NULL, + `state` varchar(255) NOT NULL COMMENT 'enabled or disabled, a vmgroup is disabled to stop autoscaling activity', + `created` datetime NOT NULL COMMENT 'date created', + `removed` datetime COMMENT 'date removed if not null', + PRIMARY KEY (`id`), + CONSTRAINT `fk_autoscale_vmgroup__autoscale_vmprofile_id` FOREIGN KEY(`profile_id`) REFERENCES `autoscale_vmprofiles`(`id`), + CONSTRAINT `fk_autoscale_vmgroup__load_balancer_id` FOREIGN KEY(`load_balancer_id`) REFERENCES `load_balancing_rules`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_autoscale_vmgroups__domain_id` FOREIGN KEY `fk_autoscale_vmgroups__domain_id` (`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_autoscale_vmgroups__account_id` FOREIGN KEY `fk_autoscale_vmgroups__account_id` (`account_id`) REFERENCES `account`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_autoscale_vmgroups__zone_id` FOREIGN KEY `fk_autoscale_vmgroups__zone_id`(`zone_id`) REFERENCES `data_center`(`id`), + CONSTRAINT `uc_autoscale_vmgroups__uuid` UNIQUE (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`autoscale_policy_condition_map` ( + `id` bigint unsigned NOT NULL auto_increment, + `policy_id` bigint unsigned NOT NULL, + `condition_id` bigint unsigned NOT NULL, + PRIMARY KEY (`id`), + CONSTRAINT `fk_autoscale_policy_condition_map__policy_id` FOREIGN KEY `fk_autoscale_policy_condition_map__policy_id` (`policy_id`) REFERENCES `autoscale_policies` (`id`) ON DELETE CASCADE, + CONSTRAINT `fk_autoscale_policy_condition_map__condition_id` FOREIGN KEY `fk_autoscale_policy_condition_map__condition_id` (`condition_id`) REFERENCES `conditions` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`autoscale_vmgroup_policy_map` ( + `id` bigint unsigned NOT NULL auto_increment, + `vmgroup_id` bigint unsigned NOT NULL, + `policy_id` bigint unsigned NOT NULL, + PRIMARY KEY (`id`), + CONSTRAINT `fk_autoscale_vmgroup_policy_map__vmgroup_id` FOREIGN KEY `fk_autoscale_vmgroup_policy_map__vmgroup_id` (`vmgroup_id`) REFERENCES `autoscale_vmgroups` (`id`) ON DELETE CASCADE, + CONSTRAINT `fk_autoscale_vmgroup_policy_map__policy_id` FOREIGN KEY `fk_autoscale_vmgroup_policy_map__policy_id` (`policy_id`) REFERENCES `autoscale_policies` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + SET foreign_key_checks = 1; diff --git a/utils/src/com/cloud/utils/net/NetUtils.java b/utils/src/com/cloud/utils/net/NetUtils.java index 13413385125..69de0dca871 100755 --- a/utils/src/com/cloud/utils/net/NetUtils.java +++ b/utils/src/com/cloud/utils/net/NetUtils.java @@ -60,6 +60,12 @@ 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; private final static Random _rand = new Random(System.currentTimeMillis()); public static long createSequenceBasedMacAddress(long macAddress) { @@ -157,7 +163,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){ @@ -167,8 +173,8 @@ public class NetUtils { } line = output.readLine(); } - } catch( Exception e ) { - } + } catch( Exception e ) { + } return null; } else { NetworkInterface nic = null; @@ -913,6 +919,11 @@ public class NetUtils { return (algo.equals("roundrobin") || algo.equals("leastconn") || algo.equals("source")); } + public static boolean isValidAutoScaleAction(String p) { + String action = p.toLowerCase(); + return (action.equals("scaleup") || action.equals("scaledown")); + } + public static String getLinkLocalNetMask() { return "255.255.0.0"; } @@ -1056,7 +1067,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; }